diff --git a/experiences/asteroids/config.json b/experiences/asteroids/config.json new file mode 100644 index 0000000..d0a64e1 --- /dev/null +++ b/experiences/asteroids/config.json @@ -0,0 +1,10 @@ +{ + "id": "asteroids", + "type": "web", + "title": "Asteroid Tracking", + "description": "A NASA simulation of all tracked asteroids in the solar system", + "action_hints": ["Find a planet", "Take a tour", "Fly through the solar system"], + "layout": "full", + "lifetime": 180, + "queueable": false +} diff --git a/experiences/asteroids/controls/lib/AsteroidWatch.tsx b/experiences/asteroids/controls/lib/AsteroidWatch.tsx new file mode 100644 index 0000000..4d4f342 --- /dev/null +++ b/experiences/asteroids/controls/lib/AsteroidWatch.tsx @@ -0,0 +1,44 @@ +import { useMessaging } from "@footron/controls-client"; +import { Box, Button } from "@mui/material"; +import { thinWidgetStyle, topUI, fullUIStyle } from "./style"; +import StandardBottomUi from "./standardBottomUi"; + +export default function AsteroidWatch() { + const { sendMessage } = useMessaging(); + + const prev = async () => { + sendMessage({ type: "watch", value: "previous" }); + }; + + const next = async () => { + sendMessage({ type: "watch", value: "next" }); + }; + + return ( +
+ +

Select the next close approach

+
+ + + + + + +
+ ); +} diff --git a/experiences/asteroids/controls/lib/FlyTo.tsx b/experiences/asteroids/controls/lib/FlyTo.tsx new file mode 100644 index 0000000..9292962 --- /dev/null +++ b/experiences/asteroids/controls/lib/FlyTo.tsx @@ -0,0 +1,156 @@ +import React, { useCallback, useState } from "react"; +import { + ClickAwayListener, + Backdrop, + IconButton, +} from "@mui/material"; +import { + Select, + MenuItem, + FormControl, + InputLabel, + Box, + Button, +} from "@material-ui/core" +import { useMessaging } from "@footron/controls-client"; +import { flyTargets } from "./flytargets"; +import { definitionHeaderStyle, overlayMenuStyle, fullSizeStyle, + halfWidthStyle, overlayStyle, standardContainerStyle, thinBottomWidgetStyle } from "./style"; +import { Close } from "@material-ui/icons"; + +interface DefinitionOverlayProps { + definition: string; +} + +export default function FlyTo() { + const [selectedCategory, setSelectedCategory] = useState(""); + const [selectedTarget, setSelectedTarget] = useState(""); + const [menuOpen, setMenuOpen] = useState(false); + const [infoText, setInfoText] = useState(""); + const [infoTitle, setInfoTitle] = useState(""); + const { sendMessage } = useMessaging((message: any) => { + console.log("Incoming info: ", message); + if (message.title != null && message.content != null) { + setInfoText(message.content); + setInfoTitle(message.title); + } + }); + + const handleCategoryChange = ( + event: React.ChangeEvent<{ value: unknown }> + ) => { + const category = event.target.value as string; + setSelectedCategory(category); + setSelectedTarget(flyTargets[category][0]); + setInfoText(""); + setInfoTitle(""); + console.log("Reset"); + }; + const handleTargetChange = (event: React.ChangeEvent<{ value: unknown }>) => { + setSelectedTarget(event.target.value as string); + setInfoText(""); + setInfoTitle(""); + }; + + const getInfoText = useCallback( + async (target) => { + await sendMessage({ type: "fly", value: target }); + }, + [sendMessage] + ); + + const handleClickAwaySettings = (event: MouseEvent | TouchEvent) => { + event.preventDefault(); + event.stopPropagation(); + setMenuOpen(false); + }; + + const DefinitionOverlay: React.FC = ({ + definition, + }) => { + return ( + + + +

{infoTitle}

+ { + setMenuOpen(false); + setInfoText(""); + setInfoTitle(""); + console.log(infoText, infoTitle) + }}> + + +
+ +
+ ); + }; + + return ( + + {menuOpen ? ( + + + + + + + + ) : null} +

Fly to somewhere in space

+ + + Select Category + + + + + + Select Destination + + + + + {selectedTarget ? ( + + ) : ( + null + )} + + {(infoText != "") && + + } +
+ ); +} diff --git a/experiences/asteroids/controls/lib/Info.tsx b/experiences/asteroids/controls/lib/Info.tsx new file mode 100644 index 0000000..dfd260d --- /dev/null +++ b/experiences/asteroids/controls/lib/Info.tsx @@ -0,0 +1,501 @@ +import React, { ReactNode, useState } from "react"; +import { + Box, + Pagination, + Backdrop, + ClickAwayListener, + Link, + Button, +} from "@mui/material"; +import { Divider, IconButton } from "@material-ui/core"; +import { Close } from "@material-ui/icons"; +import { + overlayMenuWrapperStyle, + overlayStyle, + fullUIStyle, + standardBottomUiStyle, + topUI, + paginationStyle, + overlayMenuHeaderStyle, + overlayMenuStyle, + definitionListStyle, +} from "./style"; + +interface InfoObject { + [key: string]: definitionObject; +} +interface definitionObject { + title: string; + description: ReactNode; + relatedTerms: string[]; +} + +interface DefinitionOverlayProps { + definition: string; +} + +export default function Info() { + const [currentPage, setCurrentPage] = useState(1); + const [currentDefinition, setCurrentDefinition] = useState("asteroid"); + const [menuOpen, setMenuOpen] = useState(false); + + const openDef = (word: string) => { + setCurrentDefinition(word); + setMenuOpen(true); + }; + + const pages = [ +
+

+ Welcome to +
+ Eyes on Asteroids! +

+

+ You are looking at a real-time visualization of every known{" "} + openDef("asteroid")}> + asteroid + {" "} + or{" "} + openDef("comet")}> + comet + {" "} + that is classified as a{" "} + openDef("neo")}> + Near-Earth Object (NEO) + + . +
+ With asteroids represented as blue points, and comets as white points, + our database is updated daily to give you approximately 36,000 NEOs (and + counting). Additionally, you can explore most of NASA's asteroid and + comet missions (past and present), from Galileo, to Lucy and DART. +

+
+
Extra fact:
+

+ Farther from Earth, the full asteroid belt contains over a million + members, with the majority lying between Mars and Jupiter. +

+
+
, +
+

+ From 1990 to 2033 +
+ You Control Time. +

+

+ Drag the time slider left to go backwards, or right to go forwards in + time. The LIVE button will always return you to the present time. +

+
, +
+

Learn with the footron

+

+ Select 'Learn' to access three different stories about asteroids and + comets, including a tour through NASA's historic missions. +

+
, +
+

Keep an Eye Out!

+

+ Select the 'Watch' option to see the next five closest approaches to + Earth, complete with a countdown. +

+
+
Hint:
+

Don't forget to play with that time slider!

+
+
, +
+

Fine Tuning

+

+ Use the settings menu to toggle display layers, set filters, or change + the lighting when the sun is not enough. +

+

+ toggle the filters to see just the comets, or just the asteroids, or + just the{" "} + openDef("pho")}> + Potentially Hazardous Objects (PHOs) + + . +

+
+
Just in case:
+

The info tab will take you back here if you ever need a recap.

+
+
, +
+

Dare Mighty Things

+

+ You are now armed with all the knowledge to explore Eyes on Asteroids + like a pro. Happy Learning! +

+
+
Learning can be addictive!
+

+ Watch out for any links; they may lead you down a rabbit hole of space + knowledge... +

+
+
, +
+

Thank You

+

for engaging with this experience

+

+ This experience was ported by Christian Price to the Footron from the + original NASA website{" "} + Eyes on Asteroids. +

+

I hope you enjoyed it!

+

+ The data used to generate this visualization is from the{" "} + + Center for Near-Earth Object Studies + {" "} + and JPL's{" "} + + Solar System Dynamics + {" "} + website. Visit the{" "} + + Planetary Defense Coordination Office + {" "} + for more information on how NASA monitors for potentially hazardous + asteroids and comets. +

+
+ One last secret: +
+ + I wonder what would happen if you spun the joysticks counterclockwise? + +
+ -Christian +
, + ]; + + const definitions: InfoObject = { + asteroid: { + title: "Asteroid", + description: ( +
+

+ Sometimes called minor planets, asteroids are rocky, airless + remnants left over from the early formation of our solar system + about 4.6 billion years ago. +

+

+ Most of this ancient space rubble can be found orbiting the Sun + between Mars and Jupiter within the main asteroid belt. +

+

+ Unlike{" "} + openDef("comet")}> + comets + + , asteroids remain solid under extreme temperatures; this is due to + their formation in the high heat, high density center of the solar + nebula. +

+

+ Learn more by starting the Asteroids 101 deep dive in the learn tab +

+
+ ), + relatedTerms: ["comet"], + }, + comet: { + title: "Comet", + description: ( +
+

+ Comets are frozen leftovers from the formation of the solar system + composed of dust, rock, and ice. They range from a few kilometers, + to hundreds of kilometers wide. +

+

+ As they orbit closer to the Sun, they heat up and spew gases and + dust into a glowing head that can be larger than a planet. This + material forms a tail that stretches millions of kilometers. +

+

+ Unlike{" "} + openDef("asteroid")}> + asteroids + + , comets formed in areas of the solar nebula where it was cold + enough for water and gases to freeze. Consequently, they are larger + and rarer than asteroids, and tend to originate in the far reaches + of the solar system. +

+
+ ), + relatedTerms: ["asteroid"], + }, + neo: { + title: "Near Earth Object (NEO)", + description: ( +
+

+ {" "} + A near-Earth object is any small solar system body whose orbit + brings it within a certain distance of Earth. This distance is + defined by having the closest approach to the sun, the{" "} + openDef("perihelion")}> + perihelion + + , be within 1.3{" "} + openDef("au")}> + AU + +

+

+ A sub-category of the NEO is the{" "} + openDef("pho")}> + PHO + + . +

+
+ ), + relatedTerms: ["perihelion", "pho", "au"], + }, + perihelion: { + title: "Perihelion", + description: ( +
+

+ The perihelion is the point in the orbit of an object at which it is + closest to the sun.{" "} +

+

+ The opposite case is called the{" "} + openDef("aphelion")}> + aphelion + + . +

+
+ ), + relatedTerms: ["aphelion"], + }, + aphelion: { + title: "Aphelion", + description: ( +
+

+ The aphelion is the point in the orbit of an object at which it is + farthest from the sun. +

+

+ The opposite case is called the{" "} + openDef("perihelion")}> + perihelion + + . +

+
+ ), + relatedTerms: ["perihelion"], + }, + au: { + title: "Astronomical Unit (AU)", + description: ( +
+

+ An AU is defined as exactly 92,955,807.273 miles (149,597,871 + kilometers), or roughly the distance between the Earth and the Sun. +

+

+ Jupiter orbits at about 5.2 times the Sun-Earth distance, so + Jupiter’s distance from the Sun can be expressed as 5.2 AU. +

+

+ 1 AU is equivalent to 389,174{" "} + openDef("ld")}> + LD + + s. +

+
+ ), + relatedTerms: ["moid", "ld"], + }, + ld: { + title: "Lunar Distance (LD)", + description: ( +
+

+ A lunar distance is defined exactly as 384,398 kilometers (238,854 + miles); the average distance between the centers of the Earth and + the Moon. +

+

+ More technically, it's the length of the semi-major axis of the + geocentric lunar orbit. +

+

+ 1 LD is equivalent to about 0.00257{" "} + openDef("au")}> + AU + + . +

+
+ ), + relatedTerms: ["au"], + }, + moid: { + title: "Minimum Orbit Intersection Distance (MOID)", + description: ( +
+

+ The MOID is the minimum distance between the orbits of two objects. + It indicates the closest possible approach of two objects to each + other. +

+

+ For Earth, an object with a MOID of less than or equal to 0.05{" "} + openDef("au")}> + AU + {" "} + is considered a possible{" "} + openDef("pho")}> + Potentially Hazardous Object + {" "} + if it's large enough. +

+
+ ), + relatedTerms: ["au", "pho"], + }, + pho: { + title: "Potentially Hazardous Object (PHO)", + description: ( +
+

To be defined as potentially hazardous, an object must be:

+
    +
  • + Larger than 150 meters (almost 500 feet), roughly twice as big as + the Statue of Liberty is tall. +
  • +
  • + Approach Earth's orbit to within about 7.5 million kilometers (4.6 + million miles). This can also be expressed as having a{" "} + openDef("moid")}> + MOID + {" "} + of less than 0.05{" "} + openDef("au")}> + AU + {" "} + (within 19.5{" "} + openDef("ld")}> + LD + + s). +
  • +
+

+ PHOs can be both{" "} + openDef("asteroid")}> + asteroids + {" "} + and{" "} + openDef("comet")}> + comets + + , but the vast majority are asteroids. Learn more about the PHO, + Apophis by starting the Close Approaches deep dive in the learn tab. +

+
+ ), + relatedTerms: ["asteroid", "comet", "moid", "au", "ld"], + }, + }; + + const handlePageChange = ( + _event: React.ChangeEvent, + page: number + ) => { + setCurrentPage(page); + }; + + const handleClickAwaySettings = (event: MouseEvent | TouchEvent) => { + event.preventDefault(); + event.stopPropagation(); + setMenuOpen(false); + console.log("Clicked away"); + }; + + const ButtonList: React.FC<{ items: string[] }> = ({ items }) => { + return ( +
+ {items.map((item, index) => ( + + ))} +
+ ); + }; + + const DefinitionOverlay: React.FC = ({ + definition, + }) => { + return ( + + + +

{definitions[definition].title}

+ setMenuOpen(false)}> + + +
+ {definitions[definition].description} + +
RELATED TERMS
+ +
+ ); + }; + + return ( + + {menuOpen ? ( + + + + + + + + ) : null} + {pages[currentPage - 1]} + + + + + ); +} diff --git a/experiences/asteroids/controls/lib/Learn.tsx b/experiences/asteroids/controls/lib/Learn.tsx new file mode 100644 index 0000000..505f049 --- /dev/null +++ b/experiences/asteroids/controls/lib/Learn.tsx @@ -0,0 +1,166 @@ +import { Box, Button, Fab } from "@material-ui/core"; +import { useMessaging } from "@footron/controls-client"; +import ReplayIcon from "@mui/icons-material/Replay"; +import { IconButton } from "@mui/material"; +import { + fabStyle, + fullUIStyle, + largeIconStyle, + storyBoxStyle, + thinWidgetStyle, + topUI, +} from "./style"; +import { useCallback, useState } from "react"; +import { Close } from "@mui/icons-material"; +import StandardBottomUi from "./standardBottomUi"; +import { SkipPrevious } from "@material-ui/icons"; + +const dummyText = "Loading"; + +export default function Learn() { + const [slideshowPlaying, setSlideShowPlaying] = useState(false); + const [slideshowTitle, setSlideShowTitle] = useState("No title provided"); + const [progressString, setProgressString] = useState(`[0 of 0]`); + const [showReplay, setShowReplay] = useState(false); + const [prevSlide, setPrevSlide] = useState(false); + const [nextSlide, setNextSlide] = useState(false); + const [infoText, setInfoText] = useState(dummyText); + const { sendMessage } = useMessaging((content: any) => { + if (content.type != "slideInfo") return; + content = content.slideInfo; + console.log("Incoming info: ", content); + if (content.title != null) setSlideShowTitle(content.title); + if (content.storyLength != null && content.index != null) + setProgressString(`[${content.index} of ${content.storyLength}]`); + if (content == undefined) content = { info: "Error loading info" }; + if (content.replay != null) setShowReplay(true); + else setShowReplay(false); + setInfoText(content.info); + setPrevSlide(!content.prevSlideButton); // not disabled + setNextSlide(!content.nextSlideButton); + console.log(prevSlide, nextSlide); + }); + const getInfoText = useCallback( + async (value) => { + await sendMessage({ type: "learn", value: value }); + }, + [sendMessage] + ); + + const prev = async () => { + getInfoText("previous"); + }; + + const next = async () => { + getInfoText("next"); + }; + + const first = async () => { + getInfoText("first"); + }; + + const replay = () => { + sendMessage({ type: "learn", value: "replay" }); + }; + + const close = async () => { + setSlideShowPlaying(false); + sendMessage({ type: "context", value: "home" }); + }; + + const startShow = async (value: string) => { + setSlideShowPlaying(true); + getInfoText(value); + }; + + return ( + + {slideshowPlaying ? ( + + + + + + +

{slideshowTitle}

+
{progressString}
+
+
+
+ + + {nextSlide && ( + + + + )} + + + {showReplay && ( + + + + )} + + +
+ ) : ( + +

Deep dives

+

Take a deeper dive into Asteroids with our interactive stories

+ + +

What are asteroids?

+

What does this experience show me?

+
+ + +

What is a close approach?

+

Are we in danger of impact?

+
+ + +

Can we visit an asteroid

+

What can missions achieve?

+
+
+ )} +
+ ); +} diff --git a/experiences/asteroids/controls/lib/Movement.tsx b/experiences/asteroids/controls/lib/Movement.tsx new file mode 100644 index 0000000..311b31e --- /dev/null +++ b/experiences/asteroids/controls/lib/Movement.tsx @@ -0,0 +1,119 @@ +import { Box } from "@material-ui/core"; +import { useMessaging } from "@footron/controls-client"; +import { + joystickStyle, + movementComponentStyle, + helpMessageStyle, +} from "./style"; +import { Joystick, JoystickShape } from "react-joystick-component"; +import { IJoystickUpdateEvent } from "react-joystick-component/build/lib/Joystick"; +import { useEffect, useState } from "react"; + +interface TabPanelProps { + children?: React.ReactNode; + move: (event: IJoystickUpdateEvent) => void; + stop: () => void; +} + +function CustomJoystick(props: TabPanelProps) { + const { children, move, stop, ...other } = props; + return ( + + ); +} + +export default function MovementControls() { + const [helpUi, setHelpUi] = useState(true); + const [controlOption, setControlOption] = useState("standard"); + const [stateMachine, setStateMachine] = useState([0, 0]) + const { sendMessage } = useMessaging(); + const stateMachinePattern = ['FORWARD', 'LEFT', 'BACKWARD', 'RIGHT', 'FORWARD', 'LEFT', 'BACKWARD', 'RIGHT'] + + useEffect(() => { + const timer = setTimeout(() => { + setHelpUi(false); + }, 5000); // Adjust time as needed + + // Clean up the timer when the component unmounts + return () => clearTimeout(timer); + }, []); + + const toggleFlyMode = () => { + if (controlOption == "standard") setControlOption("freefly"); + else setControlOption("standard"); + + + } + + const updateStateMachine = (machineIndex: number, direction: string | null) => { + if (direction == stateMachinePattern[stateMachine[machineIndex] % stateMachinePattern.length]) { + stateMachine[machineIndex]++; + } + else if (stateMachine[machineIndex] > 0 && direction != stateMachinePattern[(stateMachine[machineIndex] - 1) % stateMachinePattern.length]) { + setStateMachine([0, 0]); + } + if (stateMachine.every((value) => value >= stateMachinePattern.length)) { + toggleFlyMode() + setStateMachine(stateMachine.fill(0)); + } + } + + const leftStickMove = (event: IJoystickUpdateEvent) => { + updateStateMachine(0, event.direction) + if (helpUi) setHelpUi(false); + if (controlOption == "standard") { + sendMessage({ type: "move", yaw: event.x, pitch: event.y }); + } else { + sendMessage({ type: "move", xAngleDv: event.x, yAngleDv: event.y }) + } + }; + + const rightStickMove = (event: IJoystickUpdateEvent) => { + updateStateMachine(1, event.direction) + if (helpUi) setHelpUi(false); + if (controlOption == "standard") { + let invertedZoom = null; + if (event.y) invertedZoom = event.y * -1; + sendMessage({ type: "move", roll: event.x, zoom: invertedZoom }); + } else { + sendMessage({ type: "move", zAngleDv: event.x, velocity: event.y }) + } + }; + + const leftStickStop = () => { + if (controlOption == "standard") { + sendMessage({ type: "move", yaw: 0, pitch: 0 }); + } else { + sendMessage({ type: "move", xAngleDv: 0, yAngleDv: 0 }) + } + }; + + const rightStickStop = () => { + if (controlOption == "standard") { + sendMessage({ type: "move", roll: 0, zoom: 0 }); + } else { + sendMessage({ type: "move", zAngleDv: 0, velocity: 0 }) + } + }; + + return ( + + + + + + {controlOption == "standard" ? (Move the camera) : (Expert freefly mode)} + + + + + + ); +} diff --git a/experiences/asteroids/controls/lib/SettingsMenu.tsx b/experiences/asteroids/controls/lib/SettingsMenu.tsx new file mode 100644 index 0000000..b6413f9 --- /dev/null +++ b/experiences/asteroids/controls/lib/SettingsMenu.tsx @@ -0,0 +1,278 @@ +import React, { useEffect, useState } from "react"; +import { + Box, + IconButton, + List, + ListItem, + ListItemIcon, + ListItemText, + Switch, +} from "@mui/material"; +import { + AsteroidIcon, + CometIcon, + ShadowLightingIcon, + OrbitIcon, + PlanetIcon, + NaturalLightingIcon, + FloodLightingIcon, + ConstellationIcon, +} from "./icons"; +import { + AutoAwesome, + Label, + Settings, + Radar, + SatelliteAlt, +} from "@mui/icons-material"; + +import { useMessaging } from "@footron/controls-client"; +import { + overlayMenuHeaderStyle, + overlayMenuStyle, + overlaySettingsMenuStyle, +} from "./style"; +import { Close } from "@material-ui/icons"; +import { Button } from "@material-ui/core"; + +interface Props { + toggle: boolean; + onToggle: () => void; +} + +export default function SettingsMenu({ toggle, onToggle }: Props) { + const [menuOpen, setMenuOpen] = useState(false); + const { sendMessage } = useMessaging(); + const [state, setState] = useState({ + asteroidsFilter: false, + cometsFilter: false, + phosFilter: false, + }); + const [lighting, setLighting] = useState("none"); + + useEffect(() => { + setMenuOpen(toggle); + }, [toggle]); + + const handleChange = (event: React.ChangeEvent) => { + sendMessage({ + type: "settings", + setting: event.target.name, + value: event.target.checked, + }); + setState({ + ...state, + [event.target.name]: event.target.checked, + }); + }; + + const toggleButton = (setting: string) => { + sendMessage({ + type: "settings", + setting: setting, + }); + }; + + const handleLightingChange = (event: React.ChangeEvent) => { + sendMessage({ + type: "settings", + setting: "lighting", + value: event.target.name, + }); + setLighting(event.target.name as string); + }; + + return ( + + + +

Settings

+ + + +
+ +
Filters
+ + + + + + + + + + + + + + + + + + + + + +
Lighting
+ + + + + + + + + + + + + + + + + + + + + +
Layers
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ ); +} diff --git a/experiences/asteroids/controls/lib/attributions b/experiences/asteroids/controls/lib/attributions new file mode 100644 index 0000000..49c65dc --- /dev/null +++ b/experiences/asteroids/controls/lib/attributions @@ -0,0 +1,3 @@ +Star icons created by flatart_icons - Flaticon +Orbit icons created by Freepik - Flaticon +Saturn icons created by droy gambar - Flaticon \ No newline at end of file diff --git a/experiences/asteroids/controls/lib/flyTo.tsx b/experiences/asteroids/controls/lib/flyTo.tsx new file mode 100644 index 0000000..e0eaa08 --- /dev/null +++ b/experiences/asteroids/controls/lib/flyTo.tsx @@ -0,0 +1,343 @@ +import React, { useCallback, useState } from "react"; +import { + ClickAwayListener, + Backdrop, + IconButton, + Divider, +} from "@mui/material"; +import { + Select, + MenuItem, + FormControl, + InputLabel, + Box, + Button, +} from "@material-ui/core"; +import { useMessaging } from "@footron/controls-client"; +import { + flyCategories, + flyTargets, + sortedFlyTargets, + targetToId, +} from "./flytargets"; +import { + overlayMenuWrapperStyle, + fullSizeStyle, + topUI, + overlayMenuHeaderStyle, + overlayStyle, + thinWidgetStyle, + fullUIStyle, + definitionListStyle, +} from "./style"; +import { Close } from "@material-ui/icons"; +import StandardBottomUi from "./standardBottomUi"; + +interface DescriptionsProps { + blurb: string[]; + more?: string[]; +} + +interface Content { + title: string; + data: { [key: string]: number }; + description?: DescriptionsProps; + related?: string[]; + approach?: any; + stats?: any; + cards?: any; +} + +interface DescriptionMessageProms { + content?: Content; + title: string; +} + +const addUnit = (dataType: string, value: number) => { + switch (dataType) { + case "radius": + return `${value} km`; + case "volume": + return `${value} km³`; + case "density": + return `${value} g/cm³`; + default: + return value; + } +}; + +export default function FlyTo() { + const emptyDescription: Content = { + title: "None", + related: [], + description: { blurb: [], more: [] }, + data: {}, + }; + const [selectedCategory, setSelectedCategory] = useState(""); + const [selectedTarget, setSelectedTarget] = useState(""); + const [targetInfoID, setTargetInfoID] = useState(""); + const [preselectedTarget, setPreSelectedTarget] = useState(""); + const [menuOpen, setMenuOpen] = useState(false); + const [expandData, setExpandData] = useState(false); + const [infoText, setInfoText] = useState(emptyDescription); + const { sendMessage } = useMessaging((message: DescriptionMessageProms) => { + console.log(message); + if (message.title != null && message.content != null) { + setTargetInfoID(message.title); + setInfoText(message.content); + } + }); + + const handleCategoryChange = ( + event: React.ChangeEvent<{ value: unknown }> + ) => { + const category = event.target.value as string; + setSelectedCategory(category); + setSelectedTarget(flyTargets[category][0]); + setInfoText(emptyDescription); + }; + const handleTargetChange = (event: React.ChangeEvent<{ value: unknown }>) => { + setSelectedTarget(event.target.value as string); + setInfoText(emptyDescription); + }; + + const getInfoText = useCallback( + async (target) => { + await sendMessage({ type: "fly", value: targetToId[target] }); + }, + [sendMessage] + ); + + const clickLink = (target: string) => { + let targetObject = sortedFlyTargets[target]; + let category = ""; + switch (targetObject.type) { + case "system": + category = "Systems"; + break; + case "planet": + category = "Planets"; + break; + case "asteroid": + category = "Asteroids"; + break; + case "comet": + category = "Comets"; + break; + case "spacecraft": + category = "Spacecraft"; + break; + default: + console.error(`target ${target} not found`); + } + setPreSelectedTarget(target); + setMenuOpen(false); + setInfoText(emptyDescription); + getInfoText(targetObject.name); + }; + + const handleClickAwaySettings = (event: MouseEvent | TouchEvent) => { + event.preventDefault(); + event.stopPropagation(); + setMenuOpen(false); + }; + + const ButtonList: React.FC<{ items: string[] }> = ({ items }) => { + let filteredItems = items.filter((item) => sortedFlyTargets[item] != null); + return ( +
+ {filteredItems.map((item, index) => ( + + ))} +
+ ); + }; + + const DefinitionOverlay: React.FC = (content: Content) => { + const dataEntries = content.data + ? Object.entries(content.data).filter( + (element) => element[0] !== "distance" + ) + : []; + const visibleEntries = expandData ? dataEntries : dataEntries.slice(0, 3); + console.log(visibleEntries); + return ( + + + +

{content.title}

+ { + setMenuOpen(false); + setInfoText(emptyDescription); + }} + > + + +
+ {content.description?.blurb != null && ( + + {content.description.blurb.map((item, index) => ( + + ))} + + )} + {content.data && ( + +
+ + + {visibleEntries.map(([key, value]) => ( + + + + + ))} + +
+ {key} + + {": \t"} + {addUnit(key, value)} +
+ {dataEntries.length > 3 && expandData == false && ( + + )} +
+ )} + {content.description?.more != null && ( + + {content.description.more.map((item, index) => ( +

+ ))} +
+ )} + {content.related && content.related.length > 0 && ( + + +
Related
+ +
+ )} +
+
+ ); + }; + + return ( + + {menuOpen ? ( + + + + {infoText.title != "" && infoText.description && ( + + )} + + + + ) : null} + +

Fly to somewhere in space

+ {preselectedTarget ? ( + + +

+ Selected Target: {sortedFlyTargets[preselectedTarget].name} +

{" "} +
+ + + +
+ ) : ( + + + Select Category + + + + Select Destination + + + + )} + + {preselectedTarget == "" && selectedTarget && ( + + )} + + {(infoText.title == selectedTarget || + (sortedFlyTargets[targetInfoID] && + sortedFlyTargets[targetInfoID].name == selectedTarget) || + (sortedFlyTargets[preselectedTarget] && + infoText.title == sortedFlyTargets[preselectedTarget].name)) && ( + + + + )} +
+ +
+ ); +} diff --git a/experiences/asteroids/controls/lib/flytargets.tsx b/experiences/asteroids/controls/lib/flytargets.tsx new file mode 100644 index 0000000..618c970 --- /dev/null +++ b/experiences/asteroids/controls/lib/flytargets.tsx @@ -0,0 +1,1772 @@ +export const flyCategories: string[] = [ + "Systems", + "Planets", + "Moons", + "Asteroids", + "Comets", + "Spacecraft", +]; + +export const flyTargets: { [key: string]: string[] } = { + Systems: [ + "Sun", // Exception + "Inner Solar System", + "Outer Solar System", + "Earth System", + "Mars System", + "Jupiter System", + "Saturn System", + "Uranus System", + "Neptune System", + "Pluto System", + "Patroclus and Menoetius", + "Didymos and Dimorphos", + ], + Planets: [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Saturn", + "Uranus", + "Neptune", + "Ceres", + "Pluto", + "Haumea", + "Eris", + "Makemake", + ], + Moons: [ + "Earth - Moon", + "Mars - Phobos", + "Mars - Deimos", + "Jupiter - Callisto", + "Jupiter - Europa", + "Jupiter - Ganymede", + "Jupiter - Io", + "Saturn - Dione", + "Saturn - Enceladus", + // "Saturn - Hyperion", // Not flying + "Saturn - Iapetus", + "Saturn - Mimas", + "Saturn - Rhea", + "Saturn - Tethys", + "Saturn - Titan", + "Uranus - Ariel", + "Uranus - Miranda", + "Uranus - Oberon", + "Uranus - Titania", + "Uranus - Umbriel", + "Neptune - Triton", + "Pluto - Charon", + "Pluto - Hydra", + "Pluto - Kerberos", + "Pluto - Nix", + "Pluto - Styx", + "Haumea - Hiiaka", + "Haumea - Namaka", + "Ida - Dactyl", + "Didymos - Dimorphos", + "Patroclus - Menoetius", + ], + Asteroids: [ + "Psyche (asteroid)", + "Bennu", + "Leucus", + "Zephyr", + // "Hypnos", + "Polymele", + "Icarus", + // "Geographos", + "Ryugu", + // "Apollo", + // "Midas", + // "1991 vg", + // "1993 hd", + // "1994 cc a", + // "1996 xb27", + // "1998 ky26", + // "1998 ml14", + // "1998 qe2", + // "1999 ao10", + // "1999 cg9", + // "1999 vx25", + // "Pallas", + // "2000 ae205", + // "2000 lg6", + // "2000 sg344", + // "2001 bb16", + // "2001 fr85", + // "2001 gp2", + // "2001 qj142", + // "2001 sn263 a", + // "2003 sm84", + // "2003 uv11", + // "2003 yn107", + // "2005 er95", + // "2005 lc", + // "2005 qp87", + // "2005 yu55", + // "2006 bz147", + // "2006 jy26", + // "2006 qq56", + // "2006 rh120", + // "2006 ub17", + // "2007 tf15", + // "2007 un12", + // "2007 vu6", + // "2008 bt2", + // "2008 cx118", + // "2008 ea9", + // "2008 el", + // "2008 hu4", + // "2008 jl24", + // "2008 kt", + // "2008 tc3", + // "2008 ts10", + // "2008 ua202", + // "2009 bd", + // "2009 os5", + // "2009 rt1", + // "2009 yf", + // "2010 an61", + // "2010 dj", + // "2010 jw34", + // "2010 tg19", + // "2010 tn167", + // "2010 ub", + "Bacchus", + "Lutetia", + // "Adonis", + // "Tantalus", + // "Aristaeus", + // "Kleopatra", + "Orus", + // "2007 or10", + // "Hathor", + "Ida", + "Itokawa", + "Mathilde", + "Steins", + // "Juno", + // "Florence", + // "Phaethon", + // "Khufu", + "Eurybates", + // "Duende", + // "Illapa", + "Vesta", + // "Wilson", + // "Toutatis", + // "Cuno", + "Eros", + // "Pan", + // "Mithra", + // "Castalia", + "Arrokoth", + // "Ptah", + "Donaldjohanson", + "Annefrank", + "Patroclus", + // "Minos", + // "Golevka", + "Didymos", + // "Moshup", + // "Hermes", + "Sedna", + "Gaspra", + "Braille", + "Apophis", + "Dinkinesh", + ], + Comets: [ + "Hartley 2", + "Tempel 1", + "Wild 2", + "Churyumov Gerasimenko", + "Borrelly", + // "Oumuamua", + // "Halley", + // "C 1995 o1", + // "C 2010 x1", + // "C 2012 s1", + // "C 2013 a1", + // "C 2019 y4", + // "C 2020 f3", + ], + Spacecraft: [ + // "Ace", + "Acrimsat", + // "Aim", + // "Apollo 15", + // "Aqua", + "Artemis 1", + // "Ascends", + // "Aura", + "BioSentinel", + "CALIPSO", + "CAPSTONE", + "Cassini", + "Chandra X-ray Observatory", + // "Clarreo", + "Clementine", + "CloudSat", + "Rumba", + "Salsa", + "Samba", + "Tango", + // "C nofs", + // "Cygnss 1", + // "Cygnss 2", + // "Cygnss 3", + // "Cygnss 4", + // "Cygnss 5", + // "Cygnss 6", + // "Cygnss 7", + // "Cygnss 8", + "DART", + "Dawn", + "Deep Impact", + "Deep Impact Impactor", + // "Deep impact_impactor_impact_site", + "Deep Space 1", + // "Dscovr", + "EO-1", + // "Europa clipper", + // "Explorer 1", + // "Face", + // "Fgrst", + // "Gacm", + // "Galex", + "Galileo", + // "Galileo probe", + // "Geo cape", + // "Geotail", + // "Goes 12", + // "Goes 13", + // "Goes 14", + // "Goes 15", + // "Gpm", + "GRACE-1", + "GRACE-2", + "GRACE-FO1", + "GRACE-FO2", + "GRAIL A", + "GRAIL B", + // "Grifex", + "Hubble Space Telescope", + "Huygens", + // "Huygens landing site", + // "Hyspiri", + // "Ibex", + // "Icesat_2", + // "Image", + // "Insight", + // "Insight landing site", + // "Integral", + // "Ipex", + // "Isas", + "International Space Station (ISS)", + // "International Space Station (ISS) ecostress", + // "International Space Station (ISS) emit", + // "International Space Station (ISS) oco_3", + // "International Space Station (ISS) rapidscat", + "IXPE", + // "Jason-1", + "Jason-2", + "Jason-3", + "Juice", + "Juno", + "James Webb Space Telescope", + "Kepler", + // "Ladee", + // "Landsat 5", + // "Landsat 7", + // "Landsat 8", + // "Landsat 9", + "LCROSS", + // "LCROSS impact site", + // "List", + "Lucy", + // "Lunar flashlight", + "Lunar Prospector", + // "Lunar reconnaissance_orbiter", + "Magellan", + "MarCO A", + "MarCO B", + // "Mariner 2", + // "Mars 2020", + // "Mars 2020 landing site", + // "Mars climate orbiter", + // "Mars exploration rover 1", + // "Mars exploration_rover 1 landing site", + // "Mars exploration rover 2", + // "Mars exploration rover 2 landing site", + // "Mars express", + "Mars Global Surveyor", + // "Mars odyssey", + // "Mars orbiter mission", + // "Mars pathfinder", + // "Mars pathfinder landing site", + // "Mars polar lander", + // "Mars reconnaissance orbiter", + // "Mars science laboratory", + // "Mars science laboratory_landing_site", + // "Maven", + // "M cubed", + // "M cubed 2", + "MESSENGER", + // "MESSENGER impact site", + "MMS 1", + "MMS 2", + "MMS 3", + "MMS 4", + "NEAR Shoemaker", + // "NEAR Shoemaker_landing_site", + "New Horizons", + // "Nisar", + // "Noaa 14", + // "Noaa 15", + // "Noaa 16", + // "Noaa 17", + // "Noaa 18", + // "Noaa 19", + // "Nustar", + "OCO-2", + "OSIRIS-APEX (OSIRIS-REx)", + "OSIRIS-REx Sample Return Capsule", + "Parker Solar Probe", + // "Path", + "Philae", + // "Philae_landing_site", + // "Phoenix", + // "Phoenix landing site", + "Pioneer 10", + "Pioneer 11", + // "Polar", + "Psyche (spacecraft)", + // "QuikSCAT", + // "Race", + // "Raincube", + // "Rax 2", + "Van Allen Probe A", + "Van Allen Probe B", + "Rosetta", + // "Rosetta impact site", + // "Sac d", + // "Sclp", + // "Sdo", + "Sentinel-6 Michael Freilich", + // "Smap", + // "Smart 1", + // "Soho", + // "Sorce", + "Spitzer Space Telescope", + "Stardust", + // "Stardust src", + // "Starling 1", + // "Starling 2", + // "Starling 3", + // "Starling 4", + "STEREO ahead", + "STEREO behind", + // "Suomi_npp", + // "Swift", + // "Swot", + // "Tdrs 10", + // "Tdrs 11", + // "Tdrs 12", + // "Tdrs 13", + // "Tdrs 3", + // "Tdrs 5", + // "Tdrs 6", + // "Tdrs 7", + // "Tdrs 8", + // "Tdrs 9", + // "Terra", + // "Tess", + "THEMIS a", + "ARTEMIS P1", + "ARTEMIS P2", + "THEMIS d", + "THEMIS e", + // "Timed", + // "Trace gas orbiter", + // "Trmm", + // "Uars", + "Ulysses", + // "Venus express", + // "Viking 1 lander landing site", + // "Viking 1 orbiter", + // "Viking 2 lander landing site", + // "Viking 2 orbiter", + "Voyager 1", + "Voyager 2", + "WIND", + // "Wise", + // "Wmap", + ], +}; + +export const sortedFlyTargets: { + [key: string]: { name: string; type: string }; +} = { + sun: { name: "Sun", type: "system" }, // Exception. Don't use goToSystem + inner_solar_system: { name: "Inner Solar System", type: "system" }, + outer_solar_system: { name: "Outer Solar System", type: "system" }, + earth_system: { name: "Earth ", type: "system" }, + mars_system: { name: "Mars ", type: "system" }, + jupiter_system: { name: "Jupiter ", type: "system" }, + saturn_system: { name: "Saturn ", type: "system" }, + uranus_system: { name: "Uranus ", type: "system" }, + neptune_system: { name: "Neptune ", type: "system" }, + "134340_pluto_barycenter": { name: "Pluto System", type: "system" }, + "617_patroclus_barycenter": { + name: "Patroclus and Menoetius", + type: "system", + }, + "65803_didymos_system": { name: "Didymos and Dimorphos", type: "system" }, + earth: { name: "Earth", type: "planet" }, + mercury: { name: "Mercury", type: "planet" }, + venus: { name: "Venus", type: "planet" }, + mars: { name: "Mars", type: "planet" }, + jupiter: { name: "Jupiter", type: "planet" }, + saturn: { name: "Saturn", type: "planet" }, + uranus: { name: "Uranus", type: "planet" }, + neptune: { name: "Neptune", type: "planet" }, + "1_ceres": { name: "Ceres", type: "planet" }, + "134340_pluto": { name: "Pluto", type: "planet" }, + "136108_haumea": { name: "Haumea", type: "planet" }, + "136199_eris": { name: "Eris", type: "planet" }, + "136472_makemake": { name: "Makemake", type: "planet" }, + "16_psyche": { name: "Psyche (asteroid)", type: "asteroid" }, + "101955_bennu": { name: "Bennu", type: "asteroid" }, + "11351_leucus": { name: "Leucus", type: "asteroid" }, + "12923_zephyr": { name: "Zephyr", type: "asteroid" }, + "14827_hypnos": { name: "Hypnos", type: "asteroid" }, + "15094_polymele": { name: "Polymele", type: "asteroid" }, + "1566_icarus": { name: "Icarus", type: "asteroid" }, + "1620_geographos": { name: "Geographos", type: "asteroid" }, + "162173_ryugu": { name: "Ryugu", type: "asteroid" }, + "1862_apollo": { name: "Apollo", type: "asteroid" }, + "1981_midas": { name: "Midas", type: "asteroid" }, + "1991_vg": { name: "1991 vg", type: "asteroid" }, + "1993_hd": { name: "1993 hd", type: "asteroid" }, + "1994_cc_a": { name: "1994 cc a", type: "asteroid" }, + "1996_xb27": { name: "1996 xb27", type: "asteroid" }, + "1998_ky26": { name: "1998 ky26", type: "asteroid" }, + "1998_ml14": { name: "1998 ml14", type: "asteroid" }, + "1998_qe2": { name: "1998 qe2", type: "asteroid" }, + "1999_ao10": { name: "1999 ao10", type: "asteroid" }, + "1999_cg9": { name: "1999 cg9", type: "asteroid" }, + "1999_vx25": { name: "1999 vx25", type: "asteroid" }, + "2_pallas": { name: "Pallas", type: "asteroid" }, + "2000_ae205": { name: "2000 ae205", type: "asteroid" }, + "2000_lg6": { name: "2000 lg6", type: "asteroid" }, + "2000_sg344": { name: "2000 sg344", type: "asteroid" }, + "2001_bb16": { name: "2001 bb16", type: "asteroid" }, + "2001_fr85": { name: "2001 fr85", type: "asteroid" }, + "2001_gp2": { name: "2001 gp2", type: "asteroid" }, + "2001_qj142": { name: "2001 qj142", type: "asteroid" }, + "2001_sn263_a": { name: "2001 sn263 a", type: "asteroid" }, + "2003_sm84": { name: "2003 sm84", type: "asteroid" }, + "2003_uv11": { name: "2003 uv11", type: "asteroid" }, + "2003_yn107": { name: "2003 yn107", type: "asteroid" }, + "2005_er95": { name: "2005 er95", type: "asteroid" }, + "2005_lc": { name: "2005 lc", type: "asteroid" }, + "2005_qp87": { name: "2005 qp87", type: "asteroid" }, + "2005_yu55": { name: "2005 yu55", type: "asteroid" }, + "2006_bz147": { name: "2006 bz147", type: "asteroid" }, + "2006_jy26": { name: "2006 jy26", type: "asteroid" }, + "2006_qq56": { name: "2006 qq56", type: "asteroid" }, + "2006_rh120": { name: "2006 rh120", type: "asteroid" }, + "2006_ub17": { name: "2006 ub17", type: "asteroid" }, + "2007_tf15": { name: "2007 tf15", type: "asteroid" }, + "2007_un12": { name: "2007 un12", type: "asteroid" }, + "2007_vu6": { name: "2007 vu6", type: "asteroid" }, + "2008_bt2": { name: "2008 bt2", type: "asteroid" }, + "2008_cx118": { name: "2008 cx118", type: "asteroid" }, + "2008_ea9": { name: "2008 ea9", type: "asteroid" }, + "2008_el": { name: "2008 el", type: "asteroid" }, + "2008_hu4": { name: "2008 hu4", type: "asteroid" }, + "2008_jl24": { name: "2008 jl24", type: "asteroid" }, + "2008_kt": { name: "2008 kt", type: "asteroid" }, + "2008_tc3": { name: "2008 tc3", type: "asteroid" }, + "2008_ts10": { name: "2008 ts10", type: "asteroid" }, + "2008_ua202": { name: "2008 ua202", type: "asteroid" }, + "2009_bd": { name: "2009 bd", type: "asteroid" }, + "2009_os5": { name: "2009 os5", type: "asteroid" }, + "2009_rt1": { name: "2009 rt1", type: "asteroid" }, + "2009_yf": { name: "2009 yf", type: "asteroid" }, + "2010_an61": { name: "2010 an61", type: "asteroid" }, + "2010_dj": { name: "2010 dj", type: "asteroid" }, + "2010_jw34": { name: "2010 jw34", type: "asteroid" }, + "2010_tg19": { name: "2010 tg19", type: "asteroid" }, + "2010_tn167": { name: "2010 tn167", type: "asteroid" }, + "2010_ub": { name: "2010 ub", type: "asteroid" }, + "2063_bacchus": { name: "Bacchus", type: "asteroid" }, + "21_lutetia": { name: "Lutetia", type: "asteroid" }, + "2101_adonis": { name: "Adonis", type: "asteroid" }, + "2102_tantalus": { name: "Tantalus", type: "asteroid" }, + "2135_aristaeus": { name: "Aristaeus", type: "asteroid" }, + "216_kleopatra": { name: "Kleopatra", type: "asteroid" }, + "21900_orus": { name: "Orus", type: "asteroid" }, + "225088_2007_or10": { name: "2007 or10", type: "asteroid" }, + "2340_hathor": { name: "Hathor", type: "asteroid" }, + "243_ida": { name: "Ida", type: "asteroid" }, + "25143_itokawa": { name: "Itokawa", type: "asteroid" }, + "253_mathilde": { name: "Mathilde", type: "asteroid" }, + "2867_steins": { name: "Steins", type: "asteroid" }, + "3_juno": { name: "Juno", type: "asteroid" }, + "3122_florence": { name: "Florence", type: "asteroid" }, + "3200_phaethon": { name: "Phaethon", type: "asteroid" }, + "3362_khufu": { name: "Khufu", type: "asteroid" }, + "3548_eurybates": { name: "Eurybates", type: "asteroid" }, + "367943_duende": { name: "Duende", type: "asteroid" }, + "37655_illapa": { name: "Illapa", type: "asteroid" }, + "4_vesta": { name: "Vesta", type: "asteroid" }, + "4015_wilson-harrington": { name: "Wilson", type: "asteroid" }, + "4179_toutatis": { name: "Toutatis", type: "asteroid" }, + "4183_cuno": { name: "Cuno", type: "asteroid" }, + "433_eros": { name: "Eros", type: "asteroid" }, + "4450_pan": { name: "Pan", type: "asteroid" }, + "4486_mithra": { name: "Mithra", type: "asteroid" }, + "4769_castalia": { name: "Castalia", type: "asteroid" }, + "486958_arrokoth": { name: "Arrokoth", type: "asteroid" }, + "5011_ptah": { name: "Ptah", type: "asteroid" }, + "52246_donaldjohanson": { name: "Donaldjohanson", type: "asteroid" }, + "5535_annefrank": { name: "Annefrank", type: "asteroid" }, + "617_patroclus": { name: "Patroclus", type: "asteroid" }, + "6239_minos": { name: "Minos", type: "asteroid" }, + "6489_golevka": { name: "Golevka", type: "asteroid" }, + "65803_didymos": { name: "Didymos", type: "asteroid" }, + "66391_moshup": { name: "Moshup", type: "asteroid" }, + "69230_hermes": { name: "Hermes", type: "asteroid" }, + "90377_sedna": { name: "Sedna", type: "asteroid" }, + "951_gaspra": { name: "Gaspra", type: "asteroid" }, + "9969_braille": { name: "Braille", type: "asteroid" }, + "99942_apophis": { name: "Apophis", type: "asteroid" }, + "152830_dinkinesh": { name: "Dinkinesh", type: "asteroid" }, + moon: { name: "Earth - Moon", type: "moon" }, + phobos: { name: "Mars - Phobos", type: "moon" }, + deimos: { name: "Mars - Deimos", type: "moon" }, + adrastea: { name: "Jupiter - Adrastea", type: "moon" }, + amalthea: { name: "Jupiter - Amalthea", type: "moon" }, + callisto: { name: "Jupiter - Callisto", type: "moon" }, + europa: { name: "Jupiter - Europa", type: "moon" }, + ganymede: { name: "Jupiter - Ganymede", type: "moon" }, + io: { name: "Jupiter - Io", type: "moon" }, + metis: { name: "Jupiter - Metis", type: "moon" }, + thebe: { name: "Jupiter - Thebe", type: "moon" }, + aitne: { name: "Jupiter - Aitne", type: "moon" }, + ananke: { name: "Jupiter - Ananke", type: "moon" }, + aoede: { name: "Jupiter - Aoede", type: "moon" }, + arche: { name: "Jupiter - Arche", type: "moon" }, + autonoe: { name: "Jupiter - Autonoe", type: "moon" }, + callirrhoe: { name: "Jupiter - Callirrhoe", type: "moon" }, + carme: { name: "Jupiter - Carme", type: "moon" }, + carpo: { name: "Jupiter - Carpo", type: "moon" }, + chaldene: { name: "Jupiter - Chaldene", type: "moon" }, + cyllene: { name: "Jupiter - Cyllene", type: "moon" }, + dia: { name: "Jupiter - Dia", type: "moon" }, + eirene: { name: "Jupiter - Eirene", type: "moon" }, + elara: { name: "Jupiter - Elara", type: "moon" }, + erinome: { name: "Jupiter - Erinome", type: "moon" }, + ersa: { name: "Jupiter - Ersa", type: "moon" }, + euanthe: { name: "Jupiter - Euanthe", type: "moon" }, + eukelade: { name: "Jupiter - Eukelade", type: "moon" }, + eupheme: { name: "Jupiter - Eupheme", type: "moon" }, + euporie: { name: "Jupiter - Euporie", type: "moon" }, + eurydome: { name: "Jupiter - Eurydome", type: "moon" }, + harpalyke: { name: "Jupiter - Harpalyke", type: "moon" }, + hegemone: { name: "Jupiter - Hegemone", type: "moon" }, + helike: { name: "Jupiter - Helike", type: "moon" }, + hermippe: { name: "Jupiter - Hermippe", type: "moon" }, + herse: { name: "Jupiter - Herse", type: "moon" }, + himalia: { name: "Jupiter - Himalia", type: "moon" }, + iocaste: { name: "Jupiter - Iocaste", type: "moon" }, + isonoe: { name: "Jupiter - Isonoe", type: "moon" }, + jupiter_li: { name: "Jupiter - Jupiter LI", type: "moon" }, + jupiter_lii: { name: "Jupiter - Jupiter LII", type: "moon" }, + jupiter_liv: { name: "Jupiter - Jupiter LIV", type: "moon" }, + jupiter_lv: { name: "Jupiter - Jupiter LV", type: "moon" }, + jupiter_lvi: { name: "Jupiter - Jupiter LVI", type: "moon" }, + jupiter_lix: { name: "Jupiter - Jupiter LIX", type: "moon" }, + jupiter_lxi: { name: "Jupiter - Jupiter LXI", type: "moon" }, + jupiter_lxiii: { name: "Jupiter - Jupiter LXIII", type: "moon" }, + jupiter_lxiv: { name: "Jupiter - Jupiter LXIV", type: "moon" }, + jupiter_lxvi: { name: "Jupiter - Jupiter LXVI", type: "moon" }, + jupiter_lxvii: { name: "Jupiter - Jupiter LXVII", type: "moon" }, + jupiter_lxviii: { name: "Jupiter - Jupiter LXVIII", type: "moon" }, + jupiter_lxix: { name: "Jupiter - Jupiter LXIX", type: "moon" }, + jupiter_lxx: { name: "Jupiter - Jupiter LXX", type: "moon" }, + jupiter_lxxii: { name: "Jupiter - Jupiter LXXII", type: "moon" }, + kale: { name: "Jupiter - Kale", type: "moon" }, + kallichore: { name: "Jupiter - Kallichore", type: "moon" }, + kalyke: { name: "Jupiter - Kalyke", type: "moon" }, + kore: { name: "Jupiter - Kore", type: "moon" }, + leda: { name: "Jupiter - Leda", type: "moon" }, + lysithea: { name: "Jupiter - Lysithea", type: "moon" }, + megaclite: { name: "Jupiter - Megaclite", type: "moon" }, + mneme: { name: "Jupiter - Mneme", type: "moon" }, + orthosie: { name: "Jupiter - Orthosie", type: "moon" }, + pandia: { name: "Jupiter - Pandia", type: "moon" }, + pasiphae: { name: "Jupiter - Pasiphae", type: "moon" }, + pasithee: { name: "Jupiter - Pasithee", type: "moon" }, + philophrosyne: { name: "Jupiter - Philophrosyne", type: "moon" }, + praxidike: { name: "Jupiter - Praxidike", type: "moon" }, + s_2003_j_2: { name: "Jupiter - S/2003 J 2", type: "moon" }, + s_2003_j_4: { name: "Jupiter - S/2003 J 4", type: "moon" }, + s_2003_j_9: { name: "Jupiter - S/2003 J 9", type: "moon" }, + s_2003_j_10: { name: "Jupiter - S/2003 J 10", type: "moon" }, + s_2003_j_12: { name: "Jupiter - S/2003 J 12", type: "moon" }, + s_2003_j_16: { name: "Jupiter - S/2003 J 16", type: "moon" }, + s_2003_j_23: { name: "Jupiter - S/2003 J 23", type: "moon" }, + s_2003_j_24: { name: "Jupiter - S/2003 J 24", type: "moon" }, + s_2011_j_3: { name: "Jupiter - S/2011 J 3", type: "moon" }, + s_2016_j_3: { name: "Jupiter - S/2016 J 3", type: "moon" }, + s_2016_j_4: { name: "Jupiter - S/2016 J 4", type: "moon" }, + s_2018_j_2: { name: "Jupiter - S/2018 J 2", type: "moon" }, + s_2018_j_3: { name: "Jupiter - S/2018 J 3", type: "moon" }, + s_2018_j_4: { name: "Jupiter - S/2018 J 4", type: "moon" }, + s_2021_j_1: { name: "Jupiter - S/2021 J 1", type: "moon" }, + s_2021_j_2: { name: "Jupiter - S/2021 J 2", type: "moon" }, + s_2021_j_3: { name: "Jupiter - S/2021 J 3", type: "moon" }, + s_2021_j_4: { name: "Jupiter - S/2021 J 4", type: "moon" }, + s_2021_j_5: { name: "Jupiter - S/2021 J 5", type: "moon" }, + s_2021_j_6: { name: "Jupiter - S/2021 J 6", type: "moon" }, + s_2022_j_1: { name: "Jupiter - S/2022 J 1", type: "moon" }, + s_2022_j_2: { name: "Jupiter - S/2022 J 2", type: "moon" }, + s_2022_j_3: { name: "Jupiter - S/2022 J 3", type: "moon" }, + sinope: { name: "Jupiter - Sinope", type: "moon" }, + sponde: { name: "Jupiter - Sponde", type: "moon" }, + taygete: { name: "Jupiter - Taygete", type: "moon" }, + thelxinoe: { name: "Jupiter - Thelxinoe", type: "moon" }, + themisto: { name: "Jupiter - THEMISto", type: "moon" }, + thyone: { name: "Jupiter - Thyone", type: "moon" }, + valetudo: { name: "Jupiter - Valetudo", type: "moon" }, + dione: { name: "Saturn - Dione", type: "moon" }, + enceladus: { name: "Saturn - Enceladus", type: "moon" }, + hyperion: { name: "Saturn - Hyperion", type: "moon" }, + iapetus: { name: "Saturn - Iapetus", type: "moon" }, + mimas: { name: "Saturn - Mimas", type: "moon" }, + rhea: { name: "Saturn - Rhea", type: "moon" }, + tethys: { name: "Saturn - Tethys", type: "moon" }, + titan: { name: "Saturn - Titan", type: "moon" }, + aegaeon: { name: "Saturn - Aegaeon", type: "moon" }, + aegir: { name: "Saturn - Aegir", type: "moon" }, + albiorix: { name: "Saturn - Albiorix", type: "moon" }, + alvaldi: { name: "Saturn - Alvaldi", type: "moon" }, + angrboda: { name: "Saturn - Angrboda", type: "moon" }, + anthe: { name: "Saturn - Anthe", type: "moon" }, + atlas: { name: "Saturn - Atlas", type: "moon" }, + bebhionn: { name: "Saturn - Bebhionn", type: "moon" }, + beli: { name: "Saturn - Beli", type: "moon" }, + bergelmir: { name: "Saturn - Bergelmir", type: "moon" }, + bestla: { name: "Saturn - Bestla", type: "moon" }, + calypso: { name: "Saturn - Calypso", type: "moon" }, + daphnis: { name: "Saturn - Daphnis", type: "moon" }, + eggther: { name: "Saturn - Eggther", type: "moon" }, + epimetheus: { name: "Saturn - Epimetheus", type: "moon" }, + erriapus: { name: "Saturn - Erriapus", type: "moon" }, + farbauti: { name: "Saturn - Farbauti", type: "moon" }, + fenrir: { name: "Saturn - Fenrir", type: "moon" }, + fornjot: { name: "Saturn - Fornjot", type: "moon" }, + geirrod: { name: "Saturn - Geirrod", type: "moon" }, + gerd: { name: "Saturn - Gerd", type: "moon" }, + greip: { name: "Saturn - Greip", type: "moon" }, + gridr: { name: "Saturn - Gridr", type: "moon" }, + gunnlod: { name: "Saturn - Gunnlod", type: "moon" }, + hati: { name: "Saturn - Hati", type: "moon" }, + helene: { name: "Saturn - Helene", type: "moon" }, + hyrrokkin: { name: "Saturn - Hyrrokkin", type: "moon" }, + ijiraq: { name: "Saturn - Ijiraq", type: "moon" }, + janus: { name: "Saturn - Janus", type: "moon" }, + jarnsaxa: { name: "Saturn - Jarnsaxa", type: "moon" }, + kari: { name: "Saturn - Kari", type: "moon" }, + kiviuq: { name: "Saturn - Kiviuq", type: "moon" }, + loge: { name: "Saturn - Loge", type: "moon" }, + methone: { name: "Saturn - Methone", type: "moon" }, + mundilfari: { name: "Saturn - Mundilfari", type: "moon" }, + narvi: { name: "Saturn - Narvi", type: "moon" }, + paaliaq: { name: "Saturn - Paaliaq", type: "moon" }, + pallene: { name: "Saturn - Pallene", type: "moon" }, + pan: { name: "Saturn - Pan", type: "moon" }, + pandora: { name: "Saturn - Pandora", type: "moon" }, + phoebe: { name: "Saturn - Phoebe", type: "moon" }, + polydeuces: { name: "Saturn - Polydeuces", type: "moon" }, + prometheus: { name: "Saturn - Prometheus", type: "moon" }, + s_2004_s_7: { name: "Saturn - S/2004 S 7", type: "moon" }, + s_2004_s_12: { name: "Saturn - S/2004 S 12", type: "moon" }, + s_2004_s_13: { name: "Saturn - S/2004 S 13", type: "moon" }, + s_2004_s_17: { name: "Saturn - S/2004 S 17", type: "moon" }, + s_2004_s_21: { name: "Saturn - S/2004 S 21", type: "moon" }, + s_2004_s_24: { name: "Saturn - S/2004 S 24", type: "moon" }, + s_2004_s_28: { name: "Saturn - S/2004 S 28", type: "moon" }, + s_2004_s_31: { name: "Saturn - S/2004 S 31", type: "moon" }, + s_2004_s_36: { name: "Saturn - S/2004 S 36", type: "moon" }, + s_2004_s_37: { name: "Saturn - S/2004 S 37", type: "moon" }, + s_2004_s_39: { name: "Saturn - S/2004 S 39", type: "moon" }, + s_2006_s_1: { name: "Saturn - S/2006 S 1", type: "moon" }, + s_2006_s_3: { name: "Saturn - S/2006 S 3", type: "moon" }, + s_2007_s_2: { name: "Saturn - S/2007 S 2", type: "moon" }, + s_2007_s_3: { name: "Saturn - S/2007 S 3", type: "moon" }, + s_2009_s_1: { name: "Saturn - S/2009 S 1", type: "moon" }, + s_2019_s_1: { name: "Saturn - S/2019 S 1", type: "moon" }, + saturn_lviii: { name: "Saturn - Saturn_lviii", type: "moon" }, + saturn_lx: { name: "Saturn - Saturn_lx", type: "moon" }, + saturn_lxiv: { name: "Saturn - Saturn_lxiv", type: "moon" }, + siarnaq: { name: "Saturn - Siarnaq", type: "moon" }, + skathi: { name: "Saturn - Skathi", type: "moon" }, + skoll: { name: "Saturn - Skoll", type: "moon" }, + skrymir: { name: "Saturn - Skrymir", type: "moon" }, + surtur: { name: "Saturn - Surtur", type: "moon" }, + suttungr: { name: "Saturn - Suttungr", type: "moon" }, + tarqeq: { name: "Saturn - Tarqeq", type: "moon" }, + tarvos: { name: "Saturn - Tarvos", type: "moon" }, + telesto: { name: "Saturn - Telesto", type: "moon" }, + thiazzi: { name: "Saturn - Thiazzi", type: "moon" }, + thrymr: { name: "Saturn - Thrymr", type: "moon" }, + ymir: { name: "Saturn - Ymir", type: "moon" }, + s_2004_s_40: { name: "Saturn - S/2004 S 40", type: "moon" }, + s_2004_s_41: { name: "Saturn - S/2004 S 41", type: "moon" }, + s_2004_s_42: { name: "Saturn - S/2004 S 42", type: "moon" }, + s_2004_s_43: { name: "Saturn - S/2004 S 43", type: "moon" }, + s_2004_s_44: { name: "Saturn - S/2004 S 44", type: "moon" }, + s_2004_s_45: { name: "Saturn - S/2004 S 45", type: "moon" }, + s_2004_s_46: { name: "Saturn - S/2004 S 46", type: "moon" }, + s_2004_s_47: { name: "Saturn - S/2004 S 47", type: "moon" }, + s_2004_s_48: { name: "Saturn - S/2004 S 48", type: "moon" }, + s_2004_s_49: { name: "Saturn - S/2004 S 49", type: "moon" }, + s_2004_s_50: { name: "Saturn - S/2004 S 50", type: "moon" }, + s_2004_s_51: { name: "Saturn - S/2004 S 51", type: "moon" }, + s_2004_s_52: { name: "Saturn - S/2004 S 52", type: "moon" }, + s_2004_s_53: { name: "Saturn - S/2004 S 53", type: "moon" }, + s_2005_s_4: { name: "Saturn - S/2005 S 4", type: "moon" }, + s_2005_s_5: { name: "Saturn - S/2005 S 5", type: "moon" }, + s_2006_s_10: { name: "Saturn - S/2006 S 10", type: "moon" }, + s_2006_s_11: { name: "Saturn - S/2006 S 11", type: "moon" }, + s_2006_s_12: { name: "Saturn - S/2006 S 12", type: "moon" }, + s_2006_s_13: { name: "Saturn - S/2006 S 13", type: "moon" }, + s_2006_s_14: { name: "Saturn - S/2006 S 14", type: "moon" }, + s_2006_s_15: { name: "Saturn - S/2006 S 15", type: "moon" }, + s_2006_s_16: { name: "Saturn - S/2006 S 16", type: "moon" }, + s_2006_s_17: { name: "Saturn - S/2006 S 17", type: "moon" }, + s_2006_s_18: { name: "Saturn - S/2006 S 18", type: "moon" }, + s_2006_s_19: { name: "Saturn - S/2006 S 19", type: "moon" }, + s_2006_s_20: { name: "Saturn - S/2006 S 20", type: "moon" }, + s_2006_s_9: { name: "Saturn - S/2006 S 9", type: "moon" }, + s_2007_s_5: { name: "Saturn - S/2007 S 5", type: "moon" }, + s_2007_s_6: { name: "Saturn - S/2007 S 6", type: "moon" }, + s_2007_s_7: { name: "Saturn - S/2007 S 7", type: "moon" }, + s_2007_s_8: { name: "Saturn - S/2007 S 8", type: "moon" }, + s_2007_s_9: { name: "Saturn - S/2007 S 9", type: "moon" }, + s_2019_s_10: { name: "Saturn - S/2019 S 10", type: "moon" }, + s_2019_s_11: { name: "Saturn - S/2019 S 11", type: "moon" }, + s_2019_s_12: { name: "Saturn - S/2019 S 12", type: "moon" }, + s_2019_s_13: { name: "Saturn - S/2019 S 13", type: "moon" }, + s_2019_s_14: { name: "Saturn - S/2019 S 14", type: "moon" }, + s_2019_s_15: { name: "Saturn - S/2019 S 15", type: "moon" }, + s_2019_s_16: { name: "Saturn - S/2019 S 16", type: "moon" }, + s_2019_s_17: { name: "Saturn - S/2019 S 17", type: "moon" }, + s_2019_s_18: { name: "Saturn - S/2019 S 18", type: "moon" }, + s_2019_s_19: { name: "Saturn - S/2019 S 19", type: "moon" }, + s_2019_s_2: { name: "Saturn - S/2019 S 2", type: "moon" }, + s_2019_s_20: { name: "Saturn - S/2019 S 20", type: "moon" }, + s_2019_s_21: { name: "Saturn - S/2019 S 21", type: "moon" }, + s_2019_s_3: { name: "Saturn - S/2019 S 3", type: "moon" }, + s_2019_s_4: { name: "Saturn - S/2019 S 4", type: "moon" }, + s_2019_s_5: { name: "Saturn - S/2019 S 5", type: "moon" }, + s_2019_s_6: { name: "Saturn - S/2019 S 6", type: "moon" }, + s_2019_s_7: { name: "Saturn - S/2019 S 7", type: "moon" }, + s_2019_s_8: { name: "Saturn - S/2019 S 8", type: "moon" }, + s_2019_s_9: { name: "Saturn - S/2019 S 9", type: "moon" }, + s_2020_s_1: { name: "Saturn - S/2020 S 1", type: "moon" }, + s_2020_s_10: { name: "Saturn - S/2020 S 10", type: "moon" }, + s_2020_s_2: { name: "Saturn - S/2020 S 2", type: "moon" }, + s_2020_s_3: { name: "Saturn - S/2020 S 3", type: "moon" }, + s_2020_s_4: { name: "Saturn - S/2020 S 4", type: "moon" }, + s_2020_s_5: { name: "Saturn - S/2020 S 5", type: "moon" }, + s_2020_s_6: { name: "Saturn - S/2020 S 6", type: "moon" }, + s_2020_s_7: { name: "Saturn - S/2020 S 7", type: "moon" }, + s_2020_s_8: { name: "Saturn - S/2020 S 8", type: "moon" }, + s_2020_s_9: { name: "Saturn - S/2020 S 9", type: "moon" }, + ariel: { name: "Uranus - Ariel", type: "moon" }, + miranda: { name: "Uranus - Miranda", type: "moon" }, + oberon: { name: "Uranus - Oberon", type: "moon" }, + titania: { name: "Uranus - Titania", type: "moon" }, + umbriel: { name: "Uranus - Umbriel", type: "moon" }, + belinda: { name: "Uranus - Belinda", type: "moon" }, + bianca: { name: "Uranus - Bianca", type: "moon" }, + caliban: { name: "Uranus - Caliban", type: "moon" }, + cordelia: { name: "Uranus - Cordelia", type: "moon" }, + cressida: { name: "Uranus - Cressida", type: "moon" }, + cupid: { name: "Uranus - Cupid", type: "moon" }, + desdemona: { name: "Uranus - Desdemona", type: "moon" }, + ferdinand: { name: "Uranus - Ferdinand", type: "moon" }, + francisco: { name: "Uranus - Francisco", type: "moon" }, + juliet: { name: "Uranus - Juliet", type: "moon" }, + mab: { name: "Uranus - Mab", type: "moon" }, + margaret: { name: "Uranus - Margaret", type: "moon" }, + ophelia: { name: "Uranus - Ophelia", type: "moon" }, + perdita: { name: "Uranus - Perdita", type: "moon" }, + portia: { name: "Uranus - Portia", type: "moon" }, + prospero: { name: "Uranus - Prospero", type: "moon" }, + puck: { name: "Uranus - Puck", type: "moon" }, + rosalind: { name: "Uranus - Rosalind", type: "moon" }, + setebos: { name: "Uranus - Setebos", type: "moon" }, + stephano: { name: "Uranus - Stephano", type: "moon" }, + sycorax: { name: "Uranus - Sycorax", type: "moon" }, + trinculo: { name: "Uranus - Trinculo", type: "moon" }, + despina: { name: "Neptune - Despina", type: "moon" }, + galatea: { name: "Neptune - Galatea", type: "moon" }, + halimede: { name: "Neptune - Halimede", type: "moon" }, + hippocamp: { name: "Neptune - Hippocamp", type: "moon" }, + laomedeia: { name: "Neptune - Laomedeia", type: "moon" }, + larissa: { name: "Neptune - Larissa", type: "moon" }, + naiad: { name: "Neptune - Naiad", type: "moon" }, + nereid: { name: "Neptune - Nereid", type: "moon" }, + neso: { name: "Neptune - Neso", type: "moon" }, + proteus: { name: "Neptune - Proteus", type: "moon" }, + psamathe: { name: "Neptune - Psamathe", type: "moon" }, + sao: { name: "Neptune - Sao", type: "moon" }, + thalassa: { name: "Neptune - Thalassa", type: "moon" }, + triton: { name: "Neptune - Triton", type: "moon" }, + charon: { name: "Pluto - Charon", type: "moon" }, + hydra: { name: "Pluto - Hydra", type: "moon" }, + kerberos: { name: "Pluto - Kerberos", type: "moon" }, + nix: { name: "Pluto - Nix", type: "moon" }, + styx: { name: "Pluto - Styx", type: "moon" }, + dactyl: { name: "Ida - Dactyl", type: "moon" }, + dimorphos_system: { name: "Didymos and Dimorphos", type: "moon" }, + hiiaka: { name: "Haumea - Hiiaka", type: "moon" }, + namaka: { name: "Haumea - Namaka", type: "moon" }, + menoetius: { name: "Patroclus - Menoetius", type: "moon" }, + "1i_oumuamua": { name: "Oumuamua", type: "comet" }, + "1p_halley": { name: "Halley", type: "comet" }, + "103p_hartley_2": { name: "Hartley 2", type: "comet" }, + "9p_tempel_1": { name: "Tempel 1", type: "comet" }, + "81p_wild_2": { name: "Wild 2", type: "comet" }, + "67p_churyumov_gerasimenko": { name: "Churyumov Gerasimenko", type: "comet" }, + "19p_borrelly": { name: "Borrelly", type: "comet" }, + c_1995_o1: { name: "C 1995 o1", type: "comet" }, + c_2010_x1: { name: "C 2010 x1", type: "comet" }, + c_2012_s1: { name: "C 2012 s1", type: "comet" }, + c_2013_a1: { name: "C 2013 a1", type: "comet" }, + c_2019_y4: { name: "C 2019 y4", type: "comet" }, + c_2020_f3: { name: "C 2020 f3", type: "comet" }, + sc_3d_winds: { name: "3d winds", type: "spacecraft" }, + sc_ace: { name: "Ace", type: "spacecraft" }, + sc_acrimsat: { name: "Acrimsat", type: "spacecraft" }, + sc_aim: { name: "Aim", type: "spacecraft" }, + sc_aqua: { name: "Aqua", type: "spacecraft" }, + sc_ascends: { name: "Ascends", type: "spacecraft" }, + sc_aura: { name: "Aura", type: "spacecraft" }, + sc_c_nofs: { name: "C nofs", type: "spacecraft" }, + sc_calipso: { name: "CALIPSO", type: "spacecraft" }, + sc_chandra: { name: "Chandra X-ray Observatory", type: "spacecraft" }, + sc_clarreo: { name: "Clarreo", type: "spacecraft" }, + sc_cloudsat: { name: "CloudSat", type: "spacecraft" }, + sc_cluster_ii_fm5: { name: "Rumba", type: "spacecraft" }, + sc_cluster_ii_fm6: { name: "Salsa", type: "spacecraft" }, + sc_cluster_ii_fm7: { name: "Samba", type: "spacecraft" }, + sc_cluster_ii_fm8: { name: "Tango", type: "spacecraft" }, + sc_cygnss_1: { name: "Cygnss 1", type: "spacecraft" }, + sc_cygnss_2: { name: "Cygnss 2", type: "spacecraft" }, + sc_cygnss_3: { name: "Cygnss 3", type: "spacecraft" }, + sc_cygnss_4: { name: "Cygnss 4", type: "spacecraft" }, + sc_cygnss_5: { name: "Cygnss 5", type: "spacecraft" }, + sc_cygnss_6: { name: "Cygnss 6", type: "spacecraft" }, + sc_cygnss_7: { name: "Cygnss 7", type: "spacecraft" }, + sc_cygnss_8: { name: "Cygnss 8", type: "spacecraft" }, + sc_dscovr: { name: "Dscovr", type: "spacecraft" }, + sc_eo_1: { name: "EO-1", type: "spacecraft" }, + sc_explorer_1: { name: "Explorer 1", type: "spacecraft" }, + sc_face: { name: "Face", type: "spacecraft" }, + sc_fgrst: { name: "Fgrst", type: "spacecraft" }, + sc_gacm: { name: "Gacm", type: "spacecraft" }, + sc_galex: { name: "Galex", type: "spacecraft" }, + sc_geo_cape: { name: "Geo cape", type: "spacecraft" }, + sc_geotail: { name: "Geotail", type: "spacecraft" }, + sc_goes_12: { name: "Goes 12", type: "spacecraft" }, + sc_goes_13: { name: "Goes 13", type: "spacecraft" }, + sc_goes_14: { name: "Goes 14", type: "spacecraft" }, + sc_goes_15: { name: "Goes 15", type: "spacecraft" }, + sc_gpm: { name: "Gpm", type: "spacecraft" }, + sc_grace_1: { name: "GRACE-1", type: "spacecraft" }, + sc_grace_2: { name: "GRACE-2", type: "spacecraft" }, + sc_grace_fo1: { name: "GRACE-FO1", type: "spacecraft" }, + sc_grace_fo2: { name: "GRACE-FO2", type: "spacecraft" }, + sc_grifex: { name: "Grifex", type: "spacecraft" }, + sc_hubble_space_telescope: { + name: "Hubble Space Telescope", + type: "spacecraft", + }, + sc_hyspiri: { name: "Hyspiri", type: "spacecraft" }, + sc_ibex: { name: "Ibex", type: "spacecraft" }, + sc_icesat_2: { name: "Icesat_2", type: "spacecraft" }, + sc_image: { name: "Image", type: "spacecraft" }, + sc_integral: { name: "Integral", type: "spacecraft" }, + sc_ipex: { name: "Ipex", type: "spacecraft" }, + sc_isas: { name: "Isas", type: "spacecraft" }, + sc_iss: { name: "International Space Station (ISS)", type: "spacecraft" }, + sc_ixpe: { name: "IXPE", type: "spacecraft" }, + sc_jason_1: { name: "Jason-1", type: "spacecraft" }, + sc_jason_2: { name: "Jason-2", type: "spacecraft" }, + sc_jason_3: { name: "Jason-3", type: "spacecraft" }, + sc_juno: { name: "Juno", type: "spacecraft" }, + sc_jwst: { name: "James Webb Space Telescope", type: "spacecraft" }, + sc_landsat_5: { name: "Landsat 5", type: "spacecraft" }, + sc_landsat_7: { name: "Landsat 7", type: "spacecraft" }, + sc_landsat_8: { name: "Landsat 8", type: "spacecraft" }, + sc_landsat_9: { name: "Landsat 9", type: "spacecraft" }, + sc_m_cubed: { name: "M cubed", type: "spacecraft" }, + sc_mcubed_2: { name: "M cubed 2", type: "spacecraft" }, + sc_mms_1: { name: "MMS 1", type: "spacecraft" }, + sc_mms_2: { name: "MMS 2", type: "spacecraft" }, + sc_mms_3: { name: "MMS 3", type: "spacecraft" }, + sc_mms_4: { name: "MMS 4", type: "spacecraft" }, + sc_nisar: { name: "Nisar", type: "spacecraft" }, + sc_noaa_14: { name: "Noaa 14", type: "spacecraft" }, + sc_noaa_15: { name: "Noaa 15", type: "spacecraft" }, + sc_noaa_16: { name: "Noaa 16", type: "spacecraft" }, + sc_noaa_17: { name: "Noaa 17", type: "spacecraft" }, + sc_noaa_18: { name: "Noaa 18", type: "spacecraft" }, + sc_noaa_19: { name: "Noaa 19", type: "spacecraft" }, + sc_nustar: { name: "Nustar", type: "spacecraft" }, + sc_oco_2: { name: "OCO-2", type: "spacecraft" }, + sc_path: { name: "Path", type: "spacecraft" }, + sc_polar: { name: "Polar", type: "spacecraft" }, + sc_psyche: { name: "Psyche (spacecraft)", type: "spacecraft" }, + sc_quikscat: { name: "QuikSCAT", type: "spacecraft" }, + sc_race: { name: "Race", type: "spacecraft" }, + sc_raincube: { name: "Raincube", type: "spacecraft" }, + sc_rax_2: { name: "Rax 2", type: "spacecraft" }, + sc_rbsp_a: { name: "Van Allen Probe A", type: "spacecraft" }, + sc_rbsp_b: { name: "Van Allen Probe B", type: "spacecraft" }, + sc_sac_d: { name: "Sac d", type: "spacecraft" }, + sc_sclp: { name: "Sclp", type: "spacecraft" }, + sc_sdo: { name: "Sdo", type: "spacecraft" }, + sc_sentinel_6: { name: "Sentinel-6 Michael Freilich", type: "spacecraft" }, + sc_smap: { name: "Smap", type: "spacecraft" }, + sc_soho: { name: "Soho", type: "spacecraft" }, + sc_sorce: { name: "Sorce", type: "spacecraft" }, + sc_starling_1: { name: "Starling 1", type: "spacecraft" }, + sc_starling_2: { name: "Starling 2", type: "spacecraft" }, + sc_starling_3: { name: "Starling 3", type: "spacecraft" }, + sc_starling_4: { name: "Starling 4", type: "spacecraft" }, + sc_suomi_npp: { name: "Suomi_npp", type: "spacecraft" }, + sc_swift: { name: "Swift", type: "spacecraft" }, + sc_swot: { name: "Swot", type: "spacecraft" }, + sc_tdrs_3: { name: "Tdrs 3", type: "spacecraft" }, + sc_tdrs_5: { name: "Tdrs 5", type: "spacecraft" }, + sc_tdrs_6: { name: "Tdrs 6", type: "spacecraft" }, + sc_tdrs_7: { name: "Tdrs 7", type: "spacecraft" }, + sc_tdrs_8: { name: "Tdrs 8", type: "spacecraft" }, + sc_tdrs_9: { name: "Tdrs 9", type: "spacecraft" }, + sc_tdrs_10: { name: "Tdrs 10", type: "spacecraft" }, + sc_tdrs_11: { name: "Tdrs 11", type: "spacecraft" }, + sc_tdrs_12: { name: "Tdrs 12", type: "spacecraft" }, + sc_tdrs_13: { name: "Tdrs 13", type: "spacecraft" }, + sc_terra: { name: "Terra", type: "spacecraft" }, + sc_tess: { name: "Tess", type: "spacecraft" }, + sc_themis_a: { name: "THEMIS a", type: "spacecraft" }, + sc_themis_d: { name: "THEMIS d", type: "spacecraft" }, + sc_themis_e: { name: "THEMIS e", type: "spacecraft" }, + sc_timed: { name: "Timed", type: "spacecraft" }, + sc_trmm: { name: "Trmm", type: "spacecraft" }, + sc_uars: { name: "Uars", type: "spacecraft" }, + sc_wind: { name: "WIND", type: "spacecraft" }, + sc_wise: { name: "Wise", type: "spacecraft" }, + sc_apollo_15: { name: "Apollo 15", type: "spacecraft" }, + sc_artemis_1: { name: "Artemis 1", type: "spacecraft" }, + sc_capstone: { name: "CAPSTONE", type: "spacecraft" }, + sc_clementine: { name: "Clementine", type: "spacecraft" }, + sc_grail_a: { name: "GRAIL A", type: "spacecraft" }, + sc_grail_b: { name: "GRAIL B", type: "spacecraft" }, + sc_ladee: { name: "Ladee", type: "spacecraft" }, + sc_lcross: { name: "LCROSS", type: "spacecraft" }, + sc_lcross_impact_site: { name: "LCROSS impact site", type: "spacecraft" }, + sc_lunar_flashlight: { name: "Lunar flashlight", type: "spacecraft" }, + sc_lunar_prospector: { name: "Lunar Prospector", type: "spacecraft" }, + sc_lunar_reconnaissance_orbiter: { + name: "Lunar reconnaissance_orbiter", + type: "spacecraft", + }, + sc_smart_1: { name: "Smart 1", type: "spacecraft" }, + sc_themis_b: { name: "ARTEMIS P1", type: "spacecraft" }, + sc_themis_c: { name: "ARTEMIS P2", type: "spacecraft" }, + sc_mars_2020: { name: "Mars 2020", type: "spacecraft" }, + sc_mars_2020_landing_site: { + name: "Mars 2020 landing site", + type: "spacecraft", + }, + sc_mars_science_laboratory: { + name: "Mars science laboratory", + type: "spacecraft", + }, + sc_mars_science_laboratory_landing_site: { + name: "Mars science laboratory_landing_site", + type: "spacecraft", + }, + sc_insight: { name: "Insight", type: "spacecraft" }, + sc_insight_landing_site: { name: "Insight landing site", type: "spacecraft" }, + sc_marco_a: { name: "MarCO A", type: "spacecraft" }, + sc_marco_b: { name: "MarCO B", type: "spacecraft" }, + sc_mars_odyssey: { name: "Mars odyssey", type: "spacecraft" }, + sc_mars_reconnaissance_orbiter: { + name: "Mars reconnaissance orbiter", + type: "spacecraft", + }, + sc_maven: { name: "Maven", type: "spacecraft" }, + sc_mars_express: { name: "Mars express", type: "spacecraft" }, + sc_phoenix: { name: "Phoenix", type: "spacecraft" }, + sc_phoenix_landing_site: { name: "Phoenix landing site", type: "spacecraft" }, + sc_trace_gas_orbiter: { name: "Trace gas orbiter", type: "spacecraft" }, + sc_mars_orbiter_mission: { name: "Mars orbiter mission", type: "spacecraft" }, + sc_mars_global_surveyor: { name: "Mars Global Surveyor", type: "spacecraft" }, + sc_mars_climate_orbiter: { name: "Mars climate orbiter", type: "spacecraft" }, + sc_mars_pathfinder: { name: "Mars pathfinder", type: "spacecraft" }, + sc_mars_pathfinder_landing_site: { + name: "Mars pathfinder landing site", + type: "spacecraft", + }, + sc_mars_polar_lander: { name: "Mars polar lander", type: "spacecraft" }, + sc_viking_2_orbiter: { name: "Viking 2 orbiter", type: "spacecraft" }, + sc_viking_2_lander_landing_site: { + name: "Viking 2 lander landing site", + type: "spacecraft", + }, + sc_messenger: { name: "MESSENGER", type: "spacecraft" }, + sc_messenger_impact_site: { + name: "MESSENGER impact site", + type: "spacecraft", + }, + sc_cassini: { name: "Cassini", type: "spacecraft" }, + sc_europa_clipper: { name: "Europa clipper", type: "spacecraft" }, + sc_galileo: { name: "Galileo", type: "spacecraft" }, + sc_galileo_probe: { name: "Galileo probe", type: "spacecraft" }, + sc_huygens: { name: "Huygens", type: "spacecraft" }, + sc_huygens_landing_site: { name: "Huygens landing site", type: "spacecraft" }, + sc_juice: { name: "Juice", type: "spacecraft" }, + sc_pioneer_10: { name: "Pioneer 10", type: "spacecraft" }, + sc_pioneer_11: { name: "Pioneer 11", type: "spacecraft" }, + sc_voyager_1: { name: "Voyager 1", type: "spacecraft" }, + sc_voyager_2: { name: "Voyager 2", type: "spacecraft" }, + sc_dart: { name: "DART", type: "spacecraft" }, + sc_dawn: { name: "Dawn", type: "spacecraft" }, + sc_deep_impact: { name: "Deep impact", type: "spacecraft" }, + sc_deep_impact_impactor: { name: "Deep Impact Impactor", type: "spacecraft" }, + sc_deep_impact_impactor_impact_site: { + name: "Deep impact_impactor_impact_site", + type: "spacecraft", + }, + sc_deep_space_1: { name: "Deep Space 1", type: "spacecraft" }, + sc_near_shoemaker: { name: "NEAR Shoemaker", type: "spacecraft" }, + sc_near_shoemaker_landing_site: { + name: "NEAR Shoemaker_landing_site", + type: "spacecraft", + }, + sc_lucy: { name: "Lucy", type: "spacecraft" }, + sc_new_horizons: { name: "New Horizons", type: "spacecraft" }, + sc_rosetta: { name: "Rosetta", type: "spacecraft" }, + sc_rosetta_impact_site: { name: "Rosetta impact site", type: "spacecraft" }, + sc_osiris_rex: { name: "OSIRIS-APEX (OSIRIS-REx)", type: "spacecraft" }, + sc_osiris_rex_src: { name: "OSIRIS-REx Sample Return Capsule", type: "spacecraft" }, + sc_philae: { name: "Philae", type: "spacecraft" }, + sc_philae_landing_site: { name: "Philae_landing_site", type: "spacecraft" }, + sc_biosentinel: { name: "BioSentinel", type: "spacecraft" }, + sc_kepler_space_telescope: { + name: "Kepler", + type: "spacecraft", + }, + sc_mariner_2: { name: "Mariner 2", type: "spacecraft" }, + sc_parker_solar_probe: { name: "Parker Solar Probe", type: "spacecraft" }, + sc_spitzer: { name: "Spitzer Space Telescope", type: "spacecraft" }, + sc_stereo_ahead: { name: "STEREO ahead", type: "spacecraft" }, + sc_stereo_behind: { name: "STEREO behind", type: "spacecraft" }, + sc_ulysses: { name: "Ulysses", type: "spacecraft" }, + sc_wmap: { name: "Wmap", type: "spacecraft" }, + sc_magellan: { name: "Magellan", type: "spacecraft" }, + sc_venus_express: { name: "Venus express", type: "spacecraft" }, +}; + +export const targetToId: { [key: string]: string } = { + //////////////////////////////////////////////////// + // Systems // + //////////////////////////////////////////////////// + Sun: "sun", + "Inner Solar System": "inner_solar_system", + "Outer Solar System": "outer_solar_system", + "Earth System": "earth_system", + "Mars System": "mars_system", + "Jupiter System": "jupiter_system", + "Saturn System": "saturn_system", + "Uranus System": "uranus_system", + "Neptune System": "neptune_system", + "Pluto System": "134340_pluto_barycenter", + "Patroclus and Menoetius": "617_patroclus_barycenter", + "Didymos and Dimorphos": "65803_didymos_system", + //////////////////////////////////////////////////// + // Planets // + //////////////////////////////////////////////////// + Mercury: "mercury", + Venus: "venus", + Earth: "earth", + Mars: "mars", + Jupiter: "jupiter", + Saturn: "saturn", + Uranus: "uranus", + Neptune: "neptune", + //////////////////////////////////////////////////// + // Dwarf Planets // + //////////////////////////////////////////////////// + Ceres: "1_ceres", + Pluto: "134340_pluto", + Haumea: "136108_haumea", + Eris: "136199_eris", + Makemake: "136472_makemake", + //////////////////////////////////////////////////// + // Asteroids // + //////////////////////////////////////////////////// + Bennu: "101955_bennu", + Leucus: "11351_leucus", + Zephyr: "12923_zephyr", // Broken + "Pluto barycenter": "134340_pluto_barycenter", // Broken + Hypnos: "14827_hypnos", // Broken + Polymele: "15094_polymele", + Icarus: "1566_icarus", + "Psyche (asteroid)": "16_psyche", + Geographos: "1620_geographos", + Ryugu: "162173_ryugu", + Apollo: "1862_apollo", + Midas: "1981_midas", + "1991 vg": "1991_vg", + "1993 hd": "1993_hd", + "1994 cc a": "1994_cc_a", + "1996 xb27": "1996_xb27", + "1998 ky26": "1998_ky26", + "1998 ml14": "1998_ml14", + "1998 qe2": "1998_qe2", + "1999 ao10": "1999_ao10", + "1999 cg9": "1999_cg9", + "1999 vx25": "1999_vx25", + Pallas: "2_pallas", + "2000 ae205": "2000_ae205", + "2000 lg6": "2000_lg6", + "2000 sg344": "2000_sg344", + "2001 bb16": "2001_bb16", + "2001 fr85": "2001_fr85", + "2001 gp2": "2001_gp2", + "2001 qj142": "2001_qj142", + "2001 sn263 a": "2001_sn263_a", + "2003 sm84": "2003_sm84", + "2003 uv11": "2003_uv11", + "2003 yn107": "2003_yn107", + "2005 er95": "2005_er95", + "2005 lc": "2005_lc", + "2005 qp87": "2005_qp87", + "2005 yu55": "2005_yu55", + "2006 bz147": "2006_bz147", + "2006 jy26": "2006_jy26", + "2006 qq56": "2006_qq56", + "2006 rh120": "2006_rh120", + "2006 ub17": "2006_ub17", + "2007 tf15": "2007_tf15", + "2007 un12": "2007_un12", + "2007 vu6": "2007_vu6", + "2008 bt2": "2008_bt2", + "2008 cx118": "2008_cx118", + "2008 ea9": "2008_ea9", + "2008 el": "2008_el", + "2008 hu4": "2008_hu4", + "2008 jl24": "2008_jl24", + "2008 kt": "2008_kt", + "2008 tc3": "2008_tc3", + "2008 ts10": "2008_ts10", + "2008 ua202": "2008_ua202", + "2009 bd": "2009_bd", + "2009 os5": "2009_os5", + "2009 rt1": "2009_rt1", + "2009 yf": "2009_yf", + "2010 an61": "2010_an61", + "2010 dj": "2010_dj", + "2010 jw34": "2010_jw34", + "2010 tg19": "2010_tg19", + "2010 tn167": "2010_tn167", + "2010 ub": "2010_ub", + Bacchus: "2063_bacchus", + Lutetia: "21_lutetia", + Adonis: "2101_adonis", + Tantalus: "2102_tantalus", + Aristaeus: "2135_aristaeus", + Kleopatra: "216_kleopatra", + Orus: "21900_orus", + "2007 or10": "225088_2007_or10", + Hathor: "2340_hathor", + Ida: "243_ida", + Itokawa: "25143_itokawa", + Mathilde: "253_mathilde", + Steins: "2867_steins", + "3 Juno": "3_juno", + Florence: "3122_florence", + Phaethon: "3200_phaethon", + Khufu: "3362_khufu", + Eurybates: "3548_eurybates", + Duende: "367943_duende", + Illapa: "37655_illapa", + Vesta: "4_vesta", + Wilson: "4015_wilson-harrington", + Toutatis: "4179_toutatis", + Cuno: "4183_cuno", + Eros: "433_eros", + Pan: "4450_pan", + Mithra: "4486_mithra", + Castalia: "4769_castalia", + Arrokoth: "486958_arrokoth", + Ptah: "5011_ptah", + Donaldjohanson: "52246_donaldjohanson", + Annefrank: "5535_annefrank", + Patroclus: "617_patroclus", + "Patroclus barycenter": "617_patroclus_barycenter", + Minos: "6239_minos", + Golevka: "6489_golevka", + Didymos: "65803_didymos", + Moshup: "66391_moshup", + Hermes: "69230_hermes", + Sedna: "90377_sedna", + Gaspra: "951_gaspra", + Braille: "9969_braille", + Apophis: "99942_apophis", + Dinkinesh: "152830_dinkinesh", + //////////////////////////////////////////////////// + // Moons // + //////////////////////////////////////////////////// + // MISSING MOONS + // Orcus - Vanth + // Quaoar - Weywot + // Makemake - S/2015 + // Gonggong - Xiangliu + // Eris - Dysnomia + "Pluto - Charon": "charon", + "Pluto - Hydra": "hydra", + "Pluto - Kerberos": "kerberos", + "Pluto - Nix": "nix", + "Pluto - Styx": "styx", + "Ida - Dactyl": "dactyl", + "Didymos - Dimorphos": "dimorphos", + "Haumea - Hiiaka": "hiiaka", + "Haumea - Namaka": "namaka", + "Patroclus - Menoetius": "menoetius", + "Earth - Moon": "moon", + "Jupiter - Adrastea": "adrastea", + "Jupiter - Amalthea": "amalthea", + "Jupiter - Callisto": "callisto", + "Jupiter - Europa": "europa", + "Jupiter - Ganymede": "ganymede", + "Jupiter - Io": "io", + "Jupiter - Metis": "metis", + "Jupiter - Thebe": "thebe", + "Jupiter - Aitne": "aitne", + "Jupiter - Ananke": "ananke", + "Jupiter - Aoede": "aoede", + "Jupiter - Arche": "arche", + "Jupiter - Autonoe": "autonoe", + "Jupiter - Callirrhoe": "callirrhoe", + "Jupiter - Carme": "carme", + "Jupiter - Carpo": "carpo", + "Jupiter - Chaldene": "chaldene", + "Jupiter - Cyllene": "cyllene", + "Jupiter - Dia": "dia", + "Jupiter - Eirene": "eirene", + "Jupiter - Elara": "elara", + "Jupiter - Erinome": "erinome", + "Jupiter - Ersa": "ersa", + "Jupiter - Euanthe": "euanthe", + "Jupiter - Eukelade": "eukelade", + "Jupiter - Eupheme": "eupheme", + "Jupiter - Euporie": "euporie", + "Jupiter - Eurydome": "eurydome", + "Jupiter - Harpalyke": "harpalyke", + "Jupiter - Hegemone": "hegemone", + "Jupiter - Helike": "helike", + "Jupiter - Hermippe": "hermippe", + "Jupiter - Herse": "herse", + "Jupiter - Himalia": "himalia", + "Jupiter - Iocaste": "iocaste", + "Jupiter - Isonoe": "isonoe", + "Jupiter - Jupiter LI": "jupiter_li", + "Jupiter - Jupiter LII": "jupiter_lii", + "Jupiter - Jupiter LIV": "jupiter_liv", + "Jupiter - Jupiter LV": "jupiter_lv", + "Jupiter - Jupiter LVI": "jupiter_lvi", + "Jupiter - Jupiter LIX": "jupiter_lix", + "Jupiter - Jupiter LXI": "jupiter_lxi", + "Jupiter - Jupiter LXIII": "jupiter_lxiii", + "Jupiter - Jupiter LXIV": "jupiter_lxiv", + "Jupiter - Jupiter LXVI": "jupiter_lxvi", + "Jupiter - Jupiter LXVII": "jupiter_lxvii", + "Jupiter - Jupiter LXVIII": "jupiter_lxviii", + "Jupiter - Jupiter LXIX": "jupiter_lxix", + "Jupiter - Jupiter LXX": "jupiter_lxx", + "Jupiter - Jupiter LXXII": "jupiter_lxxii", + "Jupiter - Kale": "kale", + "Jupiter - Kallichore": "kallichore", + "Jupiter - Kalyke": "kalyke", + "Jupiter - Kore": "kore", + "Jupiter - Leda": "leda", + "Jupiter - Lysithea": "lysithea", + "Jupiter - Megaclite": "megaclite", + "Jupiter - Mneme": "mneme", + "Jupiter - Orthosie": "orthosie", + "Jupiter - Pandia": "pandia", + "Jupiter - Pasiphae": "pasiphae", + "Jupiter - Pasithee": "pasithee", + "Jupiter - Philophrosyne": "philophrosyne", + "Jupiter - Praxidike": "praxidike", + "Jupiter - S/2003 J 2": "s_2003_j_2", + "Jupiter - S/2003 J 4": "s_2003_j_4", + "Jupiter - S/2003 J 9": "s_2003_j_9", + "Jupiter - S/2003 J 10": "s_2003_j_10", + "Jupiter - S/2003 J 12": "s_2003_j_12", + "Jupiter - S/2003 J 16": "s_2003_j_16", + "Jupiter - S/2003 J 23": "s_2003_j_23", + "Jupiter - S/2003 J 24": "s_2003_j_24", + "Jupiter - S/2011 J 3": "s_2011_j_3", + "Jupiter - S/2016 J 3": "s_2016_j_3", + "Jupiter - S/2016 J 4": "s_2016_j_4", + "Jupiter - S/2018 J 2": "s_2018_j_2", + "Jupiter - S/2018 J 3": "s_2018_j_3", + "Jupiter - S/2018 J 4": "s_2018_j_4", + "Jupiter - S/2021 J 1": "s_2021_j_1", + "Jupiter - S/2021 J 2": "s_2021_j_2", + "Jupiter - S/2021 J 3": "s_2021_j_3", + "Jupiter - S/2021 J 4": "s_2021_j_4", + "Jupiter - S/2021 J 5": "s_2021_j_5", + "Jupiter - S/2021 J 6": "s_2021_j_6", + "Jupiter - S/2022 J 1": "s_2022_j_1", + "Jupiter - S/2022 J 2": "s_2022_j_2", + "Jupiter - S/2022 J 3": "s_2022_j_3", + "Jupiter - Sinope": "sinope", + "Jupiter - Sponde": "sponde", + "Jupiter - Taygete": "taygete", + "Jupiter - Thelxinoe": "thelxinoe", + "Jupiter - THEMISto": "themisto", + "Jupiter - Thyone": "thyone", + "Jupiter - Valetudo": "valetudo", + "Mars - Phobos": "phobos", + "Mars - Deimos": "deimos", + "Neptune - Despina": "despina", + "Neptune - Galatea": "galatea", + "Neptune - Halimede": "halimede", + "Neptune - Hippocamp": "hippocamp", + "Neptune - Laomedeia": "laomedeia", + "Neptune - Larissa": "larissa", + "Neptune - Naiad": "naiad", + "Neptune - Nereid": "nereid", + "Neptune - Neso": "neso", + "Neptune - Proteus": "proteus", + "Neptune - Psamathe": "psamathe", + "Neptune - Sao": "sao", + "Neptune - Thalassa": "thalassa", + "Neptune - Triton": "triton", + "Saturn - Dione": "dione", + "Saturn - Enceladus": "enceladus", + "Saturn - Hyperion": "hyperion", + "Saturn - Iapetus": "iapetus", + "Saturn - Mimas": "mimas", + "Saturn - Rhea": "rhea", + "Saturn - Tethys": "tethys", + "Saturn - Titan": "titan", + "Saturn - Aegaeon": "aegaeon", + "Saturn - Aegir": "aegir", + "Saturn - Albiorix": "albiorix", + "Saturn - Alvaldi": "alvaldi", + "Saturn - Angrboda": "angrboda", + "Saturn - Anthe": "anthe", + "Saturn - Atlas": "atlas", + "Saturn - Bebhionn": "bebhionn", + "Saturn - Beli": "beli", + "Saturn - Bergelmir": "bergelmir", + "Saturn - Bestla": "bestla", + "Saturn - Calypso": "calypso", + "Saturn - Daphnis": "daphnis", + "Saturn - Eggther": "eggther", + "Saturn - Epimetheus": "epimetheus", + "Saturn - Erriapus": "erriapus", + "Saturn - Farbauti": "farbauti", + "Saturn - Fenrir": "fenrir", + "Saturn - Fornjot": "fornjot", + "Saturn - Geirrod": "geirrod", + "Saturn - Gerd": "gerd", + "Saturn - Greip": "greip", + "Saturn - Gridr": "gridr", + "Saturn - Gunnlod": "gunnlod", + "Saturn - Hati": "hati", + "Saturn - Helene": "helene", + "Saturn - Hyrrokkin": "hyrrokkin", + "Saturn - Ijiraq": "ijiraq", + "Saturn - Janus": "janus", + "Saturn - Jarnsaxa": "jarnsaxa", + "Saturn - Kari": "kari", + "Saturn - Kiviuq": "kiviuq", + "Saturn - Loge": "loge", + "Saturn - Methone": "methone", + "Saturn - Mundilfari": "mundilfari", + "Saturn - Narvi": "narvi", + "Saturn - Paaliaq": "paaliaq", + "Saturn - Pallene": "pallene", + "Saturn - Pan": "pan", + "Saturn - Pandora": "pandora", + "Saturn - Phoebe": "phoebe", + "Saturn - Polydeuces": "polydeuces", + "Saturn - Prometheus": "prometheus", + "Saturn - S/2004 S 7": "s_2004_s_7", + "Saturn - S/2004 S 12": "s_2004_s_12", + "Saturn - S/2004 S 13": "s_2004_s_13", + "Saturn - S/2004 S 17": "s_2004_s_17", + "Saturn - S/2004 S 21": "s_2004_s_21", + "Saturn - S/2004 S 24": "s_2004_s_24", + "Saturn - S/2004 S 28": "s_2004_s_28", + "Saturn - S/2004 S 31": "s_2004_s_31", + "Saturn - S/2004 S 36": "s_2004_s_36", + "Saturn - S/2004 S 37": "s_2004_s_37", + "Saturn - S/2004 S 39": "s_2004_s_39", + "Saturn - S/2006 S 1": "s_2006_s_1", + "Saturn - S/2006 S 3": "s_2006_s_3", + "Saturn - S/2007 S 2": "s_2007_s_2", + "Saturn - S/2007 S 3": "s_2007_s_3", + "Saturn - S/2009 S 1": "s_2009_s_1", + "Saturn - S/2019 S 1": "s_2019_s_1", + "Saturn - Saturn_lviii": "saturn_lviii", + "Saturn - Saturn_lx": "saturn_lx", + "Saturn - Saturn_lxiv": "saturn_lxiv", + "Saturn - Siarnaq": "siarnaq", + "Saturn - Skathi": "skathi", + "Saturn - Skoll": "skoll", + "Saturn - Skrymir": "skrymir", + "Saturn - Surtur": "surtur", + "Saturn - Suttungr": "suttungr", + "Saturn - Tarqeq": "tarqeq", + "Saturn - Tarvos": "tarvos", + "Saturn - Telesto": "telesto", + "Saturn - Thiazzi": "thiazzi", + "Saturn - Thrymr": "thrymr", + "Saturn - Ymir": "ymir", + "Saturn - S/2004 S 40": "s_2004_s_40", + "Saturn - S/2004 S 41": "s_2004_s_41", + "Saturn - S/2004 S 42": "s_2004_s_42", + "Saturn - S/2004 S 43": "s_2004_s_43", + "Saturn - S/2004 S 44": "s_2004_s_44", + "Saturn - S/2004 S 45": "s_2004_s_45", + "Saturn - S/2004 S 46": "s_2004_s_46", + "Saturn - S/2004 S 47": "s_2004_s_47", + "Saturn - S/2004 S 48": "s_2004_s_48", + "Saturn - S/2004 S 49": "s_2004_s_49", + "Saturn - S/2004 S 50": "s_2004_s_50", + "Saturn - S/2004 S 51": "s_2004_s_51", + "Saturn - S/2004 S 52": "s_2004_s_52", + "Saturn - S/2004 S 53": "s_2004_s_53", + "Saturn - S/2005 S 4": "s_2005_s_4", + "Saturn - S/2005 S 5": "s_2005_s_5", + "Saturn - S/2006 S 10": "s_2006_s_10", + "Saturn - S/2006 S 11": "s_2006_s_11", + "Saturn - S/2006 S 12": "s_2006_s_12", + "Saturn - S/2006 S 13": "s_2006_s_13", + "Saturn - S/2006 S 14": "s_2006_s_14", + "Saturn - S/2006 S 15": "s_2006_s_15", + "Saturn - S/2006 S 16": "s_2006_s_16", + "Saturn - S/2006 S 17": "s_2006_s_17", + "Saturn - S/2006 S 18": "s_2006_s_18", + "Saturn - S/2006 S 19": "s_2006_s_19", + "Saturn - S/2006 S 20": "s_2006_s_20", + "Saturn - S/2006 S 9": "s_2006_s_9", + "Saturn - S/2007 S 5": "s_2007_s_5", + "Saturn - S/2007 S 6": "s_2007_s_6", + "Saturn - S/2007 S 7": "s_2007_s_7", + "Saturn - S/2007 S 8": "s_2007_s_8", + "Saturn - S/2007 S 9": "s_2007_s_9", + "Saturn - S/2019 S 10": "s_2019_s_10", + "Saturn - S/2019 S 11": "s_2019_s_11", + "Saturn - S/2019 S 12": "s_2019_s_12", + "Saturn - S/2019 S 13": "s_2019_s_13", + "Saturn - S/2019 S 14": "s_2019_s_14", + "Saturn - S/2019 S 15": "s_2019_s_15", + "Saturn - S/2019 S 16": "s_2019_s_16", + "Saturn - S/2019 S 17": "s_2019_s_17", + "Saturn - S/2019 S 18": "s_2019_s_18", + "Saturn - S/2019 S 19": "s_2019_s_19", + "Saturn - S/2019 S 2": "s_2019_s_2", + "Saturn - S/2019 S 20": "s_2019_s_20", + "Saturn - S/2019 S 21": "s_2019_s_21", + "Saturn - S/2019 S 3": "s_2019_s_3", + "Saturn - S/2019 S 4": "s_2019_s_4", + "Saturn - S/2019 S 5": "s_2019_s_5", + "Saturn - S/2019 S 6": "s_2019_s_6", + "Saturn - S/2019 S 7": "s_2019_s_7", + "Saturn - S/2019 S 8": "s_2019_s_8", + "Saturn - S/2019 S 9": "s_2019_s_9", + "Saturn - S/2020 S 1": "s_2020_s_1", + "Saturn - S/2020 S 10": "s_2020_s_10", + "Saturn - S/2020 S 2": "s_2020_s_2", + "Saturn - S/2020 S 3": "s_2020_s_3", + "Saturn - S/2020 S 4": "s_2020_s_4", + "Saturn - S/2020 S 5": "s_2020_s_5", + "Saturn - S/2020 S 6": "s_2020_s_6", + "Saturn - S/2020 S 7": "s_2020_s_7", + "Saturn - S/2020 S 8": "s_2020_s_8", + "Saturn - S/2020 S 9": "s_2020_s_9", + "Uranus - Ariel": "ariel", + "Uranus - Miranda": "miranda", + "Uranus - Oberon": "oberon", + "Uranus - Titania": "titania", + "Uranus - Umbriel": "umbriel", + "Uranus - Belinda": "belinda", + "Uranus - Bianca": "bianca", + "Uranus - Caliban": "caliban", + "Uranus - Cordelia": "cordelia", + "Uranus - Cressida": "cressida", + "Uranus - Cupid": "cupid", + "Uranus - Desdemona": "desdemona", + "Uranus - Ferdinand": "ferdinand", + "Uranus - Francisco": "francisco", + "Uranus - Juliet": "juliet", + "Uranus - Mab": "mab", + "Uranus - Margaret": "margaret", + "Uranus - Ophelia": "ophelia", + "Uranus - Perdita": "perdita", + "Uranus - Portia": "portia", + "Uranus - Prospero": "prospero", + "Uranus - Puck": "puck", + "Uranus - Rosalind": "rosalind", + "Uranus - Setebos": "setebos", + "Uranus - Stephano": "stephano", + "Uranus - Sycorax": "sycorax", + "Uranus - Trinculo": "trinculo", + //////////////////////////////////////////////////// + // Comets // + //////////////////////////////////////////////////// + Oumuamua: "1i_oumuamua", + Halley: "1p_halley", + "Hartley 2": "103p_hartley_2", + "Tempel 1": "9p_tempel_1", + "Wild 2": "81p_wild_2", + "Churyumov Gerasimenko": "67p_churyumov_gerasimenko", + Borrelly: "19p_borrelly", + "C 1995 o1": "c_1995_o1", + "C 2010 x1": "c_2010_x1", + "C 2012 s1": "c_2012_s1", + "C 2013 a1": "c_2013_a1", + "C 2019 y4": "c_2019_y4", + "C 2020 f3": "c_2020_f3", + //////////////////////////////////////////////////// + // Spacecraft // + //////////////////////////////////////////////////// + "3d winds": "sc_3d_winds", + Ace: "sc_ace", + Acrimsat: "sc_acrimsat", + Aim: "sc_aim", + Aqua: "sc_aqua", + Ascends: "sc_ascends", + Aura: "sc_aura", + "C nofs": "sc_c_nofs", + CALIPSO: "sc_calipso", + "Chandra X-ray Observatory": "sc_chandra", + Clarreo: "sc_clarreo", + CloudSat: "sc_cloudsat", + "Rumba": "sc_cluster_ii_fm5", + "Salsa": "sc_cluster_ii_fm6", + "Samba": "sc_cluster_ii_fm7", + "Tango": "sc_cluster_ii_fm8", + "Cygnss 1": "sc_cygnss_1", + "Cygnss 2": "sc_cygnss_2", + "Cygnss 3": "sc_cygnss_3", + "Cygnss 4": "sc_cygnss_4", + "Cygnss 5": "sc_cygnss_5", + "Cygnss 6": "sc_cygnss_6", + "Cygnss 7": "sc_cygnss_7", + "Cygnss 8": "sc_cygnss_8", + Dscovr: "sc_dscovr", + "EO-1": "sc_eo_1", + "Explorer 1": "sc_explorer_1", + Face: "sc_face", + Fgrst: "sc_fgrst", + Gacm: "sc_gacm", + Galex: "sc_galex", + "Geo cape": "sc_geo_cape", + Geotail: "sc_geotail", + "Goes 12": "sc_goes_12", + "Goes 13": "sc_goes_13", + "Goes 14": "sc_goes_14", + "Goes 15": "sc_goes_15", + Gpm: "sc_gpm", + "GRACE-1": "sc_grace_1", + "GRACE-2": "sc_grace_2", + "GRACE-FO1": "sc_grace_fo1", + "GRACE-FO2": "sc_grace_fo2", + Grifex: "sc_grifex", + "Hubble Space Telescope": "sc_hubble_space_telescope", + Hyspiri: "sc_hyspiri", + Ibex: "sc_ibex", + Icesat_2: "sc_icesat_2", + Image: "sc_image", + Integral: "sc_integral", + Ipex: "sc_ipex", + Isas: "sc_isas", + "International Space Station (ISS)": "sc_iss", + IXPE: "sc_ixpe", // Broken + "Jason-1": "sc_jason_1", // Broken + "Jason-2": "sc_jason_2", // Broken + "Jason-3": "sc_jason_3", // Broken + "James Webb Space Telescope": "sc_jwst", // Broken + "Landsat 5": "sc_landsat_5", // Broken + "Landsat 7": "sc_landsat_7", // Broken + "Landsat 8": "sc_landsat_8", // Broken + "Landsat 9": "sc_landsat_9", // Broken + "M cubed": "sc_m_cubed", // Broken + "M cubed 2": "sc_mcubed_2", // Broken + "MMS 1": "sc_mms_1", // Broken + "MMS 2": "sc_mms_2", // Broken + "MMS 3": "sc_mms_3", // Broken + "MMS 4": "sc_mms_4", // Broken + Nisar: "sc_nisar", // Broken + "Noaa 14": "sc_noaa_14", // Broken + "Noaa 15": "sc_noaa_15", // Broken + "Noaa 16": "sc_noaa_16", // Broken + "Noaa 17": "sc_noaa_17", // Broken + "Noaa 18": "sc_noaa_18", // Broken + "Noaa 19": "sc_noaa_19", // Broken + Nustar: "sc_nustar", // Broken + "OCO-2": "sc_oco_2", // Broken + Path: "sc_path", // Broken + Polar: "sc_polar", // Broken + QuikSCAT: "sc_quikscat", // Broken + Race: "sc_race", // Broken + Raincube: "sc_raincube", // Broken + "Rax 2": "sc_rax_2", // Broken + "Van Allen Probe A": "sc_rbsp_a", // Broken + "Van Allen Probe B": "sc_rbsp_b", // Broken + "Sac d": "sc_sac_d", // Broken + Sclp: "sc_sclp", // Broken + Sdo: "sc_sdo", // Broken + "Sentinel-6 Michael Freilich": "sc_sentinel_6", // Broken + Smap: "sc_smap", // Broken + Soho: "sc_soho", // Broken + Sorce: "sc_sorce", // Broken + "Starling 1": "sc_starling_1", // Broken + "Starling 2": "sc_starling_2", // Broken + "Starling 3": "sc_starling_3", // Broken + "Starling 4": "sc_starling_4", // Broken + Suomi_npp: "sc_suomi_npp", // Broken + Swift: "sc_swift", // Broken + Swot: "sc_swot", // Broken + "Tdrs 3": "sc_tdrs_3", // Broken + "Tdrs 5": "sc_tdrs_5", // Broken + "Tdrs 6": "sc_tdrs_6", // Broken + "Tdrs 7": "sc_tdrs_7", // Broken + "Tdrs 8": "sc_tdrs_8", // Broken + "Tdrs 9": "sc_tdrs_9", // Broken + "Tdrs 10": "sc_tdrs_10", // Broken + "Tdrs 11": "sc_tdrs_11", // Broken + "Tdrs 12": "sc_tdrs_12", // Broken + "Tdrs 13": "sc_tdrs_13", // Broken + Terra: "sc_terra", // Broken + Tess: "sc_tess", // Broken + "THEMIS a": "sc_themis_a", + "THEMIS d": "sc_themis_d", + "THEMIS e": "sc_themis_e", + Timed: "sc_timed", + Trmm: "sc_trmm", + Uars: "sc_uars", + WIND: "sc_wind", + Wise: "sc_wise", + "Apollo 15": "sc_apollo_15", + "Artemis 1": "sc_artemis_1", + CAPSTONE: "sc_capstone", + Clementine: "sc_clementine", + "GRAIL A": "sc_grail_a", + "GRAIL B": "sc_grail_b", + Ladee: "sc_ladee", + LCROSS: "sc_lcross", + "LCROSS impact site": "sc_lcross_impact_site", + "Lunar flashlight": "sc_lunar_flashlight", + "Lunar Prospector": "sc_lunar_prospector", + "Lunar reconnaissance_orbiter": "sc_lunar_reconnaissance_orbiter", + "Smart 1": "sc_smart_1", + "ARTEMIS P1": "sc_themis_b", + "ARTEMIS P2": "sc_themis_c", + "Mars 2020": "sc_mars_2020", + "Mars 2020 landing site": "sc_mars_2020_landing_site", + "Mars science laboratory": "sc_mars_science_laboratory", // Broken + "Mars science laboratory_landing_site": + "sc_mars_science_laboratory_landing_site", // Broken + Insight: "sc_insight", // Broken + "Insight landing site": "sc_insight_landing_site", // Broken + "MarCO A": "sc_marco_a", // Broken + "MarCO B": "sc_marco_b", // Broken + "Mars odyssey": "sc_mars_odyssey", // Broken + "Mars reconnaissance orbiter": "sc_mars_reconnaissance_orbiter", // Broken + Maven: "sc_maven", // Broken + "Mars express": "sc_mars_express", // Broken + Phoenix: "sc_phoenix", // Broken + "Phoenix landing site": "sc_phoenix_landing_site", // Broken + "Trace gas orbiter": "sc_trace_gas_orbiter", // Broken + "Mars orbiter mission": "sc_mars_orbiter_mission", // Broken + "Mars Global Surveyor": "sc_mars_global_surveyor", // Broken + "Mars climate orbiter": "sc_mars_climate_orbiter", // Broken + "Mars pathfinder": "sc_mars_pathfinder", // Broken + "Mars pathfinder landing site": "sc_mars_pathfinder_landing_site", // Broken + "Mars polar lander": "sc_mars_polar_lander", // Broken + "Viking 2 orbiter": "sc_viking_2_orbiter", // Broken + "Viking 2 lander landing site": "sc_viking_2_lander_landing_site", // Broken + MESSENGER: "sc_messenger", // Broken + "MESSENGER impact site": "sc_messenger_impact_site", // Broken + Juno: "sc_juno", // Broken + Cassini: "sc_cassini", // Broken + "Europa clipper": "sc_europa_clipper", // Broken + Galileo: "sc_galileo", + "Galileo probe": "sc_galileo_probe", // Broken + Huygens: "sc_huygens", + "Huygens landing site": "sc_huygens_landing_site", // Broken + Juice: "sc_juice", // Broken + "Pioneer 10": "sc_pioneer_10", // Broken + "Pioneer 11": "sc_pioneer_11", // Broken + "Voyager 1": "sc_voyager_1", // Broken + "Voyager 2": "sc_voyager_2", // Broken + DART: "sc_dart", + Dawn: "sc_dawn", + "Deep Impact": "sc_deep_impact", + "Deep Impact Impactor": "sc_deep_impact_impactor", + "Deep impact_impactor_impact_site": "sc_deep_impact_impactor_impact_site", // Broken + "Deep Space 1": "sc_deep_space_1", + "NEAR Shoemaker": "sc_near_shoemaker", + "NEAR Shoemaker_landing_site": "sc_near_shoemaker_landing_site", // Broken + Lucy: "sc_lucy", // VERY Broken + "New Horizons": "sc_new_horizons", // Broken + Rosetta: "sc_rosetta", + "Rosetta impact site": "sc_rosetta_impact_site", // Broken + "OSIRIS-APEX (OSIRIS-REx)": "sc_osiris_rex", + "OSIRIS-REx Sample Return Capsule": "sc_osiris_rex_src", + Philae: "sc_philae", + Philae_landing_site: "sc_philae_landing_site", // Broken + "Psyche (spacecraft)": "sc_psyche", + "Stardust": "sc_stardust", + BioSentinel: "sc_biosentinel", // Broken + "Kepler": "sc_kepler_space_telescope", + "Mariner 2": "sc_mariner_2", // Broken + "Parker Solar Probe": "sc_parker_solar_probe", // Broken + "Spitzer Space Telescope": "sc_spitzer", // Broken + "STEREO ahead": "sc_stereo_ahead", // Broken + "STEREO behind": "sc_stereo_behind", // Broken + Ulysses: "sc_ulysses", // Broken + Wmap: "sc_wmap", // Broken + Magellan: "sc_magellan", // Broken + "Venus express": "sc_venus_express", // Broken + //////////////////////////////////////////////////// + // Unused // + //////////////////////////////////////////////////// + // "rose_bowl", + // "school_bus", + // "scientist" +}; diff --git a/experiences/asteroids/controls/lib/icons.tsx b/experiences/asteroids/controls/lib/icons.tsx new file mode 100644 index 0000000..99b6014 --- /dev/null +++ b/experiences/asteroids/controls/lib/icons.tsx @@ -0,0 +1,176 @@ +import { Box } from "@material-ui/core"; + +export const AsteroidIcon = () => { + return ( + + + + + + + + ); +}; + +export const CometIcon = () => { + return ( + + + + + + + + + ); +}; + +export const PlanetIcon = () => { + return ( + + + + + + + + + ); +}; + +export const OrbitIcon = () => { + return ( + + + + + + + + ); +}; + +export const ShadowLightingIcon = () => { + return ( + + + + + + + + ); +}; + +export const NaturalLightingIcon = () => { + return ( + + + + + + + + ); +}; + +export const FloodLightingIcon = () => { + return ( + + + + + + + ); +}; + +// Created by Derrick LeMaster +// from the Noun Project +export const ConstellationIcon = () => { + return ( + + + + + + ); +}; diff --git a/experiences/asteroids/controls/lib/index.tsx b/experiences/asteroids/controls/lib/index.tsx new file mode 100644 index 0000000..e2a53f7 --- /dev/null +++ b/experiences/asteroids/controls/lib/index.tsx @@ -0,0 +1,156 @@ +/** @jsxImportSource @emotion/react */ +import React, { MouseEventHandler, useState } from "react"; +import { useMessaging } from "@footron/controls-client"; +import { Box, createTheme } from "@material-ui/core"; + +import { Backdrop } from "@mui/material"; + +import SettingsIcon from "@mui/icons-material/Settings"; +import CloseIcon from "@mui/icons-material/Close"; +import { ClickAwayListener } from "@mui/base/ClickAwayListener"; + +import FlyTo from "./flyTo"; +import SettingsMenu from "./SettingsMenu"; +import AsteroidWatch from "./AsteroidWatch"; +import Learn from "./Learn"; +import Info from "./Info"; +import { + dynamicUiwrapperStyle, + overlayMenuWrapperStyle, + overlayStyle, + selectedTabStyle, + tabPanelStyle, + tabsStyle, + tabStyle, + wrapperStyle, +} from "./style"; + +interface TabPanelProps { + children?: React.ReactNode; + index: number; + value: number; +} + +interface TabProps { + children?: React.ReactNode; + onClick: MouseEventHandler; + selected: boolean; +} + +function CustomTabPanel(props: TabPanelProps) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +const ControlsComponent = (): JSX.Element => { + const { sendMessage } = useMessaging(); + const [menuOpen, setMenuOpen] = useState(false); + const [value, setValue] = useState(2); + + const handleOpenSettings = () => { + setMenuOpen((prev) => !prev); + }; + + const handleClickAwaySettings = (event: MouseEvent | TouchEvent) => { + event.preventDefault(); + event.stopPropagation(); + + setMenuOpen(false); + }; + + const getWatch = () => { + setValue(1); + sendMessage({ type: "context", value: "watch" }); + }; + + const getFly = () => { + setValue(2); + sendMessage({ type: "context", value: "fly" }); + }; + + const getLearn = () => { + setValue(3); + sendMessage({ type: "context", value: "learn" }); + }; + + const getInfo = () => { + setValue(4); + }; + + function Tab(props: TabProps) { + const { children, onClick, selected, ...other } = props; + + return ( + + {children} + + ); + } + + return ( + + {/* Settings overlay */} + {menuOpen ? ( + + + + + + + + ) : null} + + + + + + + + + + + + + + + + + {menuOpen ? : } + + + Watch + + + Fly + + + Learn + + + Info + + + + ); +}; + +export default ControlsComponent; diff --git a/experiences/asteroids/controls/lib/standardBottomUi.tsx b/experiences/asteroids/controls/lib/standardBottomUi.tsx new file mode 100644 index 0000000..894cc63 --- /dev/null +++ b/experiences/asteroids/controls/lib/standardBottomUi.tsx @@ -0,0 +1,18 @@ +import { Box } from "@material-ui/core"; +import { standardBottomUiStyle } from "./style"; +import MovementControls from "./Movement"; +import TimeSlider from "./time"; + +interface Props { + children?: React.ReactNode; +} + +export default function StandardBottomUi({ children }: Props) { + return ( + + {children} + + + + ); +} diff --git a/experiences/asteroids/controls/lib/style.tsx b/experiences/asteroids/controls/lib/style.tsx new file mode 100644 index 0000000..db0cf26 --- /dev/null +++ b/experiences/asteroids/controls/lib/style.tsx @@ -0,0 +1,336 @@ +import { css } from "@emotion/react"; + +// TODO: Remove these dev styles + +export const pageWrapperStyle = css` + display: flex; + justify-content: center; + height: 100%; +`; + +export const pageWidthStyle = css` + width: 100%; + height: 100%; + + @media (min-width: 600px) { + width: 600px; + } +`; + +export const fixedFooterStyle = css` + position: fixed; + bottom: 0; + + @media (max-width: 600px) { + left: 0; + right: 0; + } + + @media (min-width: 600px) { + width: 600px; + border-radius: 8px; + overflow: hidden; + box-shadow: rgba(0, 30, 76, 0.25) 0 5px 5px; + } +`; + +export const headerStyle = css` + height: 64px; + width: calc(100% - 32px); + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 16px; + background: #f7faff; + border-bottom: 2px solid #b4bfd2; + gap: 12px; +`; + +export const titleStyle = css` + font-family: "Montserrat", sans-serif; + font-size: 20px; + font-weight: bold; + color: #001e4c; +`; + +export const controlsContainerStyle = css` + // Height of more experiences button + margin-bottom: 64px; +`; + +export const footerStyle = css` + height: 64px; + width: calc(100% - 32px); + display: flex; + align-items: center; + justify-content: center; + padding: 0 16px; + transition: background 100ms ease-out; + background: #001e4c; + + &:hover { + background: #072b6a; + } + + &:active { + background: #0b3379; + } +`; + +export const footerInnerStyle = css` + display: flex; + align-items: center; + gap: 12px; +`; + +export const bottomTitleStyle = css` + font-family: "Source Code Pro", sans-serif; + font-size: 18px; + font-weight: bold; + text-transform: uppercase; + color: #f0f6ff; +`; + +// END dev styles + +export const overlayStyle = css` + z-index: 99999; +`; + +export const overlayMenuWrapperStyle = css` +background-color: white; + max-width: min(80vw, 480px); + max-height: min(80vh, 480px); + overflow: auto; + padding: 1em; + opacity: 1; +`; + +export const overlayMenuStyle = css` +display: flex; +flex-flow: column; +overflow: auto; +`; + +export const overlaySettingsMenuStyle = css` +display: flex; +flex-flow: column; +` +export const overlaySettingsMenuContentStyle = css` + display: flex; + flex-flow: column; + overlow: auto; +` + +export const overlayMenuHeaderStyle = css` + display: flex; + width: 100%; + justify-content: space-between; +`; + +export const definitionListStyle = css` + display: flex; + flex-flow: row wrap; + width: 100%; + justify-content: flex-start; + gap: 0.5em; +`; + +export const largeIconStyle = css` + font-size = 80px; +`; + +// keeps elements from collapsing unexpectedly +export const fullSizeStyle = css` + width: 100%; + height: 100%; +`; + +export const storyBoxStyle = css` + border: solid; + border-radius: 5px; + padding: 1em; +`; + +export const thinWidgetStyle = css` + display: flex; + justify-content: center; + gap: 0.5em; + align-items: center; + height: 64px; + padding: 0px; +`; + +export const thickWidgetStyle = css` + background-color: lightsalmon; + justify-content: center; + gap: 0.5em; + align-items: center; + height: 192px; + padding: 0px; +`; + + +// We are inserted within footron's +// controlsContainer which is not the +// full screen, everything else should not +// use vh +export const wrapperStyle = css` + position: fixed; + height: calc(100vh - 128px); + max-height: calc(100vh - 128px); + padding: 0; + display: flex; + flex-flow: column; + width: min(100%, 600px); + + @media (min-width: 600px) { + height: calc(100vh - 136px); + padding: 0 0 16px 0; + } +`; + +export const dynamicUiwrapperStyle = css` + max-height: calc(100% - 64px); + flex: 1; + display: flex; + padding: 0 1em; +`; + +// If this is set to flex +// all tabs are rendered in the wrapper +export const tabPanelStyle = css` + flex: 1; +`; + +export const bottomBarStyle = css` + height: 64; + min-height: 64px; + display: flex; +`; + +export const tabsStyle = css` + display: flex; + height: 64px; + align-items: stretch; + font: bold normal 18px "Source Code Pro", sans-serif; + text-transform: uppercase; + border-block: 2px #001e4c inset; + + @media (min-width: 600px) { + border: solid #001e4c 3px; + border-radius: 8px; + } +`; + +export const tabStyle = css` + flex: 1; + display: flex; + align-items: center; + justify-content: center; +`; + +export const selectedTabStyle = css` + flex: 1; + display: flex; + align-items: center; + justify-content: center; + text-decoration: underline red solid 3px; +`; + +export const fullUIStyle = css` + width: 100%; + height: 100%; + display: flex; + flex-flow: column; +`; + +export const fabStyle = css` + float: right; +`; + +export const tabUI = css` + display: flex; + flex-flow: column nowrap; +`; + +export const topUI = css` + flex: 1; + display: flex; + flex-flow: column; + gap: 0.5em; + overflow: auto; +`; + +// Static Bottom UI + +export const paginationStyle = css` + display: flex; + justify-content: center; + gap: 0.5em; + align-items: center; + height: 32px; + padding: 0px; +`; + +export const standardBottomUiStyle = css` + padding: 1em 0; + display: flex; + flex-flow: column nowrap; + align-items: stretch; + gap: 1em; +`; + +export const largeBottomUiStyle = css` + height: 320; + max-height: 320; +`; + +export const movementComponentStyle = css` + height: 112px; + width: 100%; + display: flex; + flex-flow: row; + align-items: flex-start; + justify-content: space-around; + transition: opacity 0.5s ease-in; +`; + +export const joystickStyle = css` + flex: 1; + display: flex; + justify-content: center; +`; + +export const helpMessageStyle = (visible: boolean) => css` + flex: 1; + opacity: ${visible ? 1 : 0}; + transition: opacity 0.5s ease-in-out; + pointer-events: none; + text-align: center; +`; + +export const timeComponentStyle = css` + height: min(50%, 192px); + display: flex; + gap: 1em; + align-items: stretch; +`; + +export const timeSliderStyle = css` + flex: 4; + display: flex; + flex-flow: column nowrap; + align-items: center; + justify-content: center; + gap: 0; +`; + +export const timeButtonsContainerStyle = css` + flex: 1; + display: flex; + flex-flow: column; + align-items: stretch; + justify-content: center; + gap: 0.5em; +`; diff --git a/experiences/asteroids/controls/lib/time.tsx b/experiences/asteroids/controls/lib/time.tsx new file mode 100644 index 0000000..80e5a43 --- /dev/null +++ b/experiences/asteroids/controls/lib/time.tsx @@ -0,0 +1,142 @@ +import { Button, Slider, Box } from "@material-ui/core"; +import { useMessaging } from "@footron/controls-client"; +import { useEffect, useState } from "react"; +import { + helpMessageStyle, + timeButtonsContainerStyle, + timeComponentStyle as timeComponentStyle, + timeSliderStyle, +} from "./style"; +import PauseIcon from "@mui/icons-material/Pause"; +import PlayArrowIcon from "@mui/icons-material/PlayArrow"; + +function formatTime(seconds: number): string { + const units = [ + { label: "month", value: 60 * 60 * 24 * 30.5 }, + { label: "week", value: 60 * 60 * 24 * 7 }, + { label: "day", value: 60 * 60 * 24 }, + { label: "hour", value: 60 * 60 }, + { label: "minute", value: 60 }, + ]; + + let timeStr = "", + secondsRemaining = true; + timeStr += seconds < 0 ? "-" : ""; + seconds = Math.abs(seconds); + + for (const unit of units) { + const unitValue = Math.floor(seconds / unit.value); + if (unitValue > 0) { + timeStr += `${unitValue} ${unit.label}${unitValue > 1 ? "s" : ""} `; + secondsRemaining = false; + break; + } + } + timeStr = timeStr.trim(); + timeStr += secondsRemaining ? Math.round(seconds * 10) / 10 + " seconds" : ""; + timeStr += " / second"; + return timeStr; +} + +const sliderScale = 90 / 100; +const fiveDays = Math.log2(60 * 60 * 24 * 5 + 1) / sliderScale; +const live = Math.log2(2) / sliderScale; +const pause = 0; + +function calculateValue(value: number) { + return Math.sign(value) * (2 ** Math.abs(value * sliderScale) - 1); +} + +export default function TimeSlider() { + const [helpMessage, setHelpMessage] = useState(true); + const [rateMessage, setRateMessage] = useState(false); + const [rate, setRate] = useState(fiveDays); + const [oldRate, setOldRate] = useState(fiveDays); + const { sendMessage } = useMessaging(); + + useEffect(() => { + const timer = setTimeout(() => { + setHelpMessage(false); + }, 6000); // Adjust time as needed + + return () => clearTimeout(timer); + }, []); + + useEffect(() => { + let timer: number; + if (rateMessage) { + console.log("SHOW") + timer = setTimeout(() => { + setRateMessage(false); + console.log("RESET") + }, 3000); // Adjust time as needed + } + + return () => clearTimeout(timer); + }, [rateMessage]); + + const updateTime = (event: any, value: any) => { + setHelpMessage(false); + setRate(value); + setRateMessage(true) + sendMessage({ type: "time", value: calculateValue(value) }); + }; + + const goLive = async () => { + setRate(live); + setRateMessage(true) + sendMessage({ type: "time", value: "live" }); + }; + + const play = async () => { + setRate(oldRate); + setRateMessage(true) + sendMessage({ type: "time", value: calculateValue(oldRate) }); + }; + + const pauseTime = async () => { + setOldRate(rate); + setRate(0); + setRateMessage(true) + sendMessage({ type: "time", value: pause }); + }; + + return ( + + + + + Change the speed of time + + updateTime(e, v)} + /> + {formatTime(calculateValue(rate))} + + + + + + + + ); +} diff --git a/experiences/asteroids/controls/lib/timeSlider.tsx b/experiences/asteroids/controls/lib/timeSlider.tsx new file mode 100644 index 0000000..1961357 --- /dev/null +++ b/experiences/asteroids/controls/lib/timeSlider.tsx @@ -0,0 +1,102 @@ +import { Button, Slider, Box } from "@material-ui/core"; +import { useMessaging } from "@footron/controls-client"; +import { useState } from "react"; +import { thickBottomWidgetStyle, thinBottomWidgetStyle } from "./style"; +import PauseIcon from "@mui/icons-material/Pause"; +import PlayArrowIcon from "@mui/icons-material/PlayArrow"; + +function formatTime(seconds: number): string { + const units = [ + { label: "month", value: 60 * 60 * 24 * 30.5 }, + { label: "week", value: 60 * 60 * 24 * 7 }, + { label: "day", value: 60 * 60 * 24 }, + { label: "hour", value: 60 * 60 }, + { label: "minute", value: 60 }, + ]; + + let timeStr = "", secondsRemaining = true; + timeStr += seconds < 0 ? "-" : ""; + seconds = Math.abs(seconds); + + for (const unit of units) { + const unitValue = Math.floor(seconds / unit.value); + if (unitValue > 0) { + timeStr += `${unitValue} ${unit.label}${unitValue > 1 ? "s" : ""} `; + secondsRemaining = false; + break; + } + } + timeStr = timeStr.trim(); + timeStr += secondsRemaining ? Math.round(seconds * 10) / 10 + " seconds" : ""; + timeStr += " / second"; + return timeStr; +} + +const sliderScale = 90 / 100; +const fiveDays = Math.log2(60 * 60 * 24 * 5 + 1) / sliderScale; +const live = Math.log2(2) / sliderScale; +const pause = 0; + +function calculateValue(value: number) { + return Math.sign(value) * (2 ** Math.abs(value * sliderScale) - 1); +} + +export default function TimeSlider() { + const [rate, setRate] = useState(fiveDays); + const [oldRate, setOldRate] = useState(fiveDays); + const { sendMessage } = useMessaging(); + + const updateTime = (event: any, value: any) => { + setRate(value); + sendMessage({ type: "time", value: calculateValue(value) }); + }; + + const goLive = async () => { + setRate(live); + sendMessage({ type: "time", value: "live" }); + }; + + const play = async () => { + setRate(oldRate); + sendMessage({ type: "time", value: calculateValue(oldRate) }); + }; + + const pauseTime = async () => { + setOldRate(rate); + setRate(0); + sendMessage({ type: "time", value: pause }); + }; + + return ( + + + Change the speed of time + {formatTime(calculateValue(rate))} + + + updateTime(e, v)} + /> + + + + + + + ); +} diff --git a/experiences/asteroids/controls/lib/zoom.tsx b/experiences/asteroids/controls/lib/zoom.tsx new file mode 100644 index 0000000..7e3eaf5 --- /dev/null +++ b/experiences/asteroids/controls/lib/zoom.tsx @@ -0,0 +1,27 @@ +import { Box } from "@material-ui/core"; +import { useMessaging } from "@footron/controls-client"; +import { thinBottomWidgetStyle } from "./style"; +import { Button } from "@mui/material"; + +export default function ZoomControls() { + const { sendMessage } = useMessaging(); + + const handleZoomIn = () => { + sendMessage({ type: "zoom", value: "in" }) + } + + const handleZoomOut = () => { + sendMessage({ type: "zoom", value: "out" }) + } + + return ( + + + + + ); +} diff --git a/experiences/asteroids/controls/package.json b/experiences/asteroids/controls/package.json new file mode 100644 index 0000000..a06dc95 --- /dev/null +++ b/experiences/asteroids/controls/package.json @@ -0,0 +1,50 @@ +{ + "name": "@footron/controls-typescript-template", + "version": "0.1.0", + "scripts": { + "dev": "ftcontrols" + }, + "dependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.13.0", + "@material-ui/core": "^4.12.1", + "@material-ui/icons": "^4.11.2", + "@mui/base": "5.0.0-beta.59", + "@mui/icons-material": "^6.1.4", + "@mui/material": "^6.1.4", + "react": "^17.0.2", + "react-cool-dimensions": "^2.0.7", + "react-dom": "^17.0.2", + "react-joystick-component": "^6.2.1", + "react-router-dom": "^5.2.0" + }, + "devDependencies": { + "@footron/controls-cli": "^0.1.1", + "@footron/controls-client": "^0.1.14", + "@types/react": "^17.0.14", + "@types/react-dom": "^17.0.9", + "@types/react-router-dom": "^5.1.8", + "@typescript-eslint/eslint-plugin": "^4.28.2", + "@typescript-eslint/parser": "^4.28.2", + "@vitejs/plugin-react-refresh": "^1.3.5", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.3.0", + "eslint-config-standard": "^16.0.3", + "eslint-import-resolver-node": "^0.3.4", + "eslint-plugin-import": "^2.23.4", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^5.1.0", + "eslint-plugin-react": "^7.24.0", + "husky": ">=6", + "lint-staged": ">=10", + "pinst": ">=2", + "prettier": "^2.3.2", + "typescript": "4.3.5", + "vite": "2.4.1" + }, + "lint-staged": { + "*.{html,htm,js,jsx,ts,tsx,css,md}": "yarn prettier --max-warnings=0 --write .", + "*.{js,jsx,ts,tsx,d.ts}": "yarn eslint --fix" + }, + "packageManager": "yarn@4.5.0" +} diff --git a/experiences/asteroids/controls/tsconfig.json b/experiences/asteroids/controls/tsconfig.json new file mode 100644 index 0000000..9ea6e07 --- /dev/null +++ b/experiences/asteroids/controls/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "noImplicitAny": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "jsxImportSource": "@emotion/react" + }, + "include": ["lib"] +} diff --git a/experiences/asteroids/controls/yarn.lock b/experiences/asteroids/controls/yarn.lock new file mode 100644 index 0000000..160249d --- /dev/null +++ b/experiences/asteroids/controls/yarn.lock @@ -0,0 +1,5934 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@ampproject/remapping@npm:^2.2.0": + version: 2.3.0 + resolution: "@ampproject/remapping@npm:2.3.0" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/81d63cca5443e0f0c72ae18b544cc28c7c0ec2cea46e7cb888bb0e0f411a1191d0d6b7af798d54e30777d8d1488b2ec0732aac2be342d3d7d3ffd271c6f489ed + languageName: node + linkType: hard + +"@babel/code-frame@npm:7.12.11": + version: 7.12.11 + resolution: "@babel/code-frame@npm:7.12.11" + dependencies: + "@babel/highlight": "npm:^7.10.4" + checksum: 10c0/836ffd155506768e991d6dd8c51db37cad5958ed1c8e0a2329ccd9527165d5c752e943d66a5c3c92ffd45f343419f0742e7636629a529f4fbd5303e3637746b9 + languageName: node + linkType: hard + +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/code-frame@npm:7.25.7" + dependencies: + "@babel/highlight": "npm:^7.25.7" + picocolors: "npm:^1.0.0" + checksum: 10c0/14825c298bdec914caf3d24d1383b6d4cd6b030714686004992f4fc251831ecf432236652896f99d5d341f17170ae9a07b58d8d7b15aa0df8cfa1c5a7d5474bc + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.25.7": + version: 7.25.8 + resolution: "@babel/compat-data@npm:7.25.8" + checksum: 10c0/8b81c17580e5fb4cbb6a3c52079f8c283fc59c0c6bd2fe14cfcf9c44b32d2eaab71b02c5633e2c679f5896f73f8ac4036ba2e67a4c806e8f428e4b11f526d7f4 + languageName: node + linkType: hard + +"@babel/core@npm:^7.14.8": + version: 7.25.8 + resolution: "@babel/core@npm:7.25.8" + dependencies: + "@ampproject/remapping": "npm:^2.2.0" + "@babel/code-frame": "npm:^7.25.7" + "@babel/generator": "npm:^7.25.7" + "@babel/helper-compilation-targets": "npm:^7.25.7" + "@babel/helper-module-transforms": "npm:^7.25.7" + "@babel/helpers": "npm:^7.25.7" + "@babel/parser": "npm:^7.25.8" + "@babel/template": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.8" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10c0/8411ea506e6f7c8a39ab5c1524b00589fa3b087edb47389708f7fe07170929192171734666e3ea10b95a951643a531a6d09eedfe071572c9ea28516646265086 + languageName: node + linkType: hard + +"@babel/generator@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/generator@npm:7.25.7" + dependencies: + "@babel/types": "npm:^7.25.7" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + jsesc: "npm:^3.0.2" + checksum: 10c0/c03a26c79864d60d04ce36b649c3fa0d6fd7b2bf6a22e22854a0457aa09206508392dd73ee40e7bc8d50b3602f9ff068afa47770cda091d332e7db1ca382ee96 + languageName: node + linkType: hard + +"@babel/helper-compilation-targets@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-compilation-targets@npm:7.25.7" + dependencies: + "@babel/compat-data": "npm:^7.25.7" + "@babel/helper-validator-option": "npm:^7.25.7" + browserslist: "npm:^4.24.0" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10c0/705be7e5274a3fdade68e3e2cf42e2b600316ab52794e13b91299a16f16c926f15886b6e9d6df20eb943ccc1cdba5a363d4766f8d01e47b8e6f4e01175f5e66c + languageName: node + linkType: hard + +"@babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-module-imports@npm:7.25.7" + dependencies: + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/0fd0c3673835e5bf75558e184bcadc47c1f6dd2fe2016d53ebe1e5a6ae931a44e093015c2f9a6651c1a89f25c76d9246710c2b0b460b95ee069c464f2837fa2c + languageName: node + linkType: hard + +"@babel/helper-module-transforms@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-module-transforms@npm:7.25.7" + dependencies: + "@babel/helper-module-imports": "npm:^7.25.7" + "@babel/helper-simple-access": "npm:^7.25.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" + "@babel/traverse": "npm:^7.25.7" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/f37fa7d1d4df21690535b278468cbd5faf0133a3080f282000cfa4f3ffc9462a1458f866b04b6a2f2d1eec4691236cba9a867da61270dab3ab19846e62f05090 + languageName: node + linkType: hard + +"@babel/helper-plugin-utils@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-plugin-utils@npm:7.25.7" + checksum: 10c0/241f8cf3c5b7700e91cab7cfe5b432a3c710ae3cd5bb96dc554da536a6d25f5b9f000cc0c0917501ceb4f76ba92599ee3beb25e10adaf96be59f8df89a842faf + languageName: node + linkType: hard + +"@babel/helper-simple-access@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-simple-access@npm:7.25.7" + dependencies: + "@babel/traverse": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/eed1b499bfb4f613c18debd61517e3de77b6da2727ca025aa05ac81599e0269f1dddb5237db04e8bb598115d015874752e0a7f11ff38672d74a4976097417059 + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-string-parser@npm:7.25.7" + checksum: 10c0/73ef2ceb81f8294678a0afe8ab0103729c0370cac2e830e0d5128b03be5f6a2635838af31d391d763e3c5a4460ed96f42fd7c9b552130670d525be665913bc4c + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-validator-identifier@npm:7.25.7" + checksum: 10c0/07438e5bf01ab2882a15027fdf39ac3b0ba1b251774a5130917907014684e2f70fef8fd620137ca062c4c4eedc388508d2ea7a3a7d9936a32785f4fe116c68c0 + languageName: node + linkType: hard + +"@babel/helper-validator-option@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-validator-option@npm:7.25.7" + checksum: 10c0/12ed418c8e3ed9ed44c8c80d823f4e42d399b5eb2e423adccb975e31a31a008cd3b5d8eab688b31f740caff4a1bb28fe06ea2fa7d635aee34cc0ad6995d50f0a + languageName: node + linkType: hard + +"@babel/helpers@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helpers@npm:7.25.7" + dependencies: + "@babel/template": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/3b3ae9e373bd785414195ef8f59976a69d5a6ebe0ef2165fdcc5165e5c3ee09e0fcee94bb457df2ddb8c0532e4146d0a9b7a96b3497399a4bff4ffe196b30228 + languageName: node + linkType: hard + +"@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/highlight@npm:7.25.7" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.25.7" + chalk: "npm:^2.4.2" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.0.0" + checksum: 10c0/1f5894fdb0a0af6101fb2822369b2eeeae32cbeae2ef73ff73fc6a0a4a20471565cd9cfa589f54ed69df66adeca7c57266031ca9134b7bd244d023a488d419aa + languageName: node + linkType: hard + +"@babel/parser@npm:^7.25.7, @babel/parser@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/parser@npm:7.25.8" + dependencies: + "@babel/types": "npm:^7.25.8" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/a1a13845b7e8dda4c970791814a4bbf60004969882f18f470e260ad822d2e1f8941948f851e9335895563610f240fa6c98481ce8019865e469502bbf21daafa4 + languageName: node + linkType: hard + +"@babel/plugin-transform-react-jsx-self@npm:^7.14.5": + version: 7.25.7 + resolution: "@babel/plugin-transform-react-jsx-self@npm:7.25.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.25.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/51ab0302f808186b671722db40ef25d6f691f969aeaa8f7ef8565c5ca227c8b4dbd1002997478414d3f6984b1fd80a01303e98853fd8bd9606c35bcd72c94065 + languageName: node + linkType: hard + +"@babel/plugin-transform-react-jsx-source@npm:^7.14.5": + version: 7.25.7 + resolution: "@babel/plugin-transform-react-jsx-source@npm:7.25.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.25.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/c014de49a466c18ab77bea409542f40409a6a561afc8879ecbeca6a4618161b5aa71ab0825b733c5c87bebe09a19455a79bc1bed86488a84ef712e42e1ed2875 + languageName: node + linkType: hard + +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.7": + version: 7.25.7 + resolution: "@babel/runtime@npm:7.25.7" + dependencies: + regenerator-runtime: "npm:^0.14.0" + checksum: 10c0/86b7829d2fc9343714a9afe92757cf96c4dc799006ca61d73cda62f4b9e29bfa1ce36794955bc6cb4c188f5b10db832c949339895e1bbe81a69022d9d578ce29 + languageName: node + linkType: hard + +"@babel/template@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/template@npm:7.25.7" + dependencies: + "@babel/code-frame": "npm:^7.25.7" + "@babel/parser": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + checksum: 10c0/8ae9e36e4330ee83d4832531d1d9bec7dc2ef6a2a8afa1ef1229506fd60667abcb17f306d1c3d7e582251270597022990c845d5d69e7add70a5aea66720decb9 + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/traverse@npm:7.25.7" + dependencies: + "@babel/code-frame": "npm:^7.25.7" + "@babel/generator": "npm:^7.25.7" + "@babel/parser": "npm:^7.25.7" + "@babel/template": "npm:^7.25.7" + "@babel/types": "npm:^7.25.7" + debug: "npm:^4.3.1" + globals: "npm:^11.1.0" + checksum: 10c0/75d73e52c507a7a7a4c7971d6bf4f8f26fdd094e0d3a0193d77edf6a5efa36fc3db91ec5cc48e8b94e6eb5d5ad21af0a1040e71309172851209415fd105efb1a + languageName: node + linkType: hard + +"@babel/types@npm:^7.25.7, @babel/types@npm:^7.25.8": + version: 7.25.8 + resolution: "@babel/types@npm:7.25.8" + dependencies: + "@babel/helper-string-parser": "npm:^7.25.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" + to-fast-properties: "npm:^2.0.0" + checksum: 10c0/55ca2d6df6426c98db2769ce884ce5e9de83a512ea2dd7bcf56c811984dc14351cacf42932a723630c5afcff2455809323decd645820762182f10b7b5252b59f + languageName: node + linkType: hard + +"@cush/relative@npm:^1.0.0": + version: 1.0.0 + resolution: "@cush/relative@npm:1.0.0" + checksum: 10c0/8c91a1c9875c9a4f8b5e7baf93625fc1381c7964508c8df99ea9e731bd46a148ce6df4934d0c69fbb16188a65ddc263a65b97e62a7e58119a1a805fa309e579d + languageName: node + linkType: hard + +"@emotion/babel-plugin@npm:^11.12.0": + version: 11.12.0 + resolution: "@emotion/babel-plugin@npm:11.12.0" + dependencies: + "@babel/helper-module-imports": "npm:^7.16.7" + "@babel/runtime": "npm:^7.18.3" + "@emotion/hash": "npm:^0.9.2" + "@emotion/memoize": "npm:^0.9.0" + "@emotion/serialize": "npm:^1.2.0" + babel-plugin-macros: "npm:^3.1.0" + convert-source-map: "npm:^1.5.0" + escape-string-regexp: "npm:^4.0.0" + find-root: "npm:^1.1.0" + source-map: "npm:^0.5.7" + stylis: "npm:4.2.0" + checksum: 10c0/930ff6f8768b0c24d05896ad696be20e1c65f32ed61fb5c1488f571120a947ef0a2cf69187b17114cc76e7886f771fac150876ed7b5341324fec2377185d6573 + languageName: node + linkType: hard + +"@emotion/cache@npm:^11.13.0, @emotion/cache@npm:^11.13.1": + version: 11.13.1 + resolution: "@emotion/cache@npm:11.13.1" + dependencies: + "@emotion/memoize": "npm:^0.9.0" + "@emotion/sheet": "npm:^1.4.0" + "@emotion/utils": "npm:^1.4.0" + "@emotion/weak-memoize": "npm:^0.4.0" + stylis: "npm:4.2.0" + checksum: 10c0/321e97d8980885737de13b47e41fd4febfbd83086f10c620f865fcbddb29b8fe198adec7e1c69cc7b137638ea9242d7c475c57f954f7ca229157fa92e368f473 + languageName: node + linkType: hard + +"@emotion/hash@npm:^0.8.0": + version: 0.8.0 + resolution: "@emotion/hash@npm:0.8.0" + checksum: 10c0/706303d35d416217cd7eb0d36dbda4627bb8bdf4a32ea387e8dd99be11b8e0a998e10af21216e8a5fade518ad955ff06aa8890f20e694ce3a038ae7fc1000556 + languageName: node + linkType: hard + +"@emotion/hash@npm:^0.9.2": + version: 0.9.2 + resolution: "@emotion/hash@npm:0.9.2" + checksum: 10c0/0dc254561a3cc0a06a10bbce7f6a997883fd240c8c1928b93713f803a2e9153a257a488537012efe89dbe1246f2abfe2add62cdb3471a13d67137fcb808e81c2 + languageName: node + linkType: hard + +"@emotion/is-prop-valid@npm:^1.3.0": + version: 1.3.1 + resolution: "@emotion/is-prop-valid@npm:1.3.1" + dependencies: + "@emotion/memoize": "npm:^0.9.0" + checksum: 10c0/123215540c816ff510737ec68dcc499c53ea4deb0bb6c2c27c03ed21046e2e69f6ad07a7a174d271c6cfcbcc9ea44e1763e0cf3875c92192f7689216174803cd + languageName: node + linkType: hard + +"@emotion/memoize@npm:^0.9.0": + version: 0.9.0 + resolution: "@emotion/memoize@npm:0.9.0" + checksum: 10c0/13f474a9201c7f88b543e6ea42f55c04fb2fdc05e6c5a3108aced2f7e7aa7eda7794c56bba02985a46d8aaa914fcdde238727a98341a96e2aec750d372dadd15 + languageName: node + linkType: hard + +"@emotion/react@npm:^11.4.1": + version: 11.13.3 + resolution: "@emotion/react@npm:11.13.3" + dependencies: + "@babel/runtime": "npm:^7.18.3" + "@emotion/babel-plugin": "npm:^11.12.0" + "@emotion/cache": "npm:^11.13.0" + "@emotion/serialize": "npm:^1.3.1" + "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.1.0" + "@emotion/utils": "npm:^1.4.0" + "@emotion/weak-memoize": "npm:^0.4.0" + hoist-non-react-statics: "npm:^3.3.1" + peerDependencies: + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/a55e770b9ea35de5d35db05a7ad40a4a3f442809fa8e4fabaf56da63ac9444f09aaf691c4e75a1455dc388991ab0c0ab4e253ce67c5836f27513e45ebd01b673 + languageName: node + linkType: hard + +"@emotion/serialize@npm:^1.2.0, @emotion/serialize@npm:^1.3.0, @emotion/serialize@npm:^1.3.1, @emotion/serialize@npm:^1.3.2": + version: 1.3.2 + resolution: "@emotion/serialize@npm:1.3.2" + dependencies: + "@emotion/hash": "npm:^0.9.2" + "@emotion/memoize": "npm:^0.9.0" + "@emotion/unitless": "npm:^0.10.0" + "@emotion/utils": "npm:^1.4.1" + csstype: "npm:^3.0.2" + checksum: 10c0/b4873b643721d28b4450f9d77b71e6c8d0109e6825c54fc79e649d2fa438fe4080d2fa696ec8fda421b8e713fcd42306d6197b6121ddd2486ffab8e4b6311ce0 + languageName: node + linkType: hard + +"@emotion/sheet@npm:^1.4.0": + version: 1.4.0 + resolution: "@emotion/sheet@npm:1.4.0" + checksum: 10c0/3ca72d1650a07d2fbb7e382761b130b4a887dcd04e6574b2d51ce578791240150d7072a9bcb4161933abbcd1e38b243a6fb4464a7fe991d700c17aa66bb5acc7 + languageName: node + linkType: hard + +"@emotion/styled@npm:^11.13.0": + version: 11.13.0 + resolution: "@emotion/styled@npm:11.13.0" + dependencies: + "@babel/runtime": "npm:^7.18.3" + "@emotion/babel-plugin": "npm:^11.12.0" + "@emotion/is-prop-valid": "npm:^1.3.0" + "@emotion/serialize": "npm:^1.3.0" + "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.1.0" + "@emotion/utils": "npm:^1.4.0" + peerDependencies: + "@emotion/react": ^11.0.0-rc.0 + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/5e2cc85c8a2f6e7bd012731cf0b6da3aef5906225e87e8d4a5c19da50572e24d9aaf92615aa36aa863f0fe6b62a121033356e1cad62617c48bfdaa2c3cf0d8a4 + languageName: node + linkType: hard + +"@emotion/unitless@npm:^0.10.0": + version: 0.10.0 + resolution: "@emotion/unitless@npm:0.10.0" + checksum: 10c0/150943192727b7650eb9a6851a98034ddb58a8b6958b37546080f794696141c3760966ac695ab9af97efe10178690987aee4791f9f0ad1ff76783cdca83c1d49 + languageName: node + linkType: hard + +"@emotion/use-insertion-effect-with-fallbacks@npm:^1.1.0": + version: 1.1.0 + resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.1.0" + peerDependencies: + react: ">=16.8.0" + checksum: 10c0/a883480f3a7139fb4a43e71d3114ca57e2b7ae5ff204e05cd9e59251a113773b8f64eb75d3997726250aca85eb73447638c8f51930734bdd16b96762b65e58c3 + languageName: node + linkType: hard + +"@emotion/utils@npm:^1.4.0, @emotion/utils@npm:^1.4.1": + version: 1.4.1 + resolution: "@emotion/utils@npm:1.4.1" + checksum: 10c0/f4704e0bdf48062fd6eb9c64771c88f521aab1e108a48cb23d65b6438597c63a6945301cef4c43611e79e0e76a304ec5481c31025ea8f573d7ad5423d747602c + languageName: node + linkType: hard + +"@emotion/weak-memoize@npm:^0.4.0": + version: 0.4.0 + resolution: "@emotion/weak-memoize@npm:0.4.0" + checksum: 10c0/64376af11f1266042d03b3305c30b7502e6084868e33327e944b539091a472f089db307af69240f7188f8bc6b319276fd7b141a36613f1160d73d12a60f6ca1a + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.14.54": + version: 0.14.54 + resolution: "@esbuild/linux-loong64@npm:0.14.54" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^0.4.3": + version: 0.4.3 + resolution: "@eslint/eslintrc@npm:0.4.3" + dependencies: + ajv: "npm:^6.12.4" + debug: "npm:^4.1.1" + espree: "npm:^7.3.0" + globals: "npm:^13.9.0" + ignore: "npm:^4.0.6" + import-fresh: "npm:^3.2.1" + js-yaml: "npm:^3.13.1" + minimatch: "npm:^3.0.4" + strip-json-comments: "npm:^3.1.1" + checksum: 10c0/0eed93369f72ef044686d07824742121f9b95153ff34f4614e4e69d64332ee68c84eb70da851a9005bb76b3d1d64ad76c2e6293a808edc0f7dfb883689ca136d + languageName: node + linkType: hard + +"@floating-ui/core@npm:^1.6.0": + version: 1.6.8 + resolution: "@floating-ui/core@npm:1.6.8" + dependencies: + "@floating-ui/utils": "npm:^0.2.8" + checksum: 10c0/d6985462aeccae7b55a2d3f40571551c8c42bf820ae0a477fc40ef462e33edc4f3f5b7f11b100de77c9b58ecb581670c5c3f46d0af82b5e30aa185c735257eb9 + languageName: node + linkType: hard + +"@floating-ui/dom@npm:^1.0.0": + version: 1.6.11 + resolution: "@floating-ui/dom@npm:1.6.11" + dependencies: + "@floating-ui/core": "npm:^1.6.0" + "@floating-ui/utils": "npm:^0.2.8" + checksum: 10c0/02ef34a75a515543c772880338eea7b66724997bd5ec7cd58d26b50325709d46d480a306b84e7d5509d734434411a4bcf23af5680c2e461e6e6a8bf45d751df8 + languageName: node + linkType: hard + +"@floating-ui/react-dom@npm:^2.1.1": + version: 2.1.2 + resolution: "@floating-ui/react-dom@npm:2.1.2" + dependencies: + "@floating-ui/dom": "npm:^1.0.0" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 10c0/e855131c74e68cab505f7f44f92cd4e2efab1c125796db3116c54c0859323adae4bf697bf292ee83ac77b9335a41ad67852193d7aeace90aa2e1c4a640cafa60 + languageName: node + linkType: hard + +"@floating-ui/utils@npm:^0.2.8": + version: 0.2.8 + resolution: "@floating-ui/utils@npm:0.2.8" + checksum: 10c0/a8cee5f17406c900e1c3ef63e3ca89b35e7a2ed645418459a73627b93b7377477fc888081011c6cd177cac45ec2b92a6cab018c14ea140519465498dddd2d3f9 + languageName: node + linkType: hard + +"@footron/controls-cli@npm:^0.1.1": + version: 0.1.3 + resolution: "@footron/controls-cli@npm:0.1.3" + dependencies: + "@footron/controls-client": "npm:^0.1.14" + "@material-ui/core": "npm:^4.12.1" + "@material-ui/icons": "npm:^4.11.2" + connect: "npm:^3.7.0" + fs-extra: "npm:^10.0.0" + react: "npm:^17.0.2" + react-dom: "npm:^17.0.2" + rollup: "npm:^2.53.0" + vite: "npm:^2.4.1" + vite-tsconfig-paths: "npm:^3.3.13" + yargs: "npm:^17.0.1" + bin: + ftcontrols: dist/lib/cli.js + checksum: 10c0/d05cf5ffc87e004202b54aefae993de21908aee4124c7e8309c76d99a0be71dfb03c1c9e804b48509d4e725df6692fad04fafe0950f5843c974bf11a6426fe49 + languageName: node + linkType: hard + +"@footron/controls-client@npm:^0.1.14": + version: 0.1.34 + resolution: "@footron/controls-client@npm:0.1.34" + dependencies: + uuid: "npm:^8.3.2" + checksum: 10c0/a73c9ce3d23f92b02d2a18022fb2385e3b726ddb7519fbde9bf56ee5c5f9048bfd18c550bc7d56d96715d20a1ff349329f000b04b9766725a185bf09eaefbd75 + languageName: node + linkType: hard + +"@footron/controls-typescript-template@workspace:.": + version: 0.0.0-use.local + resolution: "@footron/controls-typescript-template@workspace:." + dependencies: + "@emotion/react": "npm:^11.4.1" + "@emotion/styled": "npm:^11.13.0" + "@footron/controls-cli": "npm:^0.1.1" + "@footron/controls-client": "npm:^0.1.14" + "@material-ui/core": "npm:^4.12.1" + "@material-ui/icons": "npm:^4.11.2" + "@mui/base": "npm:5.0.0-beta.59" + "@mui/icons-material": "npm:^6.1.4" + "@mui/material": "npm:^6.1.4" + "@types/react": "npm:^17.0.14" + "@types/react-dom": "npm:^17.0.9" + "@types/react-router-dom": "npm:^5.1.8" + "@typescript-eslint/eslint-plugin": "npm:^4.28.2" + "@typescript-eslint/parser": "npm:^4.28.2" + "@vitejs/plugin-react-refresh": "npm:^1.3.5" + eslint: "npm:^7.32.0" + eslint-config-prettier: "npm:^8.3.0" + eslint-config-standard: "npm:^16.0.3" + eslint-import-resolver-node: "npm:^0.3.4" + eslint-plugin-import: "npm:^2.23.4" + eslint-plugin-node: "npm:^11.1.0" + eslint-plugin-promise: "npm:^5.1.0" + eslint-plugin-react: "npm:^7.24.0" + husky: "npm:>=6" + lint-staged: "npm:>=10" + pinst: "npm:>=2" + prettier: "npm:^2.3.2" + react: "npm:^17.0.2" + react-cool-dimensions: "npm:^2.0.7" + react-dom: "npm:^17.0.2" + react-joystick-component: "npm:^6.2.1" + react-router-dom: "npm:^5.2.0" + typescript: "npm:4.3.5" + vite: "npm:2.4.1" + languageName: unknown + linkType: soft + +"@humanwhocodes/config-array@npm:^0.5.0": + version: 0.5.0 + resolution: "@humanwhocodes/config-array@npm:0.5.0" + dependencies: + "@humanwhocodes/object-schema": "npm:^1.2.0" + debug: "npm:^4.1.1" + minimatch: "npm:^3.0.4" + checksum: 10c0/217fac9e03492361825a2bf761d4bb7ec6d10002a10f7314142245eb13ac9d123523d24d5619c3c4159af215c7b3e583ed386108e227014bef4efbf9caca8ccc + languageName: node + linkType: hard + +"@humanwhocodes/object-schema@npm:^1.2.0": + version: 1.2.1 + resolution: "@humanwhocodes/object-schema@npm:1.2.1" + checksum: 10c0/c3c35fdb70c04a569278351c75553e293ae339684ed75895edc79facc7276e351115786946658d78133130c0cca80e57e2203bc07f8fa7fe7980300e8deef7db + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" + dependencies: + "@jridgewell/set-array": "npm:^1.2.1" + "@jridgewell/sourcemap-codec": "npm:^1.4.10" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/1be4fd4a6b0f41337c4f5fdf4afc3bd19e39c3691924817108b82ffcb9c9e609c273f936932b9fba4b3a298ce2eb06d9bff4eb1cc3bd81c4f4ee1b4917e25feb + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e + languageName: node + linkType: hard + +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 10c0/2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 10c0/2eb864f276eb1096c3c11da3e9bb518f6d9fc0023c78344cdc037abadc725172c70314bdb360f2d4b7bffec7f5d657ce006816bc5d4ecb35e61b66132db00c18 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10c0/3d1ce6ebc69df9682a5a8896b414c6537e428a1d68b02fcc8363b04284a8ca0df04d0ee3013132252ab14f2527bc13bea6526a912ecb5658f0e39fd2860b4df4 + languageName: node + linkType: hard + +"@material-ui/core@npm:^4.12.1": + version: 4.12.4 + resolution: "@material-ui/core@npm:4.12.4" + dependencies: + "@babel/runtime": "npm:^7.4.4" + "@material-ui/styles": "npm:^4.11.5" + "@material-ui/system": "npm:^4.12.2" + "@material-ui/types": "npm:5.1.0" + "@material-ui/utils": "npm:^4.11.3" + "@types/react-transition-group": "npm:^4.2.0" + clsx: "npm:^1.0.4" + hoist-non-react-statics: "npm:^3.3.2" + popper.js: "npm:1.16.1-lts" + prop-types: "npm:^15.7.2" + react-is: "npm:^16.8.0 || ^17.0.0" + react-transition-group: "npm:^4.4.0" + peerDependencies: + "@types/react": ^16.8.6 || ^17.0.0 + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/4a6544d4a535f0b5bf4a900509391640f490cef9022f7667cf5dceb75d5bec7df1e9b68bc44bbfa4e5d47d0093ac2477e77d76d8a6d241791753c6e8e7bd6603 + languageName: node + linkType: hard + +"@material-ui/icons@npm:^4.11.2": + version: 4.11.3 + resolution: "@material-ui/icons@npm:4.11.3" + dependencies: + "@babel/runtime": "npm:^7.4.4" + peerDependencies: + "@material-ui/core": ^4.0.0 + "@types/react": ^16.8.6 || ^17.0.0 + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/2c405785fc9f98a7d50a796fd294c52b5447b61c5a3d4563d86e07164400cda2ac667c944110b0ab8eca80f880b01846cf3525cbd05c5584b782c3bb4fd2d6eb + languageName: node + linkType: hard + +"@material-ui/styles@npm:^4.11.5": + version: 4.11.5 + resolution: "@material-ui/styles@npm:4.11.5" + dependencies: + "@babel/runtime": "npm:^7.4.4" + "@emotion/hash": "npm:^0.8.0" + "@material-ui/types": "npm:5.1.0" + "@material-ui/utils": "npm:^4.11.3" + clsx: "npm:^1.0.4" + csstype: "npm:^2.5.2" + hoist-non-react-statics: "npm:^3.3.2" + jss: "npm:^10.5.1" + jss-plugin-camel-case: "npm:^10.5.1" + jss-plugin-default-unit: "npm:^10.5.1" + jss-plugin-global: "npm:^10.5.1" + jss-plugin-nested: "npm:^10.5.1" + jss-plugin-props-sort: "npm:^10.5.1" + jss-plugin-rule-value-function: "npm:^10.5.1" + jss-plugin-vendor-prefixer: "npm:^10.5.1" + prop-types: "npm:^15.7.2" + peerDependencies: + "@types/react": ^16.8.6 || ^17.0.0 + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/b03b930d16cb97926629e3643054abf9fdc1f963398699d9c0e57023d4a80e743337d2e5c1020af90f0ced16665c73dd79025c2322292ffdac21b5f65450e165 + languageName: node + linkType: hard + +"@material-ui/system@npm:^4.12.2": + version: 4.12.2 + resolution: "@material-ui/system@npm:4.12.2" + dependencies: + "@babel/runtime": "npm:^7.4.4" + "@material-ui/utils": "npm:^4.11.3" + csstype: "npm:^2.5.2" + prop-types: "npm:^15.7.2" + peerDependencies: + "@types/react": ^16.8.6 || ^17.0.0 + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/7c423b1259c593385626abd414216f901aeab6dd54f0a3d8bf132eb2008b3e748c44c10c0315aa33cebd44ddbb1be789bc06c9dc652d191091e3198a07758d79 + languageName: node + linkType: hard + +"@material-ui/types@npm:5.1.0": + version: 5.1.0 + resolution: "@material-ui/types@npm:5.1.0" + peerDependencies: + "@types/react": "*" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/89ec44cb31c1098fd20864f487c79f1b7267fc53dbbf132e5fad7090480e0e43a2a5e4d5e343c51ff7fc12a90484685cf286233c754af05b5fb03ac34416145b + languageName: node + linkType: hard + +"@material-ui/utils@npm:^4.11.3": + version: 4.11.3 + resolution: "@material-ui/utils@npm:4.11.3" + dependencies: + "@babel/runtime": "npm:^7.4.4" + prop-types: "npm:^15.7.2" + react-is: "npm:^16.8.0 || ^17.0.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + checksum: 10c0/af6d227bee05cae9044a683da94f9463748aa6166ddabc85e5301612a66067a35b20661f212a3118556ce40d6f0d3d9a70f559bfb41c036b57f710e5901c5809 + languageName: node + linkType: hard + +"@mui/base@npm:5.0.0-beta.59": + version: 5.0.0-beta.59 + resolution: "@mui/base@npm:5.0.0-beta.59" + dependencies: + "@babel/runtime": "npm:^7.25.7" + "@floating-ui/react-dom": "npm:^2.1.1" + "@mui/types": "npm:^7.2.18" + "@mui/utils": "npm:^6.1.4" + "@popperjs/core": "npm:^2.11.8" + clsx: "npm:^2.1.1" + prop-types: "npm:^15.8.1" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/ba211b939346b78a1848861501fbddd35a40d99f3455d4e6af889681cf28fc9e8392afe5e1f6ef3c58d12142a301df02d3b232352a19d018762f6366995a5eae + languageName: node + linkType: hard + +"@mui/core-downloads-tracker@npm:^6.1.4": + version: 6.1.4 + resolution: "@mui/core-downloads-tracker@npm:6.1.4" + checksum: 10c0/bfd84a726c883dd681b2cda13b977eb6646c1da66ea59905dbe7b857ec4ac86576a318eb116d54633e7c479aecb52fe0c75fb957f1b6081a6c8857dd5ce4c5b9 + languageName: node + linkType: hard + +"@mui/icons-material@npm:^6.1.4": + version: 6.1.4 + resolution: "@mui/icons-material@npm:6.1.4" + dependencies: + "@babel/runtime": "npm:^7.25.7" + peerDependencies: + "@mui/material": ^6.1.4 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/8e4e8a20c7183fae76f1e013669212404696e9e146aa413afbc705ee56f0a32cfef6143a16f9ec24aeb1e8dfb567d50f9b04b9bdf381ad8bd7a2c9b09d25186c + languageName: node + linkType: hard + +"@mui/material@npm:^6.1.4": + version: 6.1.4 + resolution: "@mui/material@npm:6.1.4" + dependencies: + "@babel/runtime": "npm:^7.25.7" + "@mui/core-downloads-tracker": "npm:^6.1.4" + "@mui/system": "npm:^6.1.4" + "@mui/types": "npm:^7.2.18" + "@mui/utils": "npm:^6.1.4" + "@popperjs/core": "npm:^2.11.8" + "@types/react-transition-group": "npm:^4.4.11" + clsx: "npm:^2.1.1" + csstype: "npm:^3.1.3" + prop-types: "npm:^15.8.1" + react-is: "npm:^18.3.1" + react-transition-group: "npm:^4.4.5" + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@mui/material-pigment-css": ^6.1.4 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@mui/material-pigment-css": + optional: true + "@types/react": + optional: true + checksum: 10c0/3729e56129b27706ebfab67428035dc7f0136dfd745281b467c7da07e78248cc8e2f36939cd6c33967fd565c5b5eff336629e3f7a2d877e9b176d24df67c9c81 + languageName: node + linkType: hard + +"@mui/private-theming@npm:^6.1.4": + version: 6.1.4 + resolution: "@mui/private-theming@npm:6.1.4" + dependencies: + "@babel/runtime": "npm:^7.25.7" + "@mui/utils": "npm:^6.1.4" + prop-types: "npm:^15.8.1" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/37c81ca4529afbec2a4710d4dfa1597a5f9a33ff3ae775fa68474f86b223ed4ab953526e49883d77638ad62f0c944716c2b0dc58a105624ca91fe60a633e3b4a + languageName: node + linkType: hard + +"@mui/styled-engine@npm:^6.1.4": + version: 6.1.4 + resolution: "@mui/styled-engine@npm:6.1.4" + dependencies: + "@babel/runtime": "npm:^7.25.7" + "@emotion/cache": "npm:^11.13.1" + "@emotion/serialize": "npm:^1.3.2" + "@emotion/sheet": "npm:^1.4.0" + csstype: "npm:^3.1.3" + prop-types: "npm:^15.8.1" + peerDependencies: + "@emotion/react": ^11.4.1 + "@emotion/styled": ^11.3.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + checksum: 10c0/ce8f53a704aa607152ef5ef25d95bdd5c4399f7dbf240acd6e4057c24d84536bb3c884fcb13c5e88d87dbfff42935c82af2e63800ba033ad481847b1967ccf52 + languageName: node + linkType: hard + +"@mui/system@npm:^6.1.4": + version: 6.1.4 + resolution: "@mui/system@npm:6.1.4" + dependencies: + "@babel/runtime": "npm:^7.25.7" + "@mui/private-theming": "npm:^6.1.4" + "@mui/styled-engine": "npm:^6.1.4" + "@mui/types": "npm:^7.2.18" + "@mui/utils": "npm:^6.1.4" + clsx: "npm:^2.1.1" + csstype: "npm:^3.1.3" + prop-types: "npm:^15.8.1" + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: 10c0/766f1c695254df54b06de1af231cdf30752f71a79181edd4c24044405144b7a72c4c23248155f4041999993aa4f568878eccd130c100b4b332e7dd6b322dfd75 + languageName: node + linkType: hard + +"@mui/types@npm:^7.2.18": + version: 7.2.18 + resolution: "@mui/types@npm:7.2.18" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/338404bdef7c7f9ebcd389ebbf429c44d2cc9c25c65d8669dc900a24b2c8718240482273bf6cd953578965e3838ad40a8e7376c71d3d9146be3afb88bff1b67a + languageName: node + linkType: hard + +"@mui/utils@npm:^6.1.4": + version: 6.1.4 + resolution: "@mui/utils@npm:6.1.4" + dependencies: + "@babel/runtime": "npm:^7.25.7" + "@mui/types": "npm:^7.2.18" + "@types/prop-types": "npm:^15.7.13" + clsx: "npm:^2.1.1" + prop-types: "npm:^15.8.1" + react-is: "npm:^18.3.1" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/cac4f05904897c28444e7ef2a6891678d36c0a8fae921ccacebcd7b53da99e4c6cab05669328fdabff624313de68f1b5bcd427cba36024b6c3505b5ee945eb05 + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^2.0.0": + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.3" + checksum: 10c0/325e0db7b287d4154ecd164c0815c08007abfb07653cc57bceded17bb7fd240998a3cbdbe87d700e30bef494885eccc725ab73b668020811d56623d145b524ae + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.1 + resolution: "@npmcli/fs@npm:3.1.1" + dependencies: + semver: "npm:^7.3.5" + checksum: 10c0/c37a5b4842bfdece3d14dfdb054f73fe15ed2d3da61b34ff76629fb5b1731647c49166fd2a8bf8b56fcfa51200382385ea8909a3cbecdad612310c114d3f6c99 + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd + languageName: node + linkType: hard + +"@popperjs/core@npm:^2.11.8": + version: 2.11.8 + resolution: "@popperjs/core@npm:2.11.8" + checksum: 10c0/4681e682abc006d25eb380d0cf3efc7557043f53b6aea7a5057d0d1e7df849a00e281cd8ea79c902a35a414d7919621fc2ba293ecec05f413598e0b23d5a1e63 + languageName: node + linkType: hard + +"@rollup/pluginutils@npm:^4.1.1": + version: 4.2.1 + resolution: "@rollup/pluginutils@npm:4.2.1" + dependencies: + estree-walker: "npm:^2.0.1" + picomatch: "npm:^2.2.2" + checksum: 10c0/3ee56b2c8f1ed8dfd0a92631da1af3a2dfdd0321948f089b3752b4de1b54dc5076701eadd0e5fc18bd191b77af594ac1db6279e83951238ba16bf8a414c64c48 + languageName: node + linkType: hard + +"@rtsao/scc@npm:^1.1.0": + version: 1.1.0 + resolution: "@rtsao/scc@npm:1.1.0" + checksum: 10c0/b5bcfb0d87f7d1c1c7c0f7693f53b07866ed9fec4c34a97a8c948fb9a7c0082e416ce4d3b60beb4f5e167cbe04cdeefbf6771320f3ede059b9ce91188c409a5b + languageName: node + linkType: hard + +"@types/history@npm:^4.7.11": + version: 4.7.11 + resolution: "@types/history@npm:4.7.11" + checksum: 10c0/3facf37c2493d1f92b2e93a22cac7ea70b06351c2ab9aaceaa3c56aa6099fb63516f6c4ec1616deb5c56b4093c026a043ea2d3373e6c0644d55710364d02c934 + languageName: node + linkType: hard + +"@types/json-schema@npm:^7.0.7": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db + languageName: node + linkType: hard + +"@types/json5@npm:^0.0.29": + version: 0.0.29 + resolution: "@types/json5@npm:0.0.29" + checksum: 10c0/6bf5337bc447b706bb5b4431d37686aa2ea6d07cfd6f79cc31de80170d6ff9b1c7384a9c0ccbc45b3f512bae9e9f75c2e12109806a15331dc94e8a8db6dbb4ac + languageName: node + linkType: hard + +"@types/parse-json@npm:^4.0.0": + version: 4.0.2 + resolution: "@types/parse-json@npm:4.0.2" + checksum: 10c0/b1b863ac34a2c2172fbe0807a1ec4d5cb684e48d422d15ec95980b81475fac4fdb3768a8b13eef39130203a7c04340fc167bae057c7ebcafd7dec9fe6c36aeb1 + languageName: node + linkType: hard + +"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.13": + version: 15.7.13 + resolution: "@types/prop-types@npm:15.7.13" + checksum: 10c0/1b20fc67281902c6743379960247bc161f3f0406ffc0df8e7058745a85ea1538612109db0406290512947f9632fe9e10e7337bf0ce6338a91d6c948df16a7c61 + languageName: node + linkType: hard + +"@types/react-dom@npm:^17.0.9": + version: 17.0.25 + resolution: "@types/react-dom@npm:17.0.25" + dependencies: + "@types/react": "npm:^17" + checksum: 10c0/18a95d4d684cacc697d97ae66e3c8402da2f866c053fa6a5982694aa8eb6229afcefd3bfaaab4175c1b0ef3494c881e4d25e2167aa669bcbbb84114fd02ae5ba + languageName: node + linkType: hard + +"@types/react-router-dom@npm:^5.1.8": + version: 5.3.3 + resolution: "@types/react-router-dom@npm:5.3.3" + dependencies: + "@types/history": "npm:^4.7.11" + "@types/react": "npm:*" + "@types/react-router": "npm:*" + checksum: 10c0/a9231a16afb9ed5142678147eafec9d48582809295754fb60946e29fcd3757a4c7a3180fa94b45763e4c7f6e3f02379e2fcb8dd986db479dcab40eff5fc62a91 + languageName: node + linkType: hard + +"@types/react-router@npm:*": + version: 5.1.20 + resolution: "@types/react-router@npm:5.1.20" + dependencies: + "@types/history": "npm:^4.7.11" + "@types/react": "npm:*" + checksum: 10c0/1f7eee61981d2f807fa01a34a0ef98ebc0774023832b6611a69c7f28fdff01de5a38cabf399f32e376bf8099dcb7afaf724775bea9d38870224492bea4cb5737 + languageName: node + linkType: hard + +"@types/react-transition-group@npm:^4.2.0, @types/react-transition-group@npm:^4.4.11": + version: 4.4.11 + resolution: "@types/react-transition-group@npm:4.4.11" + dependencies: + "@types/react": "npm:*" + checksum: 10c0/8fbf0dcc1b81985cdcebe3c59d769fe2ea3f4525f12c3a10a7429a59f93e303c82b2abb744d21cb762879f4514969d70a7ab11b9bf486f92213e8fe70e04098d + languageName: node + linkType: hard + +"@types/react@npm:*": + version: 18.3.11 + resolution: "@types/react@npm:18.3.11" + dependencies: + "@types/prop-types": "npm:*" + csstype: "npm:^3.0.2" + checksum: 10c0/ce80512246ca5bda69db85b9f4f1835189334acfb6b2c4f3eda8cabff1ff1a3ea9ce4f3b895bdbc18c94140aa45592331aa3fdeb557f525c1b048de7ce84fc0e + languageName: node + linkType: hard + +"@types/react@npm:^17, @types/react@npm:^17.0.14": + version: 17.0.83 + resolution: "@types/react@npm:17.0.83" + dependencies: + "@types/prop-types": "npm:*" + "@types/scheduler": "npm:^0.16" + csstype: "npm:^3.0.2" + checksum: 10c0/c8f76790190a9df42099f5f78d08dd4095f2da3bd97ff7cce0001d5a97ff3ffb31f703575acf2c457606e0d0b229ca8d1ba0ff459b77a4e44c5ea5154fe3fb4b + languageName: node + linkType: hard + +"@types/scheduler@npm:^0.16": + version: 0.16.8 + resolution: "@types/scheduler@npm:0.16.8" + checksum: 10c0/f86de504945b8fc41b1f391f847444d542e2e4067cf7e5d9bfeb5d2d2393d3203b1161bc0ef3b1e104d828dabfb60baf06e8d2c27e27ff7e8258e6e618d8c4ec + languageName: node + linkType: hard + +"@typescript-eslint/eslint-plugin@npm:^4.28.2": + version: 4.33.0 + resolution: "@typescript-eslint/eslint-plugin@npm:4.33.0" + dependencies: + "@typescript-eslint/experimental-utils": "npm:4.33.0" + "@typescript-eslint/scope-manager": "npm:4.33.0" + debug: "npm:^4.3.1" + functional-red-black-tree: "npm:^1.0.1" + ignore: "npm:^5.1.8" + regexpp: "npm:^3.1.0" + semver: "npm:^7.3.5" + tsutils: "npm:^3.21.0" + peerDependencies: + "@typescript-eslint/parser": ^4.0.0 + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/c1e1e424e257fa6e5e8b18d7ff77e8a983a761f4acc0cd58ebd31de8ec56c8c472689989cff0290eee41457662a1e664b555cf74bfc1b37bdf8c87ccac2a4663 + languageName: node + linkType: hard + +"@typescript-eslint/experimental-utils@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/experimental-utils@npm:4.33.0" + dependencies: + "@types/json-schema": "npm:^7.0.7" + "@typescript-eslint/scope-manager": "npm:4.33.0" + "@typescript-eslint/types": "npm:4.33.0" + "@typescript-eslint/typescript-estree": "npm:4.33.0" + eslint-scope: "npm:^5.1.1" + eslint-utils: "npm:^3.0.0" + peerDependencies: + eslint: "*" + checksum: 10c0/bb2a48c9df21ef06ccbcd083753b8c51b30a46cde67ab56d278b30ad7868d2e07641e51b6f7fb54437dcb7aff134fac44708e730e2b8f6e43027fefe8629bcb9 + languageName: node + linkType: hard + +"@typescript-eslint/parser@npm:^4.28.2": + version: 4.33.0 + resolution: "@typescript-eslint/parser@npm:4.33.0" + dependencies: + "@typescript-eslint/scope-manager": "npm:4.33.0" + "@typescript-eslint/types": "npm:4.33.0" + "@typescript-eslint/typescript-estree": "npm:4.33.0" + debug: "npm:^4.3.1" + peerDependencies: + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/d6f91479b2c0d0ff20ac2dbc7540b28c175fd834a220a4f227209f6c74c55401ac6bd41b2bb4cf40b3ba7761075ccded2019bfc6096c2e4f273bd4ae86c44172 + languageName: node + linkType: hard + +"@typescript-eslint/scope-manager@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/scope-manager@npm:4.33.0" + dependencies: + "@typescript-eslint/types": "npm:4.33.0" + "@typescript-eslint/visitor-keys": "npm:4.33.0" + checksum: 10c0/1dfe65777eeb430c1ef778bdad35e6065d4b3075ddb2639d0747d8db93c02eebf6832ba82388a7f80662e0e9f61f1922fe939b53a20889e11fb9f80c4029c6b7 + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/types@npm:4.33.0" + checksum: 10c0/6c94780a589eca7a75ae2b014f320bc412b50794c39ab04889918bb39a40e72584b65c8c0b035330cb0599579afaa3adccee40701f63cf39c0e89299de199d4b + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/typescript-estree@npm:4.33.0" + dependencies: + "@typescript-eslint/types": "npm:4.33.0" + "@typescript-eslint/visitor-keys": "npm:4.33.0" + debug: "npm:^4.3.1" + globby: "npm:^11.0.3" + is-glob: "npm:^4.0.1" + semver: "npm:^7.3.5" + tsutils: "npm:^3.21.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/67609a7bdd680136765d103dec4b8afb38a17436e8a5cd830da84f62c6153c3acba561da3b9e2140137b1a0bcbbfc19d4256c692f7072acfebcff88db079e22b + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/visitor-keys@npm:4.33.0" + dependencies: + "@typescript-eslint/types": "npm:4.33.0" + eslint-visitor-keys: "npm:^2.0.0" + checksum: 10c0/95b3904db6113ef365892567d47365e6af3708e6fa905743426036f99e1b7fd4a275facec5d939afecb618369f9d615e379d39f96b8936f469e75507c41c249c + languageName: node + linkType: hard + +"@vitejs/plugin-react-refresh@npm:^1.3.5": + version: 1.3.6 + resolution: "@vitejs/plugin-react-refresh@npm:1.3.6" + dependencies: + "@babel/core": "npm:^7.14.8" + "@babel/plugin-transform-react-jsx-self": "npm:^7.14.5" + "@babel/plugin-transform-react-jsx-source": "npm:^7.14.5" + "@rollup/pluginutils": "npm:^4.1.1" + react-refresh: "npm:^0.10.0" + checksum: 10c0/991c714beca345f3693ff61409b2c5a8c63b1c09e8f5c71af9f107173889a97a57b1a209c92b8a20113028114e1206971fb3acc85a608f249ff5cf2d103db7fa + languageName: node + linkType: hard + +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372 + languageName: node + linkType: hard + +"acorn-jsx@npm:^5.3.1": + version: 5.3.2 + resolution: "acorn-jsx@npm:5.3.2" + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: 10c0/4c54868fbef3b8d58927d5e33f0a4de35f59012fe7b12cf9dfbb345fb8f46607709e1c4431be869a23fb63c151033d84c4198fa9f79385cec34fcb1dd53974c1 + languageName: node + linkType: hard + +"acorn@npm:^7.4.0": + version: 7.4.1 + resolution: "acorn@npm:7.4.1" + bin: + acorn: bin/acorn + checksum: 10c0/bd0b2c2b0f334bbee48828ff897c12bd2eb5898d03bf556dcc8942022cec795ac5bb5b6b585e2de687db6231faf07e096b59a361231dd8c9344d5df5f7f0e526 + languageName: node + linkType: hard + +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" + dependencies: + debug: "npm:^4.3.4" + checksum: 10c0/e59ce7bed9c63bf071a30cc471f2933862044c97fd9958967bfe22521d7a0f601ce4ed5a8c011799d0c726ca70312142ae193bbebb60f576b52be19d4a363b50 + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039 + languageName: node + linkType: hard + +"ajv@npm:^6.10.0, ajv@npm:^6.12.4": + version: 6.12.6 + resolution: "ajv@npm:6.12.6" + dependencies: + fast-deep-equal: "npm:^3.1.1" + fast-json-stable-stringify: "npm:^2.0.0" + json-schema-traverse: "npm:^0.4.1" + uri-js: "npm:^4.2.2" + checksum: 10c0/41e23642cbe545889245b9d2a45854ebba51cda6c778ebced9649420d9205f2efb39cb43dbc41e358409223b1ea43303ae4839db682c848b891e4811da1a5a71 + languageName: node + linkType: hard + +"ajv@npm:^8.0.1": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^3.0.1" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35 + languageName: node + linkType: hard + +"ansi-colors@npm:^4.1.1": + version: 4.1.3 + resolution: "ansi-colors@npm:4.1.3" + checksum: 10c0/ec87a2f59902f74e61eada7f6e6fe20094a628dab765cfdbd03c3477599368768cffccdb5d3bb19a1b6c99126783a143b1fee31aab729b31ffe5836c7e5e28b9 + languageName: node + linkType: hard + +"ansi-escapes@npm:^7.0.0": + version: 7.0.0 + resolution: "ansi-escapes@npm:7.0.0" + dependencies: + environment: "npm:^1.0.0" + checksum: 10c0/86e51e36fabef18c9c004af0a280573e828900641cea35134a124d2715e0c5a473494ab4ce396614505da77638ae290ff72dd8002d9747d2ee53f5d6bbe336be + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.1.0 + resolution: "ansi-regex@npm:6.1.0" + checksum: 10c0/a91daeddd54746338478eef88af3439a7edf30f8e23196e2d6ed182da9add559c601266dbef01c2efa46a958ad6f1f8b176799657616c702b5b02e799e7fd8dc + languageName: node + linkType: hard + +"ansi-styles@npm:^3.2.1": + version: 3.2.1 + resolution: "ansi-styles@npm:3.2.1" + dependencies: + color-convert: "npm:^1.9.0" + checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: 10c0/5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c + languageName: node + linkType: hard + +"any-promise@npm:^1.0.0": + version: 1.3.0 + resolution: "any-promise@npm:1.3.0" + checksum: 10c0/60f0298ed34c74fef50daab88e8dab786036ed5a7fad02e012ab57e376e0a0b4b29e83b95ea9b5e7d89df762f5f25119b83e00706ecaccb22cfbacee98d74889 + languageName: node + linkType: hard + +"argparse@npm:^1.0.7": + version: 1.0.10 + resolution: "argparse@npm:1.0.10" + dependencies: + sprintf-js: "npm:~1.0.2" + checksum: 10c0/b2972c5c23c63df66bca144dbc65d180efa74f25f8fd9b7d9a0a6c88ae839db32df3d54770dcb6460cf840d232b60695d1a6b1053f599d84e73f7437087712de + languageName: node + linkType: hard + +"array-buffer-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "array-buffer-byte-length@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.5" + is-array-buffer: "npm:^3.0.4" + checksum: 10c0/f5cdf54527cd18a3d2852ddf73df79efec03829e7373a8322ef5df2b4ef546fb365c19c71d6b42d641cb6bfe0f1a2f19bc0ece5b533295f86d7c3d522f228917 + languageName: node + linkType: hard + +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8": + version: 3.1.8 + resolution: "array-includes@npm:3.1.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-object-atoms: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.4" + is-string: "npm:^1.0.7" + checksum: 10c0/5b1004d203e85873b96ddc493f090c9672fd6c80d7a60b798da8a14bff8a670ff95db5aafc9abc14a211943f05220dacf8ea17638ae0af1a6a47b8c0b48ce370 + languageName: node + linkType: hard + +"array-union@npm:^2.1.0": + version: 2.1.0 + resolution: "array-union@npm:2.1.0" + checksum: 10c0/429897e68110374f39b771ec47a7161fc6a8fc33e196857c0a396dc75df0b5f65e4d046674db764330b6bb66b39ef48dd7c53b6a2ee75cfb0681e0c1a7033962 + languageName: node + linkType: hard + +"array.prototype.findlast@npm:^1.2.5": + version: 1.2.5 + resolution: "array.prototype.findlast@npm:1.2.5" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10c0/ddc952b829145ab45411b9d6adcb51a8c17c76bf89c9dd64b52d5dffa65d033da8c076ed2e17091779e83bc892b9848188d7b4b33453c5565e65a92863cb2775 + languageName: node + linkType: hard + +"array.prototype.findlastindex@npm:^1.2.5": + version: 1.2.5 + resolution: "array.prototype.findlastindex@npm:1.2.5" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10c0/962189487728b034f3134802b421b5f39e42ee2356d13b42d2ddb0e52057ffdcc170b9524867f4f0611a6f638f4c19b31e14606e8bcbda67799e26685b195aa3 + languageName: node + linkType: hard + +"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": + version: 1.3.2 + resolution: "array.prototype.flat@npm:1.3.2" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.2.0" + es-abstract: "npm:^1.22.1" + es-shim-unscopables: "npm:^1.0.0" + checksum: 10c0/a578ed836a786efbb6c2db0899ae80781b476200617f65a44846cb1ed8bd8b24c8821b83703375d8af639c689497b7b07277060024b9919db94ac3e10dc8a49b + languageName: node + linkType: hard + +"array.prototype.flatmap@npm:^1.3.2": + version: 1.3.2 + resolution: "array.prototype.flatmap@npm:1.3.2" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.2.0" + es-abstract: "npm:^1.22.1" + es-shim-unscopables: "npm:^1.0.0" + checksum: 10c0/67b3f1d602bb73713265145853128b1ad77cc0f9b833c7e1e056b323fbeac41a4ff1c9c99c7b9445903caea924d9ca2450578d9011913191aa88cc3c3a4b54f4 + languageName: node + linkType: hard + +"array.prototype.tosorted@npm:^1.1.4": + version: 1.1.4 + resolution: "array.prototype.tosorted@npm:1.1.4" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.3" + es-errors: "npm:^1.3.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10c0/eb3c4c4fc0381b0bf6dba2ea4d48d367c2827a0d4236a5718d97caaccc6b78f11f4cadf090736e86301d295a6aa4967ed45568f92ced51be8cbbacd9ca410943 + languageName: node + linkType: hard + +"arraybuffer.prototype.slice@npm:^1.0.3": + version: 1.0.3 + resolution: "arraybuffer.prototype.slice@npm:1.0.3" + dependencies: + array-buffer-byte-length: "npm:^1.0.1" + call-bind: "npm:^1.0.5" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.22.3" + es-errors: "npm:^1.2.1" + get-intrinsic: "npm:^1.2.3" + is-array-buffer: "npm:^3.0.4" + is-shared-array-buffer: "npm:^1.0.2" + checksum: 10c0/d32754045bcb2294ade881d45140a5e52bda2321b9e98fa514797b7f0d252c4c5ab0d1edb34112652c62fa6a9398def568da63a4d7544672229afea283358c36 + languageName: node + linkType: hard + +"astral-regex@npm:^2.0.0": + version: 2.0.0 + resolution: "astral-regex@npm:2.0.0" + checksum: 10c0/f63d439cc383db1b9c5c6080d1e240bd14dae745f15d11ec5da863e182bbeca70df6c8191cffef5deba0b566ef98834610a68be79ac6379c95eeb26e1b310e25 + languageName: node + linkType: hard + +"available-typed-arrays@npm:^1.0.7": + version: 1.0.7 + resolution: "available-typed-arrays@npm:1.0.7" + dependencies: + possible-typed-array-names: "npm:^1.0.0" + checksum: 10c0/d07226ef4f87daa01bd0fe80f8f310982e345f372926da2e5296aecc25c41cab440916bbaa4c5e1034b453af3392f67df5961124e4b586df1e99793a1374bdb2 + languageName: node + linkType: hard + +"babel-plugin-macros@npm:^3.1.0": + version: 3.1.0 + resolution: "babel-plugin-macros@npm:3.1.0" + dependencies: + "@babel/runtime": "npm:^7.12.5" + cosmiconfig: "npm:^7.0.0" + resolve: "npm:^1.19.0" + checksum: 10c0/c6dfb15de96f67871d95bd2e8c58b0c81edc08b9b087dc16755e7157f357dc1090a8dc60ebab955e92587a9101f02eba07e730adc253a1e4cf593ca3ebd3839c + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" + dependencies: + balanced-match: "npm:^1.0.0" + concat-map: "npm:0.0.1" + checksum: 10c0/695a56cd058096a7cb71fb09d9d6a7070113c7be516699ed361317aca2ec169f618e28b8af352e02ab4233fb54eb0168460a40dc320bab0034b36ab59aaad668 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: 10c0/b358f2fe060e2d7a87aa015979ecea07f3c37d4018f8d6deb5bd4c229ad3a0384fe6029bb76cd8be63c81e516ee52d1a0673edbe2023d53a5191732ae3c3e49f + languageName: node + linkType: hard + +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: "npm:^7.1.1" + checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04 + languageName: node + linkType: hard + +"browserslist@npm:^4.24.0": + version: 4.24.0 + resolution: "browserslist@npm:4.24.0" + dependencies: + caniuse-lite: "npm:^1.0.30001663" + electron-to-chromium: "npm:^1.5.28" + node-releases: "npm:^2.0.18" + update-browserslist-db: "npm:^1.1.0" + bin: + browserslist: cli.js + checksum: 10c0/95e76ad522753c4c470427f6e3c8a4bb5478ff448841e22b3d3e53f89ecaf17b6984666d6c7e715c370f1e7fa0cf684f42e34e554236a8b2fab38ea76b9e4c52 + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.4 + resolution: "cacache@npm:18.0.4" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: 10c0/6c055bafed9de4f3dcc64ac3dc7dd24e863210902b7c470eb9ce55a806309b3efff78033e3d8b4f7dcc5d467f2db43c6a2857aaaf26f0094b8a351d44c42179f + languageName: node + linkType: hard + +"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + set-function-length: "npm:^1.2.1" + checksum: 10c0/a3ded2e423b8e2a265983dba81c27e125b48eefb2655e7dfab6be597088da3d47c47976c24bc51b8fd9af1061f8f87b4ab78a314f3c77784b2ae2ba535ad8b8d + languageName: node + linkType: hard + +"callsites@npm:^3.0.0": + version: 3.1.0 + resolution: "callsites@npm:3.1.0" + checksum: 10c0/fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301 + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001663": + version: 1.0.30001669 + resolution: "caniuse-lite@npm:1.0.30001669" + checksum: 10c0/f125f23440d3dbb6c25ffb8d55f4ce48af36a84d0932b152b3b74f143a4170cbe92e02b0a9676209c86609bf7bf34119ff10cc2bc7c1b7ea40e936cc16598408 + languageName: node + linkType: hard + +"chalk@npm:^2.4.2": + version: 2.4.2 + resolution: "chalk@npm:2.4.2" + dependencies: + ansi-styles: "npm:^3.2.1" + escape-string-regexp: "npm:^1.0.5" + supports-color: "npm:^5.3.0" + checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 + languageName: node + linkType: hard + +"chalk@npm:^4.0.0": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: "npm:^4.1.0" + supports-color: "npm:^7.1.0" + checksum: 10c0/4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880 + languageName: node + linkType: hard + +"chalk@npm:~5.3.0": + version: 5.3.0 + resolution: "chalk@npm:5.3.0" + checksum: 10c0/8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09 + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: 10c0/594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6 + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1 + languageName: node + linkType: hard + +"cli-cursor@npm:^5.0.0": + version: 5.0.0 + resolution: "cli-cursor@npm:5.0.0" + dependencies: + restore-cursor: "npm:^5.0.0" + checksum: 10c0/7ec62f69b79f6734ab209a3e4dbdc8af7422d44d360a7cb1efa8a0887bbe466a6e625650c466fe4359aee44dbe2dc0b6994b583d40a05d0808a5cb193641d220 + languageName: node + linkType: hard + +"cli-truncate@npm:^4.0.0": + version: 4.0.0 + resolution: "cli-truncate@npm:4.0.0" + dependencies: + slice-ansi: "npm:^5.0.0" + string-width: "npm:^7.0.0" + checksum: 10c0/d7f0b73e3d9b88cb496e6c086df7410b541b56a43d18ade6a573c9c18bd001b1c3fba1ad578f741a4218fdc794d042385f8ac02c25e1c295a2d8b9f3cb86eb4c + languageName: node + linkType: hard + +"cliui@npm:^8.0.1": + version: 8.0.1 + resolution: "cliui@npm:8.0.1" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^7.0.0" + checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5 + languageName: node + linkType: hard + +"clsx@npm:^1.0.4": + version: 1.2.1 + resolution: "clsx@npm:1.2.1" + checksum: 10c0/34dead8bee24f5e96f6e7937d711978380647e936a22e76380290e35486afd8634966ce300fc4b74a32f3762c7d4c0303f442c3e259f4ce02374eb0c82834f27 + languageName: node + linkType: hard + +"clsx@npm:^2.1.1": + version: 2.1.1 + resolution: "clsx@npm:2.1.1" + checksum: 10c0/c4c8eb865f8c82baab07e71bfa8897c73454881c4f99d6bc81585aecd7c441746c1399d08363dc096c550cceaf97bd4ce1e8854e1771e9998d9f94c4fe075839 + languageName: node + linkType: hard + +"color-convert@npm:^1.9.0": + version: 1.9.3 + resolution: "color-convert@npm:1.9.3" + dependencies: + color-name: "npm:1.1.3" + checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 + languageName: node + linkType: hard + +"color-name@npm:1.1.3": + version: 1.1.3 + resolution: "color-name@npm:1.1.3" + checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 + languageName: node + linkType: hard + +"colorette@npm:^2.0.20": + version: 2.0.20 + resolution: "colorette@npm:2.0.20" + checksum: 10c0/e94116ff33b0ff56f3b83b9ace895e5bf87c2a7a47b3401b8c3f3226e050d5ef76cf4072fb3325f9dc24d1698f9b730baf4e05eeaf861d74a1883073f4c98a40 + languageName: node + linkType: hard + +"commander@npm:^4.0.0": + version: 4.1.1 + resolution: "commander@npm:4.1.1" + checksum: 10c0/84a76c08fe6cc08c9c93f62ac573d2907d8e79138999312c92d4155bc2325d487d64d13f669b2000c9f8caf70493c1be2dac74fec3c51d5a04f8bc3ae1830bab + languageName: node + linkType: hard + +"commander@npm:~12.1.0": + version: 12.1.0 + resolution: "commander@npm:12.1.0" + checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9 + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f + languageName: node + linkType: hard + +"connect@npm:^3.7.0": + version: 3.7.0 + resolution: "connect@npm:3.7.0" + dependencies: + debug: "npm:2.6.9" + finalhandler: "npm:1.1.2" + parseurl: "npm:~1.3.3" + utils-merge: "npm:1.0.1" + checksum: 10c0/f120c6116bb16a0a7d2703c0b4a0cd7ed787dc5ec91978097bf62aa967289020a9f41a9cd3c3276a7b92aaa36f382d2cd35fed7138fd466a55c8e9fdbed11ca8 + languageName: node + linkType: hard + +"convert-source-map@npm:^1.5.0": + version: 1.9.0 + resolution: "convert-source-map@npm:1.9.0" + checksum: 10c0/281da55454bf8126cbc6625385928c43479f2060984180c42f3a86c8b8c12720a24eac260624a7d1e090004028d2dee78602330578ceec1a08e27cb8bb0a8a5b + languageName: node + linkType: hard + +"convert-source-map@npm:^2.0.0": + version: 2.0.0 + resolution: "convert-source-map@npm:2.0.0" + checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b + languageName: node + linkType: hard + +"cosmiconfig@npm:^7.0.0": + version: 7.1.0 + resolution: "cosmiconfig@npm:7.1.0" + dependencies: + "@types/parse-json": "npm:^4.0.0" + import-fresh: "npm:^3.2.1" + parse-json: "npm:^5.0.0" + path-type: "npm:^4.0.0" + yaml: "npm:^1.10.0" + checksum: 10c0/b923ff6af581638128e5f074a5450ba12c0300b71302398ea38dbeabd33bbcaa0245ca9adbedfcf284a07da50f99ede5658c80bb3e39e2ce770a99d28a21ef03 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 10c0/5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750 + languageName: node + linkType: hard + +"css-vendor@npm:^2.0.8": + version: 2.0.8 + resolution: "css-vendor@npm:2.0.8" + dependencies: + "@babel/runtime": "npm:^7.8.3" + is-in-browser: "npm:^1.0.2" + checksum: 10c0/2538bc37adf72eb79781929dbb8c48e12c6a4b926594ad4134408b3000249f1a50d25be374f0e63f688c863368814aa6cc2e9ea11ea22a7309a7d966b281244c + languageName: node + linkType: hard + +"csstype@npm:^2.5.2": + version: 2.6.21 + resolution: "csstype@npm:2.6.21" + checksum: 10c0/e07f27f2100bce9890bb4c3cb9263af97388f0d99b50073b663f1e363fa51b68ac7e2c8a612cd911d2b33c52d83afd1b0b8bc4de1d3ca76ee019a230295daffb + languageName: node + linkType: hard + +"csstype@npm:^3.0.2, csstype@npm:^3.1.3": + version: 3.1.3 + resolution: "csstype@npm:3.1.3" + checksum: 10c0/80c089d6f7e0c5b2bd83cf0539ab41474198579584fa10d86d0cafe0642202343cbc119e076a0b1aece191989477081415d66c9fefbf3c957fc2fc4b7009f248 + languageName: node + linkType: hard + +"data-view-buffer@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-buffer@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.6" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: 10c0/8984119e59dbed906a11fcfb417d7d861936f16697a0e7216fe2c6c810f6b5e8f4a5281e73f2c28e8e9259027190ac4a33e2a65fdd7fa86ac06b76e838918583 + languageName: node + linkType: hard + +"data-view-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-byte-length@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.7" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: 10c0/b7d9e48a0cf5aefed9ab7d123559917b2d7e0d65531f43b2fd95b9d3a6b46042dd3fca597c42bba384e66b70d7ad66ff23932f8367b241f53d93af42cfe04ec2 + languageName: node + linkType: hard + +"data-view-byte-offset@npm:^1.0.0": + version: 1.0.0 + resolution: "data-view-byte-offset@npm:1.0.0" + dependencies: + call-bind: "npm:^1.0.6" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: 10c0/21b0d2e53fd6e20cc4257c873bf6d36d77bd6185624b84076c0a1ddaa757b49aaf076254006341d35568e89f52eecd1ccb1a502cfb620f2beca04f48a6a62a8f + languageName: node + linkType: hard + +"debug@npm:2.6.9": + version: 2.6.9 + resolution: "debug@npm:2.6.9" + dependencies: + ms: "npm:2.0.0" + checksum: 10c0/121908fb839f7801180b69a7e218a40b5a0b718813b886b7d6bdb82001b931c938e2941d1e4450f33a1b1df1da653f5f7a0440c197f29fbf8a6e9d45ff6ef589 + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.4, debug@npm:~4.3.6": + version: 4.3.7 + resolution: "debug@npm:4.3.7" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/1471db19c3b06d485a622d62f65947a19a23fbd0dd73f7fd3eafb697eec5360cde447fb075919987899b1a2096e85d35d4eb5a4de09a57600ac9cf7e6c8e768b + languageName: node + linkType: hard + +"debug@npm:^3.2.7": + version: 3.2.7 + resolution: "debug@npm:3.2.7" + dependencies: + ms: "npm:^2.1.1" + checksum: 10c0/37d96ae42cbc71c14844d2ae3ba55adf462ec89fd3a999459dec3833944cd999af6007ff29c780f1c61153bcaaf2c842d1e4ce1ec621e4fc4923244942e4a02a + languageName: node + linkType: hard + +"deep-is@npm:^0.1.3": + version: 0.1.4 + resolution: "deep-is@npm:0.1.4" + checksum: 10c0/7f0ee496e0dff14a573dc6127f14c95061b448b87b995fc96c017ce0a1e66af1675e73f1d6064407975bc4ea6ab679497a29fff7b5b9c4e99cb10797c1ad0b4c + languageName: node + linkType: hard + +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.0.1" + checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37 + languageName: node + linkType: hard + +"define-properties@npm:^1.1.3, define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + object-keys: "npm:^1.1.1" + checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3 + languageName: node + linkType: hard + +"dir-glob@npm:^3.0.1": + version: 3.0.1 + resolution: "dir-glob@npm:3.0.1" + dependencies: + path-type: "npm:^4.0.0" + checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c + languageName: node + linkType: hard + +"doctrine@npm:^2.1.0": + version: 2.1.0 + resolution: "doctrine@npm:2.1.0" + dependencies: + esutils: "npm:^2.0.2" + checksum: 10c0/b6416aaff1f380bf56c3b552f31fdf7a69b45689368deca72d28636f41c16bb28ec3ebc40ace97db4c1afc0ceeb8120e8492fe0046841c94c2933b2e30a7d5ac + languageName: node + linkType: hard + +"doctrine@npm:^3.0.0": + version: 3.0.0 + resolution: "doctrine@npm:3.0.0" + dependencies: + esutils: "npm:^2.0.2" + checksum: 10c0/c96bdccabe9d62ab6fea9399fdff04a66e6563c1d6fb3a3a063e8d53c3bb136ba63e84250bbf63d00086a769ad53aef92d2bd483f03f837fc97b71cbee6b2520 + languageName: node + linkType: hard + +"dom-helpers@npm:^5.0.1": + version: 5.2.1 + resolution: "dom-helpers@npm:5.2.1" + dependencies: + "@babel/runtime": "npm:^7.8.7" + csstype: "npm:^3.0.2" + checksum: 10c0/f735074d66dd759b36b158fa26e9d00c9388ee0e8c9b16af941c38f014a37fc80782de83afefd621681b19ac0501034b4f1c4a3bff5caa1b8667f0212b5e124c + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 + languageName: node + linkType: hard + +"ee-first@npm:1.1.1": + version: 1.1.1 + resolution: "ee-first@npm:1.1.1" + checksum: 10c0/b5bb125ee93161bc16bfe6e56c6b04de5ad2aa44234d8f644813cc95d861a6910903132b05093706de2b706599367c4130eb6d170f6b46895686b95f87d017b7 + languageName: node + linkType: hard + +"electron-to-chromium@npm:^1.5.28": + version: 1.5.40 + resolution: "electron-to-chromium@npm:1.5.40" + checksum: 10c0/3f97360627cf179b344a7d45b3d12fd3f18f1287529d9835a8e802c7a3b99f09e326b4ed3097be1b135e45a33e8497e758b0c101e38e5bb405eaa6aa887eca82 + languageName: node + linkType: hard + +"emoji-regex@npm:^10.3.0": + version: 10.4.0 + resolution: "emoji-regex@npm:10.4.0" + checksum: 10c0/a3fcedfc58bfcce21a05a5f36a529d81e88d602100145fcca3dc6f795e3c8acc4fc18fe773fbf9b6d6e9371205edb3afa2668ec3473fa2aa7fd47d2a9d46482d + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 + languageName: node + linkType: hard + +"encodeurl@npm:~1.0.2": + version: 1.0.2 + resolution: "encodeurl@npm:1.0.2" + checksum: 10c0/f6c2387379a9e7c1156c1c3d4f9cb7bb11cf16dd4c1682e1f6746512564b053df5781029b6061296832b59fb22f459dbe250386d217c2f6e203601abb2ee0bec + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039 + languageName: node + linkType: hard + +"enquirer@npm:^2.3.5": + version: 2.4.1 + resolution: "enquirer@npm:2.4.1" + dependencies: + ansi-colors: "npm:^4.1.1" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/43850479d7a51d36a9c924b518dcdc6373b5a8ae3401097d336b7b7e258324749d0ad37a1fcaa5706f04799baa05585cd7af19ebdf7667673e7694435fcea918 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 + languageName: node + linkType: hard + +"environment@npm:^1.0.0": + version: 1.1.0 + resolution: "environment@npm:1.1.0" + checksum: 10c0/fb26434b0b581ab397039e51ff3c92b34924a98b2039dcb47e41b7bca577b9dbf134a8eadb364415c74464b682e2d3afe1a4c0eb9873dc44ea814c5d3103331d + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 10c0/b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66 + languageName: node + linkType: hard + +"error-ex@npm:^1.3.1": + version: 1.3.2 + resolution: "error-ex@npm:1.3.2" + dependencies: + is-arrayish: "npm:^0.2.1" + checksum: 10c0/ba827f89369b4c93382cfca5a264d059dfefdaa56ecc5e338ffa58a6471f5ed93b71a20add1d52290a4873d92381174382658c885ac1a2305f7baca363ce9cce + languageName: node + linkType: hard + +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.1, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3": + version: 1.23.3 + resolution: "es-abstract@npm:1.23.3" + dependencies: + array-buffer-byte-length: "npm:^1.0.1" + arraybuffer.prototype.slice: "npm:^1.0.3" + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.7" + data-view-buffer: "npm:^1.0.1" + data-view-byte-length: "npm:^1.0.1" + data-view-byte-offset: "npm:^1.0.0" + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + es-set-tostringtag: "npm:^2.0.3" + es-to-primitive: "npm:^1.2.1" + function.prototype.name: "npm:^1.1.6" + get-intrinsic: "npm:^1.2.4" + get-symbol-description: "npm:^1.0.2" + globalthis: "npm:^1.0.3" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.2" + has-proto: "npm:^1.0.3" + has-symbols: "npm:^1.0.3" + hasown: "npm:^2.0.2" + internal-slot: "npm:^1.0.7" + is-array-buffer: "npm:^3.0.4" + is-callable: "npm:^1.2.7" + is-data-view: "npm:^1.0.1" + is-negative-zero: "npm:^2.0.3" + is-regex: "npm:^1.1.4" + is-shared-array-buffer: "npm:^1.0.3" + is-string: "npm:^1.0.7" + is-typed-array: "npm:^1.1.13" + is-weakref: "npm:^1.0.2" + object-inspect: "npm:^1.13.1" + object-keys: "npm:^1.1.1" + object.assign: "npm:^4.1.5" + regexp.prototype.flags: "npm:^1.5.2" + safe-array-concat: "npm:^1.1.2" + safe-regex-test: "npm:^1.0.3" + string.prototype.trim: "npm:^1.2.9" + string.prototype.trimend: "npm:^1.0.8" + string.prototype.trimstart: "npm:^1.0.8" + typed-array-buffer: "npm:^1.0.2" + typed-array-byte-length: "npm:^1.0.1" + typed-array-byte-offset: "npm:^1.0.2" + typed-array-length: "npm:^1.0.6" + unbox-primitive: "npm:^1.0.2" + which-typed-array: "npm:^1.1.15" + checksum: 10c0/d27e9afafb225c6924bee9971a7f25f20c314f2d6cb93a63cada4ac11dcf42040896a6c22e5fb8f2a10767055ed4ddf400be3b1eb12297d281726de470b75666 + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: "npm:^1.2.4" + checksum: 10c0/6bf3191feb7ea2ebda48b577f69bdfac7a2b3c9bcf97307f55fd6ef1bbca0b49f0c219a935aca506c993d8c5d8bddd937766cb760cd5e5a1071351f2df9f9aa4 + languageName: node + linkType: hard + +"es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85 + languageName: node + linkType: hard + +"es-iterator-helpers@npm:^1.0.19": + version: 1.1.0 + resolution: "es-iterator-helpers@npm:1.1.0" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.3" + es-errors: "npm:^1.3.0" + es-set-tostringtag: "npm:^2.0.3" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + globalthis: "npm:^1.0.4" + has-property-descriptors: "npm:^1.0.2" + has-proto: "npm:^1.0.3" + has-symbols: "npm:^1.0.3" + internal-slot: "npm:^1.0.7" + iterator.prototype: "npm:^1.1.3" + safe-array-concat: "npm:^1.1.2" + checksum: 10c0/84d6c240c7da6e62323b336cb1497781546dab16bebdbd879ccfdf588979712d3e941d41165b6c2ffce5a03a7b929d4e6131d3124d330da1a0e2bfa1da7cd99f + languageName: node + linkType: hard + +"es-object-atoms@npm:^1.0.0": + version: 1.0.0 + resolution: "es-object-atoms@npm:1.0.0" + dependencies: + es-errors: "npm:^1.3.0" + checksum: 10c0/1fed3d102eb27ab8d983337bb7c8b159dd2a1e63ff833ec54eea1311c96d5b08223b433060ba240541ca8adba9eee6b0a60cdbf2f80634b784febc9cc8b687b4 + languageName: node + linkType: hard + +"es-set-tostringtag@npm:^2.0.3": + version: 2.0.3 + resolution: "es-set-tostringtag@npm:2.0.3" + dependencies: + get-intrinsic: "npm:^1.2.4" + has-tostringtag: "npm:^1.0.2" + hasown: "npm:^2.0.1" + checksum: 10c0/f22aff1585eb33569c326323f0b0d175844a1f11618b86e193b386f8be0ea9474cfbe46df39c45d959f7aa8f6c06985dc51dd6bce5401645ec5a74c4ceaa836a + languageName: node + linkType: hard + +"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": + version: 1.0.2 + resolution: "es-shim-unscopables@npm:1.0.2" + dependencies: + hasown: "npm:^2.0.0" + checksum: 10c0/f495af7b4b7601a4c0cfb893581c352636e5c08654d129590386a33a0432cf13a7bdc7b6493801cadd990d838e2839b9013d1de3b880440cb537825e834fe783 + languageName: node + linkType: hard + +"es-to-primitive@npm:^1.2.1": + version: 1.2.1 + resolution: "es-to-primitive@npm:1.2.1" + dependencies: + is-callable: "npm:^1.1.4" + is-date-object: "npm:^1.0.1" + is-symbol: "npm:^1.0.2" + checksum: 10c0/0886572b8dc075cb10e50c0af62a03d03a68e1e69c388bd4f10c0649ee41b1fbb24840a1b7e590b393011b5cdbe0144b776da316762653685432df37d6de60f1 + languageName: node + linkType: hard + +"esbuild-android-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-android-64@npm:0.14.54" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"esbuild-android-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-android-arm64@npm:0.14.54" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-darwin-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-darwin-64@npm:0.14.54" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"esbuild-darwin-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-darwin-arm64@npm:0.14.54" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-freebsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-freebsd-64@npm:0.14.54" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"esbuild-freebsd-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-freebsd-arm64@npm:0.14.54" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-linux-32@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-32@npm:0.14.54" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"esbuild-linux-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-64@npm:0.14.54" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"esbuild-linux-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-arm64@npm:0.14.54" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-linux-arm@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-arm@npm:0.14.54" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"esbuild-linux-mips64le@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-mips64le@npm:0.14.54" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"esbuild-linux-ppc64le@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-ppc64le@npm:0.14.54" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"esbuild-linux-riscv64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-riscv64@npm:0.14.54" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"esbuild-linux-s390x@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-s390x@npm:0.14.54" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"esbuild-netbsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-netbsd-64@npm:0.14.54" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"esbuild-openbsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-openbsd-64@npm:0.14.54" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"esbuild-sunos-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-sunos-64@npm:0.14.54" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"esbuild-windows-32@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-32@npm:0.14.54" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"esbuild-windows-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-64@npm:0.14.54" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"esbuild-windows-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-arm64@npm:0.14.54" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"esbuild@npm:^0.12.8": + version: 0.12.29 + resolution: "esbuild@npm:0.12.29" + bin: + esbuild: bin/esbuild + checksum: 10c0/23e5fb9fc4e3c94e36aeecc86963964911bbdb7faeb163f1e4702d62a0c897e3cd32945218804d44367af035d05f2705b5e32f46c28c31a14106a7cdbcb68a04 + languageName: node + linkType: hard + +"esbuild@npm:^0.14.27": + version: 0.14.54 + resolution: "esbuild@npm:0.14.54" + dependencies: + "@esbuild/linux-loong64": "npm:0.14.54" + esbuild-android-64: "npm:0.14.54" + esbuild-android-arm64: "npm:0.14.54" + esbuild-darwin-64: "npm:0.14.54" + esbuild-darwin-arm64: "npm:0.14.54" + esbuild-freebsd-64: "npm:0.14.54" + esbuild-freebsd-arm64: "npm:0.14.54" + esbuild-linux-32: "npm:0.14.54" + esbuild-linux-64: "npm:0.14.54" + esbuild-linux-arm: "npm:0.14.54" + esbuild-linux-arm64: "npm:0.14.54" + esbuild-linux-mips64le: "npm:0.14.54" + esbuild-linux-ppc64le: "npm:0.14.54" + esbuild-linux-riscv64: "npm:0.14.54" + esbuild-linux-s390x: "npm:0.14.54" + esbuild-netbsd-64: "npm:0.14.54" + esbuild-openbsd-64: "npm:0.14.54" + esbuild-sunos-64: "npm:0.14.54" + esbuild-windows-32: "npm:0.14.54" + esbuild-windows-64: "npm:0.14.54" + esbuild-windows-arm64: "npm:0.14.54" + dependenciesMeta: + "@esbuild/linux-loong64": + optional: true + esbuild-android-64: + optional: true + esbuild-android-arm64: + optional: true + esbuild-darwin-64: + optional: true + esbuild-darwin-arm64: + optional: true + esbuild-freebsd-64: + optional: true + esbuild-freebsd-arm64: + optional: true + esbuild-linux-32: + optional: true + esbuild-linux-64: + optional: true + esbuild-linux-arm: + optional: true + esbuild-linux-arm64: + optional: true + esbuild-linux-mips64le: + optional: true + esbuild-linux-ppc64le: + optional: true + esbuild-linux-riscv64: + optional: true + esbuild-linux-s390x: + optional: true + esbuild-netbsd-64: + optional: true + esbuild-openbsd-64: + optional: true + esbuild-sunos-64: + optional: true + esbuild-windows-32: + optional: true + esbuild-windows-64: + optional: true + esbuild-windows-arm64: + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/1df3cf7c5175ebee284fd027f287385a07ce8a0f0460a4412881aeff707577d91e55302f220ee8397b3b5aa17f4ceeb80eac16f36fc676532ff1b744e5965f2d + languageName: node + linkType: hard + +"escalade@npm:^3.1.1, escalade@npm:^3.2.0": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 + languageName: node + linkType: hard + +"escape-html@npm:~1.0.3": + version: 1.0.3 + resolution: "escape-html@npm:1.0.3" + checksum: 10c0/524c739d776b36c3d29fa08a22e03e8824e3b2fd57500e5e44ecf3cc4707c34c60f9ca0781c0e33d191f2991161504c295e98f68c78fe7baa6e57081ec6ac0a3 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^1.0.5": + version: 1.0.5 + resolution: "escape-string-regexp@npm:1.0.5" + checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 + languageName: node + linkType: hard + +"eslint-config-prettier@npm:^8.3.0": + version: 8.10.0 + resolution: "eslint-config-prettier@npm:8.10.0" + peerDependencies: + eslint: ">=7.0.0" + bin: + eslint-config-prettier: bin/cli.js + checksum: 10c0/19f8c497d9bdc111a17a61b25ded97217be3755bbc4714477dfe535ed539dddcaf42ef5cf8bb97908b058260cf89a3d7c565cb0be31096cbcd39f4c2fa5fe43c + languageName: node + linkType: hard + +"eslint-config-standard@npm:^16.0.3": + version: 16.0.3 + resolution: "eslint-config-standard@npm:16.0.3" + peerDependencies: + eslint: ^7.12.1 + eslint-plugin-import: ^2.22.1 + eslint-plugin-node: ^11.1.0 + eslint-plugin-promise: ^4.2.1 || ^5.0.0 + checksum: 10c0/6c7276b15329c3ed3c516b442b99cab9b30cb750a58b3bc6994574103f843bf7ea4f7e86bb815c206a610b12fb765d9cd283e45580f9e8549c6d9510fc8177c5 + languageName: node + linkType: hard + +"eslint-import-resolver-node@npm:^0.3.4, eslint-import-resolver-node@npm:^0.3.9": + version: 0.3.9 + resolution: "eslint-import-resolver-node@npm:0.3.9" + dependencies: + debug: "npm:^3.2.7" + is-core-module: "npm:^2.13.0" + resolve: "npm:^1.22.4" + checksum: 10c0/0ea8a24a72328a51fd95aa8f660dcca74c1429806737cf10261ab90cfcaaf62fd1eff664b76a44270868e0a932711a81b250053942595bcd00a93b1c1575dd61 + languageName: node + linkType: hard + +"eslint-module-utils@npm:^2.12.0": + version: 2.12.0 + resolution: "eslint-module-utils@npm:2.12.0" + dependencies: + debug: "npm:^3.2.7" + peerDependenciesMeta: + eslint: + optional: true + checksum: 10c0/4d8b46dcd525d71276f9be9ffac1d2be61c9d54cc53c992e6333cf957840dee09381842b1acbbb15fc6b255ebab99cd481c5007ab438e5455a14abe1a0468558 + languageName: node + linkType: hard + +"eslint-plugin-es@npm:^3.0.0": + version: 3.0.1 + resolution: "eslint-plugin-es@npm:3.0.1" + dependencies: + eslint-utils: "npm:^2.0.0" + regexpp: "npm:^3.0.0" + peerDependencies: + eslint: ">=4.19.1" + checksum: 10c0/12ae730aa9603e680af048e1653aac15e529411b68b8d0da6e290700b17c695485af7c3f5360f531f80970786cab7288c2c1d4a58c35ec1bb89649897c016c4a + languageName: node + linkType: hard + +"eslint-plugin-import@npm:^2.23.4": + version: 2.31.0 + resolution: "eslint-plugin-import@npm:2.31.0" + dependencies: + "@rtsao/scc": "npm:^1.1.0" + array-includes: "npm:^3.1.8" + array.prototype.findlastindex: "npm:^1.2.5" + array.prototype.flat: "npm:^1.3.2" + array.prototype.flatmap: "npm:^1.3.2" + debug: "npm:^3.2.7" + doctrine: "npm:^2.1.0" + eslint-import-resolver-node: "npm:^0.3.9" + eslint-module-utils: "npm:^2.12.0" + hasown: "npm:^2.0.2" + is-core-module: "npm:^2.15.1" + is-glob: "npm:^4.0.3" + minimatch: "npm:^3.1.2" + object.fromentries: "npm:^2.0.8" + object.groupby: "npm:^1.0.3" + object.values: "npm:^1.2.0" + semver: "npm:^6.3.1" + string.prototype.trimend: "npm:^1.0.8" + tsconfig-paths: "npm:^3.15.0" + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + checksum: 10c0/e21d116ddd1900e091ad120b3eb68c5dd5437fe2c930f1211781cd38b246f090a6b74d5f3800b8255a0ed29782591521ad44eb21c5534960a8f1fb4040fd913a + languageName: node + linkType: hard + +"eslint-plugin-node@npm:^11.1.0": + version: 11.1.0 + resolution: "eslint-plugin-node@npm:11.1.0" + dependencies: + eslint-plugin-es: "npm:^3.0.0" + eslint-utils: "npm:^2.0.0" + ignore: "npm:^5.1.1" + minimatch: "npm:^3.0.4" + resolve: "npm:^1.10.1" + semver: "npm:^6.1.0" + peerDependencies: + eslint: ">=5.16.0" + checksum: 10c0/c7716adac4020cb852fd2410dcd8bdb13a227004de77f96d7f9806d0cf2274f24e0920a7ca73bcd72d90003696c1f17fdd9fe3ca218e64ee03dc2b840e4416fa + languageName: node + linkType: hard + +"eslint-plugin-promise@npm:^5.1.0": + version: 5.2.0 + resolution: "eslint-plugin-promise@npm:5.2.0" + peerDependencies: + eslint: ^7.0.0 + checksum: 10c0/73a6da06e2efe32d04f3a872268b728c47b0b4946af852c6be142180d8d8284555991a6f946ec47792fad88c35393b331f8e54ff9e0e76d2b73a6d74cacd8aaa + languageName: node + linkType: hard + +"eslint-plugin-react@npm:^7.24.0": + version: 7.37.1 + resolution: "eslint-plugin-react@npm:7.37.1" + dependencies: + array-includes: "npm:^3.1.8" + array.prototype.findlast: "npm:^1.2.5" + array.prototype.flatmap: "npm:^1.3.2" + array.prototype.tosorted: "npm:^1.1.4" + doctrine: "npm:^2.1.0" + es-iterator-helpers: "npm:^1.0.19" + estraverse: "npm:^5.3.0" + hasown: "npm:^2.0.2" + jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" + minimatch: "npm:^3.1.2" + object.entries: "npm:^1.1.8" + object.fromentries: "npm:^2.0.8" + object.values: "npm:^1.2.0" + prop-types: "npm:^15.8.1" + resolve: "npm:^2.0.0-next.5" + semver: "npm:^6.3.1" + string.prototype.matchall: "npm:^4.0.11" + string.prototype.repeat: "npm:^1.0.0" + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + checksum: 10c0/13cf55666f16d2ca45b14aad1b0e14741d1817679c86d20aff0bc1e802439a8541f40a42c4c8e3486ffb710f1bcc2f3e56697f2b5f724306a7fca174e1ad6433 + languageName: node + linkType: hard + +"eslint-scope@npm:^5.1.1": + version: 5.1.1 + resolution: "eslint-scope@npm:5.1.1" + dependencies: + esrecurse: "npm:^4.3.0" + estraverse: "npm:^4.1.1" + checksum: 10c0/d30ef9dc1c1cbdece34db1539a4933fe3f9b14e1ffb27ecc85987902ee663ad7c9473bbd49a9a03195a373741e62e2f807c4938992e019b511993d163450e70a + languageName: node + linkType: hard + +"eslint-utils@npm:^2.0.0, eslint-utils@npm:^2.1.0": + version: 2.1.0 + resolution: "eslint-utils@npm:2.1.0" + dependencies: + eslint-visitor-keys: "npm:^1.1.0" + checksum: 10c0/69521c5d6569384b24093125d037ba238d3d6e54367f7143af9928f5286369e912c26cad5016d730c0ffb9797ac9e83831059d7f1d863f7dc84330eb02414611 + languageName: node + linkType: hard + +"eslint-utils@npm:^3.0.0": + version: 3.0.0 + resolution: "eslint-utils@npm:3.0.0" + dependencies: + eslint-visitor-keys: "npm:^2.0.0" + peerDependencies: + eslint: ">=5" + checksum: 10c0/45aa2b63667a8d9b474c98c28af908d0a592bed1a4568f3145cd49fb5d9510f545327ec95561625290313fe126e6d7bdfe3fdbdb6f432689fab6b9497d3bfb52 + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^1.1.0, eslint-visitor-keys@npm:^1.3.0": + version: 1.3.0 + resolution: "eslint-visitor-keys@npm:1.3.0" + checksum: 10c0/10c91fdbbe36810dd4308e57f9a8bc7177188b2a70247e54e3af1fa05ebc66414ae6fd4ce3c6c6821591f43a556e9037bc6b071122e099b5f8b7d2f76df553e3 + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^2.0.0": + version: 2.1.0 + resolution: "eslint-visitor-keys@npm:2.1.0" + checksum: 10c0/9f0e3a2db751d84067d15977ac4b4472efd6b303e369e6ff241a99feac04da758f46d5add022c33d06b53596038dbae4b4aceb27c7e68b8dfc1055b35e495787 + languageName: node + linkType: hard + +"eslint@npm:^7.32.0": + version: 7.32.0 + resolution: "eslint@npm:7.32.0" + dependencies: + "@babel/code-frame": "npm:7.12.11" + "@eslint/eslintrc": "npm:^0.4.3" + "@humanwhocodes/config-array": "npm:^0.5.0" + ajv: "npm:^6.10.0" + chalk: "npm:^4.0.0" + cross-spawn: "npm:^7.0.2" + debug: "npm:^4.0.1" + doctrine: "npm:^3.0.0" + enquirer: "npm:^2.3.5" + escape-string-regexp: "npm:^4.0.0" + eslint-scope: "npm:^5.1.1" + eslint-utils: "npm:^2.1.0" + eslint-visitor-keys: "npm:^2.0.0" + espree: "npm:^7.3.1" + esquery: "npm:^1.4.0" + esutils: "npm:^2.0.2" + fast-deep-equal: "npm:^3.1.3" + file-entry-cache: "npm:^6.0.1" + functional-red-black-tree: "npm:^1.0.1" + glob-parent: "npm:^5.1.2" + globals: "npm:^13.6.0" + ignore: "npm:^4.0.6" + import-fresh: "npm:^3.0.0" + imurmurhash: "npm:^0.1.4" + is-glob: "npm:^4.0.0" + js-yaml: "npm:^3.13.1" + json-stable-stringify-without-jsonify: "npm:^1.0.1" + levn: "npm:^0.4.1" + lodash.merge: "npm:^4.6.2" + minimatch: "npm:^3.0.4" + natural-compare: "npm:^1.4.0" + optionator: "npm:^0.9.1" + progress: "npm:^2.0.0" + regexpp: "npm:^3.1.0" + semver: "npm:^7.2.1" + strip-ansi: "npm:^6.0.0" + strip-json-comments: "npm:^3.1.0" + table: "npm:^6.0.9" + text-table: "npm:^0.2.0" + v8-compile-cache: "npm:^2.0.3" + bin: + eslint: bin/eslint.js + checksum: 10c0/84409f7767556179cb11529f1215f335c7dfccf90419df6147f949f14c347a960c7b569e80ed84011a0b6d10da1ef5046edbbb9b11c3e59aa6696d5217092e93 + languageName: node + linkType: hard + +"espree@npm:^7.3.0, espree@npm:^7.3.1": + version: 7.3.1 + resolution: "espree@npm:7.3.1" + dependencies: + acorn: "npm:^7.4.0" + acorn-jsx: "npm:^5.3.1" + eslint-visitor-keys: "npm:^1.3.0" + checksum: 10c0/f4e81b903f03eaf0e6925cea20571632da427deb6e14ca37e481f72c11f36d7bb4945fe8a2ff15ab22d078d3cd93ee65355fa94de9c27485c356481775f25d85 + languageName: node + linkType: hard + +"esprima@npm:^4.0.0": + version: 4.0.1 + resolution: "esprima@npm:4.0.1" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: 10c0/ad4bab9ead0808cf56501750fd9d3fb276f6b105f987707d059005d57e182d18a7c9ec7f3a01794ebddcca676773e42ca48a32d67a250c9d35e009ca613caba3 + languageName: node + linkType: hard + +"esquery@npm:^1.4.0": + version: 1.6.0 + resolution: "esquery@npm:1.6.0" + dependencies: + estraverse: "npm:^5.1.0" + checksum: 10c0/cb9065ec605f9da7a76ca6dadb0619dfb611e37a81e318732977d90fab50a256b95fee2d925fba7c2f3f0523aa16f91587246693bc09bc34d5a59575fe6e93d2 + languageName: node + linkType: hard + +"esrecurse@npm:^4.3.0": + version: 4.3.0 + resolution: "esrecurse@npm:4.3.0" + dependencies: + estraverse: "npm:^5.2.0" + checksum: 10c0/81a37116d1408ded88ada45b9fb16dbd26fba3aadc369ce50fcaf82a0bac12772ebd7b24cd7b91fc66786bf2c1ac7b5f196bc990a473efff972f5cb338877cf5 + languageName: node + linkType: hard + +"estraverse@npm:^4.1.1": + version: 4.3.0 + resolution: "estraverse@npm:4.3.0" + checksum: 10c0/9cb46463ef8a8a4905d3708a652d60122a0c20bb58dec7e0e12ab0e7235123d74214fc0141d743c381813e1b992767e2708194f6f6e0f9fd00c1b4e0887b8b6d + languageName: node + linkType: hard + +"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": + version: 5.3.0 + resolution: "estraverse@npm:5.3.0" + checksum: 10c0/1ff9447b96263dec95d6d67431c5e0771eb9776427421260a3e2f0fdd5d6bd4f8e37a7338f5ad2880c9f143450c9b1e4fc2069060724570a49cf9cf0312bd107 + languageName: node + linkType: hard + +"estree-walker@npm:^2.0.1": + version: 2.0.2 + resolution: "estree-walker@npm:2.0.2" + checksum: 10c0/53a6c54e2019b8c914dc395890153ffdc2322781acf4bd7d1a32d7aedc1710807bdcd866ac133903d5629ec601fbb50abe8c2e5553c7f5a0afdd9b6af6c945af + languageName: node + linkType: hard + +"esutils@npm:^2.0.2": + version: 2.0.3 + resolution: "esutils@npm:2.0.3" + checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7 + languageName: node + linkType: hard + +"eventemitter3@npm:^5.0.1": + version: 5.0.1 + resolution: "eventemitter3@npm:5.0.1" + checksum: 10c0/4ba5c00c506e6c786b4d6262cfbce90ddc14c10d4667e5c83ae993c9de88aa856033994dd2b35b83e8dc1170e224e66a319fa80adc4c32adcd2379bbc75da814 + languageName: node + linkType: hard + +"execa@npm:~8.0.1": + version: 8.0.1 + resolution: "execa@npm:8.0.1" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^8.0.1" + human-signals: "npm:^5.0.0" + is-stream: "npm:^3.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^5.1.0" + onetime: "npm:^6.0.0" + signal-exit: "npm:^4.1.0" + strip-final-newline: "npm:^3.0.0" + checksum: 10c0/2c52d8775f5bf103ce8eec9c7ab3059909ba350a5164744e9947ed14a53f51687c040a250bda833f906d1283aa8803975b84e6c8f7a7c42f99dc8ef80250d1af + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 10c0/160456d2d647e6019640bd07111634d8c353038d9fa40176afb7cd49b0548bdae83b56d05e907c2cce2300b81cae35d800ef92fefb9d0208e190fa3b7d6bb579 + languageName: node + linkType: hard + +"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": + version: 3.1.3 + resolution: "fast-deep-equal@npm:3.1.3" + checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0 + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.9": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 10c0/42baad7b9cd40b63e42039132bde27ca2cb3a4950d0a0f9abe4639ea1aa9d3e3b40f98b1fe31cbc0cc17b664c9ea7447d911a152fa34ec5b72977b125a6fc845 + languageName: node + linkType: hard + +"fast-json-stable-stringify@npm:^2.0.0": + version: 2.1.0 + resolution: "fast-json-stable-stringify@npm:2.1.0" + checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b + languageName: node + linkType: hard + +"fast-levenshtein@npm:^2.0.6": + version: 2.0.6 + resolution: "fast-levenshtein@npm:2.0.6" + checksum: 10c0/111972b37338bcb88f7d9e2c5907862c280ebf4234433b95bc611e518d192ccb2d38119c4ac86e26b668d75f7f3894f4ff5c4982899afced7ca78633b08287c4 + languageName: node + linkType: hard + +"fast-uri@npm:^3.0.1": + version: 3.0.3 + resolution: "fast-uri@npm:3.0.3" + checksum: 10c0/4b2c5ce681a062425eae4f15cdc8fc151fd310b2f69b1f96680677820a8b49c3cd6e80661a406e19d50f0c40a3f8bffdd458791baf66f4a879d80be28e10a320 + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.17.1 + resolution: "fastq@npm:1.17.1" + dependencies: + reusify: "npm:^1.0.4" + checksum: 10c0/1095f16cea45fb3beff558bb3afa74ca7a9250f5a670b65db7ed585f92b4b48381445cd328b3d87323da81e43232b5d5978a8201bde84e0cd514310f1ea6da34 + languageName: node + linkType: hard + +"file-entry-cache@npm:^6.0.1": + version: 6.0.1 + resolution: "file-entry-cache@npm:6.0.1" + dependencies: + flat-cache: "npm:^3.0.4" + checksum: 10c0/58473e8a82794d01b38e5e435f6feaf648e3f36fdb3a56e98f417f4efae71ad1c0d4ebd8a9a7c50c3ad085820a93fc7494ad721e0e4ebc1da3573f4e1c3c7cdd + languageName: node + linkType: hard + +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018 + languageName: node + linkType: hard + +"finalhandler@npm:1.1.2": + version: 1.1.2 + resolution: "finalhandler@npm:1.1.2" + dependencies: + debug: "npm:2.6.9" + encodeurl: "npm:~1.0.2" + escape-html: "npm:~1.0.3" + on-finished: "npm:~2.3.0" + parseurl: "npm:~1.3.3" + statuses: "npm:~1.5.0" + unpipe: "npm:~1.0.0" + checksum: 10c0/6a96e1f5caab085628c11d9fdceb82ba608d5e426c6913d4d918409baa271037a47f28fbba73279e8ad614f0b8fa71ea791d265e408d760793829edd8c2f4584 + languageName: node + linkType: hard + +"find-root@npm:^1.1.0": + version: 1.1.0 + resolution: "find-root@npm:1.1.0" + checksum: 10c0/1abc7f3bf2f8d78ff26d9e00ce9d0f7b32e5ff6d1da2857bcdf4746134c422282b091c672cde0572cac3840713487e0a7a636af9aa1b74cb11894b447a521efa + languageName: node + linkType: hard + +"flat-cache@npm:^3.0.4": + version: 3.2.0 + resolution: "flat-cache@npm:3.2.0" + dependencies: + flatted: "npm:^3.2.9" + keyv: "npm:^4.5.3" + rimraf: "npm:^3.0.2" + checksum: 10c0/b76f611bd5f5d68f7ae632e3ae503e678d205cf97a17c6ab5b12f6ca61188b5f1f7464503efae6dc18683ed8f0b41460beb48ac4b9ac63fe6201296a91ba2f75 + languageName: node + linkType: hard + +"flatted@npm:^3.2.9": + version: 3.3.1 + resolution: "flatted@npm:3.3.1" + checksum: 10c0/324166b125ee07d4ca9bcf3a5f98d915d5db4f39d711fba640a3178b959919aae1f7cfd8aabcfef5826ed8aa8a2aa14cc85b2d7d18ff638ddf4ae3df39573eaf + languageName: node + linkType: hard + +"for-each@npm:^0.3.3": + version: 0.3.3 + resolution: "for-each@npm:0.3.3" + dependencies: + is-callable: "npm:^1.1.3" + checksum: 10c0/22330d8a2db728dbf003ec9182c2d421fbcd2969b02b4f97ec288721cda63eb28f2c08585ddccd0f77cb2930af8d958005c9e72f47141dc51816127a118f39aa + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.3.0 + resolution: "foreground-child@npm:3.3.0" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 10c0/028f1d41000553fcfa6c4bb5c372963bf3d9bf0b1f25a87d1a6253014343fb69dfb1b42d9625d7cf44c8ba429940f3d0ff718b62105d4d4a4f6ef8ca0a53faa2 + languageName: node + linkType: hard + +"fs-extra@npm:^10.0.0": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/5f579466e7109719d162a9249abbeffe7f426eb133ea486e020b89bc6d67a741134076bf439983f2eb79276ceaf6bd7b7c1e43c3fd67fe889863e69072fb0a5e + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004 + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94 + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948 + languageName: node + linkType: hard + +"fsevents@npm:~2.3.2": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5 + languageName: node + linkType: hard + +"function.prototype.name@npm:^1.1.6": + version: 1.1.6 + resolution: "function.prototype.name@npm:1.1.6" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.2.0" + es-abstract: "npm:^1.22.1" + functions-have-names: "npm:^1.2.3" + checksum: 10c0/9eae11294905b62cb16874adb4fc687927cda3162285e0ad9612e6a1d04934005d46907362ea9cdb7428edce05a2f2c3dabc3b2d21e9fd343e9bb278230ad94b + languageName: node + linkType: hard + +"functional-red-black-tree@npm:^1.0.1": + version: 1.0.1 + resolution: "functional-red-black-tree@npm:1.0.1" + checksum: 10c0/5959eed0375803d9924f47688479bb017e0c6816a0e5ac151e22ba6bfe1d12c41de2f339188885e0aa8eeea2072dad509d8e4448467e816bde0a2ca86a0670d3 + languageName: node + linkType: hard + +"functions-have-names@npm:^1.2.3": + version: 1.2.3 + resolution: "functions-have-names@npm:1.2.3" + checksum: 10c0/33e77fd29bddc2d9bb78ab3eb854c165909201f88c75faa8272e35899e2d35a8a642a15e7420ef945e1f64a9670d6aa3ec744106b2aa42be68ca5114025954ca + languageName: node + linkType: hard + +"gensync@npm:^1.0.0-beta.2": + version: 1.0.0-beta.2 + resolution: "gensync@npm:1.0.0-beta.2" + checksum: 10c0/782aba6cba65b1bb5af3b095d96249d20edbe8df32dbf4696fd49be2583faf676173bf4809386588828e4dd76a3354fcbeb577bab1c833ccd9fc4577f26103f8 + languageName: node + linkType: hard + +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde + languageName: node + linkType: hard + +"get-east-asian-width@npm:^1.0.0": + version: 1.3.0 + resolution: "get-east-asian-width@npm:1.3.0" + checksum: 10c0/1a049ba697e0f9a4d5514c4623781c5246982bdb61082da6b5ae6c33d838e52ce6726407df285cdbb27ec1908b333cf2820989bd3e986e37bb20979437fdf34b + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + has-proto: "npm:^1.0.1" + has-symbols: "npm:^1.0.3" + hasown: "npm:^2.0.0" + checksum: 10c0/0a9b82c16696ed6da5e39b1267104475c47e3a9bdbe8b509dfe1710946e38a87be70d759f4bb3cda042d76a41ef47fe769660f3b7c0d1f68750299344ffb15b7 + languageName: node + linkType: hard + +"get-stream@npm:^8.0.1": + version: 8.0.1 + resolution: "get-stream@npm:8.0.1" + checksum: 10c0/5c2181e98202b9dae0bb4a849979291043e5892eb40312b47f0c22b9414fc9b28a3b6063d2375705eb24abc41ecf97894d9a51f64ff021511b504477b27b4290 + languageName: node + linkType: hard + +"get-symbol-description@npm:^1.0.2": + version: 1.0.2 + resolution: "get-symbol-description@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.5" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.4" + checksum: 10c0/867be6d63f5e0eb026cb3b0ef695ec9ecf9310febb041072d2e142f260bd91ced9eeb426b3af98791d1064e324e653424afa6fd1af17dee373bea48ae03162bc + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee + languageName: node + linkType: hard + +"glob-regex@npm:^0.3.0": + version: 0.3.2 + resolution: "glob-regex@npm:0.3.2" + checksum: 10c0/73cbaef56796ab967b516e0db07375c26535274fa259ce06da82b7dd25a138bf318237fd0cd93a6b0490e4d90db9f127193d8184e5c1acc296d2e5b879e66206 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.4.5 + resolution: "glob@npm:10.4.5" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^1.11.1" + bin: + glob: dist/esm/bin.mjs + checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e + languageName: node + linkType: hard + +"glob@npm:^7.1.3": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe + languageName: node + linkType: hard + +"globals@npm:^11.1.0": + version: 11.12.0 + resolution: "globals@npm:11.12.0" + checksum: 10c0/758f9f258e7b19226bd8d4af5d3b0dcf7038780fb23d82e6f98932c44e239f884847f1766e8fa9cc5635ccb3204f7fa7314d4408dd4002a5e8ea827b4018f0a1 + languageName: node + linkType: hard + +"globals@npm:^13.6.0, globals@npm:^13.9.0": + version: 13.24.0 + resolution: "globals@npm:13.24.0" + dependencies: + type-fest: "npm:^0.20.2" + checksum: 10c0/d3c11aeea898eb83d5ec7a99508600fbe8f83d2cf00cbb77f873dbf2bcb39428eff1b538e4915c993d8a3b3473fa71eeebfe22c9bb3a3003d1e26b1f2c8a42cd + languageName: node + linkType: hard + +"globalthis@npm:^1.0.3, globalthis@npm:^1.0.4": + version: 1.0.4 + resolution: "globalthis@npm:1.0.4" + dependencies: + define-properties: "npm:^1.2.1" + gopd: "npm:^1.0.1" + checksum: 10c0/9d156f313af79d80b1566b93e19285f481c591ad6d0d319b4be5e03750d004dde40a39a0f26f7e635f9007a3600802f53ecd85a759b86f109e80a5f705e01846 + languageName: node + linkType: hard + +"globby@npm:^11.0.3": + version: 11.1.0 + resolution: "globby@npm:11.1.0" + dependencies: + array-union: "npm:^2.1.0" + dir-glob: "npm:^3.0.1" + fast-glob: "npm:^3.2.9" + ignore: "npm:^5.2.0" + merge2: "npm:^1.4.1" + slash: "npm:^3.0.0" + checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189 + languageName: node + linkType: hard + +"globrex@npm:^0.1.2": + version: 0.1.2 + resolution: "globrex@npm:0.1.2" + checksum: 10c0/a54c029520cf58bda1d8884f72bd49b4cd74e977883268d931fd83bcbd1a9eb96d57c7dbd4ad80148fb9247467ebfb9b215630b2ed7563b2a8de02e1ff7f89d1 + languageName: node + linkType: hard + +"gopd@npm:^1.0.1": + version: 1.0.1 + resolution: "gopd@npm:1.0.1" + dependencies: + get-intrinsic: "npm:^1.1.3" + checksum: 10c0/505c05487f7944c552cee72087bf1567debb470d4355b1335f2c262d218ebbff805cd3715448fe29b4b380bae6912561d0467233e4165830efd28da241418c63 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 + languageName: node + linkType: hard + +"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": + version: 1.0.2 + resolution: "has-bigints@npm:1.0.2" + checksum: 10c0/724eb1485bfa3cdff6f18d95130aa190561f00b3fcf9f19dc640baf8176b5917c143b81ec2123f8cddb6c05164a198c94b13e1377c497705ccc8e1a80306e83b + languageName: node + linkType: hard + +"has-flag@npm:^3.0.0": + version: 3.0.0 + resolution: "has-flag@npm:3.0.0" + checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 10c0/2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1 + languageName: node + linkType: hard + +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: "npm:^1.0.0" + checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236 + languageName: node + linkType: hard + +"has-proto@npm:^1.0.1, has-proto@npm:^1.0.3": + version: 1.0.3 + resolution: "has-proto@npm:1.0.3" + checksum: 10c0/35a6989f81e9f8022c2f4027f8b48a552de714938765d019dbea6bb547bd49ce5010a3c7c32ec6ddac6e48fc546166a3583b128f5a7add8b058a6d8b4afec205 + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": + version: 1.0.3 + resolution: "has-symbols@npm:1.0.3" + checksum: 10c0/e6922b4345a3f37069cdfe8600febbca791c94988c01af3394d86ca3360b4b93928bbf395859158f88099cb10b19d98e3bbab7c9ff2c1bd09cf665ee90afa2c3 + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" + dependencies: + has-symbols: "npm:^1.0.3" + checksum: 10c0/a8b166462192bafe3d9b6e420a1d581d93dd867adb61be223a17a8d6dad147aa77a8be32c961bb2f27b3ef893cae8d36f564ab651f5e9b7938ae86f74027c48c + languageName: node + linkType: hard + +"hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 10c0/3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9 + languageName: node + linkType: hard + +"history@npm:^4.9.0": + version: 4.10.1 + resolution: "history@npm:4.10.1" + dependencies: + "@babel/runtime": "npm:^7.1.2" + loose-envify: "npm:^1.2.0" + resolve-pathname: "npm:^3.0.0" + tiny-invariant: "npm:^1.0.2" + tiny-warning: "npm:^1.0.0" + value-equal: "npm:^1.0.1" + checksum: 10c0/35377694e4f10f2cf056a9cb1a8ee083e04e4b4717a63baeee4afd565658a62c7e73700bf9e82aa53dbe1ec94e0a25a83c080d63bad8ee6b274a98d2fbc5ed4c + languageName: node + linkType: hard + +"hoist-non-react-statics@npm:^3.1.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": + version: 3.3.2 + resolution: "hoist-non-react-statics@npm:3.3.2" + dependencies: + react-is: "npm:^16.7.0" + checksum: 10c0/fe0889169e845d738b59b64badf5e55fa3cf20454f9203d1eb088df322d49d4318df774828e789898dcb280e8a5521bb59b3203385662ca5e9218a6ca5820e74 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 10c0/ce1319b8a382eb3cbb4a37c19f6bfe14e5bb5be3d09079e885e8c513ab2d3cd9214902f8a31c9dc4e37022633ceabfc2d697405deeaf1b8f3552bb4ed996fdfc + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.5 + resolution: "https-proxy-agent@npm:7.0.5" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 10c0/2490e3acec397abeb88807db52cac59102d5ed758feee6df6112ab3ccd8325e8a1ce8bce6f4b66e5470eca102d31e425ace904242e4fa28dbe0c59c4bafa7b2c + languageName: node + linkType: hard + +"human-signals@npm:^5.0.0": + version: 5.0.0 + resolution: "human-signals@npm:5.0.0" + checksum: 10c0/5a9359073fe17a8b58e5a085e9a39a950366d9f00217c4ff5878bd312e09d80f460536ea6a3f260b5943a01fe55c158d1cea3fc7bee3d0520aeef04f6d915c82 + languageName: node + linkType: hard + +"husky@npm:>=6": + version: 9.1.6 + resolution: "husky@npm:9.1.6" + bin: + husky: bin.js + checksum: 10c0/705673db4a247c1febd9c5df5f6a3519106cf0335845027bb50a15fba9b1f542cb2610932ede96fd08008f6d9f49db0f15560509861808b0031cdc0e7c798bac + languageName: node + linkType: hard + +"hyphenate-style-name@npm:^1.0.3": + version: 1.1.0 + resolution: "hyphenate-style-name@npm:1.1.0" + checksum: 10c0/bfe88deac2414a41a0d08811e277c8c098f23993d6a1eb17f14a0f11b54c4d42865a63d3cfe1914668eefb9a188e2de58f38b55a179a238fd1fef606893e194f + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 + languageName: node + linkType: hard + +"ignore@npm:^4.0.6": + version: 4.0.6 + resolution: "ignore@npm:4.0.6" + checksum: 10c0/836ee7dc7fd9436096e2dba429359dbb9fa0e33d309e2b2d81692f375f6ca82024fc00567f798613d50c6b989e9cd2ad2b065acf116325cde177f02c86b7d4e0 + languageName: node + linkType: hard + +"ignore@npm:^5.1.1, ignore@npm:^5.1.8, ignore@npm:^5.2.0": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 + languageName: node + linkType: hard + +"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": + version: 3.3.0 + resolution: "import-fresh@npm:3.3.0" + dependencies: + parent-module: "npm:^1.0.0" + resolve-from: "npm:^4.0.0" + checksum: 10c0/7f882953aa6b740d1f0e384d0547158bc86efbf2eea0f1483b8900a6f65c5a5123c2cf09b0d542cc419d0b98a759ecaeb394237e97ea427f2da221dc3cd80cc3 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: 10c0/1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2 + languageName: node + linkType: hard + +"inherits@npm:2": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 + languageName: node + linkType: hard + +"internal-slot@npm:^1.0.7": + version: 1.0.7 + resolution: "internal-slot@npm:1.0.7" + dependencies: + es-errors: "npm:^1.3.0" + hasown: "npm:^2.0.0" + side-channel: "npm:^1.0.4" + checksum: 10c0/f8b294a4e6ea3855fc59551bbf35f2b832cf01fd5e6e2a97f5c201a071cc09b49048f856e484b67a6c721da5e55736c5b6ddafaf19e2dbeb4a3ff1821680de6c + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 10c0/331cd07fafcb3b24100613e4b53e1a2b4feab11e671e655d46dc09ee233da5011284d09ca40c4ecbdfe1d0004f462958675c224a804259f2f78d2465a87824bc + languageName: node + linkType: hard + +"is-array-buffer@npm:^3.0.4": + version: 3.0.4 + resolution: "is-array-buffer@npm:3.0.4" + dependencies: + call-bind: "npm:^1.0.2" + get-intrinsic: "npm:^1.2.1" + checksum: 10c0/42a49d006cc6130bc5424eae113e948c146f31f9d24460fc0958f855d9d810e6fd2e4519bf19aab75179af9c298ea6092459d8cafdec523cd19e529b26eab860 + languageName: node + linkType: hard + +"is-arrayish@npm:^0.2.1": + version: 0.2.1 + resolution: "is-arrayish@npm:0.2.1" + checksum: 10c0/e7fb686a739068bb70f860b39b67afc62acc62e36bb61c5f965768abce1873b379c563e61dd2adad96ebb7edf6651111b385e490cf508378959b0ed4cac4e729 + languageName: node + linkType: hard + +"is-async-function@npm:^2.0.0": + version: 2.0.0 + resolution: "is-async-function@npm:2.0.0" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/787bc931576aad525d751fc5ce211960fe91e49ac84a5c22d6ae0bc9541945fbc3f686dc590c3175722ce4f6d7b798a93f6f8ff4847fdb2199aea6f4baf5d668 + languageName: node + linkType: hard + +"is-bigint@npm:^1.0.1": + version: 1.0.4 + resolution: "is-bigint@npm:1.0.4" + dependencies: + has-bigints: "npm:^1.0.1" + checksum: 10c0/eb9c88e418a0d195ca545aff2b715c9903d9b0a5033bc5922fec600eb0c3d7b1ee7f882dbf2e0d5a6e694e42391be3683e4368737bd3c4a77f8ac293e7773696 + languageName: node + linkType: hard + +"is-boolean-object@npm:^1.1.0": + version: 1.1.2 + resolution: "is-boolean-object@npm:1.1.2" + dependencies: + call-bind: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/6090587f8a8a8534c0f816da868bc94f32810f08807aa72fa7e79f7e11c466d281486ffe7a788178809c2aa71fe3e700b167fe80dd96dad68026bfff8ebf39f7 + languageName: node + linkType: hard + +"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": + version: 1.2.7 + resolution: "is-callable@npm:1.2.7" + checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f + languageName: node + linkType: hard + +"is-core-module@npm:^2.13.0, is-core-module@npm:^2.15.1": + version: 2.15.1 + resolution: "is-core-module@npm:2.15.1" + dependencies: + hasown: "npm:^2.0.2" + checksum: 10c0/53432f10c69c40bfd2fa8914133a68709ff9498c86c3bf5fca3cdf3145a56fd2168cbf4a43b29843a6202a120a5f9c5ffba0a4322e1e3441739bc0b641682612 + languageName: node + linkType: hard + +"is-data-view@npm:^1.0.1": + version: 1.0.1 + resolution: "is-data-view@npm:1.0.1" + dependencies: + is-typed-array: "npm:^1.1.13" + checksum: 10c0/a3e6ec84efe303da859107aed9b970e018e2bee7ffcb48e2f8096921a493608134240e672a2072577e5f23a729846241d9634806e8a0e51d9129c56d5f65442d + languageName: node + linkType: hard + +"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": + version: 1.0.5 + resolution: "is-date-object@npm:1.0.5" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/eed21e5dcc619c48ccef804dfc83a739dbb2abee6ca202838ee1bd5f760fe8d8a93444f0d49012ad19bb7c006186e2884a1b92f6e1c056da7fd23d0a9ad5992e + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 + languageName: node + linkType: hard + +"is-finalizationregistry@npm:^1.0.2": + version: 1.0.2 + resolution: "is-finalizationregistry@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.2" + checksum: 10c0/81caecc984d27b1a35c68741156fc651fb1fa5e3e6710d21410abc527eb226d400c0943a167922b2e920f6b3e58b0dede9aa795882b038b85f50b3a4b877db86 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^4.0.0": + version: 4.0.0 + resolution: "is-fullwidth-code-point@npm:4.0.0" + checksum: 10c0/df2a717e813567db0f659c306d61f2f804d480752526886954a2a3e2246c7745fd07a52b5fecf2b68caf0a6c79dcdace6166fdf29cc76ed9975cc334f0a018b8 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^5.0.0": + version: 5.0.0 + resolution: "is-fullwidth-code-point@npm:5.0.0" + dependencies: + get-east-asian-width: "npm:^1.0.0" + checksum: 10c0/cd591b27d43d76b05fa65ed03eddce57a16e1eca0b7797ff7255de97019bcaf0219acfc0c4f7af13319e13541f2a53c0ace476f442b13267b9a6a7568f2b65c8 + languageName: node + linkType: hard + +"is-generator-function@npm:^1.0.10": + version: 1.0.10 + resolution: "is-generator-function@npm:1.0.10" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/df03514df01a6098945b5a0cfa1abff715807c8e72f57c49a0686ad54b3b74d394e2d8714e6f709a71eb00c9630d48e73ca1796c1ccc84ac95092c1fecc0d98b + languageName: node + linkType: hard + +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a + languageName: node + linkType: hard + +"is-in-browser@npm:^1.0.2, is-in-browser@npm:^1.1.3": + version: 1.1.3 + resolution: "is-in-browser@npm:1.1.3" + checksum: 10c0/87e6119a56ec3d84910eb6ad855b4a3ac05b242fc2bc2c28abbf978f76b5a834ec5622165035acaf2844a85856b1a0fbc12bd0cb1ce9e86314ebec675c6fe856 + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 10c0/85fee098ae62ba6f1e24cf22678805473c7afd0fb3978a3aa260e354cb7bcb3a5806cf0a98403188465efedec41ab4348e8e4e79305d409601323855b3839d4d + languageName: node + linkType: hard + +"is-map@npm:^2.0.3": + version: 2.0.3 + resolution: "is-map@npm:2.0.3" + checksum: 10c0/2c4d431b74e00fdda7162cd8e4b763d6f6f217edf97d4f8538b94b8702b150610e2c64961340015fe8df5b1fcee33ccd2e9b62619c4a8a3a155f8de6d6d355fc + languageName: node + linkType: hard + +"is-negative-zero@npm:^2.0.3": + version: 2.0.3 + resolution: "is-negative-zero@npm:2.0.3" + checksum: 10c0/bcdcf6b8b9714063ffcfa9929c575ac69bfdabb8f4574ff557dfc086df2836cf07e3906f5bbc4f2a5c12f8f3ba56af640c843cdfc74da8caed86c7c7d66fd08e + languageName: node + linkType: hard + +"is-number-object@npm:^1.0.4": + version: 1.0.7 + resolution: "is-number-object@npm:1.0.7" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/aad266da1e530f1804a2b7bd2e874b4869f71c98590b3964f9d06cc9869b18f8d1f4778f838ecd2a11011bce20aeecb53cb269ba916209b79c24580416b74b1b + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 + languageName: node + linkType: hard + +"is-regex@npm:^1.1.4": + version: 1.1.4 + resolution: "is-regex@npm:1.1.4" + dependencies: + call-bind: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/bb72aae604a69eafd4a82a93002058c416ace8cde95873589a97fc5dac96a6c6c78a9977d487b7b95426a8f5073969124dd228f043f9f604f041f32fcc465fc1 + languageName: node + linkType: hard + +"is-set@npm:^2.0.3": + version: 2.0.3 + resolution: "is-set@npm:2.0.3" + checksum: 10c0/f73732e13f099b2dc879c2a12341cfc22ccaca8dd504e6edae26484bd5707a35d503fba5b4daad530a9b088ced1ae6c9d8200fd92e09b428fe14ea79ce8080b7 + languageName: node + linkType: hard + +"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": + version: 1.0.3 + resolution: "is-shared-array-buffer@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.7" + checksum: 10c0/adc11ab0acbc934a7b9e5e9d6c588d4ec6682f6fea8cda5180721704fa32927582ede5b123349e32517fdadd07958973d24716c80e7ab198970c47acc09e59c7 + languageName: node + linkType: hard + +"is-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "is-stream@npm:3.0.0" + checksum: 10c0/eb2f7127af02ee9aa2a0237b730e47ac2de0d4e76a4a905a50a11557f2339df5765eaea4ceb8029f1efa978586abe776908720bfcb1900c20c6ec5145f6f29d8 + languageName: node + linkType: hard + +"is-string@npm:^1.0.5, is-string@npm:^1.0.7": + version: 1.0.7 + resolution: "is-string@npm:1.0.7" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/905f805cbc6eedfa678aaa103ab7f626aac9ebbdc8737abb5243acaa61d9820f8edc5819106b8fcd1839e33db21de9f0116ae20de380c8382d16dc2a601921f6 + languageName: node + linkType: hard + +"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": + version: 1.0.4 + resolution: "is-symbol@npm:1.0.4" + dependencies: + has-symbols: "npm:^1.0.2" + checksum: 10c0/9381dd015f7c8906154dbcbf93fad769de16b4b961edc94f88d26eb8c555935caa23af88bda0c93a18e65560f6d7cca0fd5a3f8a8e1df6f1abbb9bead4502ef7 + languageName: node + linkType: hard + +"is-typed-array@npm:^1.1.13": + version: 1.1.13 + resolution: "is-typed-array@npm:1.1.13" + dependencies: + which-typed-array: "npm:^1.1.14" + checksum: 10c0/fa5cb97d4a80e52c2cc8ed3778e39f175a1a2ae4ddf3adae3187d69586a1fd57cfa0b095db31f66aa90331e9e3da79184cea9c6abdcd1abc722dc3c3edd51cca + languageName: node + linkType: hard + +"is-weakmap@npm:^2.0.2": + version: 2.0.2 + resolution: "is-weakmap@npm:2.0.2" + checksum: 10c0/443c35bb86d5e6cc5929cd9c75a4024bb0fff9586ed50b092f94e700b89c43a33b186b76dbc6d54f3d3d09ece689ab38dcdc1af6a482cbe79c0f2da0a17f1299 + languageName: node + linkType: hard + +"is-weakref@npm:^1.0.2": + version: 1.0.2 + resolution: "is-weakref@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.2" + checksum: 10c0/1545c5d172cb690c392f2136c23eec07d8d78a7f57d0e41f10078aa4f5daf5d7f57b6513a67514ab4f073275ad00c9822fc8935e00229d0a2089e1c02685d4b1 + languageName: node + linkType: hard + +"is-weakset@npm:^2.0.3": + version: 2.0.3 + resolution: "is-weakset@npm:2.0.3" + dependencies: + call-bind: "npm:^1.0.7" + get-intrinsic: "npm:^1.2.4" + checksum: 10c0/8ad6141b6a400e7ce7c7442a13928c676d07b1f315ab77d9912920bf5f4170622f43126f111615788f26c3b1871158a6797c862233124507db0bcc33a9537d1a + languageName: node + linkType: hard + +"isarray@npm:0.0.1": + version: 0.0.1 + resolution: "isarray@npm:0.0.1" + checksum: 10c0/ed1e62da617f71fe348907c71743b5ed550448b455f8d269f89a7c7ddb8ae6e962de3dab6a74a237b06f5eb7f6ece7a45ada8ce96d87fe972926530f91ae3311 + languageName: node + linkType: hard + +"isarray@npm:^2.0.5": + version: 2.0.5 + resolution: "isarray@npm:2.0.5" + checksum: 10c0/4199f14a7a13da2177c66c31080008b7124331956f47bca57dd0b6ea9f11687aa25e565a2c7a2b519bc86988d10398e3049a1f5df13c9f6b7664154690ae79fd + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 + languageName: node + linkType: hard + +"iterator.prototype@npm:^1.1.3": + version: 1.1.3 + resolution: "iterator.prototype@npm:1.1.3" + dependencies: + define-properties: "npm:^1.2.1" + get-intrinsic: "npm:^1.2.1" + has-symbols: "npm:^1.0.3" + reflect.getprototypeof: "npm:^1.0.4" + set-function-name: "npm:^2.0.1" + checksum: 10c0/68b0320c14291fbb3d8ed5a17e255d3127e7971bec19108076667e79c9ff4c7d69f99de4b0b3075c789c3f318366d7a0a35bb086eae0f2cf832dd58465b2f9e6 + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9 + languageName: node + linkType: hard + +"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed + languageName: node + linkType: hard + +"js-yaml@npm:^3.13.1": + version: 3.14.1 + resolution: "js-yaml@npm:3.14.1" + dependencies: + argparse: "npm:^1.0.7" + esprima: "npm:^4.0.0" + bin: + js-yaml: bin/js-yaml.js + checksum: 10c0/6746baaaeac312c4db8e75fa22331d9a04cccb7792d126ed8ce6a0bbcfef0cedaddd0c5098fade53db067c09fe00aa1c957674b4765610a8b06a5a189e46433b + languageName: node + linkType: hard + +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: 10c0/4f907fb78d7b712e11dea8c165fe0921f81a657d3443dde75359ed52eb2b5d33ce6773d97985a089f09a65edd80b11cb75c767b57ba47391fee4c969f7215c96 + languageName: node + linkType: hard + +"jsesc@npm:^3.0.2": + version: 3.0.2 + resolution: "jsesc@npm:3.0.2" + bin: + jsesc: bin/jsesc + checksum: 10c0/ef22148f9e793180b14d8a145ee6f9f60f301abf443288117b4b6c53d0ecd58354898dc506ccbb553a5f7827965cd38bc5fb726575aae93c5e8915e2de8290e1 + languageName: node + linkType: hard + +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7 + languageName: node + linkType: hard + +"json-parse-even-better-errors@npm:^2.3.0": + version: 2.3.1 + resolution: "json-parse-even-better-errors@npm:2.3.1" + checksum: 10c0/140932564c8f0b88455432e0f33c4cb4086b8868e37524e07e723f4eaedb9425bdc2bafd71bd1d9765bd15fd1e2d126972bc83990f55c467168c228c24d665f3 + languageName: node + linkType: hard + +"json-schema-traverse@npm:^0.4.1": + version: 0.4.1 + resolution: "json-schema-traverse@npm:0.4.1" + checksum: 10c0/108fa90d4cc6f08243aedc6da16c408daf81793bf903e9fd5ab21983cda433d5d2da49e40711da016289465ec2e62e0324dcdfbc06275a607fe3233fde4942ce + languageName: node + linkType: hard + +"json-schema-traverse@npm:^1.0.0": + version: 1.0.0 + resolution: "json-schema-traverse@npm:1.0.0" + checksum: 10c0/71e30015d7f3d6dc1c316d6298047c8ef98a06d31ad064919976583eb61e1018a60a0067338f0f79cabc00d84af3fcc489bd48ce8a46ea165d9541ba17fb30c6 + languageName: node + linkType: hard + +"json-stable-stringify-without-jsonify@npm:^1.0.1": + version: 1.0.1 + resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" + checksum: 10c0/cb168b61fd4de83e58d09aaa6425ef71001bae30d260e2c57e7d09a5fd82223e2f22a042dedaab8db23b7d9ae46854b08bb1f91675a8be11c5cffebef5fb66a5 + languageName: node + linkType: hard + +"json5@npm:^1.0.2": + version: 1.0.2 + resolution: "json5@npm:1.0.2" + dependencies: + minimist: "npm:^1.2.0" + bin: + json5: lib/cli.js + checksum: 10c0/9ee316bf21f000b00752e6c2a3b79ecf5324515a5c60ee88983a1910a45426b643a4f3461657586e8aeca87aaf96f0a519b0516d2ae527a6c3e7eed80f68717f + languageName: node + linkType: hard + +"json5@npm:^2.2.2, json5@npm:^2.2.3": + version: 2.2.3 + resolution: "json5@npm:2.2.3" + bin: + json5: lib/cli.js + checksum: 10c0/5a04eed94810fa55c5ea138b2f7a5c12b97c3750bc63d11e511dcecbfef758003861522a070c2272764ee0f4e3e323862f386945aeb5b85b87ee43f084ba586c + languageName: node + linkType: hard + +"jsonfile@npm:^6.0.1": + version: 6.1.0 + resolution: "jsonfile@npm:6.1.0" + dependencies: + graceful-fs: "npm:^4.1.6" + universalify: "npm:^2.0.0" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/4f95b5e8a5622b1e9e8f33c96b7ef3158122f595998114d1e7f03985649ea99cb3cd99ce1ed1831ae94c8c8543ab45ebd044207612f31a56fd08462140e46865 + languageName: node + linkType: hard + +"jss-plugin-camel-case@npm:^10.5.1": + version: 10.10.0 + resolution: "jss-plugin-camel-case@npm:10.10.0" + dependencies: + "@babel/runtime": "npm:^7.3.1" + hyphenate-style-name: "npm:^1.0.3" + jss: "npm:10.10.0" + checksum: 10c0/29dedf0866837425258eae3b12b72c1de435ea7caddef94ac13044b3a04c4abd8dd238a81fd6e0a4afdbf10c9cb4674df41f50af79554c34c736cd2ecf3752da + languageName: node + linkType: hard + +"jss-plugin-default-unit@npm:^10.5.1": + version: 10.10.0 + resolution: "jss-plugin-default-unit@npm:10.10.0" + dependencies: + "@babel/runtime": "npm:^7.3.1" + jss: "npm:10.10.0" + checksum: 10c0/f394d5411114fde7056249f4650de51e6f3e47c64a3d48cee80180a6e75876f0d0d68c96d81458880e1024ca880ed53baade682d36a5f7177046bfef0b280572 + languageName: node + linkType: hard + +"jss-plugin-global@npm:^10.5.1": + version: 10.10.0 + resolution: "jss-plugin-global@npm:10.10.0" + dependencies: + "@babel/runtime": "npm:^7.3.1" + jss: "npm:10.10.0" + checksum: 10c0/2d24ef0e16cd6ebcce59f132756716ae37fdffe3f59461018636a57ef68298e649f43bd5c346041f1642872aa2cc0629f5ecfb48a20bfb471813318cb8f3935f + languageName: node + linkType: hard + +"jss-plugin-nested@npm:^10.5.1": + version: 10.10.0 + resolution: "jss-plugin-nested@npm:10.10.0" + dependencies: + "@babel/runtime": "npm:^7.3.1" + jss: "npm:10.10.0" + tiny-warning: "npm:^1.0.2" + checksum: 10c0/868ac4e4bea9dc02fac33f15e3165c008669d69e6b87201f1d8574eb213408b67366302288b49f46acda1320164460daa50e6aac817d34ae3b1c256a03f4ebba + languageName: node + linkType: hard + +"jss-plugin-props-sort@npm:^10.5.1": + version: 10.10.0 + resolution: "jss-plugin-props-sort@npm:10.10.0" + dependencies: + "@babel/runtime": "npm:^7.3.1" + jss: "npm:10.10.0" + checksum: 10c0/5579bb21bfe514c12f43bd5e57458badc37c8e5676a47109f45195466a3aed633c61609daef079622421ef7c902b8342d1f96578543fefcb729f0b8dcfd2fe37 + languageName: node + linkType: hard + +"jss-plugin-rule-value-function@npm:^10.5.1": + version: 10.10.0 + resolution: "jss-plugin-rule-value-function@npm:10.10.0" + dependencies: + "@babel/runtime": "npm:^7.3.1" + jss: "npm:10.10.0" + tiny-warning: "npm:^1.0.2" + checksum: 10c0/678bedb49da3b5e93fc1971d691f7f3ad2d7cf15dfc220edab934b70c7571fc383a435371a687a8ae125ab5ccd7bada9712574620959a3d1cd961fbca1583c29 + languageName: node + linkType: hard + +"jss-plugin-vendor-prefixer@npm:^10.5.1": + version: 10.10.0 + resolution: "jss-plugin-vendor-prefixer@npm:10.10.0" + dependencies: + "@babel/runtime": "npm:^7.3.1" + css-vendor: "npm:^2.0.8" + jss: "npm:10.10.0" + checksum: 10c0/e3ad2dfe93d126f722586782aebddcd68dc46c0ad59f99edd65e164ecbb6e4cad6ce85c874f90553fa5fec50c2fd2b1f5984abfc4e3dd49d24033bbc378a2e11 + languageName: node + linkType: hard + +"jss@npm:10.10.0, jss@npm:^10.5.1": + version: 10.10.0 + resolution: "jss@npm:10.10.0" + dependencies: + "@babel/runtime": "npm:^7.3.1" + csstype: "npm:^3.0.2" + is-in-browser: "npm:^1.1.3" + tiny-warning: "npm:^1.0.2" + checksum: 10c0/aa5e743a3f40d6df05ae951c6913b6495ef42b3e9539f6875c32bf01c42ab405bd91038d6feca2ed5c67a2947111b0137213983089e2a310ee11fc563208ad61 + languageName: node + linkType: hard + +"jsx-ast-utils@npm:^2.4.1 || ^3.0.0": + version: 3.3.5 + resolution: "jsx-ast-utils@npm:3.3.5" + dependencies: + array-includes: "npm:^3.1.6" + array.prototype.flat: "npm:^1.3.1" + object.assign: "npm:^4.1.4" + object.values: "npm:^1.1.6" + checksum: 10c0/a32679e9cb55469cb6d8bbc863f7d631b2c98b7fc7bf172629261751a6e7bc8da6ae374ddb74d5fbd8b06cf0eb4572287b259813d92b36e384024ed35e4c13e1 + languageName: node + linkType: hard + +"keyv@npm:^4.5.3": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: "npm:3.0.1" + checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e + languageName: node + linkType: hard + +"levn@npm:^0.4.1": + version: 0.4.1 + resolution: "levn@npm:0.4.1" + dependencies: + prelude-ls: "npm:^1.2.1" + type-check: "npm:~0.4.0" + checksum: 10c0/effb03cad7c89dfa5bd4f6989364bfc79994c2042ec5966cb9b95990e2edee5cd8969ddf42616a0373ac49fac1403437deaf6e9050fbbaa3546093a59b9ac94e + languageName: node + linkType: hard + +"lilconfig@npm:~3.1.2": + version: 3.1.2 + resolution: "lilconfig@npm:3.1.2" + checksum: 10c0/f059630b1a9bddaeba83059db00c672b64dc14074e9f232adce32b38ca1b5686ab737eb665c5ba3c32f147f0002b4bee7311ad0386a9b98547b5623e87071fbe + languageName: node + linkType: hard + +"lines-and-columns@npm:^1.1.6": + version: 1.2.4 + resolution: "lines-and-columns@npm:1.2.4" + checksum: 10c0/3da6ee62d4cd9f03f5dc90b4df2540fb85b352081bee77fe4bbcd12c9000ead7f35e0a38b8d09a9bb99b13223446dd8689ff3c4959807620726d788701a83d2d + languageName: node + linkType: hard + +"lint-staged@npm:>=10": + version: 15.2.10 + resolution: "lint-staged@npm:15.2.10" + dependencies: + chalk: "npm:~5.3.0" + commander: "npm:~12.1.0" + debug: "npm:~4.3.6" + execa: "npm:~8.0.1" + lilconfig: "npm:~3.1.2" + listr2: "npm:~8.2.4" + micromatch: "npm:~4.0.8" + pidtree: "npm:~0.6.0" + string-argv: "npm:~0.3.2" + yaml: "npm:~2.5.0" + bin: + lint-staged: bin/lint-staged.js + checksum: 10c0/6ad7b41f5e87a84fa2eb1990080ea3c68a2f2031b4e81edcdc2a458cc878538eedb310e6f98ffd878a1287e1a52ac968e540ee8a0e96c247e04b0cbc36421cdd + languageName: node + linkType: hard + +"listr2@npm:~8.2.4": + version: 8.2.5 + resolution: "listr2@npm:8.2.5" + dependencies: + cli-truncate: "npm:^4.0.0" + colorette: "npm:^2.0.20" + eventemitter3: "npm:^5.0.1" + log-update: "npm:^6.1.0" + rfdc: "npm:^1.4.1" + wrap-ansi: "npm:^9.0.0" + checksum: 10c0/f5a9599514b00c27d7eb32d1117c83c61394b2a985ec20e542c798bf91cf42b19340215701522736f5b7b42f557e544afeadec47866e35e5d4f268f552729671 + languageName: node + linkType: hard + +"lodash.merge@npm:^4.6.2": + version: 4.6.2 + resolution: "lodash.merge@npm:4.6.2" + checksum: 10c0/402fa16a1edd7538de5b5903a90228aa48eb5533986ba7fa26606a49db2572bf414ff73a2c9f5d5fd36b31c46a5d5c7e1527749c07cbcf965ccff5fbdf32c506 + languageName: node + linkType: hard + +"lodash.truncate@npm:^4.4.2": + version: 4.4.2 + resolution: "lodash.truncate@npm:4.4.2" + checksum: 10c0/4e870d54e8a6c86c8687e057cec4069d2e941446ccab7f40b4d9555fa5872d917d0b6aa73bece7765500a3123f1723bcdba9ae881b679ef120bba9e1a0b0ed70 + languageName: node + linkType: hard + +"log-update@npm:^6.1.0": + version: 6.1.0 + resolution: "log-update@npm:6.1.0" + dependencies: + ansi-escapes: "npm:^7.0.0" + cli-cursor: "npm:^5.0.0" + slice-ansi: "npm:^7.1.0" + strip-ansi: "npm:^7.1.0" + wrap-ansi: "npm:^9.0.0" + checksum: 10c0/4b350c0a83d7753fea34dcac6cd797d1dc9603291565de009baa4aa91c0447eab0d3815a05c8ec9ac04fdfffb43c82adcdb03ec1fceafd8518e1a8c1cff4ff89 + languageName: node + linkType: hard + +"loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": + version: 1.4.0 + resolution: "loose-envify@npm:1.4.0" + dependencies: + js-tokens: "npm:^3.0.0 || ^4.0.0" + bin: + loose-envify: cli.js + checksum: 10c0/655d110220983c1a4b9c0c679a2e8016d4b67f6e9c7b5435ff5979ecdb20d0813f4dec0a08674fcbdd4846a3f07edbb50a36811fd37930b94aaa0d9daceb017e + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb + languageName: node + linkType: hard + +"lru-cache@npm:^5.1.1": + version: 5.1.1 + resolution: "lru-cache@npm:5.1.1" + dependencies: + yallist: "npm:^3.0.2" + checksum: 10c0/89b2ef2ef45f543011e38737b8a8622a2f8998cddf0e5437174ef8f1f70a8b9d14a918ab3e232cb3ba343b7abddffa667f0b59075b2b80e6b4d63c3de6127482 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^13.0.0": + version: 13.0.1 + resolution: "make-fetch-happen@npm:13.0.1" + dependencies: + "@npmcli/agent": "npm:^2.0.0" + cacache: "npm:^18.0.0" + http-cache-semantics: "npm:^4.1.1" + is-lambda: "npm:^1.0.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + proc-log: "npm:^4.2.0" + promise-retry: "npm:^2.0.1" + ssri: "npm:^10.0.0" + checksum: 10c0/df5f4dbb6d98153b751bccf4dc4cc500de85a96a9331db9805596c46aa9f99d9555983954e6c1266d9f981ae37a9e4647f42b9a4bb5466f867f4012e582c9e7e + languageName: node + linkType: hard + +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 10c0/867fdbb30a6d58b011449b8885601ec1690c3e41c759ecd5a9d609094f7aed0096c37823ff4a7190ef0b8f22cc86beb7049196ff68c016e3b3c671d0dac91ce5 + languageName: node + linkType: hard + +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb + languageName: node + linkType: hard + +"micromatch@npm:^4.0.4, micromatch@npm:~4.0.8": + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" + dependencies: + braces: "npm:^3.0.3" + picomatch: "npm:^2.3.1" + checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8 + languageName: node + linkType: hard + +"mimic-fn@npm:^4.0.0": + version: 4.0.0 + resolution: "mimic-fn@npm:4.0.0" + checksum: 10c0/de9cc32be9996fd941e512248338e43407f63f6d497abe8441fa33447d922e927de54d4cc3c1a3c6d652857acd770389d5a3823f311a744132760ce2be15ccbf + languageName: node + linkType: hard + +"mimic-function@npm:^5.0.0": + version: 5.0.1 + resolution: "mimic-function@npm:5.0.1" + checksum: 10c0/f3d9464dd1816ecf6bdf2aec6ba32c0728022039d992f178237d8e289b48764fee4131319e72eedd4f7f094e22ded0af836c3187a7edc4595d28dd74368fd81d + languageName: node + linkType: hard + +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311 + languageName: node + linkType: hard + +"minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed + languageName: node + linkType: hard + +"minimist@npm:^1.2.0, minimist@npm:^1.2.6": + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.5 + resolution: "minipass-fetch@npm:3.0.5" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: 10c0/9d702d57f556274286fdd97e406fc38a2f5c8d15e158b498d7393b1105974b21249289ec571fa2b51e038a4872bfc82710111cf75fae98c662f3d6f95e72152b + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2 + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 10c0/a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 10c0/b0fd20bb9fb56e5fa9a8bfac539e8915ae07430a619e4b86ff71f5fc757ef3924b23b2c4230393af1eda647ed3d75739e4e0acb250a6b1eb277cf7f8fe449557 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: 10c0/64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf + languageName: node + linkType: hard + +"ms@npm:2.0.0": + version: 2.0.0 + resolution: "ms@npm:2.0.0" + checksum: 10c0/f8fda810b39fd7255bbdc451c46286e549794fcc700dc9cd1d25658bbc4dc2563a5de6fe7c60f798a16a60c6ceb53f033cb353f493f0cf63e5199b702943159d + languageName: node + linkType: hard + +"ms@npm:^2.1.1, ms@npm:^2.1.3": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 + languageName: node + linkType: hard + +"mz@npm:^2.7.0": + version: 2.7.0 + resolution: "mz@npm:2.7.0" + dependencies: + any-promise: "npm:^1.0.0" + object-assign: "npm:^4.0.1" + thenify-all: "npm:^1.0.0" + checksum: 10c0/103114e93f87362f0b56ab5b2e7245051ad0276b646e3902c98397d18bb8f4a77f2ea4a2c9d3ad516034ea3a56553b60d3f5f78220001ca4c404bd711bd0af39 + languageName: node + linkType: hard + +"nanoid@npm:^3.3.7": + version: 3.3.7 + resolution: "nanoid@npm:3.3.7" + bin: + nanoid: bin/nanoid.cjs + checksum: 10c0/e3fb661aa083454f40500473bb69eedb85dc160e763150b9a2c567c7e9ff560ce028a9f833123b618a6ea742e311138b591910e795614a629029e86e180660f3 + languageName: node + linkType: hard + +"natural-compare@npm:^1.4.0": + version: 1.4.0 + resolution: "natural-compare@npm:1.4.0" + checksum: 10c0/f5f9a7974bfb28a91afafa254b197f0f22c684d4a1731763dda960d2c8e375b36c7d690e0d9dc8fba774c537af14a7e979129bca23d88d052fbeb9466955e447 + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 10.2.0 + resolution: "node-gyp@npm:10.2.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^4.1.0" + semver: "npm:^7.3.5" + tar: "npm:^6.2.1" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 10c0/00630d67dbd09a45aee0a5d55c05e3916ca9e6d427ee4f7bc392d2d3dc5fad7449b21fc098dd38260a53d9dcc9c879b36704a1994235d4707e7271af7e9a835b + languageName: node + linkType: hard + +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: 10c0/786ac9db9d7226339e1dc84bbb42007cb054a346bd9257e6aa154d294f01bc6a6cddb1348fa099f079be6580acbb470e3c048effd5f719325abd0179e566fd27 + languageName: node + linkType: hard + +"nopt@npm:^7.0.0": + version: 7.2.1 + resolution: "nopt@npm:7.2.1" + dependencies: + abbrev: "npm:^2.0.0" + bin: + nopt: bin/nopt.js + checksum: 10c0/a069c7c736767121242037a22a788863accfa932ab285a1eb569eb8cd534b09d17206f68c37f096ae785647435e0c5a5a0a67b42ec743e481a455e5ae6a6df81 + languageName: node + linkType: hard + +"npm-run-path@npm:^5.1.0": + version: 5.3.0 + resolution: "npm-run-path@npm:5.3.0" + dependencies: + path-key: "npm:^4.0.0" + checksum: 10c0/124df74820c40c2eb9a8612a254ea1d557ddfab1581c3e751f825e3e366d9f00b0d76a3c94ecd8398e7f3eee193018622677e95816e8491f0797b21e30b2deba + languageName: node + linkType: hard + +"object-assign@npm:^4.0.1, object-assign@npm:^4.1.1": + version: 4.1.1 + resolution: "object-assign@npm:4.1.1" + checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 + languageName: node + linkType: hard + +"object-inspect@npm:^1.13.1": + version: 1.13.2 + resolution: "object-inspect@npm:1.13.2" + checksum: 10c0/b97835b4c91ec37b5fd71add84f21c3f1047d1d155d00c0fcd6699516c256d4fcc6ff17a1aced873197fe447f91a3964178fd2a67a1ee2120cdaf60e81a050b4 + languageName: node + linkType: hard + +"object-keys@npm:^1.1.1": + version: 1.1.1 + resolution: "object-keys@npm:1.1.1" + checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d + languageName: node + linkType: hard + +"object.assign@npm:^4.1.4, object.assign@npm:^4.1.5": + version: 4.1.5 + resolution: "object.assign@npm:4.1.5" + dependencies: + call-bind: "npm:^1.0.5" + define-properties: "npm:^1.2.1" + has-symbols: "npm:^1.0.3" + object-keys: "npm:^1.1.1" + checksum: 10c0/60108e1fa2706f22554a4648299b0955236c62b3685c52abf4988d14fffb0e7731e00aa8c6448397e3eb63d087dcc124a9f21e1980f36d0b2667f3c18bacd469 + languageName: node + linkType: hard + +"object.entries@npm:^1.1.8": + version: 1.1.8 + resolution: "object.entries@npm:1.1.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10c0/db9ea979d2956a3bc26c262da4a4d212d36f374652cc4c13efdd069c1a519c16571c137e2893d1c46e1cb0e15c88fd6419eaf410c945f329f09835487d7e65d3 + languageName: node + linkType: hard + +"object.fromentries@npm:^2.0.8": + version: 2.0.8 + resolution: "object.fromentries@npm:2.0.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-object-atoms: "npm:^1.0.0" + checksum: 10c0/cd4327e6c3369cfa805deb4cbbe919bfb7d3aeebf0bcaba291bb568ea7169f8f8cdbcabe2f00b40db0c20cd20f08e11b5f3a5a36fb7dd3fe04850c50db3bf83b + languageName: node + linkType: hard + +"object.groupby@npm:^1.0.3": + version: 1.0.3 + resolution: "object.groupby@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + checksum: 10c0/60d0455c85c736fbfeda0217d1a77525956f76f7b2495edeca9e9bbf8168a45783199e77b894d30638837c654d0cc410e0e02cbfcf445bc8de71c3da1ede6a9c + languageName: node + linkType: hard + +"object.values@npm:^1.1.6, object.values@npm:^1.2.0": + version: 1.2.0 + resolution: "object.values@npm:1.2.0" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10c0/15809dc40fd6c5529501324fec5ff08570b7d70fb5ebbe8e2b3901afec35cf2b3dc484d1210c6c642cd3e7e0a5e18dd1d6850115337fef46bdae14ab0cb18ac3 + languageName: node + linkType: hard + +"on-finished@npm:~2.3.0": + version: 2.3.0 + resolution: "on-finished@npm:2.3.0" + dependencies: + ee-first: "npm:1.1.1" + checksum: 10c0/c904f9e518b11941eb60279a3cbfaf1289bd0001f600a950255b1dede9fe3df8cd74f38483550b3bb9485165166acb5db500c3b4c4337aec2815c88c96fcc2ea + languageName: node + linkType: hard + +"once@npm:^1.3.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 + languageName: node + linkType: hard + +"onetime@npm:^6.0.0": + version: 6.0.0 + resolution: "onetime@npm:6.0.0" + dependencies: + mimic-fn: "npm:^4.0.0" + checksum: 10c0/4eef7c6abfef697dd4479345a4100c382d73c149d2d56170a54a07418c50816937ad09500e1ed1e79d235989d073a9bade8557122aee24f0576ecde0f392bb6c + languageName: node + linkType: hard + +"onetime@npm:^7.0.0": + version: 7.0.0 + resolution: "onetime@npm:7.0.0" + dependencies: + mimic-function: "npm:^5.0.0" + checksum: 10c0/5cb9179d74b63f52a196a2e7037ba2b9a893245a5532d3f44360012005c9cadb60851d56716ebff18a6f47129dab7168022445df47c2aff3b276d92585ed1221 + languageName: node + linkType: hard + +"optionator@npm:^0.9.1": + version: 0.9.4 + resolution: "optionator@npm:0.9.4" + dependencies: + deep-is: "npm:^0.1.3" + fast-levenshtein: "npm:^2.0.6" + levn: "npm:^0.4.1" + prelude-ls: "npm:^1.2.1" + type-check: "npm:^0.4.0" + word-wrap: "npm:^1.2.5" + checksum: 10c0/4afb687a059ee65b61df74dfe87d8d6815cd6883cb8b3d5883a910df72d0f5d029821f37025e4bccf4048873dbdb09acc6d303d27b8f76b1a80dd5a7d5334675 + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75 + languageName: node + linkType: hard + +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 10c0/62ba2785eb655fec084a257af34dbe24292ab74516d6aecef97ef72d4897310bc6898f6c85b5cd22770eaa1ce60d55a0230e150fb6a966e3ecd6c511e23d164b + languageName: node + linkType: hard + +"parent-module@npm:^1.0.0": + version: 1.0.1 + resolution: "parent-module@npm:1.0.1" + dependencies: + callsites: "npm:^3.0.0" + checksum: 10c0/c63d6e80000d4babd11978e0d3fee386ca7752a02b035fd2435960ffaa7219dc42146f07069fb65e6e8bf1caef89daf9af7535a39bddf354d78bf50d8294f556 + languageName: node + linkType: hard + +"parse-json@npm:^5.0.0": + version: 5.2.0 + resolution: "parse-json@npm:5.2.0" + dependencies: + "@babel/code-frame": "npm:^7.0.0" + error-ex: "npm:^1.3.1" + json-parse-even-better-errors: "npm:^2.3.0" + lines-and-columns: "npm:^1.1.6" + checksum: 10c0/77947f2253005be7a12d858aedbafa09c9ae39eb4863adf330f7b416ca4f4a08132e453e08de2db46459256fb66afaac5ee758b44fe6541b7cdaf9d252e59585 + languageName: node + linkType: hard + +"parseurl@npm:~1.3.3": + version: 1.3.3 + resolution: "parseurl@npm:1.3.3" + checksum: 10c0/90dd4760d6f6174adb9f20cf0965ae12e23879b5f5464f38e92fce8073354341e4b3b76fa3d878351efe7d01e617121955284cfd002ab087fba1a0726ec0b4f5 + languageName: node + linkType: hard + +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078 + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c + languageName: node + linkType: hard + +"path-key@npm:^4.0.0": + version: 4.0.0 + resolution: "path-key@npm:4.0.0" + checksum: 10c0/794efeef32863a65ac312f3c0b0a99f921f3e827ff63afa5cb09a377e202c262b671f7b3832a4e64731003fa94af0263713962d317b9887bd1e0c48a342efba3 + languageName: node + linkType: hard + +"path-parse@npm:^1.0.7": + version: 1.0.7 + resolution: "path-parse@npm:1.0.7" + checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1 + languageName: node + linkType: hard + +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 10c0/32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d + languageName: node + linkType: hard + +"path-to-regexp@npm:^1.7.0": + version: 1.9.0 + resolution: "path-to-regexp@npm:1.9.0" + dependencies: + isarray: "npm:0.0.1" + checksum: 10c0/de9ddb01b84d9c2c8e2bed18630d8d039e2d6f60a6538595750fa08c7a6482512257464c8da50616f266ab2cdd2428387e85f3b089e4c3f25d0c537e898a0751 + languageName: node + linkType: hard + +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c + languageName: node + linkType: hard + +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.0": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 + languageName: node + linkType: hard + +"picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be + languageName: node + linkType: hard + +"pidtree@npm:~0.6.0": + version: 0.6.0 + resolution: "pidtree@npm:0.6.0" + bin: + pidtree: bin/pidtree.js + checksum: 10c0/0829ec4e9209e230f74ebf4265f5ccc9ebfb488334b525cb13f86ff801dca44b362c41252cd43ae4d7653a10a5c6ab3be39d2c79064d6895e0d78dc50a5ed6e9 + languageName: node + linkType: hard + +"pinst@npm:>=2": + version: 3.0.0 + resolution: "pinst@npm:3.0.0" + bin: + pinst: bin.js + checksum: 10c0/abb1ed62ea2acb2207a7a860715bdb26ecbde74ede8fad5f6200194f3e22db25e2b7a49af05e5cc7fc05384709c651e0000323f0077d7239060c4b68c8acd428 + languageName: node + linkType: hard + +"pirates@npm:^4.0.1": + version: 4.0.6 + resolution: "pirates@npm:4.0.6" + checksum: 10c0/00d5fa51f8dded94d7429700fb91a0c1ead00ae2c7fd27089f0c5b63e6eca36197fe46384631872690a66f390c5e27198e99006ab77ae472692ab9c2ca903f36 + languageName: node + linkType: hard + +"popper.js@npm:1.16.1-lts": + version: 1.16.1-lts + resolution: "popper.js@npm:1.16.1-lts" + checksum: 10c0/f859226804c95f18499d3b8f3e00b293ae0f1ffd0c75a64c0b7632fc3e12ac1cc5f717fa91ff64a12559f69dcee0c95cbae66ffea41ba420e511a150173c435a + languageName: node + linkType: hard + +"possible-typed-array-names@npm:^1.0.0": + version: 1.0.0 + resolution: "possible-typed-array-names@npm:1.0.0" + checksum: 10c0/d9aa22d31f4f7680e20269db76791b41c3a32c01a373e25f8a4813b4d45f7456bfc2b6d68f752dc4aab0e0bb0721cb3d76fb678c9101cb7a16316664bc2c73fd + languageName: node + linkType: hard + +"postcss@npm:^8.3.5, postcss@npm:^8.4.13": + version: 8.4.47 + resolution: "postcss@npm:8.4.47" + dependencies: + nanoid: "npm:^3.3.7" + picocolors: "npm:^1.1.0" + source-map-js: "npm:^1.2.1" + checksum: 10c0/929f68b5081b7202709456532cee2a145c1843d391508c5a09de2517e8c4791638f71dd63b1898dba6712f8839d7a6da046c72a5e44c162e908f5911f57b5f44 + languageName: node + linkType: hard + +"prelude-ls@npm:^1.2.1": + version: 1.2.1 + resolution: "prelude-ls@npm:1.2.1" + checksum: 10c0/b00d617431e7886c520a6f498a2e14c75ec58f6d93ba48c3b639cf241b54232d90daa05d83a9e9b9fef6baa63cb7e1e4602c2372fea5bc169668401eb127d0cd + languageName: node + linkType: hard + +"prettier@npm:^2.3.2": + version: 2.8.8 + resolution: "prettier@npm:2.8.8" + bin: + prettier: bin-prettier.js + checksum: 10c0/463ea8f9a0946cd5b828d8cf27bd8b567345cf02f56562d5ecde198b91f47a76b7ac9eae0facd247ace70e927143af6135e8cf411986b8cb8478784a4d6d724a + languageName: node + linkType: hard + +"proc-log@npm:^4.1.0, proc-log@npm:^4.2.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 10c0/17db4757c2a5c44c1e545170e6c70a26f7de58feb985091fb1763f5081cab3d01b181fb2dd240c9f4a4255a1d9227d163d5771b7e69c9e49a561692db865efb9 + languageName: node + linkType: hard + +"progress@npm:^2.0.0": + version: 2.0.3 + resolution: "progress@npm:2.0.3" + checksum: 10c0/1697e07cb1068055dbe9fe858d242368ff5d2073639e652b75a7eb1f2a1a8d4afd404d719de23c7b48481a6aa0040686310e2dac2f53d776daa2176d3f96369c + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 10c0/9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96 + languageName: node + linkType: hard + +"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": + version: 15.8.1 + resolution: "prop-types@npm:15.8.1" + dependencies: + loose-envify: "npm:^1.4.0" + object-assign: "npm:^4.1.1" + react-is: "npm:^16.13.1" + checksum: 10c0/59ece7ca2fb9838031d73a48d4becb9a7cc1ed10e610517c7d8f19a1e02fa47f7c27d557d8a5702bec3cfeccddc853579832b43f449e54635803f277b1c78077 + languageName: node + linkType: hard + +"punycode@npm:^2.1.0": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9 + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102 + languageName: node + linkType: hard + +"react-cool-dimensions@npm:^2.0.7": + version: 2.0.7 + resolution: "react-cool-dimensions@npm:2.0.7" + peerDependencies: + react: ">= 16.8.0" + checksum: 10c0/45f7bef4660758f6affebcee1ca5c51ebf68fc935a8359c536a57bc4ceb37a87424b413366048d6f94d5e72704b91dc7a0ee63b44a62e35ed772a180fe82ec72 + languageName: node + linkType: hard + +"react-dom@npm:^17.0.2": + version: 17.0.2 + resolution: "react-dom@npm:17.0.2" + dependencies: + loose-envify: "npm:^1.1.0" + object-assign: "npm:^4.1.1" + scheduler: "npm:^0.20.2" + peerDependencies: + react: 17.0.2 + checksum: 10c0/51abbcb72450fe527ebf978c3bc989ba266630faaa53f47a2fae5392369729e8de62b2e4683598cbe651ea7873cd34ec7d5127e2f50bf4bfe6bd0c3ad9bddcb0 + languageName: node + linkType: hard + +"react-is@npm:^16.13.1, react-is@npm:^16.6.0, react-is@npm:^16.7.0": + version: 16.13.1 + resolution: "react-is@npm:16.13.1" + checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1 + languageName: node + linkType: hard + +"react-is@npm:^16.8.0 || ^17.0.0": + version: 17.0.2 + resolution: "react-is@npm:17.0.2" + checksum: 10c0/2bdb6b93fbb1820b024b496042cce405c57e2f85e777c9aabd55f9b26d145408f9f74f5934676ffdc46f3dcff656d78413a6e43968e7b3f92eea35b3052e9053 + languageName: node + linkType: hard + +"react-is@npm:^18.3.1": + version: 18.3.1 + resolution: "react-is@npm:18.3.1" + checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 + languageName: node + linkType: hard + +"react-joystick-component@npm:^6.2.1": + version: 6.2.1 + resolution: "react-joystick-component@npm:6.2.1" + peerDependencies: + react: ">=17.0.2" + react-dom: ">=17.0.2" + checksum: 10c0/3d70eec89140c8b3a73f3d7115d1f71be0afac9d2ee4dc6a082883ba5d7bd911400ca3cbc3df30cf0e79d647f45bc9c521aab926894ab89047a5b484c1fa728d + languageName: node + linkType: hard + +"react-refresh@npm:^0.10.0": + version: 0.10.0 + resolution: "react-refresh@npm:0.10.0" + checksum: 10c0/616e82bed3787bf4e55dcc1c9836f251b93523dd4b0ffb1c24c2dcf5d09f686fbf3cffc7d489cd7f12429f76ddf66eb431748fc07df56b18a888a7705cbc079e + languageName: node + linkType: hard + +"react-router-dom@npm:^5.2.0": + version: 5.3.4 + resolution: "react-router-dom@npm:5.3.4" + dependencies: + "@babel/runtime": "npm:^7.12.13" + history: "npm:^4.9.0" + loose-envify: "npm:^1.3.1" + prop-types: "npm:^15.6.2" + react-router: "npm:5.3.4" + tiny-invariant: "npm:^1.0.2" + tiny-warning: "npm:^1.0.0" + peerDependencies: + react: ">=15" + checksum: 10c0/f04f727e2ed2e9d1d3830af02cc61690ff67b1524c0d18690582bfba0f4d14142ccc88fb6da6befad644fddf086f5ae4c2eb7048c67da8a0b0929c19426421b0 + languageName: node + linkType: hard + +"react-router@npm:5.3.4": + version: 5.3.4 + resolution: "react-router@npm:5.3.4" + dependencies: + "@babel/runtime": "npm:^7.12.13" + history: "npm:^4.9.0" + hoist-non-react-statics: "npm:^3.1.0" + loose-envify: "npm:^1.3.1" + path-to-regexp: "npm:^1.7.0" + prop-types: "npm:^15.6.2" + react-is: "npm:^16.6.0" + tiny-invariant: "npm:^1.0.2" + tiny-warning: "npm:^1.0.0" + peerDependencies: + react: ">=15" + checksum: 10c0/e15c00dfef199249b4c6e6d98e5e76cc352ce66f3270f13df37cc069ddf7c05e43281e8c308fc407e4435d72924373baef1d2890e0f6b0b1eb423cf47315a053 + languageName: node + linkType: hard + +"react-transition-group@npm:^4.4.0, react-transition-group@npm:^4.4.5": + version: 4.4.5 + resolution: "react-transition-group@npm:4.4.5" + dependencies: + "@babel/runtime": "npm:^7.5.5" + dom-helpers: "npm:^5.0.1" + loose-envify: "npm:^1.4.0" + prop-types: "npm:^15.6.2" + peerDependencies: + react: ">=16.6.0" + react-dom: ">=16.6.0" + checksum: 10c0/2ba754ba748faefa15f87c96dfa700d5525054a0141de8c75763aae6734af0740e77e11261a1e8f4ffc08fd9ab78510122e05c21c2d79066c38bb6861a886c82 + languageName: node + linkType: hard + +"react@npm:^17.0.2": + version: 17.0.2 + resolution: "react@npm:17.0.2" + dependencies: + loose-envify: "npm:^1.1.0" + object-assign: "npm:^4.1.1" + checksum: 10c0/07ae8959acf1596f0550685102fd6097d461a54a4fd46a50f88a0cd7daaa97fdd6415de1dcb4bfe0da6aa43221a6746ce380410fa848acc60f8ac41f6649c148 + languageName: node + linkType: hard + +"recrawl-sync@npm:^2.0.3": + version: 2.2.3 + resolution: "recrawl-sync@npm:2.2.3" + dependencies: + "@cush/relative": "npm:^1.0.0" + glob-regex: "npm:^0.3.0" + slash: "npm:^3.0.0" + sucrase: "npm:^3.20.3" + tslib: "npm:^1.9.3" + checksum: 10c0/3129ce44a97b2d8f2f18c4bc13d9faccd90dda7bff82c498d14c6e3720eb3249d8cb21576ca41c0a236cfe9b81e02a3e84b160256f359669450a8a628bd2df73 + languageName: node + linkType: hard + +"reflect.getprototypeof@npm:^1.0.4": + version: 1.0.6 + resolution: "reflect.getprototypeof@npm:1.0.6" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.1" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.4" + globalthis: "npm:^1.0.3" + which-builtin-type: "npm:^1.1.3" + checksum: 10c0/baf4ef8ee6ff341600f4720b251cf5a6cb552d6a6ab0fdc036988c451bf16f920e5feb0d46bd4f530a5cce568f1f7aca2d77447ca798920749cfc52783c39b55 + languageName: node + linkType: hard + +"regenerator-runtime@npm:^0.14.0": + version: 0.14.1 + resolution: "regenerator-runtime@npm:0.14.1" + checksum: 10c0/1b16eb2c4bceb1665c89de70dcb64126a22bc8eb958feef3cd68fe11ac6d2a4899b5cd1b80b0774c7c03591dc57d16631a7f69d2daa2ec98100e2f29f7ec4cc4 + languageName: node + linkType: hard + +"regexp.prototype.flags@npm:^1.5.2": + version: 1.5.3 + resolution: "regexp.prototype.flags@npm:1.5.3" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-errors: "npm:^1.3.0" + set-function-name: "npm:^2.0.2" + checksum: 10c0/e1a7c7dc42cc91abf73e47a269c4b3a8f225321b7f617baa25821f6a123a91d23a73b5152f21872c566e699207e1135d075d2251cd3e84cc96d82a910adf6020 + languageName: node + linkType: hard + +"regexpp@npm:^3.0.0, regexpp@npm:^3.1.0": + version: 3.2.0 + resolution: "regexpp@npm:3.2.0" + checksum: 10c0/d1da82385c8754a1681416b90b9cca0e21b4a2babef159099b88f640637d789c69011d0bc94705dacab85b81133e929d027d85210e8b8b03f8035164dbc14710 + languageName: node + linkType: hard + +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 + languageName: node + linkType: hard + +"require-from-string@npm:^2.0.2": + version: 2.0.2 + resolution: "require-from-string@npm:2.0.2" + checksum: 10c0/aaa267e0c5b022fc5fd4eef49d8285086b15f2a1c54b28240fdf03599cbd9c26049fee3eab894f2e1f6ca65e513b030a7c264201e3f005601e80c49fb2937ce2 + languageName: node + linkType: hard + +"resolve-from@npm:^4.0.0": + version: 4.0.0 + resolution: "resolve-from@npm:4.0.0" + checksum: 10c0/8408eec31a3112ef96e3746c37be7d64020cda07c03a920f5024e77290a218ea758b26ca9529fd7b1ad283947f34b2291c1c0f6aa0ed34acfdda9c6014c8d190 + languageName: node + linkType: hard + +"resolve-pathname@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-pathname@npm:3.0.0" + checksum: 10c0/c6ec49b670dc35b9a303c47fa83ba9348a71e92d64a4c4bb85e1b659a29b407aa1ac1cb14a9b5b502982132ca77482bd80534bca147439d66880d35a137fe723 + languageName: node + linkType: hard + +"resolve@npm:^1.10.1, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.0, resolve@npm:^1.22.4": + version: 1.22.8 + resolution: "resolve@npm:1.22.8" + dependencies: + is-core-module: "npm:^2.13.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/07e179f4375e1fd072cfb72ad66d78547f86e6196c4014b31cb0b8bb1db5f7ca871f922d08da0fbc05b94e9fd42206f819648fa3b5b873ebbc8e1dc68fec433a + languageName: node + linkType: hard + +"resolve@npm:^2.0.0-next.5": + version: 2.0.0-next.5 + resolution: "resolve@npm:2.0.0-next.5" + dependencies: + is-core-module: "npm:^2.13.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/a6c33555e3482ea2ec4c6e3d3bf0d78128abf69dca99ae468e64f1e30acaa318fd267fb66c8836b04d558d3e2d6ed875fe388067e7d8e0de647d3c21af21c43a + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A^1.10.1#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin": + version: 1.22.8 + resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.13.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/0446f024439cd2e50c6c8fa8ba77eaa8370b4180f401a96abf3d1ebc770ac51c1955e12764cde449fde3fff480a61f84388e3505ecdbab778f4bef5f8212c729 + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A^2.0.0-next.5#optional!builtin": + version: 2.0.0-next.5 + resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#optional!builtin::version=2.0.0-next.5&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.13.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/78ad6edb8309a2bfb720c2c1898f7907a37f858866ce11a5974643af1203a6a6e05b2fa9c53d8064a673a447b83d42569260c306d43628bff5bb101969708355 + languageName: node + linkType: hard + +"restore-cursor@npm:^5.0.0": + version: 5.1.0 + resolution: "restore-cursor@npm:5.1.0" + dependencies: + onetime: "npm:^7.0.0" + signal-exit: "npm:^4.1.0" + checksum: 10c0/c2ba89131eea791d1b25205bdfdc86699767e2b88dee2a590b1a6caa51737deac8bad0260a5ded2f7c074b7db2f3a626bcf1fcf3cdf35974cbeea5e2e6764f60 + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 10c0/59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: 10c0/c19ef26e4e188f408922c46f7ff480d38e8dfc55d448310dfb518736b23ed2c4f547fb64a6ed5bdba92cd7e7ddc889d36ff78f794816d5e71498d645ef476107 + languageName: node + linkType: hard + +"rfdc@npm:^1.4.1": + version: 1.4.1 + resolution: "rfdc@npm:1.4.1" + checksum: 10c0/4614e4292356cafade0b6031527eea9bc90f2372a22c012313be1dcc69a3b90c7338158b414539be863fa95bfcb2ddcd0587be696841af4e6679d85e62c060c7 + languageName: node + linkType: hard + +"rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: bin.js + checksum: 10c0/9cb7757acb489bd83757ba1a274ab545eafd75598a9d817e0c3f8b164238dd90eba50d6b848bd4dcc5f3040912e882dc7ba71653e35af660d77b25c381d402e8 + languageName: node + linkType: hard + +"rollup@npm:>=2.59.0 <2.78.0": + version: 2.77.3 + resolution: "rollup@npm:2.77.3" + dependencies: + fsevents: "npm:~2.3.2" + dependenciesMeta: + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/7e04ba4e8fdbc3a4a368013e4b788044c16fe94e7301aacbf38e37210983e159b97887ddd3333be9f78fedb30264f094c111ff56a0207c21d4e1745248a7aa42 + languageName: node + linkType: hard + +"rollup@npm:^2.38.5, rollup@npm:^2.53.0": + version: 2.79.2 + resolution: "rollup@npm:2.79.2" + dependencies: + fsevents: "npm:~2.3.2" + dependenciesMeta: + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/bc3746c988d903c2211266ddc539379d53d92689b9cc5c2b4e3ae161689de9af491957a567c629b6cc81f48d0928a7591fc4c383fba68a48d2966c9fb8a2bce9 + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39 + languageName: node + linkType: hard + +"safe-array-concat@npm:^1.1.2": + version: 1.1.2 + resolution: "safe-array-concat@npm:1.1.2" + dependencies: + call-bind: "npm:^1.0.7" + get-intrinsic: "npm:^1.2.4" + has-symbols: "npm:^1.0.3" + isarray: "npm:^2.0.5" + checksum: 10c0/12f9fdb01c8585e199a347eacc3bae7b5164ae805cdc8c6707199dbad5b9e30001a50a43c4ee24dc9ea32dbb7279397850e9208a7e217f4d8b1cf5d90129dec9 + languageName: node + linkType: hard + +"safe-regex-test@npm:^1.0.3": + version: 1.0.3 + resolution: "safe-regex-test@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.6" + es-errors: "npm:^1.3.0" + is-regex: "npm:^1.1.4" + checksum: 10c0/900bf7c98dc58f08d8523b7012b468e4eb757afa624f198902c0643d7008ba777b0bdc35810ba0b758671ce887617295fb742b3f3968991b178ceca54cb07603 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 + languageName: node + linkType: hard + +"scheduler@npm:^0.20.2": + version: 0.20.2 + resolution: "scheduler@npm:0.20.2" + dependencies: + loose-envify: "npm:^1.1.0" + object-assign: "npm:^4.1.1" + checksum: 10c0/b0982e4b0f34f4ffa4f2f486161c0fd9ce9b88680b045dccbf250eb1aa4fd27413570645455187a83535e2370f5c667a251045547765408492bd883cbe95fcdb + languageName: node + linkType: hard + +"semver@npm:^6.1.0, semver@npm:^6.3.1": + version: 6.3.1 + resolution: "semver@npm:6.3.1" + bin: + semver: bin/semver.js + checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d + languageName: node + linkType: hard + +"semver@npm:^7.2.1, semver@npm:^7.3.5": + version: 7.6.3 + resolution: "semver@npm:7.6.3" + bin: + semver: bin/semver.js + checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf + languageName: node + linkType: hard + +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.2" + checksum: 10c0/82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c + languageName: node + linkType: hard + +"set-function-name@npm:^2.0.1, set-function-name@npm:^2.0.2": + version: 2.0.2 + resolution: "set-function-name@npm:2.0.2" + dependencies: + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" + functions-have-names: "npm:^1.2.3" + has-property-descriptors: "npm:^1.0.2" + checksum: 10c0/fce59f90696c450a8523e754abb305e2b8c73586452619c2bad5f7bf38c7b6b4651895c9db895679c5bef9554339cf3ef1c329b66ece3eda7255785fbe299316 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 + languageName: node + linkType: hard + +"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" + dependencies: + call-bind: "npm:^1.0.7" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.4" + object-inspect: "npm:^1.13.1" + checksum: 10c0/d2afd163dc733cc0a39aa6f7e39bf0c436293510dbccbff446733daeaf295857dbccf94297092ec8c53e2503acac30f0b78830876f0485991d62a90e9cad305f + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 + languageName: node + linkType: hard + +"slash@npm:^3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b + languageName: node + linkType: hard + +"slice-ansi@npm:^4.0.0": + version: 4.0.0 + resolution: "slice-ansi@npm:4.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + astral-regex: "npm:^2.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + checksum: 10c0/6c25678db1270d4793e0327620f1e0f9f5bea4630123f51e9e399191bc52c87d6e6de53ed33538609e5eacbd1fab769fae00f3705d08d029f02102a540648918 + languageName: node + linkType: hard + +"slice-ansi@npm:^5.0.0": + version: 5.0.0 + resolution: "slice-ansi@npm:5.0.0" + dependencies: + ansi-styles: "npm:^6.0.0" + is-fullwidth-code-point: "npm:^4.0.0" + checksum: 10c0/2d4d40b2a9d5cf4e8caae3f698fe24ae31a4d778701724f578e984dcb485ec8c49f0c04dab59c401821e80fcdfe89cace9c66693b0244e40ec485d72e543914f + languageName: node + linkType: hard + +"slice-ansi@npm:^7.1.0": + version: 7.1.0 + resolution: "slice-ansi@npm:7.1.0" + dependencies: + ansi-styles: "npm:^6.2.1" + is-fullwidth-code-point: "npm:^5.0.0" + checksum: 10c0/631c971d4abf56cf880f034d43fcc44ff883624867bf11ecbd538c47343911d734a4656d7bc02362b40b89d765652a7f935595441e519b59e2ad3f4d5d6fe7ca + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.4 + resolution: "socks-proxy-agent@npm:8.0.4" + dependencies: + agent-base: "npm:^7.1.1" + debug: "npm:^4.3.4" + socks: "npm:^2.8.3" + checksum: 10c0/345593bb21b95b0508e63e703c84da11549f0a2657d6b4e3ee3612c312cb3a907eac10e53b23ede3557c6601d63252103494caa306b66560f43af7b98f53957a + languageName: node + linkType: hard + +"socks@npm:^2.8.3": + version: 2.8.3 + resolution: "socks@npm:2.8.3" + dependencies: + ip-address: "npm:^9.0.5" + smart-buffer: "npm:^4.2.0" + checksum: 10c0/d54a52bf9325165770b674a67241143a3d8b4e4c8884560c4e0e078aace2a728dffc7f70150660f51b85797c4e1a3b82f9b7aa25e0a0ceae1a243365da5c51a7 + languageName: node + linkType: hard + +"source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf + languageName: node + linkType: hard + +"source-map@npm:^0.5.7": + version: 0.5.7 + resolution: "source-map@npm:0.5.7" + checksum: 10c0/904e767bb9c494929be013017380cbba013637da1b28e5943b566031e29df04fba57edf3f093e0914be094648b577372bd8ad247fa98cfba9c600794cd16b599 + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec + languageName: node + linkType: hard + +"sprintf-js@npm:~1.0.2": + version: 1.0.3 + resolution: "sprintf-js@npm:1.0.3" + checksum: 10c0/ecadcfe4c771890140da5023d43e190b7566d9cf8b2d238600f31bec0fc653f328da4450eb04bd59a431771a8e9cc0e118f0aa3974b683a4981b4e07abc2a5bb + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.6 + resolution: "ssri@npm:10.0.6" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/e5a1e23a4057a86a97971465418f22ea89bd439ac36ade88812dd920e4e61873e8abd6a9b72a03a67ef50faa00a2daf1ab745c5a15b46d03e0544a0296354227 + languageName: node + linkType: hard + +"statuses@npm:~1.5.0": + version: 1.5.0 + resolution: "statuses@npm:1.5.0" + checksum: 10c0/e433900956357b3efd79b1c547da4d291799ac836960c016d10a98f6a810b1b5c0dcc13b5a7aa609a58239b5190e1ea176ad9221c2157d2fd1c747393e6b2940 + languageName: node + linkType: hard + +"string-argv@npm:~0.3.2": + version: 0.3.2 + resolution: "string-argv@npm:0.3.2" + checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82 + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca + languageName: node + linkType: hard + +"string-width@npm:^7.0.0": + version: 7.2.0 + resolution: "string-width@npm:7.2.0" + dependencies: + emoji-regex: "npm:^10.3.0" + get-east-asian-width: "npm:^1.0.0" + strip-ansi: "npm:^7.1.0" + checksum: 10c0/eb0430dd43f3199c7a46dcbf7a0b34539c76fe3aa62763d0b0655acdcbdf360b3f66f3d58ca25ba0205f42ea3491fa00f09426d3b7d3040e506878fc7664c9b9 + languageName: node + linkType: hard + +"string.prototype.matchall@npm:^4.0.11": + version: 4.0.11 + resolution: "string.prototype.matchall@npm:4.0.11" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.4" + gopd: "npm:^1.0.1" + has-symbols: "npm:^1.0.3" + internal-slot: "npm:^1.0.7" + regexp.prototype.flags: "npm:^1.5.2" + set-function-name: "npm:^2.0.2" + side-channel: "npm:^1.0.6" + checksum: 10c0/915a2562ac9ab5e01b7be6fd8baa0b2b233a0a9aa975fcb2ec13cc26f08fb9a3e85d5abdaa533c99c6fc4c5b65b914eba3d80c4aff9792a4c9fed403f28f7d9d + languageName: node + linkType: hard + +"string.prototype.repeat@npm:^1.0.0": + version: 1.0.0 + resolution: "string.prototype.repeat@npm:1.0.0" + dependencies: + define-properties: "npm:^1.1.3" + es-abstract: "npm:^1.17.5" + checksum: 10c0/94c7978566cffa1327d470fd924366438af9b04b497c43a9805e476e2e908aa37a1fd34cc0911156c17556dab62159d12c7b92b3cc304c3e1281fe4c8e668f40 + languageName: node + linkType: hard + +"string.prototype.trim@npm:^1.2.9": + version: 1.2.9 + resolution: "string.prototype.trim@npm:1.2.9" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.0" + es-object-atoms: "npm:^1.0.0" + checksum: 10c0/dcef1a0fb61d255778155006b372dff8cc6c4394bc39869117e4241f41a2c52899c0d263ffc7738a1f9e61488c490b05c0427faa15151efad721e1a9fb2663c2 + languageName: node + linkType: hard + +"string.prototype.trimend@npm:^1.0.8": + version: 1.0.8 + resolution: "string.prototype.trimend@npm:1.0.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10c0/0a0b54c17c070551b38e756ae271865ac6cc5f60dabf2e7e343cceae7d9b02e1a1120a824e090e79da1b041a74464e8477e2da43e2775c85392be30a6f60963c + languageName: node + linkType: hard + +"string.prototype.trimstart@npm:^1.0.8": + version: 1.0.8 + resolution: "string.prototype.trimstart@npm:1.0.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10c0/d53af1899959e53c83b64a5fd120be93e067da740e7e75acb433849aa640782fb6c7d4cd5b84c954c84413745a3764df135a8afeb22908b86a835290788d8366 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 10c0/a198c3762e8832505328cbf9e8c8381de14a4fa50a4f9b2160138158ea88c0f5549fb50cb13c651c3088f47e63a108b34622ec18c0499b6c8c3a5ddf6b305ac4 + languageName: node + linkType: hard + +"strip-bom@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-bom@npm:3.0.0" + checksum: 10c0/51201f50e021ef16672593d7434ca239441b7b760e905d9f33df6e4f3954ff54ec0e0a06f100d028af0982d6f25c35cd5cda2ce34eaebccd0250b8befb90d8f1 + languageName: node + linkType: hard + +"strip-final-newline@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-final-newline@npm:3.0.0" + checksum: 10c0/a771a17901427bac6293fd416db7577e2bc1c34a19d38351e9d5478c3c415f523f391003b42ed475f27e33a78233035df183525395f731d3bfb8cdcbd4da08ce + languageName: node + linkType: hard + +"strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1": + version: 3.1.1 + resolution: "strip-json-comments@npm:3.1.1" + checksum: 10c0/9681a6257b925a7fa0f285851c0e613cc934a50661fa7bb41ca9cbbff89686bb4a0ee366e6ecedc4daafd01e83eee0720111ab294366fe7c185e935475ebcecd + languageName: node + linkType: hard + +"stylis@npm:4.2.0": + version: 4.2.0 + resolution: "stylis@npm:4.2.0" + checksum: 10c0/a7128ad5a8ed72652c6eba46bed4f416521bc9745a460ef5741edc725252cebf36ee45e33a8615a7057403c93df0866ab9ee955960792db210bb80abd5ac6543 + languageName: node + linkType: hard + +"sucrase@npm:^3.20.3": + version: 3.35.0 + resolution: "sucrase@npm:3.35.0" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.2" + commander: "npm:^4.0.0" + glob: "npm:^10.3.10" + lines-and-columns: "npm:^1.1.6" + mz: "npm:^2.7.0" + pirates: "npm:^4.0.1" + ts-interface-checker: "npm:^0.1.9" + bin: + sucrase: bin/sucrase + sucrase-node: bin/sucrase-node + checksum: 10c0/ac85f3359d2c2ecbf5febca6a24ae9bf96c931f05fde533c22a94f59c6a74895e5d5f0e871878dfd59c2697a75ebb04e4b2224ef0bfc24ca1210735c2ec191ef + languageName: node + linkType: hard + +"supports-color@npm:^5.3.0": + version: 5.5.0 + resolution: "supports-color@npm:5.5.0" + dependencies: + has-flag: "npm:^3.0.0" + checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 + languageName: node + linkType: hard + +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124 + languageName: node + linkType: hard + +"supports-preserve-symlinks-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "supports-preserve-symlinks-flag@npm:1.0.0" + checksum: 10c0/6c4032340701a9950865f7ae8ef38578d8d7053f5e10518076e6554a9381fa91bd9c6850193695c141f32b21f979c985db07265a758867bac95de05f7d8aeb39 + languageName: node + linkType: hard + +"table@npm:^6.0.9": + version: 6.8.2 + resolution: "table@npm:6.8.2" + dependencies: + ajv: "npm:^8.0.1" + lodash.truncate: "npm:^4.4.2" + slice-ansi: "npm:^4.0.0" + string-width: "npm:^4.2.3" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/f8b348af38ee34e419d8ce7306ba00671ce6f20e861ccff22555f491ba264e8416086063ce278a8d81abfa8d23b736ec2cca7ac4029b5472f63daa4b4688b803 + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.2.1": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: 10c0/a5eca3eb50bc11552d453488344e6507156b9193efd7635e98e867fab275d527af53d8866e2370cd09dfe74378a18111622ace35af6a608e5223a7d27fe99537 + languageName: node + linkType: hard + +"text-table@npm:^0.2.0": + version: 0.2.0 + resolution: "text-table@npm:0.2.0" + checksum: 10c0/02805740c12851ea5982686810702e2f14369a5f4c5c40a836821e3eefc65ffeec3131ba324692a37608294b0fd8c1e55a2dd571ffed4909822787668ddbee5c + languageName: node + linkType: hard + +"thenify-all@npm:^1.0.0": + version: 1.6.0 + resolution: "thenify-all@npm:1.6.0" + dependencies: + thenify: "npm:>= 3.1.0 < 4" + checksum: 10c0/9b896a22735e8122754fe70f1d65f7ee691c1d70b1f116fda04fea103d0f9b356e3676cb789506e3909ae0486a79a476e4914b0f92472c2e093d206aed4b7d6b + languageName: node + linkType: hard + +"thenify@npm:>= 3.1.0 < 4": + version: 3.3.1 + resolution: "thenify@npm:3.3.1" + dependencies: + any-promise: "npm:^1.0.0" + checksum: 10c0/f375aeb2b05c100a456a30bc3ed07ef03a39cbdefe02e0403fb714b8c7e57eeaad1a2f5c4ecfb9ce554ce3db9c2b024eba144843cd9e344566d9fcee73b04767 + languageName: node + linkType: hard + +"tiny-invariant@npm:^1.0.2": + version: 1.3.3 + resolution: "tiny-invariant@npm:1.3.3" + checksum: 10c0/65af4a07324b591a059b35269cd696aba21bef2107f29b9f5894d83cc143159a204b299553435b03874ebb5b94d019afa8b8eff241c8a4cfee95872c2e1c1c4a + languageName: node + linkType: hard + +"tiny-warning@npm:^1.0.0, tiny-warning@npm:^1.0.2": + version: 1.0.3 + resolution: "tiny-warning@npm:1.0.3" + checksum: 10c0/ef8531f581b30342f29670cb41ca248001c6fd7975ce22122bd59b8d62b4fc84ad4207ee7faa95cde982fa3357cd8f4be650142abc22805538c3b1392d7084fa + languageName: node + linkType: hard + +"to-fast-properties@npm:^2.0.0": + version: 2.0.0 + resolution: "to-fast-properties@npm:2.0.0" + checksum: 10c0/b214d21dbfb4bce3452b6244b336806ffea9c05297148d32ebb428d5c43ce7545bdfc65a1ceb58c9ef4376a65c0cb2854d645f33961658b3e3b4f84910ddcdd7 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 + languageName: node + linkType: hard + +"ts-interface-checker@npm:^0.1.9": + version: 0.1.13 + resolution: "ts-interface-checker@npm:0.1.13" + checksum: 10c0/232509f1b84192d07b81d1e9b9677088e590ac1303436da1e92b296e9be8e31ea042e3e1fd3d29b1742ad2c959e95afe30f63117b8f1bc3a3850070a5142fea7 + languageName: node + linkType: hard + +"tsconfig-paths@npm:^3.15.0": + version: 3.15.0 + resolution: "tsconfig-paths@npm:3.15.0" + dependencies: + "@types/json5": "npm:^0.0.29" + json5: "npm:^1.0.2" + minimist: "npm:^1.2.6" + strip-bom: "npm:^3.0.0" + checksum: 10c0/5b4f301a2b7a3766a986baf8fc0e177eb80bdba6e396792ff92dc23b5bca8bb279fc96517dcaaef63a3b49bebc6c4c833653ec58155780bc906bdbcf7dda0ef5 + languageName: node + linkType: hard + +"tsconfig-paths@npm:^4.0.0": + version: 4.2.0 + resolution: "tsconfig-paths@npm:4.2.0" + dependencies: + json5: "npm:^2.2.2" + minimist: "npm:^1.2.6" + strip-bom: "npm:^3.0.0" + checksum: 10c0/09a5877402d082bb1134930c10249edeebc0211f36150c35e1c542e5b91f1047b1ccf7da1e59babca1ef1f014c525510f4f870de7c9bda470c73bb4e2721b3ea + languageName: node + linkType: hard + +"tslib@npm:^1.8.1, tslib@npm:^1.9.3": + version: 1.14.1 + resolution: "tslib@npm:1.14.1" + checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 + languageName: node + linkType: hard + +"tsutils@npm:^3.21.0": + version: 3.21.0 + resolution: "tsutils@npm:3.21.0" + dependencies: + tslib: "npm:^1.8.1" + peerDependencies: + typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + checksum: 10c0/02f19e458ec78ead8fffbf711f834ad8ecd2cc6ade4ec0320790713dccc0a412b99e7fd907c4cda2a1dc602c75db6f12e0108e87a5afad4b2f9e90a24cabd5a2 + languageName: node + linkType: hard + +"type-check@npm:^0.4.0, type-check@npm:~0.4.0": + version: 0.4.0 + resolution: "type-check@npm:0.4.0" + dependencies: + prelude-ls: "npm:^1.2.1" + checksum: 10c0/7b3fd0ed43891e2080bf0c5c504b418fbb3e5c7b9708d3d015037ba2e6323a28152ec163bcb65212741fa5d2022e3075ac3c76440dbd344c9035f818e8ecee58 + languageName: node + linkType: hard + +"type-fest@npm:^0.20.2": + version: 0.20.2 + resolution: "type-fest@npm:0.20.2" + checksum: 10c0/dea9df45ea1f0aaa4e2d3bed3f9a0bfe9e5b2592bddb92eb1bf06e50bcf98dbb78189668cd8bc31a0511d3fc25539b4cd5c704497e53e93e2d40ca764b10bfc3 + languageName: node + linkType: hard + +"typed-array-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-buffer@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.7" + es-errors: "npm:^1.3.0" + is-typed-array: "npm:^1.1.13" + checksum: 10c0/9e043eb38e1b4df4ddf9dde1aa64919ae8bb909571c1cc4490ba777d55d23a0c74c7d73afcdd29ec98616d91bb3ae0f705fad4421ea147e1daf9528200b562da + languageName: node + linkType: hard + +"typed-array-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "typed-array-byte-length@npm:1.0.1" + dependencies: + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-proto: "npm:^1.0.3" + is-typed-array: "npm:^1.1.13" + checksum: 10c0/fcebeffb2436c9f355e91bd19e2368273b88c11d1acc0948a2a306792f1ab672bce4cfe524ab9f51a0505c9d7cd1c98eff4235c4f6bfef6a198f6cfc4ff3d4f3 + languageName: node + linkType: hard + +"typed-array-byte-offset@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-byte-offset@npm:1.0.2" + dependencies: + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-proto: "npm:^1.0.3" + is-typed-array: "npm:^1.1.13" + checksum: 10c0/d2628bc739732072e39269389a758025f75339de2ed40c4f91357023c5512d237f255b633e3106c461ced41907c1bf9a533c7e8578066b0163690ca8bc61b22f + languageName: node + linkType: hard + +"typed-array-length@npm:^1.0.6": + version: 1.0.6 + resolution: "typed-array-length@npm:1.0.6" + dependencies: + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-proto: "npm:^1.0.3" + is-typed-array: "npm:^1.1.13" + possible-typed-array-names: "npm:^1.0.0" + checksum: 10c0/74253d7dc488eb28b6b2711cf31f5a9dcefc9c41b0681fd1c178ed0a1681b4468581a3626d39cd4df7aee3d3927ab62be06aa9ca74e5baf81827f61641445b77 + languageName: node + linkType: hard + +"typescript@npm:4.3.5": + version: 4.3.5 + resolution: "typescript@npm:4.3.5" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/7699b1635e34008eb4167ede70d475e4eaece150622e9a143de6c58b160df3c52bae00beb1cd3a836a35cb32defc4d1dc56bdfb11f7ddbebaa003e405f97ad3a + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A4.3.5#optional!builtin": + version: 4.3.5 + resolution: "typescript@patch:typescript@npm%3A4.3.5#optional!builtin::version=4.3.5&hash=dba6d9" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/8991b4a568bd5a9dab8fa470b5e51368f588e46aebde3a773d9c993ef83e8a1ec0832deae4496d2c788a23c400471117d60b8f9607578ae79779cb3f379308ae + languageName: node + linkType: hard + +"unbox-primitive@npm:^1.0.2": + version: 1.0.2 + resolution: "unbox-primitive@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.2" + has-bigints: "npm:^1.0.2" + has-symbols: "npm:^1.0.3" + which-boxed-primitive: "npm:^1.0.2" + checksum: 10c0/81ca2e81134167cc8f75fa79fbcc8a94379d6c61de67090986a2273850989dd3bae8440c163121b77434b68263e34787a675cbdcb34bb2f764c6b9c843a11b66 + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 10c0/6363e40b2fa758eb5ec5e21b3c7fb83e5da8dcfbd866cc0c199d5534c42f03b9ea9ab069769cc388e1d7ab93b4eeef28ef506ab5f18d910ef29617715101884f + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 10c0/cb811d9d54eb5821b81b18205750be84cb015c20a4a44280794e915f5a0a70223ce39066781a354e872df3572e8155c228f43ff0cce94c7cbf4da2cc7cbdd635 + languageName: node + linkType: hard + +"universalify@npm:^2.0.0": + version: 2.0.1 + resolution: "universalify@npm:2.0.1" + checksum: 10c0/73e8ee3809041ca8b818efb141801a1004e3fc0002727f1531f4de613ea281b494a40909596dae4a042a4fb6cd385af5d4db2e137b1362e0e91384b828effd3a + languageName: node + linkType: hard + +"unpipe@npm:~1.0.0": + version: 1.0.0 + resolution: "unpipe@npm:1.0.0" + checksum: 10c0/193400255bd48968e5c5383730344fbb4fa114cdedfab26e329e50dd2d81b134244bb8a72c6ac1b10ab0281a58b363d06405632c9d49ca9dfd5e90cbd7d0f32c + languageName: node + linkType: hard + +"update-browserslist-db@npm:^1.1.0": + version: 1.1.1 + resolution: "update-browserslist-db@npm:1.1.1" + dependencies: + escalade: "npm:^3.2.0" + picocolors: "npm:^1.1.0" + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 10c0/536a2979adda2b4be81b07e311bd2f3ad5e978690987956bc5f514130ad50cac87cd22c710b686d79731e00fbee8ef43efe5fcd72baa241045209195d43dcc80 + languageName: node + linkType: hard + +"uri-js@npm:^4.2.2": + version: 4.4.1 + resolution: "uri-js@npm:4.4.1" + dependencies: + punycode: "npm:^2.1.0" + checksum: 10c0/4ef57b45aa820d7ac6496e9208559986c665e49447cb072744c13b66925a362d96dd5a46c4530a6b8e203e5db5fe849369444440cb22ecfc26c679359e5dfa3c + languageName: node + linkType: hard + +"utils-merge@npm:1.0.1": + version: 1.0.1 + resolution: "utils-merge@npm:1.0.1" + checksum: 10c0/02ba649de1b7ca8854bfe20a82f1dfbdda3fb57a22ab4a8972a63a34553cf7aa51bc9081cf7e001b035b88186d23689d69e71b510e610a09a4c66f68aa95b672 + languageName: node + linkType: hard + +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 10c0/bcbb807a917d374a49f475fae2e87fdca7da5e5530820ef53f65ba1d12131bd81a92ecf259cc7ce317cbe0f289e7d79fdfebcef9bfa3087c8c8a2fa304c9be54 + languageName: node + linkType: hard + +"v8-compile-cache@npm:^2.0.3": + version: 2.4.0 + resolution: "v8-compile-cache@npm:2.4.0" + checksum: 10c0/387851192545e7f4d691ba674de90890bba76c0f08ee4909ab862377f556221e75b3a361466490e201203401d64d7795f889882bdabc98b6f3c0bf1038a535be + languageName: node + linkType: hard + +"value-equal@npm:^1.0.1": + version: 1.0.1 + resolution: "value-equal@npm:1.0.1" + checksum: 10c0/79068098355483ef29f4d3753999ad880875b87625d7e9055cad9346ea4b7662aad3a66f87976801b0dd7a6f828ba973d28b1669ebcd37eaf88cc5f687c1a691 + languageName: node + linkType: hard + +"vite-tsconfig-paths@npm:^3.3.13": + version: 3.6.0 + resolution: "vite-tsconfig-paths@npm:3.6.0" + dependencies: + debug: "npm:^4.1.1" + globrex: "npm:^0.1.2" + recrawl-sync: "npm:^2.0.3" + tsconfig-paths: "npm:^4.0.0" + peerDependencies: + vite: ">2.0.0-0" + checksum: 10c0/96dffa52020f09331df6acd66cd67c95eafcd2f24dfdac4e518b6be7e5dba0408d23a543faa7bece3e1c740803c583802db9bcf74a2fde4b563c449e8f9ad67f + languageName: node + linkType: hard + +"vite@npm:2.4.1": + version: 2.4.1 + resolution: "vite@npm:2.4.1" + dependencies: + esbuild: "npm:^0.12.8" + fsevents: "npm:~2.3.2" + postcss: "npm:^8.3.5" + resolve: "npm:^1.20.0" + rollup: "npm:^2.38.5" + dependenciesMeta: + fsevents: + optional: true + bin: + vite: bin/vite.js + checksum: 10c0/954a38cf2d3fa7a1fdc66f239aa5a09e285f087c11f82469e881291c2eca847069cf5aa00cacbcab57f19cae9a84d74970d588c6d6826f9a33b551a587d63b1f + languageName: node + linkType: hard + +"vite@npm:^2.4.1": + version: 2.9.18 + resolution: "vite@npm:2.9.18" + dependencies: + esbuild: "npm:^0.14.27" + fsevents: "npm:~2.3.2" + postcss: "npm:^8.4.13" + resolve: "npm:^1.22.0" + rollup: "npm:>=2.59.0 <2.78.0" + peerDependencies: + less: "*" + sass: "*" + stylus: "*" + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + less: + optional: true + sass: + optional: true + stylus: + optional: true + bin: + vite: bin/vite.js + checksum: 10c0/2325b272e473981d7c589f4b28485a60d641bad2a42bae387002ea92c6f8d9664f76b2d35aaf52c81feac5c642399db62598668f40db4198fce138a5df9a3e06 + languageName: node + linkType: hard + +"which-boxed-primitive@npm:^1.0.2": + version: 1.0.2 + resolution: "which-boxed-primitive@npm:1.0.2" + dependencies: + is-bigint: "npm:^1.0.1" + is-boolean-object: "npm:^1.1.0" + is-number-object: "npm:^1.0.4" + is-string: "npm:^1.0.5" + is-symbol: "npm:^1.0.3" + checksum: 10c0/0a62a03c00c91dd4fb1035b2f0733c341d805753b027eebd3a304b9cb70e8ce33e25317add2fe9b5fea6f53a175c0633ae701ff812e604410ddd049777cd435e + languageName: node + linkType: hard + +"which-builtin-type@npm:^1.1.3": + version: 1.1.4 + resolution: "which-builtin-type@npm:1.1.4" + dependencies: + function.prototype.name: "npm:^1.1.6" + has-tostringtag: "npm:^1.0.2" + is-async-function: "npm:^2.0.0" + is-date-object: "npm:^1.0.5" + is-finalizationregistry: "npm:^1.0.2" + is-generator-function: "npm:^1.0.10" + is-regex: "npm:^1.1.4" + is-weakref: "npm:^1.0.2" + isarray: "npm:^2.0.5" + which-boxed-primitive: "npm:^1.0.2" + which-collection: "npm:^1.0.2" + which-typed-array: "npm:^1.1.15" + checksum: 10c0/a4a76d20d869a81b1dbb4adea31edc7e6c1a4466d3ab7c2cd757c9219d48d3723b04076c85583257b0f0f8e3ebe5af337248b8ceed57b9051cb97bce5bd881d1 + languageName: node + linkType: hard + +"which-collection@npm:^1.0.2": + version: 1.0.2 + resolution: "which-collection@npm:1.0.2" + dependencies: + is-map: "npm:^2.0.3" + is-set: "npm:^2.0.3" + is-weakmap: "npm:^2.0.2" + is-weakset: "npm:^2.0.3" + checksum: 10c0/3345fde20964525a04cdf7c4a96821f85f0cc198f1b2ecb4576e08096746d129eb133571998fe121c77782ac8f21cbd67745a3d35ce100d26d4e684c142ea1f2 + languageName: node + linkType: hard + +"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15": + version: 1.1.15 + resolution: "which-typed-array@npm:1.1.15" + dependencies: + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.7" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.2" + checksum: 10c0/4465d5348c044032032251be54d8988270e69c6b7154f8fcb2a47ff706fe36f7624b3a24246b8d9089435a8f4ec48c1c1025c5d6b499456b9e5eff4f48212983 + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f + languageName: node + linkType: hard + +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: 10c0/449fa5c44ed120ccecfe18c433296a4978a7583bf2391c50abce13f76878d2476defde04d0f79db8165bdf432853c1f8389d0485ca6e8ebce3bbcded513d5e6a + languageName: node + linkType: hard + +"word-wrap@npm:^1.2.5": + version: 1.2.5 + resolution: "word-wrap@npm:1.2.5" + checksum: 10c0/e0e4a1ca27599c92a6ca4c32260e8a92e8a44f4ef6ef93f803f8ed823f486e0889fc0b93be4db59c8d51b3064951d25e43d434e95dc8c960cc3a63d65d00ba20 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 + languageName: node + linkType: hard + +"wrap-ansi@npm:^9.0.0": + version: 9.0.0 + resolution: "wrap-ansi@npm:9.0.0" + dependencies: + ansi-styles: "npm:^6.2.1" + string-width: "npm:^7.0.0" + strip-ansi: "npm:^7.1.0" + checksum: 10c0/a139b818da9573677548dd463bd626a5a5286271211eb6e4e82f34a4f643191d74e6d4a9bb0a3c26ec90e6f904f679e0569674ac099ea12378a8b98e20706066 + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 + languageName: node + linkType: hard + +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249 + languageName: node + linkType: hard + +"yallist@npm:^3.0.2": + version: 3.1.1 + resolution: "yallist@npm:3.1.1" + checksum: 10c0/c66a5c46bc89af1625476f7f0f2ec3653c1a1791d2f9407cfb4c2ba812a1e1c9941416d71ba9719876530e3340a99925f697142989371b72d93b9ee628afd8c1 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a + languageName: node + linkType: hard + +"yaml@npm:^1.10.0": + version: 1.10.2 + resolution: "yaml@npm:1.10.2" + checksum: 10c0/5c28b9eb7adc46544f28d9a8d20c5b3cb1215a886609a2fd41f51628d8aaa5878ccd628b755dbcd29f6bb4921bd04ffbc6dcc370689bb96e594e2f9813d2605f + languageName: node + linkType: hard + +"yaml@npm:~2.5.0": + version: 2.5.1 + resolution: "yaml@npm:2.5.1" + bin: + yaml: bin.mjs + checksum: 10c0/40fba5682898dbeeb3319e358a968fe886509fab6f58725732a15f8dda3abac509f91e76817c708c9959a15f786f38ff863c1b88062d7c1162c5334a7d09cb4a + languageName: node + linkType: hard + +"yargs-parser@npm:^21.1.1": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 + languageName: node + linkType: hard + +"yargs@npm:^17.0.1": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: "npm:^8.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.3" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^21.1.1" + checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05 + languageName: node + linkType: hard diff --git a/experiences/asteroids/thumb.jpg b/experiences/asteroids/thumb.jpg new file mode 100644 index 0000000..3c61997 Binary files /dev/null and b/experiences/asteroids/thumb.jpg differ diff --git a/experiences/asteroids/web/all-info.js b/experiences/asteroids/web/all-info.js new file mode 100644 index 0000000..8177c27 --- /dev/null +++ b/experiences/asteroids/web/all-info.js @@ -0,0 +1,7263 @@ +const allInfo = { + sun: { + title: "Sun", + description: { + blurb: [ + "The Sun—the heart of our solar system—is a yellow dwarf star, a hot ball of glowing gases.", + ], + more: [ + "Its gravity holds the solar system together, keeping everything from the biggest planets to the smallest particles of debris in its orbit. Electric currents in the Sun generate a magnetic field that is carried out through the solar system by the solar wind—a stream of electrically charged gas blowing outward from the Sun in all directions.", + "The connection and interactions between the Sun and Earth drive the seasons, ocean currents, weather, climate, radiation belts and aurorae. Though it is special to us, there are billions of stars like our Sun scattered across the Milky Way galaxy. The Sun, and everything that orbits it, is located in the Milky Way galaxy. More specifically, our Sun is in a spiral arm called the Orion Spur that extends outward from the Sagittarius arm. From there, the Sun orbits the center of the Milky Way Galaxy, bringing the planets, asteroids, comets and other objects along with it. Our solar system is moving with an average velocity of 450,000 miles per hour (720,000 kilometers per hour). But even at this speed, it takes us about 230 million years to make one complete orbit around the Milky Way.", + "The Sun rotates as it orbits the center of the Milky Way. Its spin has an axial tilt of 7.25 degrees with respect to the plane of the planets’ orbits. Since the Sun is not a solid body, different parts of the Sun rotate at different rates. At the equator, the Sun spins around once about every 25 days, but at its poles the Sun rotates once on its axis every 36 Earth days.", + ], + }, + related: [ + "sc_ulysses", + "sc_parker_solar_probe", + "sc_soho", + "sc_stereo_ahead", + "sc_stereo_behind", + "sc_sdo", + "sc_acrimsat", + ], + }, + mercury: { + title: "Mercury", + description: { + blurb: [ + "The smallest planet in our solar system and nearest to the Sun, Mercury is only slightly larger than Earth's Moon.", + ], + more: [ + "Mercury's surface temperatures are both extremely hot and cold. Because the planet is so close to the Sun, day temperatures can reach highs of 800°F (430°C). Without an atmosphere to retain that heat at night, temperatures can dip as low as -290°F (-180°C). From the surface of Mercury, the Sun would appear more than three times as large as it does when viewed from Earth, and the sunlight would be as much as seven times brighter. Despite its proximity to the Sun, Mercury is not the hottest planet in our solar system – that title belongs to nearby Venus, thanks to its dense atmosphere. But Mercury is the fastest planet, zipping around the Sun every 88 Earth days. Mercury's surface resembles that of Earth's moon, scarred by many impact craters resulting from collisions with meteoroids and comets. The first spacecraft to visit Mercury was Mariner 10, which imaged about 45 percent of the surface. NASA's MErcury Surface, Space ENvironment, GEochemistry, and Ranging (MESSENGER) mission flew by Mercury three times in 2008-2009 and orbited the planet from 2011 to 2015, mapping the entire surface.", + ], + }, + related: ["sc_messenger"], + data: { + distance: 57909227, + radius: 2439.7, + volume: 60827208742, + density: 5.427, + mass: 3.30104e23, + area: 74797000, + gravity: 3.7, + eccentricity: 0.20563593, + inclination: 0, + velocity: 15300, + circumference: 15329.1, + }, + }, + venus: { + title: "Venus", + description: { + blurb: [ + "Similar in size and structure to Earth, Venus has been called Earth's twin. These are not identical twins, however – there are radical differences between the two worlds.", + ], + more: [ + "Venus and Earth are similar in size, mass, density, composition, and gravity. There, however, the similarities end. Venus has a thick, toxic atmosphere filled with carbon dioxide and it’s perpetually shrouded in thick, yellowish clouds of mostly sulfuric acid that trap heat, causing a runaway greenhouse effect. It’s the hottest planet in our solar system, even though Mercury is closer to the Sun. Venus has crushing air pressure at its surface – more than 90 times that of Earth – similar to the pressure you'd encounter a mile below the ocean on Earth. Venus was the first planet to be explored by a spacecraft – NASA’s Mariner 2 successfully flew by and scanned the cloud-covered world on Dec. 14, 1962. Since then, numerous spacecraft from the U.S. and other space agencies have explored Venus, including NASA’s Magellan, which mapped the planet's surface with radar. The former Soviet Union is the only nation to land on the surface of Venus to date, though the spacecraft did not survive long in the harsh environment.", + ], + }, + related: ["sc_magellan", "sc_galileo", "sc_cassini", "sc_messenger"], + }, + earth: { + title: "Earth", + description: { + blurb: [ + "Earth—our home planet—is the only place we know of so far that’s inhabited by living things. It's also the only planet in our solar system with liquid water on the surface.", + ], + more: [ + "Earth is only the fifth largest planet in the solar system, just slightly larger than nearby Venus. Earth is the biggest of the four planets closest to the Sun, all of which are made of rock and metal. NASA has the most missions of all operating on our home planet. NASA’s Earth Observing System (EOS) is a coordinated series of polar-orbiting and low inclination satellites for long-term global observations of the land surface, biosphere, solid Earth, atmosphere, and oceans.", + ], + }, + related: ["sc_iss", "sc_eo_1", "sc_acrimsat", "moon"], + }, + mars: { + title: "Mars", + description: { + blurb: [ + "The fourth planet from the Sun, Mars is a dusty, cold, desert world with a very thin atmosphere.", + ], + more: [ + "Mars was named by the ancient Romans for their god of war because its reddish color was reminiscent of blood. The Red Planet is actually many colors. At the surface we see colors such as brown, gold and tan. The reason Mars looks reddish is due to oxidization—or rusting—of iron in the rocks, regolith (Martian “soil”), and dust of Mars. This dust gets kicked up into the atmosphere and from a distance makes the planet appear mostly red. Mars is home to the largest volcano in the solar system, Olympus Mons. It's three times taller than Earth's Mt. Everest with a base the size of the state of New Mexico.", + "Mars appears to have had a watery past, with ancient river valley networks, deltas and lakebeds, as well as rocks and minerals on the surface that could only have formed in liquid water. Some features suggest that Mars experienced huge floods about 3.5 billion years ago. There is water on Mars today, but the Martian atmosphere is too thin for liquid water to exist for long on the surface. Today, water on Mars is found in the form of water-ice just under the surface in the polar regions as well as in briny (salty) water, which seasonally flows down some hillsides and crater walls.", + "No planet beyond Earth has been studied as intensely as Mars. Today, a science fleet of robotic spacecraft study Mars from all angles.", + ], + }, + data: { + distance: 227943824, + radius: 3389.5, + volume: 163115609799, + density: 3.934, + mass: 6.41693e23, + area: 144371391, + gravity: 3.71, + eccentricity: 0.0933941, + inclination: 25.2, + velocity: 18108, + circumference: 21296.9, + }, + related: ["sc_mars_global_surveyor"], + }, + jupiter: { + title: "Jupiter", + description: { + blurb: [ + "Jupiter is the fifth planet from our Sun and is, by far, the largest planet in the solar system – more than twice as massive as all the other planets combined.", + ], + more: [ + "Jupiter's stripes and swirls are actually cold, windy clouds of ammonia and water, floating in an atmosphere of hydrogen and helium. Jupiter’s iconic Great Red Spot is a giant storm bigger than Earth that has raged for hundreds of years. Jupiter is surrounded by dozens of moons. Jupiter also has several rings, but unlike the famous rings of Saturn, Jupiter’s rings are very faint and made of dust, not ice. Jupiter has the shortest day in the solar system. One day on Jupiter takes only about 10 hours (the time it takes for Jupiter to rotate or spin around once), and Jupiter makes a complete orbit around the Sun (a year in Jovian time) in about 12 Earth years (4,333 Earth days). Its equator is tilted with respect to its orbital path around the Sun by just 3 degrees. This means Jupiter spins nearly upright and does not have seasons as extreme as other planets do. Jupiter took shape when the rest of the solar system formed about 4.5 billion years ago, when gravity pulled swirling gas and dust in to become this gas giant. Jupiter took most of the mass left over after the formation of the Sun, ending up with more than twice the combined material of the other bodies in the solar system. In fact, Jupiter has the same ingredients as a star, but it did not grow massive enough to ignite.", + ], + }, + related: [ + "sc_juno", + "sc_cassini", + "sc_voyager_1", + "sc_voyager_2", + "sc_galileo", + "sc_pioneer_10", + "sc_ulysses", + "sc_new_horizons", + ], + }, + saturn: { + title: "Saturn", + description: { + blurb: [ + "Saturn is the sixth planet from the Sun and the second largest planet in our solar system. Adorned with thousands of beautiful ringlets, Saturn is unique among the planets. It is not the only planet to have rings—made of chunks of ice and rock—but none are as spectacular or as complicated as Saturn's. Like fellow gas giant Jupiter, Saturn is a massive ball made mostly of hydrogen and helium.", + ], + more: [ + "Surrounded by more than 140 known moons, Saturn is home to some of the most fascinating landscapes in our solar system. From the jets of water that spray from Enceladus to the methane lakes on smoggy Titan, the Saturn system is a rich source of scientific discovery and still holds many mysteries.The farthest planet from Earth discovered by the unaided human eye, Saturn has been known since ancient times. The planet is named for the Roman god of agriculture and wealth, who was also the father of Jupiter. Saturn's rings are thought to be pieces of comets, asteroids or shattered moons that broke up before they reached the planet, torn apart by Saturn's powerful gravity. They are made of billions of small chunksof ice and rock coated with another material such as dust. The ring particles mostly range from tiny, dust-sized icy grains to chunks as big as a house. A few particles are as large as mountains. The rings would look mostly white if you looked at them from the cloud tops of Saturn, and interestingly, each ring orbits at a different speed around the planet.", + ], + }, + related: ["sc_cassini", "sc_voyager_1", "sc_voyager_2", "sc_pioneer_11"], + }, + neptune: { + title: "Neptune", + description: { + blurb: [ + "Dark, cold and whipped by supersonic winds, ice giant Neptune is the eighth and most distant planet in our solar system.", + ], + more: [ + "More than 30 times as far from the Sun as Earth, Neptune is the only planet in our solar system not visible to the naked eye. In 2011 Neptune completed its first 165-year orbit since its discovery in 1846.", + 'Neptune is so far from the Sun that high noon on the big blue planet would seem like dim twilight to us. The warm light we see here on our home planet is roughly 900 times as bright as sunlight on Neptune. Neptune is one of two ice giants in the outer solar system (the other is Uranus). Most (80 percent or more) of the planet\'s mass is made up of a hot dense fluid of "icy" materials — water, methane and ammonia — above a small, rocky core. Of the giant planets, Neptune is the densest.', + "Scientists think there might be an ocean of super hot water under Neptune's cold clouds. It does not boil away because incredibly high pressure keeps it locked inside. Neptune's atmosphere is made up mostly of hydrogen and helium with just a little bit of methane. Neptune's neighbor Uranus is a blue-green color due to such atmospheric methane, but Neptune is a more vivid, brighter blue, so there must be an unknown component that causes the more intense color.", + ], + }, + related: ["sc_voyager_2"], + }, + uranus: { + title: "Uranus", + description: { + blurb: [ + "The seventh planet from the Sun with the third largest diameter in our solar system, Uranus is very cold and windy.", + ], + more: [ + "The ice giant is surrounded by 13 faint rings and 27 small moons as it rotates at a nearly 90-degree angle from the plane of its orbit. This unique tilt makes Uranus appear to spin on its side, orbiting the Sun like a rolling ball. Uranus is the only planet whose equator is nearly at a right angle to its orbit, with a tilt of 97.77 degrees—possibly the result of a collision with an Earth-sized object long ago. This unique tilt causes the most extreme seasons in the solar system. For nearly a quarter of each Uranian year, the Sun shines directly over each pole, plunging the other half of the planet into a 21-year-long, dark winter.", + "Uranus is also one of just two planets that rotate in the opposite direction than most of the planets (Venus is the other one), from east to west.", + ], + }, + related: ["sc_voyager_2"], + }, + "134340_pluto": { + title: "Pluto", + description: { + blurb: [ + "Pluto – which is smaller than Earth’s Moon – has a heart-shaped glacier that’s the size of Texas and Oklahoma. This fascinating dwarf planet has blue skies, spinning moons, mountains as high as the Rockies, and it snows – but the snow is red.", + ], + more: [ + "Pluto is a complex and mysterious world with mountains, valleys, plains, craters, and maybe glaciers. Discovered in 1930, Pluto was long considered our solar system's ninth planet. But after the discovery of similar intriguing worlds deeper in the distant Kuiper Belt, icy Pluto was reclassified as a dwarf planet.", + ' Pluto is orbited by five known moons, the largest of which is Charon. Charon is about half the size of Pluto itself, making it the largest satellite relative to the planet it orbits in our solar system. Pluto and Charon are often referred to as a "double planet". On July 14, 2015, NASA’s New Horizons spacecraft made its historic flight through the Pluto system – providing the first close-up images of Pluto and its moons and collecting other data that has transformed our understanding of these mysterious worlds on the solar system’s outer frontier.', + "In the years since that groundbreaking flyby, nearly every conjecture about Pluto possibly being an inert ball of ice has been thrown out the window or flipped on its head.", + ], + }, + related: ["sc_new_horizons"], + }, + earth_system: { + title: "Earth System", + description: { + blurb: [ + "Earth is orbited by one moon known simply as 'The Moon' or less commonly 'Luna'. The moon completes its orbit around the earth every 27.5 days.", + ], + }, + data: { + "Number of moons": 1, + }, + related: ["earth", "moon"], + }, + mars_system: { + title: "Mars System", + description: { + blurb: [ + "Mars is orbited by two small moons Phobos and Deimos named for the Greek gods of fear and terror respectively.", + ], + }, + data: { + "Number of moons": 2, + }, + related: ["mars", "phobos", "deimos"], + }, + jupiter_system: { + title: "Jupiter System", + description: { + blurb: [ + "Jupiter is orbited by many moons. 95 are currently known, but more likely exist.", + ], + more: [ + "Many of these moons are small, less than 10km across, but several are among the largest and most interesting in the Solar System.", + "Jupiter's Gallilean moons (Io, Europa, Ganymede) are also notable for their orbits forming a resonance pattern. For every single orbit of Ganymede, Europa will orbit twice and Io will orbit four times.", + ], + }, + data: { + "Number of moons": "95+", + }, + related: ["jupiter", "callisto", "europa", "ganymede", "io"], + }, + saturn_system: { + title: "Saturn System", + description: { + blurb: [ + "Saturn, in addition to its thousands of rings, has the most moons in the solar system by far; over 140 have been found so far.", + ], + more: [ + "Saturn's largest moon Titan has the densest atmosphere of any moon. Consisting of nitrogen and methane Titan's atmosphere is even thicker than Earth's." + ] + }, + data: { + "Number of moons": "140+", + }, + related: [ + "saturn", + "dione", + "enceladus", + "iapetus", + "mimas", + "rhea", + "tethys", + "titan", + ], + }, + uranus_system: { + title: "Uranus System", + description: { + blurb: [ + "While most moons in the Solar System are named for characters from ancient mythology, Uranus's moons are named after characters written by Shakespeare and Alexander Pope.", + ], + }, + data: { + "Number of moons": 24, + }, + related: ["uranus", "miranda", "oberon", "titania", "umbriel"], + }, + neptune_system: { + title: "Neptune System", + description: { + blurb: [ + "Neptune has several moons, but the largest by far is Triton. Triton is roughly half the diameter of earths moon, but over 500 times more massive than Neptunes next largest moon, Proteus", + ], + }, + data: { + "Number of moons": 16, + }, + related: ["neptune", "triton"], + }, + "134340_pluto_barycenter": { + title: "Pluto system", + description: { + blurb: [ + "The Pluto system's barycenter, or the center of mass of two or more bodies that orbit one another, is not inside Pluto. It is between Pluto and Charon.", + ], + more: [""], + }, + related: [ + "pluto", + "charon", + "hydra", + "kerberos", + "nix", + "styx", + ], + }, + "134340_pluto_barycenter": { + title: "Pluto system", + description: { + blurb: [ + "The Pluto system's barycenter, or the center of mass of two or more bodies that orbit one another, is not inside Pluto. It is between Pluto and Charon.", + ], + more: [""], + }, + related: [ + "pluto", + "charon", + "hydra", + "kerberos", + "nix", + "styx", + ], + }, + "617_patroclus_barycenter": { + title: "Patroclus and Menoetius", + description: { + }, + related: [ + "617_patroclus", + "menoetius" + ], + }, + "65803_didymos_system": { + title: "Didymos and Dimorphos", + description: { + }, + related: [ + "617_patroclus", + "menoetius", + "sc_dart" + ], + }, + "21_lutetia": { + title: "Lutetia", + description: { + blurb: [ + "Lutetia is a large asteroid that was visited by Europe's Rosetta space probe in 2010.", + ], + more: [""], + }, + related: ["sc_rosetta"], + stats: { + discovery: + "Discovered in 1852, the asteroid was visited by the European space probe Rosetta in July of 2010.", + rotation: 8.1655, + }, + }, + "253_mathilde": { + title: "Mathilde", + description: { + blurb: [ + "The asteroid Mathilde was visited by the NEAR Shoemaker mission in 1997.", + ], + more: [""], + }, + related: ["sc_near_shoemaker"], + }, + "11351_leucus": { + title: "Leucus", + description: { + blurb: [ + 'Leucus is an asteroid located in the orbit of Jupiter, always orbiting "ahead" of Jupiter by sixty degrees. Referred to as a Trojan asteroid, it will be visited by the Lucy mission in April of 2028.', + ], + more: [ + "The Lucy mission will also fly by Leucus. This 40 km (25 mile) D-type asteroid rotates extremely slowly. Its day is 446 hours! This slow rotation period means that it will likely get hotter during the day and colder at night than the other asteroids, so by comparing it with other D-type asteroids we should learn more about the materials that make up these asteroids. Also, as it rotates its brightness as observed from Earth varies a lot, suggesting that it is quite elongated. Lucy will know for sure when it flies by on April 18, 2028.", + ], + }, + related: [ + "sc_lucy", + "55246_donaldjohanson", + "3548_eurybates", + "15094_polymele", + "21900_orus", + "617_patroclus", + ], + stats: { + discovery: + "Discovered in 1997, Leucus is a Trojan Asteroid that will be visited by the Lucy mission in April of 2028.", + rotation: 445.73, + }, + }, + "15094_polymele": { + title: "Polymele", + description: { + blurb: [ + 'Polymele is an asteroid located in the orbit of Jupiter, always orbiting "ahead" of Jupiter by sixty degrees. Referred to as a Trojan asteroid, it will be visited by the Lucy mission in September of 2027.', + ], + more: [ + "Polymele is the smallest of Lucy's Trojan targets at 21 km (13 miles) in diameter. It is a P-type asteroid, the same type as the much larger Patroclus and Menoetius binary. This will be the first time a spacecraft has ever flown by this dark, reddish class of asteroid that is believed to be rich in organics. Scientists think that Polymele is a collisional fragment of a larger P-type asteroid, and thus it will be very interesting to compare to its larger brethren. Lucy will fly by on September 15, 2027.", + ], + }, + related: [ + "sc_lucy", + "jupiter", + "52246_donaldjohanson", + "3548_eurybates", + "11351_leucus", + "21900_orus", + "617_patroclus", + ], + stats: { + discovery: + "Discovered in 1999, Polymele is a Trojan Asteroid that will be visited by the Lucy mission in September of 2027.", + rotation: 5.86, + }, + }, + "21900_orus": { + title: "Orus", + description: { + blurb: [ + 'Orus is an asteroid located in the orbit of Jupiter, always orbiting "ahead" of Jupiter by sixty degrees. Referred to as a Trojan asteroid, It will be visited by the Lucy mission in November of 2028.', + ], + more: [ + "The Lucy mission will fly by Orus in November of 2028. Lucy will be able to compare this larger 51 km (31.7 mile) diameter Trojan to both the smaller Leucus, which is of the same type of very dark, very red objects thought to be rich in organics and carbon, and to the similarly-sized, but different spectrally typed, Eurybates.", + ], + }, + related: [ + "sc_lucy", + "55246_donaldjohanson", + "3548_eurybates", + "15094_polymele", + "11351_leucus", + "617_patroclus", + ], + stats: { + discovery: + "Discovered in 1999, Orus is a Trojan Asteroid that will be visited by the Lucy mission in November of 2028.", + rotation: 13.45, + }, + }, + "3548_eurybates": { + title: "Eurybates", + description: { + blurb: [ + "Eurybates is a carbonaceous asteroid located in the orbit of Jupiter, and is referred to as a Trojan asteroid. Eurybates has a small satellite named Queta, and will be visited by the Lucy mission in August of 2027.", + ], + more: [ + "Eurybates is the first Trojan Asteroid that Lucy will visit, in August of 2027. In January of 2019 the Lucy team learned about the satellite Queta, which is likely around 1 km (0.5 miles) in size.", + ], + }, + related: [ + "sc_lucy", + "55246_donaldjohanson", + "15094_polymele", + "11351_leucus", + "21900_orus", + "617_patroclus", + ], + stats: { + discovery: + "Discovered in 1973, Eurybates is the first Trojan Asteroid that the Lucy mission will visit in August of 2027. It has a small satellite named Queta.", + rotation: 8.7, + }, + }, + "5535_annefrank": { + title: "Annefrank", + description: { + blurb: [ + "Annefrank is a main belt asteroid that was visited by the Stardust mission in November of 2002.", + ], + more: [ + "On Nov. 2, 2002, at 04:50 UT, Stardust flew by asteroid 5535 Annefrank at a range of about 1,900 miles (3,078 kilometers). This asteroid was used as a practice run by the Stardust mission for its eventual flyby of the comet Wild 2(81P/Wild). During the encounter, the spacecraft’s dust collectors collected samples while its camera returned 72 images.", + ], + }, + related: ["sc_stardust", "81p_wild_2"], + stats: { + discovery: + "Discovered in 1942, the main belt asteroid 5535 Annefrank was used as a practice flyby target by the Stardust mission on November 2nd, 2002.", + rotation: 15.12, + }, + }, + "52246_donaldjohanson": { + title: "Donaldjohanson", + description: { + blurb: [ + "Donaldjohanson is a carbonaceous asteroid located in the inner asteroid belt. It will be visited by the Lucy mission in April of 2025.", + ], + more: [ + "This object will mostly provide a test rehearsal for all of Lucy's instruments before the spacecraft heads further out towards the Trojan asteroids that share an orbit with Jupiter. The asteroid is named after the paleoanthropologist Donald Johanson, who discovered the famous Lucy fossil in Ethiopia in 1974. Just as the Lucy skeleton taught us how evolution occurred with humans, the Lucy mission will be investigating a different kind of fossil: the Trojan asteroids, which are almost as old as the solar system itself.", + ], + }, + related: [ + "sc_lucy", + "617_patroclus", + "3548_eurybates", + "15094_polymele", + "11351_leucus", + "21900_orus", + ], + stats: { + discovery: + 'Discovered in 1981, and named after the paleoanthropologist who discovered the "Lucy" fossil, this will be the second small body that the Lucy mission will encounter in 2025.', + rotation: 252, + }, + }, + "617_patroclus": { + title: "Patroclus", + description: { + blurb: [ + 'Patroclus is a large binary asteroid located in the orbit of Jupiter, always "trailing" the planet by 60 degrees. It is in a binary system with its slightly smaller twin, Menoetius. Referred to as a Trojan asteroid, it will be visited by the Lucy mission in 2033.', + ], + more: [ + "This asteroid will be the final encounter of Lucy's primary mission, in March of 2033. After a long journey from the Greek L4 swarm to the Trojan L5 swarm, Lucy will fly by the binary pair of asteroids (617) Patroclus and Menoetius. They are large P-type Trojans, with average diameters of 113 km and 104 km (about 70 and 65 miles), respectively. Scientists hypothesize that they may be primordial asteroids left over from the very early Solar System.", + ], + }, + related: [ + "sc_lucy", + "55246_donaldjohanson", + "3548_eurybates", + "15094_polymele", + "11351_leucus", + "21900_orus", + "menoetius", + ], + stats: { + discovery: + "Discovered in 1906, Patroclus is a Trojan Asteroid that will be visited by the Lucy mission in 2033. In 2001, Patroclus was found to be part of a binary asteroid system with its smaller twin, named Menoetius.", + rotation: 102.8, + }, + }, + "951_gaspra": { + title: "Gaspra", + description: { + blurb: [ + "951 Gaspra was the first asteroid ever to be closely approached when it was visited by the Galileo spacecraft, which flew by on its way to Jupiter on 29 October 1991.", + ], + more: [ + "Gaspra orbits the Sun at an average distance of about 2.21 astronomical units. Gaspra completes one orbit around the Sun in 3.29 years. Galileo flew by Gaspra on 29 October 1991, passing within 1,600 km (990 mi) at a relative speed of about 8 km/s (18,000 mph). 57 images were returned to Earth, the closest taken from a distance of 5,300 km (3,300 mi). The best images have a resolution of about 54 meters per pixel (177.16 ft). The area around the southern pole was not seen during the flyby, but the remaining 80% of the asteroid was imaged.", + ], + }, + related: ["sc_galileo"], + stats: { + discovery: + "Discovered in 1916, Gaspra is the first asteroid to be closely approached by a spacecraft, which was Galileo in 1991.", + rotation: 7.042, + }, + }, + "2867_steins": { + title: "Steins", + description: { + blurb: [ + "Steins is an irregular-shaped asteroid that was visited by Europe's Rosetta space probe in 2008.", + ], + more: [""], + }, + related: [], + }, + ariel: { + title: "Ariel", + description: { + blurb: ["Ariel is a moon of Uranus."], + more: [ + "All of Uranus' larger moons, including Ariel, are thought to consist mostly of roughly equal amounts of water ice and silicate rock. Carbon dioxide has also been detected on Ariel.", + "Ariel's surface appears to be the youngest of all the moons of Uranus. It has few large craters and many small ones, indicating that fairly recent low-impact collisions wiped out the large craters that would have been left by much earlier, bigger strikes. Ariel is also thought to have had the most recent geologic activity of Uranus' larger moons. It is transected by grabens, which are fault-bounded valleys.", + "Ariel has the brightest surface of the five largest Uranian moons, but none of them reflect more than about a third of the sunlight that strikes them. This suggests that their surfaces have been darkened by a carbonaceous material. Ariel's brightness increases dramatically when it is in opposition―that is, when the observer is directly between it and the Sun. This indicates that its surface is porous, casting reflectivity-decreasing shadows when illuminated at other angles.", + ], + }, + related: ["sc_voyager_2"], + }, + "90377_sedna": { + title: "Sedna", + description: { + blurb: [ + "Sedna is a possible dwarf planet well beyond the orbit of Neptune. It has an exceptionally long and elongated orbit, taking approximately 11,400 years to complete.", + ], + more: [""], + }, + related: [], + }, + "99942_apophis": { + title: "Apophis", + description: { + blurb: [ + "Asteroid 99942 Apophis is a near-Earth asteroid more than 1000 feet (over 300 meters) in size that will harmlessly pass close to Earth on April 13, 2029.", + ], + more: [ + "When it was discovered in 2004, the asteroid caused a stir because initial calculations indicated a small possibility it would impact Earth in 2029. After searching through some older astronomical images, scientists ruled out the possibility of a 2029 impact. It’s now predicted the asteroid will safely pass about 19,800 miles (31,900 kilometers) from our planet’s surface. While that’s a safe distance, it’s close enough that the asteroid will come between Earth and our Moon, which is about 238,855 miles (384,400 kilometers) away. It’s also within the distance that some spacecraft orbit Earth.", + ], + }, + related: [], + stats: { + discovery: + "Discovered on June 19, 2004 at the Kitt Peak National Observatory in Arizona.", + rotation: 30.4, + }, + approach: { + fact: "On April 13, 2029, the asteroid Apophis will pass less than 23,239 miles (37,399 kilometers) from our planet’s surface – just outside the distance of geosynchronous satellites, and closer to Earth than any similarly sized PHO (potentially hazardous object) in recorded history. At that time, Apophis will be visible to observers on the ground in the Eastern Hemisphere without the aid of a telescope or binoculars.", + }, + }, + "486958_arrokoth": { + title: "Arrokoth", + description: { + blurb: [ + "The small Kuiper Belt object officially known as Arrokoth is the most distant and most primitive object ever explored by a spacecraft.", + ], + more: [ + "Arrokoth is in a region of space beyond Neptune called the Kuiper Belt that is swarming with small, icy and ancient objects. Because they are so far from the Sun, Kuiper Belt objects have only been slightly heated since forming, and are thought to be well-preserved, frozen samples of what the outer solar system was like after its birth more than 4.5 billion years ago.", + "It was discovered in 2014 by NASA’s New Horizons science team, using the Hubble Space Telescope. New Horizons flew by Arrokoth on Jan. 1, 2019, snapping images that showed a double-lobed object that looked like a partially flattened snowman. It’s also very red — even redder than Pluto. The object's strange shape — unlike any ever seen — was the biggest surprise of the flyby. Arrokoth means means “sky” in the Powhatan/Algonquian language.", + ], + }, + related: ["sc_new_horizons"], + }, + "101955_bennu": { + title: "Bennu", + description: { + blurb: [ + "An ancient relic of our solar system’s early days, Bennu has seen more than 4.5 billion years of history. Scientists think that within 10 million years of our solar system’s formation, Bennu’s present-day composition was already established.", + ], + more: [ + "Bennu likely broke off from a much larger carbon-rich asteroid about 700million to 2 billion years ago. It likely formed in the Main Asteroid Belt between Mars and Jupiter, and has drifted much closer to Earth since then. Because its materials are so old, Bennu may contain organic molecules similar to those that could have been involved with the start of life on Earth. NASA’s OSIRIS-REx mission, which launched in 2016, performed the most in-depth exploration of Bennu to date and returned a sample of its material to Earth in 2023. This spacecraft’s data will also help scientists better understand the likelihood of Bennu striking Earth someday.", + ], + }, + related: ["sc_osiris_rex"], + stats: { + discovery: + "Discovered in September of 1999, Bennu was the subject of the OSIRIS-REx mission, which touched down on the asteroid and collected a sample of the surface on October 20th, 2020. OSIRIS-REx departed Bennu in 2021, and delivered the capsule with pieces of the asteroid to Earth on September 24, 2023.", + rotation: 4.296, + }, + approach: { + fact: "Bennu is a PHO (potentially hazardous object), and will have multiple close approaches with Earth over time. The next close approach will be in 2023, at a distance of 0.497 AU (astronomical units)", + }, + }, + "152830_dinkinesh": { + title: "Dinkinesh", + description: { + blurb: [ + "Dinkinesh is a main belt asteroid that was visited by the Lucy mission on November 1st, 2023.", + ], + more: [ + "Dinkinesh was discovered in 1999 and is 700 meters (2,300 feet) in diameter. Dinkinesh was Lucy's first and smallest flyby target, and the smallest main-belt asteroid ever visited by a spacecraft. Dinkinesh is the Ethiopian name for the Lucy fossil, for which the Lucy mission is named.", + ], + }, + related: [ + "sc_lucy", + "jupiter", + "52246_donaldjohanson", + "3548_eurybates", + "11351_leucus", + "21900_orus", + "617_patroclus", + ], + stats: { + discovery: + "Discovered in 1999, Dinkinesh will be the Lucy mission's first flyby target in early November of 2023. It will become the smallest main-belt asteroid ever visited.", + }, + }, + "16_psyche": { + title: "Psyche", + description: { + blurb: [ + "Psyche is one of the largest asteroids in the solar system, and is mostly made of metal.", + ], + more: [ + "One of the most intriguing targets in the main asteroid belt, 16 Psyche is a giant metal asteroid, about three times farther away from the sun than is the Earth. Its average diameter is about 140 miles (226 kilometers) — about one-sixteenth the diameter of Earth’s Moon or about the distance between Los Angeles and San Diego. Unlike most other asteroids that are rocky or icy bodies, scientists think the M-type (metallic) asteroid 16 Psyche is comprised mostly of metallic iron and nickel similar to Earth’s core. Scientists wonder whether Psyche could be an exposed core of an early planet, maybe as large as Mars, that lost its rocky outer layers due to a number of violent collisions billions of years ago. This intriguing asteroid is now the primary target of the Psyche mission. The Psyche spacecraft launched on October 13th, 2023, and will arrive at the asteroid in 2029.", + ], + }, + related: ["sc_psyche"], + stats: { + discovery: + "Discovered in 1852, the Psyche asteroid is the subject of the upcoming Psyche mission which will launch no earlier than 2023.", + rotation: 4.196, + }, + }, + "1_ceres": { + title: "Ceres", + description: { + blurb: [ + "Dwarf planet Ceres is the largest object in the asteroid belt between Mars and Jupiter and the only dwarf planet located in the inner solar system.", + ], + more: [ + "Ceres was the first member of the asteroid belt to be discovered when Giuseppe Piazzi spotted it in 1801. And when Dawn arrived in 2015, Ceres became the first dwarf planet to receive a visit from a spacecraft.", + "Called an asteroid for many years, Ceres is so much bigger and so different from its rocky neighbors that scientists classified it as a dwarf planet in 2006. Even though Ceres comprises 25 percent of the asteroid belt's total mass, tiny Pluto is still 14 times more massive.", + "Ceres is named for the Roman goddess of corn and harvests. The word cereal comes from the same name.", + ], + }, + related: ["sc_dawn"], + stats: { + discovery: + "Discovered in January of 1801, Ceres was the first asteroid ever found, though it was initially classified as a planet. It remained an asteroid until 2006, when it was reclassified as a dwarf planet.", + rotation: 9.0741, + }, + }, + "2_pallas": { + title: "Pallas", + description: { + blurb: [ + "2 Pallas is the second asteroid to have been discovered, after 1 Ceres.", + ], + more: [ + "Pallas is the third-largest asteroid in the Solar System by both volume and mass, and is a likely remnant protoplanet. At 513 km in diameter, Pallas is slightly smaller than Vesta. The mass of Pallas is 79%±1% that of Vesta, 22% that of Ceres, and a quarter of one percent that of the Moon. Even so, Pallas by itself makes up 7% of the mass of the entire asteroid belt.", + ], + }, + related: [], + }, + "3_juno": { + title: "Juno", + description: { + blurb: [ + "3 Juno is a large asteroid in the asteroid belt, and the third asteroid ever to be discovered.", + ], + more: [ + "Juno is one of the larger asteroids, perhaps tenth by size and containing approximately 1% the mass of the entire asteroid belt. Even so, Juno has only 3% the mass of Ceres. Juno was originally considered a planet, along with 1 Ceres, 2 Pallas, and 4 Vesta, but its small size and irregular shape preclude it from being designated a dwarf planet.", + ], + }, + related: [], + }, + "216_kleopatra": { + title: "Kleopatra", + description: { + blurb: [ + "216 Kleopatra is a metallic, ham-bone-shaped asteroid approximately 120 kilometers (75 miles) in diameter.", + ], + more: [ + "Kleopatra is a relatively large asteroid, measuring 217 × 94 × 81 km, and has two moons of its own. Calculations from its radar albedo and the orbits of its moons show it to be a rubble pile, a loose amalgam of metal, rock, and 30–50% empty space by volume, likely due to a disruptive impact prior to the impact that created its moons.", + ], + }, + related: [], + }, + "243_ida": { + title: "Ida", + description: { + blurb: [ + "243 Ida is an asteroid in the Koronis family of the asteroid belt, with a mean radius of 15.7 kilometers.", + ], + more: [ + "243 Ida is the second asteroid visited by a spacecraft and the first found to have its own moon. Its close encounter happened on Aug. 29, 1993 as Galileo flew by at a distance of about 1,500 miles (about 2,400 kilometers) en route to Jupiter. (The spacecraft flew by another asteroid, Gaspra, on Oct. 29, 1991.) A little more than five months later, scientists studying the images Galileo sent back to Earth noticed that a tiny moon accompanied the asteroid, which was named Dactyl.", + ], + }, + related: ["sc_galileo"], + stats: { + discovery: + "Discovered in 1884, Ida was visited by the Galileo spacecraft in August of 1993.", + rotation: 4.634, + }, + }, + "1566_icarus": { + title: "Icarus", + description: { + blurb: [ + "1566 Icarus is an extremely eccentric asteroid, approximately 1.4 km (0.87 mi) in diameter.", + ], + more: [ + "It is a near-Earth object and potentially hazardous, but has a closest possible intersection with Earth at 13.7 lunar distances, or 13.7 times the distance from the Earth to the moon. In 1968 it became the first asteroid ever observed by radar.", + ], + }, + related: [], + }, + "1620_geographos": { + title: "Geographos", + description: { + blurb: [ + "1620 Geographos is a highly elongated asteroid with a mean-diameter of approximately 2.5 km (1.6 mi).", + ], + more: [ + "In 1994, NASA's Goldstone radar telescope in the California desert revealed that asteroid Geographos had the largest length-to-width ratio of any solar system object imaged to date. As a potentially hazardous asteroid, Geographos has a minimum orbital intersection distance with Earth of less than 0.05 AU and a diameter of greater than 150 meters. It is currently 0.0301 AU (4,500,000 km), which translates into 11.7 lunar distances.", + ], + }, + related: [], + }, + "1862_apollo": { + title: "Apollo", + description: { + blurb: [ + "1862 Apollo is a stony asteroid, approximately 1.5 kilometers in diameter.", + ], + more: [ + "Apollo is the namesake and the first recognized member of the Apollo asteroids, a subgroup of near-Earth objectss which are Earth-crossers, that is, they cross the orbit of the Earth. 1862 Apollo is a potentially hazardous asteroid because its minimum orbit intersection distance (MOID) is less than 0.05 AU and its diameter is greater than 150 meters. It can cross Earth's orbit as close as about 10 lunar distances.", + ], + }, + related: [], + }, + "1981_midas": { + title: "Midas", + description: { + blurb: [ + "1981 Midas is an asteroid approximately 2 kilometers in diameter that is classified as a near-Earth object.", + ], + more: [ + "Midas has a low minimum orbit intersection distance with Earth of 0.0036 AU (540,000 km; 330,000 mi), which corresponds to 1.5 lunar distance (Earth–Moon distance). However, it does not pose an impact risk for the foreseeable future.", + ], + }, + related: [], + }, + "2063_bacchus": { + title: "Bacchus", + description: { + blurb: [ + "2063 Bacchus is a near-Earth object of the Apollo group, approximately 1 kilometer in diameter.", + ], + more: [ + "Bacchus has an Earth minimum orbital intersection distance of 0.0677 AU (10,130,000 km), which corresponds to 26.4 lunar distances. On March 31st, 1996, it passed 0.0677525 AU (10,135,600 km) from Earth.", + ], + }, + related: [], + }, + "2101_adonis": { + title: "Adonis", + description: { + blurb: [ + "2101 Adonis is classified as potentially hazardous asteroid and near-Earth object of the Apollo group, approximately 1 kilometer in diameter.", + ], + more: [ + "Its Earth minimum orbit intersection distance is 0.0116 AU (1,740,000 km), or 4.5 lunar distances. It also makes close approaches of Venus and Mars.", + ], + }, + related: [], + }, + "2102_tantalus": { + title: "Tantalus", + description: { + blurb: ["2102 Tantalus is an Apollo asteroid about 2–4 km in diameter."], + more: [ + "2102 Tantalus is a potentially hazardous asteroid (PHA) because its minimum orbit intersection distance (MOID) is less than 0.05 AU and its diameter is greater than 150 meters. The Earth-MOID is 0.0439 AU (6,570,000 km; 4,080,000 mi), or about 17.2 lunar distances.", + ], + }, + related: [], + }, + "2135_aristaeus": { + title: "Aristaeus", + description: { + blurb: [ + "2135 Aristaeus is an Apollo asteroid discovered on April 17, 1977 at Palomar Observatory. It is named for Aristaeus, the son of Apollo and the nymph Cyrene.", + ], + more: [ + "2135 Aristaeus is a potentially hazardous asteroid because its minimum orbit intersection distance is less than 0.05 AU and its diameter is greater than 150 meters. The Earth-MOID is 0.0100 AU (1,500,000 km; 930,000 mi), or about 3.9 lunar distances.", + ], + }, + related: [], + }, + "2340_hathor": { + title: "Hathor", + description: { + blurb: [ + "2340 Hathor is an eccentric stony asteroid, classified as near-Earth object and potentially hazardous asteroid. It belongs to the Aten group of asteroids and measures approximately 210 meters in diameter.", + ], + more: [ + "Hathor has an Earth orbit intersection distance of 0.0069 AU (1,030,000 km), which corresponds to 2.7 lunar distances.", + ], + }, + related: [], + }, + "3122_florence": { + title: "Florence", + description: { + blurb: [ + "3122 Florence is an asteroid withi two moons of its own. It is classified as a near-Earth object and potentially hazardous asteroid, measuring approximately 5 kilometers in diameter.", + ], + more: [ + "On September 1st, 2017, Florence passed 0.047237 AU (7,066,600 km; 4,391,000 mi) from Earth, approximately eighteen times the average distance of the Moon. As seen from Earth, it brightened to apparent magnitude 8.5, and was visible in small telescopes for several nights as it moved south to north through the constellations Piscis Austrinus, Capricornus, Aquarius, and Delphinus. This was the asteroid's closest approach since 1890 and the closest until after 2500. The asteroid is named after Florence Nightingale, the founder of modern nursing.", + ], + }, + related: [], + }, + "3200_phaethon": { + title: "Phaethon", + description: { + blurb: [ + "3200 Phaethon is an active Apollo asteroid with an orbit that brings it closer to the Sun than any other named asteroid. It is also the parent body of the Geminids meteor shower in mid-December.", + ], + more: [ + "The Earth minimum orbit intersection distance (E-MOID) is 0.01945 AU (2,910,000 km; 1,808,000 mi, about 7.5 lunar distances), which is defined by the shortest distance between the orbit of Phaethon and the orbit of Earth. With a 30+ year observation arc, the orbit of Phaethon is very well understood with very small uncertainties. Close approaches of Phaethon are well constrained for the next 400 years.", + ], + }, + related: [], + }, + "3362_khufu": { + title: "Khufu", + description: { + blurb: ["3362 Khufu is a near-Earth asteroid discovered in 1984."], + more: [ + "3362 Khufu is a potentially hazardous asteroid because its minimum orbit intersection distance (MOID) is less than 0.05 AU and its diameter is greater than 150 meters. The Earth-MOID is 0.0135 AU (2,020,000 km; 1,250,000 mi, or about 5.23 lunar distances). Its orbit is well-determined for the next several hundred years.", + ], + }, + related: [], + }, + "4015_wilson-harrington": { + title: "Wilson-Harrington", + description: { + blurb: [ + "4015 Wilson–Harrington is an active asteroid known both as comet 107P/Wilson–Harrington and as asteroid 4015 Wilson–Harrington.", + ], + more: [ + "This near-Earth object is considered both an Apollo asteroid with the designation 4015 Wilson–Harrington and a periodic comet known as Comet Wilson–Harrington or 107P/Wilson–Harrington. It was initially discovered in 1949 as a comet and then lost to further observations. Thirty years later it was rediscovered as an asteroid, after which it took over a decade to determine that these observations were of the same object. Therefore, it has both a comet designation and an asteroid designation, and with a name length of 17 characters it is currently the asteroid with the longest name, having one more character than the 16-character limit imposed by the IAU.", + ], + }, + related: [], + }, + "4179_toutatis": { + title: "Toutatis", + description: { + blurb: [ + "4179 Toutatis is an elongated asteroid and slow rotator, classified as near-Earth object and potentially hazardous asteroid of the Apollo and Alinda group, approximately 2.5 kilometers in diameter.", + ], + more: [ + "Toutatis is not a monolith, but most likely a coalescence of shattered fragments. This bifurcated asteroid is shown to be mainly consisting of a head (small lobe) and a body (large lobe).The Chinese lunar probe Chang'e 2 departed from the Sun–Earth L2 point in April of 2012and made a flyby of Toutatis on December 13th, 2012, with the closest approach being 3.2 kilometers and a relative velocity of 10.73 km/s, exactly when Toutatis was near its closest approach to Earth. It took several pictures of the asteroid, revealing it to be a dusty red/orange color.", + ], + }, + related: [], + }, + "4183_cuno": { + title: "Cuno", + description: { + blurb: [ + "4183 Cuno is an eccentric, rare-type asteroid, classified as near-Earth object, roughly 4 kilometers in diameter.", + ], + more: [ + "The asteroid has an Earth minimum orbital intersection distance of 0.0283 AU (4,230,000 km), which translates into 11 lunar distances. Cuno approaches the Earth to within 40 million kilometers six times in the 21st century. On May 20th, 2012, it made its closest Earth approach at a distance of 0.122 AU (18,000,000 km). It will not make a closer approach until 2093 when it will pass Earth at 0.084 AU (13,000,000 km).", + ], + }, + related: [], + }, + "4450_pan": { + title: "Pan", + description: { + blurb: [ + "4450 Pan is a highly eccentric asteroid classified as a near-Earth object of the Apollo group, approximately 1.1 kilometers in diameter.", + ], + more: [ + "As an Apollo asteroid, it is an Earth-crosser and has a minimum orbit intersection distance with Earth of 0.0287 AU (4,290,000 km), which corresponds to 11.2 lunar distances. Due to its extremely eccentric orbit, it is also a Venus- and Mars-crosser and approaches Mercury as well.", + ], + }, + related: [], + }, + "4486_mithra": { + title: "Mithra", + description: { + blurb: [ + "4486 Mithra is an eccentric asteroid , classified as near-Earth object approximately 2 kilometers in diameter.", + ], + more: [ + "As a potentially hazardous asteroid, it has a low minimum orbit intersection distance with Earth of 0.0463 AU (6,930,000 km) or 18 lunar distances. On 14 August 2000, it passed 0.0465 AU (6,960,000 km) from Earth.", + ], + }, + related: [], + }, + "4769_castalia": { + title: "Castalia", + description: { + blurb: [ + "4769 Castalia is a near-Earth object and potentially hazardous asteroid of the Apollo group, approximately 1.4 kilometers (0.87 miles) in diameter and was the first asteroid to be modeled by radar imaging.", + ], + more: [ + "Castalia has a peanut shape, suggesting two approximately 800-meter-diameter pieces held together by their weak mutual gravity. Castalia is a potentially hazardous asteroid because its minimum orbit intersection distance (MOID) is less than 0.05 AU and its diameter is greater than 150 meters. The Earth-MOID is 0.0204 AU (3,050,000 km; 1,900,000 miles, or about 8 lunar distances). Its orbit is well-determined for the next several hundred years.", + ], + }, + related: [], + }, + "5011_ptah": { + title: "Ptah", + description: { + blurb: [ + "5011 Ptah is a near-Earth object and potentially hazardous asteroid of the Apollo group. It has an eccentric oribt measures approximately 1.6 kilometers (1 mile) in diameter.", + ], + more: [ + "The potentially hazardous asteroid has a minimum orbit intersection distance with Earth of 0.0256 AU (3,830,000 km) or 10 lunar distances. It passes within that distance of Earth 15 times between 1900 and 2100, most recently on 21 January 2007, at 29.6 million kilometers.", + ], + }, + related: [], + }, + "6239_minos": { + title: "Minos", + description: { + blurb: [ + "6239 Minos is an asteroid that is classified as a near-Earth object.", + ], + more: [ + "Approximately half kilometer in length and with a rotation period of 3.6 hours, Minos was discovered in 1989 by astronomers Carolyn and Eugene Shoemaker at Palomar Observatory in California.", + ], + }, + related: [], + }, + "6489_golevka": { + title: "Golevka", + description: { + blurb: [ + "6489 Golevka is a small Apollo-class asteroid discovered in 1991.", + ], + more: [ + "Its name has a complicated origin. In 1995, Golevka was studied simultaneously by three radar observatories across the world: Goldstone in California, Yevpatoria RT-70 radio telescope in Ukraine (Yevpatoria is sometimes romanized as Evpatoria) and Kashima in Japan. 'Golevka' comes from the first few letters of each observatory's name.", + ], + }, + related: [], + }, + "9969_braille": { + title: "Braille", + description: { + blurb: [ + "9969 Braille is an eccentric, rare-type and elongated asteroid from the innermost regions of the asteroid belt, classified as Mars-crosser and slow rotator, approximately 1–2 kilometers in diameter.", + ], + more: [ + "It was discovered in 1992 by astronomers at Palomar Observatory and later named after Louis Braille, the inventor of the writing system for the blind. It was photographed in closeup by the spacecraft Deep Space 1 in 1999, but a malfunction resulted in indistinct images.", + ], + }, + related: ["sc_deep_space_1"], + stats: { + discovery: + "Discovered in 1992, Braille was visited by the Deep Space 1 mission on July 29th, 1999. The spacecraft passed within 26 km (16 miles) of the asteroid, which was the closest asteroid flyby ever at that time.", + rotation: 226.4, + }, + }, + "12923_zephyr": { + title: "Zephyr", + description: { + blurb: [ + "12923 Zephyr is a stony asteroid, classified as potentially hazardous asteroid and near-Earth object of the Apollo group, approximately 2 kilometers (1.2 miles) in diameter.", + ], + more: [ + "Zephyr was discovered in 1999 by the Lowell Observatory Near-Earth Object Search at the Anderson Mesa Station in Arizona. The word zephyr derives from the name of the ancient Greek god of the west wind, Zephyros. This near-Earth asteroid has an Earth minimum orbital intersection distance of 3,160,000 km, which corresponds to 8.2 lunar distances. This short distance as well as its sufficiently large size makes it a potentially hazardous asteroid. On September 2010, the asteroid approached Earth at 38,100,000 km; it will make close encounters with Earth again in 2021, 2032 and 2043.", + ], + }, + related: [], + }, + "14827_hypnos": { + title: "Hypnos", + description: { + blurb: [ + "14827 Hypnos is a highly eccentric, sub-kilometer-sized carbonaceous asteroid that is thought to be an extinct comet.", + ], + more: [ + "Discovered in 1986, Hypnos is classified as a near-Earth object that can potentially approach Earth as close as 5.7 lunar distances.", + ], + }, + related: [], + }, + "25143_itokawa": { + title: "Itokawa", + description: { + blurb: [ + "25143 Itokawa is a sub-kilometer near-Earth object, and is the first asteroid from which samples were retrieved and brought to Earth.", + ], + more: [ + "The asteroid 25143 Itokawa was discovered on Sept. 26, 1998, by the Lincoln Laboratory Near-Earth Asteroid Research Team at Socorro, New Mexico. The Japanese spacecraft Hayabusa (Japanese for falcon) touched down twice on the asteroid and collected a small amount of dust despite the failure of the mechanism designed for the purpose. It delivered the sample to Earth on the 13th of June, 2010. tokawa belongs to the Apollo asteroids, which are Earth-crossing asteroids and the largest dynamical group of near-Earth objects with nearly 10,000 known members. Itokawa orbits the Sun at a distance of 0.95–1.70 AU once every 18 months, and can pass by Earth as close as 5.1 lunar distances (the distance from the Earth to the moon).", + ], + }, + stats: { + discovery: + "Discovered in 1998, Itokawa was the first asteroid to be the target of a sample return mission. The Japanese space probe Hayabusa took a sample from the comet in November of 2005.", + rotation: 12.132, + }, + approach: { + fact: "Itokawa is classified as a PHO (potentially hazardous object), and will next approach the Earth on March 6th, 2030, at a distance of 0.376 AU (astronomical units).", + }, + }, + "37655_illapa": { + title: "Illapa", + description: { + blurb: [ + "37655 Illapa is a carbonaceous asteroid, classified as a near-Earth object and iapproximately 1.5 kilometers in diameter.", + ], + more: [ + "Discovered in 1994, Illapa has a short rotation period of 2.6556 hours. On 16 August 2003, Illapa made a close approach to Earth of 0.025037 AU (3,750,000 km; 2,330,000 mi, or about 10 lunar distances).", + ], + }, + related: [], + }, + "65803_didymos": { + title: "Didymos", + description: { + blurb: [ + "65803 Didymos is a sub-kilometer asteroid classified as both a potentially hazardous asteroid and a near-Earth object of both the Apollo and Amor group.", + ], + more: [ + 'The asteroid was discovered in 1996, by the Spacewatch survey at Kitt Peak, and its small 160-metre minor-planet moon was discovered in 2003, named Dimorphos. Due to its binary nature, it was then named "Didymos", the Greek word for twin. The Didymos binary system was the target of the DART mission, which was designed to impact with Dimorphos. The collision occurred on September 26th, 2022, and was a resounding success, changing the orbital period of the smaller moon by approximately thirty minutes.', + ], + }, + related: ["sc_dart"], + stats: { + discovery: + "Discovered in 1996, Didymos is part of a binary asteroid system with its smaller partner, Dimorphos. The DART mission targeted this system, successfully crashing a probe into Dimorphos on September 26th, 2022.", + rotation: 2.2593, + }, + approach: { + fact: "Didymos is a PHO (potentially hazardous object), and approached Earth at a distance of 0.07123 AU (astronomical units) on October 4th, 2022.", + }, + }, + "69230_hermes": { + title: "Hermes", + description: { + blurb: [ + "69230 Hermes is a sub-kilometer sized asteroid and binary system, classified as a potentially hazardous asteroid and near-Earth object. It passed Earth at approximately twice the distance of the Moon on October 30th, 1937.", + ], + more: [ + "The asteroid has an Earth minimum orbital intersection distance of 0.0041 AU (610,000 km) which translates into 1.6 lunar distances. In retrospect it turned out that Hermes came even closer to the Earth in 1942 than in 1937, within 1.7 lunar distances; the second pass was unobserved due to the events of World War 2. It was originally lost after its discovery in 1937, but was discovered again in 2003. Radar observations in October and November 2003 showed Hermes to be a binary asteroid. The primary and secondary components have nearly identical radii of 315 m (1,033 ft) and 280 m (920 ft), respectively, and their orbital separation is only 1,200 metres.", + ], + }, + related: [], + }, + "136199_eris": { + title: "Eris", + description: { + blurb: [ + "Eris is one of the largest known dwarf planets in our solar system. It's about the same size as Pluto, but is three times farther from the Sun.", + ], + more: [ + "Eris first appeared to be larger than Pluto. This triggered a debate in the scientific community that led to the International Astronomical Union's decision in 2006 to clarify the definition of a planet. Pluto, Eris and other similar objects are now classified as dwarf planets.", + "Originally designated 2003 UB313 (and nicknamed for the television warrior Xena by its discovery team), Eris is named for the ancient Greek goddess of discord and strife. The name fits since Eris remains at the center of a scientific debate about the definition of a planet.", + ], + }, + related: [], + }, + "136108_haumea": { + title: "Haumea", + description: { + blurb: [ + "Located in the Kuiper Belt beyond Neptune’s orbit, the dwarf planet Haumea is an oval-shaped object about the same size as Pluto.", + ], + more: [ + "Haumea is an oval-shaped object with a radius of about 385 miles. It has two moons, Namaka and Hi’iaka. Aday on Haumea lasts only four Earth hours, making it one of the fastest rotating large objects in our solar system.", + ], + }, + related: [], + }, + "136472_makemake": { + title: "Makemake", + description: { + blurb: [ + "Along with fellow dwarf planets Pluto, Eris and Haumea, Makemake is located in the Kuiper Belt, a region outside the orbit of Neptune.", + ], + more: [ + "Slightly smaller than Pluto, Makemake is the second-brightest object in the Kuiper Belt as seen from Earth (while Pluto is the brightest). It takes about 305 Earth years for this dwarf planet to make one trip around the sun.", + "Makemake holds an important place in the history of solar system studies because it—along with Eris—was one of the objects whose discovery prompted the International Astronomical Union to reconsider the definition of a planet and to create the new group of dwarf planets.", + "Makemake was named after the Rapanui god of fertility.", + ], + }, + related: [], + }, + "162173_ryugu": { + title: "Ryugu", + description: { + blurb: [ + "Ryugu is an asteroid whose orbit could bring it very near to Earth. It was visited by the Hayabusa2 mission in 2018, where it sampled the surface and returned the asteroid material to Earth in December of 2020.", + ], + more: [ + "Ryugu measures approximately 1 kilometre (0.62 mi) in diameter and orbits the earth every 1.3 years. The Japanese space agency JAXA launched the Hayabusa2 mission to Ryugu in 2014, and arrived in 2018. The spacecraft spent a year and a half in orbit around the asteroid before returning to Earth to drop off samples of the surface. The spacecraft had multiple objects land on the asteroid and collect data, including two small rovers. The samples of the surface were returned to Earth in December of 2020.", + ], + }, + related: [], + stats: { + discovery: + "Discovered in 1999, Ryugu was the target of the Hayabusa2 mission, which orbited the asteroid for a year and a half, landed small rovers on it, and collected samples that were returned to Earth in December of 2020.", + rotation: 7.63, + }, + approach: { + fact: "Ryugu is a PHO (potentially hazardous object), and will next approach Earth at a distance of 0.373 AU (astronomical units)s on June 3rd, 2025.", + }, + }, + "4_vesta": { + title: "Vesta", + description: { + blurb: [ + "Vesta is one of the largest objects in the asteroid belt, and was visited for over a year by NASA's Dawn Spacecraft.", + ], + more: [ + "The asteroid's official name is 4 Vesta because it was the fourth asteroid discovered. About the length of Arizona, it appears to have a surface of basaltic rock - frozen lava - which oozed out of the asteroid's presumably hot interior shortly after its formation 4.5 billion years ago, and has remained largely intact ever since. Telescopic observations reveal mineralogical variations across its surface.", + "Vesta has a unique surface feature which scientists look forward to peering into. At the asteroid's south pole is a giant crater - 460 kilometers (285 miles) across and 13 kilometers (8 miles) deep. The massive collision that created this crater gouged out one percent of the asteroid's volume, blasting over one-half million cubic miles of rock into space. What happened to the one percent that was propelled from its Vesta home? The debris, ranging in size from sand and gravel to boulder and mountain, was ejected into space where it began its own journey through the solar system. Scientist believe that about 5 percent of all meteorites we find on Earth are a result of this single ancient crash in deep space.", + ], + }, + related: ["sc_dawn"], + stats: { + discovery: + "One of the largest and earliest known asteroids, Vesta was discovered on March 29th, 1807, and was visited by the Dawn mission in 2011.", + rotation: 5.342, + }, + }, + "433_eros": { + title: "Eros", + description: { + blurb: [ + "Eros is famous as the first asteroid to be orbited by a spacecraft, and as the first one on which a spacecraft landed.", + ], + more: [ + "The NEAR spacecraft first flew by Eros on Dec. 23, 1998 at a distance of about 2,400 miles (about 3,800 kilometers) and found that the asteroid was smaller than expected and had two medium-sized craters, a long surface ridge and a density similar to that of Earth's crust. Afterseveral trajectory adjustments, NEAR finally moved into orbit around Eros on Valentine's Day (befitting an asteroid named for the Greek god of love), Feb. 14, 2000.", + 'After nearly a year in orbit, during which time the spacecraft was renamed "NEAR Shoemaker" in honor of astrogeology pioneer Eugene Shoemaker, the mission carried out humanity\'s first asteroid landing on Feb. 12, 2001. Eros was 196 million miles (315 million kilometers) from Earth at the time.', + ], + }, + related: ["sc_near_shoemaker"], + stats: { + discovery: + "Discovered on August 13th, 1898, Eros was the first near-Earth Object (NEO (near earth object)) ever found, and the first asteroid ever orbited by a spacecraft, NEAR-Shoemaker.", + rotation: 5.27, + }, + approach: { + fact: "Eros will approach Earth within 0.39765 AU (astronomical units) on November 30th, 2025.", + }, + }, + callisto: { + title: "Callisto", + description: { + blurb: [ + "Callisto is Jupiter’s second largest moon and the third largest moon in our solar system.", + ], + more: [ + "Callisto is about the same size as Mercury. In the past, some scientists thought of Callisto as a boring “ugly duckling moon” and a “hunk of rock and ice.” That’s because the crater-covered world didn’t seem to have much going on—no active volcanoes or shifting tectonic plates. But data from NASA’s Galileo spacecraft in the 1990s revealed Callisto may have a secret: a salty ocean beneath its surface. That finding put the once seemingly dead moon on the list of worlds that could possibly harbor life.", + ], + }, + related: ["sc_voyager_1", "sc_voyager_2", "sc_galileo", "sc_cassini"], + }, + sc_chandra: { + title: "Chandra X-ray Observatory", + description: { + blurb: [ + "Chandra allows scientists from around the world to obtain X-ray images of exotic environments to help understand the structure and evolution of the universe.", + ], + more: [ + 'The Chandra X-ray Observatory is part of NASA\'s fleet of "Great Observatories" along with the Hubble Space Telescope, Spitizer Space Telescope and the now deorbited Compton Gamma Ray Observatory.', + "The Chandra X-ray Observatory, which was launched by Space Shuttle Columbia in 1999, can better define the hot, turbulent regions of space. This increased clarity can help scientists answer fundamental questions about the origin, evolution, and destiny of the universe.", + ], + }, + dates: { + start: "1999-07-23T04:30:59.984", + end: "2014-01-09T07:35:59.984", // Coercing chandra to load; not actual end date + landing: "", + highlight: "2014-01-09T07:35:59.984", + }, + parent: "earth", + related: ["sc_hubble_space_telescope", "sc_spitzer"], + }, + charon: { + title: "Charon", + description: { + blurb: [ + "At half the size of Pluto, Charon is the largest of Pluto's moons and the largest known satellite relative to its parent body.", + ], + more: [ + "The little moon is so big that Pluto and Charon are sometimes referred to as a double dwarf planet system. The distance between them is 19,640 km (12,200 miles). Pluto-Charon is our solar system's only known double planetary system. The same surfaces of Charon and Pluto always face each other, a phenomenon called mutual tidal locking. Charon orbits Pluto every 6.4 Earth days.", + ], + }, + related: ["sc_new_horizons"], + }, + "67p_churyumov_gerasimenko": { + title: "Churyumov Gerasimenko", + description: { + blurb: [ + "Comet 67P/ Churyumov-Gerasimenko made history as the first comet to be orbited and landed upon by robots from Earth.", + ], + more: [ + "Churyumov-Gerasimenko loops around the Sun in an orbit that crosses those of Jupiter and Mars, approaching but not reaching Earth's orbit. Like most Jupiter Family comets, it is thought to have fallen from the Kuiper Belt, a region beyond Neptune's orbit, as a result of one or more collisions or gravitational tugs. The Rosetta spacecraft, carrying the Philae lander, rendezvoused with this comet in August 2014 and to escorted it on its journey to the inner solar system and back out again. Rosetta is a mission of the European Space Agency (ESA) for which NASA is providing key instruments and support.", + ], + }, + related: ["sc_rosetta"], + stats: { + discovery: + "Discovered in 1969, this comet was the first to be landed upon by a robotic mission from Earth, the European Space Agency's Rosetta mission. The Philae lander touched down in November of 2014.", + rotation: 12.76, + }, + approach: { + fact: "The comet approached Earth within 0.418 AU (astronomical units) on November 12th, 2021, and then will approach again in November of 2034 at a distance of 0.4523 AU (astronomical units).", + }, + }, + "1p_halley": { + title: "P/Halley", + description: { + blurb: [ + "Halley's Comet or Comet Halley, officially designated 1P/Halley, is a short-period comet visible from Earth every 75–76 years. Halley is the only known short-period comet that is regularly visible to the naked eye from Earth, and the only naked-eye comet that can appear twice in a human lifetime.", + ], + more: [ + "Halley's dimensions are about 9.3 by 5 miles (15 kilometers by 8 kilometers). It is one of the darkest, or least reflective, objects in the solar system. It has an albedo of 0.03, which means that it reflects only 3% of the light that falls on it. In 1986, an international fleet spacecraft met the comet for an unprecedented study from a variety of vantage points. The science fleet included Japan's Suisei and Sakigake spacecraft, the Soviet Union's Vega 1 and Vega 2,the international ISEE-3 (ICE) spacecraft and the European Space Agency's Giotto. NASA's Pioneer 7 and Pioneer 12 also contributed the the bounty of science data collected.", + ], + }, + related: [], + }, + "103p_hartley_2": { + title: "Hartley 2", + description: { + blurb: [ + "Comet Hartley 2 is a small, oval-shaped comet -- its nucleus measures approximately one mile (1.6 kilometers) in diameter. It takes Hartley 2 about 6.47 years to orbit the Sun once.n It was visited by NASA's Deep Impact (EPOXI) mission in 2010.", + ], + more: [ + "Comet 103P/Hartley 2 was discovered by Malcolm Hartley in 1986 at the Siding Springs Observatory in Australia. The Deep Impact spacecraft flew past Hartley 2 in its extended mission called EPOXI in November 2010.", + "During the spacecraft's flyby of the comet - with closest approach of 694 kilometers - carbon-dioxide-driven jets were seen at the ends of the comet, with most occurring at the small end. In the middle region, or waist of the comet, water was released as vapor with very little carbon dioxide or ice. The latter findings indicate that material in the waist likely came off the ends of the comet and was redeposited.", + ], + }, + related: ["sc_deep_impact"], + stats: { + discovery: + "Discovered in 1986, Comet Hartley 2 was the target of the Deep Impact/EPOXI mission, which flew by in November of 2010.", + rotation: 18.1, + }, + approach: { + fact: "103p/Hartley 2 is classified as an NEO (near earth object), and will approach Earth within 0.3826 AU (astronomical units) on September 26th, 2023.", + }, + }, + "1i_oumuamua": { + title: "Oumuamua", + description: { + blurb: [ + "ʻOumuamua is the first known interstellar object detected passing through the Solar System.", + ], + more: [ + "The first confirmed object from another star to visit our solar system, this interstellar interloper appears to be a rocky, cigar-shaped object with a somewhat reddish hue. The object, named ‘Oumuamua by its discoverers, is up to one-quarter mile (400 meters) long and highly-elongated—perhaps 10 times as long as it is wide. That aspect ratio is greater than that of any asteroid or comet observed in our solar system to date. Its elongated shape is quite surprising, and unlike objects seen in our solar system, it may provide new clues into how other solar systems formed. The observations suggest this unusual object had been wandering through the Milky Way, unattached to any star system, for hundreds of millions of years before its chance encounter with our star system.", + ], + }, + related: [], + }, + "9p_tempel_1": { + title: "Tempel 1", + description: { + blurb: [ + "Comet 9P/Tempel 1 orbits the sun within the asteroid belt, which lies between the orbits of Mars and Jupiter. Tempel 1 last reached perihelion (closest approach to the sun) in 2016.", + ], + more: [ + "Two missions have encountered this comet: Deep Impact in 2005 and Stardust NExT in in 2011. Deep Impact sent an impactor into Tempel 1, becoming the first spacecraft to eject material from the surface of a comet. Changes in the surface of Tempel 1 were obscured by all the material ejected during and after the collision.", + ], + }, + related: ["sc_deep_impact", "sc_deep_impact_impactor", "sc_stardust"], + stats: { + discovery: + "Discovered in 1867, comet Tempel 1 was the target of the Deep Impact mission, which physically collided with the comet on July 4th, 2005.", + rotation: 40.7, + }, + }, + "19p_borrelly": { + title: "Borrelly", + description: { + blurb: [ + "19P/Borrelly is a periodic comet, which was visited by the spacecraft Deep Space 1 in 2001.", + ], + more: [ + 'With a shape resembling a chicken leg, the nucleus of comet 19P/Borrelly is approximately 5 miles (8 kilometers) long. The nucleus is inside a much larger cloud of gas and dust known as the "coma." Borrelly follows an elliptical orbit around the Sun, looping from inside the orbit of Mars to outside the orbit of Jupiter and back again. It is a "Jupiter-family comet," with an orbit period of less than 20 years and one ds1that has been significantly modified by the gravity of the gas giant planet through close passages. It takes 6.9 years for Borrelly to orbit the Sun once. The comet last reached perihelion (closest approach to the Sun) in 2015.', + "Deep Space 1 encountered comet Borrelly on Sept. 22, 2001. Flying by a speed of 10.3 miles (16.6 kilometers) per second (more than 37,000 mph, or almost 60,000 kph), Deep Space 1 traveled just 1,349 miles (2,171 kilometers) from Borrelly's nucleus. This spacecraft captured the best pictures of any comet's nucleus at the time and collected other valuable scientific data as well.", + ], + }, + related: ["sc_deep_space_1"], + stats: { + discovery: + "Discovered in 1904, comet Borrelly was the target of the Deep Space 1 mission, which flew by in September of 2001.", + }, + }, + "81p_wild_2": { + title: "Wild 2", + description: { + blurb: [ + "81P/Wild (Wild 2) (Wild is pronounced vilt) is a small comet with the shape of a flattened sphere. NASA made use of this special comet, when in 2004 it sent the Stardust mission to fly by it and gather particles.", + ], + more: [ + "Comet 81P/Wild-2 is a fresh periodic comet. Until September 10, 1974, when it passed within 0.006 AU of Jupiter, its orbit lay between Jupiter and a point near Uranus. That encounter with Jupiter, at only 10 times the distance which fragmented P/Shoemaker-Levy 9 in 1994, brought it into the inner solar system, where its perihelion now lies just beyond the distance of Mars and its aphelion near Jupiter.", + ], + }, + related: ["sc_stardust"], + stats: { + discovery: + "This comet was discovered on January 6th, 1978, and was visited by the Stardust mission in January of 2004.", + }, + }, + adrastea: { + title: "Adrastea", + description: { + blurb: [ + "Adrastea was discovered in July 1979 by the Voyager science team.", + ], + more: [ + "Orbiting within Io's orbit, which is the innermost of the four largest moons of Jupiter (called the Galilean moons), are four smaller moons named Metis, Adrastea, Amalthea, and Thebe.", + "All the moons within this grouping are oddly shaped, lacking either the mass and/or fluidity of composition to pull themselves into a reasonably spherical shape. The Galileo spacecraft has revealed some surface features, including impact craters, hills and valleys.", + "Adrastea is the smallest within this group having a mean radius of about 8.2 ± 2.0 km. Adrastea orbits 129,000 km from its parent planet Jupiter and it takes 0.298 Earth days for Adrastea to complete one orbit. We do not know the rotational period for Adrastea, but its orbital period is 7 hours.", + "Since Io orbits about 422,000 km above Jupiter and, at this close distance, is subjected to extreme tidal flexing from Jupiter's gravity, one would imagine that this even closer satellite would be pulled to pieces. However, because it is so small Adrastea is relatively immune to the effects of tidal forces. Adrastea is one of the two closest moons (the other is Metis) that orbit inside what is called the synchronous orbit radius of Jupiter. That is, Adrastea orbits Jupiter faster than Jupiter rotates on its axis. At this distance, Adrastea's orbit will eventually decay and it will fall into the planet.", + "Adrastea and Metis also orbit inside Jupiter's main ring and are undoubtedly the source of the material for this ring. Amalthea and Thebe provide the material for the Gossamer ring.", + ], + }, + related: ["sc_voyager_2"], + }, + aegaeon: { + title: "Aegaeon", + description: { + blurb: [ + "Aegaeon is the smallest known moon of Saturn and scientists imaged it on Aug. 15, 2008, and then confirmed its presence by finding it in two earlier images.", + ], + more: [ + "The moonlet is too small to be resolved by Cassini's cameras, so its size cannot be measured directly. However, Cassini scientists estimated the moonlet's size by comparing its brightness to another small Saturnian moon, Pallene. It has also been found that the moonlet's orbit is being disturbed by the larger, nearby moon Mimas, which is responsible for keeping the ring arc together. Aegaeon is embedded within a partial ring, or ring arc, previously found by Cassini, the G ring. Debris knocked off the moon forms a bright arc near the inner edge, which in turn spreads to form the rest of the ring. Based on its interaction with the dust particles that make up the G ring arc Aegaeon is embedded in, this small moon most likely has a density around half that of water ice. But unlike ice, Aegaeon is very dark. It's the least reflective of any Saturnian moon inward of Titan. Originally designated S/2008 S1, Aegaeon is named for a fierce giant with many heads and arms who helped conquer the Titans.", + ], + }, + related: ["sc_cassini"], + }, + aegir: { + title: "Aegir", + description: { + blurb: [ + "Aegir was discovered on Dec. 12, 2004 (one of 12 Saturnian moons found that day) using a wide-field camera on Mauna Kea, Hawaii.", + ], + more: [ + "Aegir has a mean radius of 1.9 miles (3 km), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 167 degrees and an eccentricity of 0.25. At a mean distance of 12.9 million miles (20.7 million km) from Saturn, the moon takes about 1,118 Earth days to complete one orbit. Aegir is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn—traveling around in the opposite direction from the planet's rotation. Aegir and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Aegir is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2004 S10, Aegir was named for a giant in Norse mythology who personified the ocean.", + ], + }, + related: [], + }, + aitne: { + title: "Aitne", + description: { + blurb: [ + "Aitne was discovered on December 9, 2001 by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Aitne is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99% of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color -- light red -- except for Kalyke, which is considerably redder than the others. All of these characteristics support the idea that the Carme satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. Originally called S/2001 J11, Aitne was named for a Sicilian nymph said to have been raped by the Roman god Jupiter, while he was in the form of a vulture.", + ], + }, + related: [], + }, + albiorix: { + title: "Albiorix", + description: { + blurb: [ + "Albiorix was discovered on Nov. 9, 2000 on Mt. Hopkins, near Amado, Ariz.", + ], + more: [ + "Albiorix is one of the four known members of the Gallic group of moons. These moons have prograde orbits (they travel around Saturn in the same direction as the planet's rotation), but their egg-shaped, angled orbits classify them as \"irregular\" moons. Like Saturn's other irregular moons, they are thought to be objects that were captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet, as the regular moons are thought to have done. The other members of this group are Bebhionn, Erriapus, and Tarvos. Observations by Tommy Grav and James Bauer using telescopes on Mauna Kea, Hawaii in 2006 found that the color of Albiorix varies over its surface. They hypothesize that Tarvos and Erriapus, which were both seen to be light red, are the largest fragments from an impact on Albiorix, leaving a less-red crater (these observations did not include Bebhionn). Originally called S/2000 S11, Albiorix was named for a Gallic deity who may have been equivalent to the Roman god Mars.", + ], + }, + related: [], + }, + amalthea: { + title: "Amalthea", + description: { + blurb: [ + "Amalthea was discovered Sept. 9, 1892 by Edward Emerson Barnard.", + ], + more: [ + "Orbiting within Io's orbit, which is the innermost of the four largest moons of Jupiter (called the Galilean moons), are four smaller moons named Metis, Adrastea, Amalthea, and Thebe.", + "All the moons within this grouping are oddly shaped, lacking either the mass and/or fluidity of composition to pull themselves into a reasonably spherical shape. The Galileo spacecraft has revealed some surface features, including impact craters, hills and valleys.", + "Amalthea is the largest within this grouping with a mean radius of about 83.5 ± 2.4 km. Amalthea orbits 181,400 km from its parent planet Jupiter. Amalthea takes 0.498 Earth days to complete one orbit.", + "Amalthea is the reddest object in the solar system and it appears to give out more heat than it receives from the sun. This may be because, as it orbits within Jupiter's powerful magnetic field, electric currents are included in the moon's core. Alternatively, the heat could be from tidal stresses.", + "Amalthea and Thebe rotate on their axes once for each orbit around Jupiter, always keeping the same side facing the planet. This orbit takes about one-half an Earth day for Amalthea and two-thirds an Earth day for Thebe.", + "Amalthea and the moon Thebe provide the material for the Gossamer ring.", + "Since Io orbits about 422,000 km above Jupiter and, at this close distance, is subjected to extreme tidal flexing from Jupiter's gravity, one would imagine that this even closer satellite would be pulled to pieces. However, because it is so small (Amalthea's diameter is 1/19th that of Io's diameter) it is relatively immune to the effects of tidal forces. Since Amalthea is so close to its parent planet its orbit will eventually decay and it will fall into the planet.", + ], + }, + related: [], + }, + ananke: { + title: "Ananke", + description: { + blurb: [ + "Ananke was discovered on Sept. 28, 195 on a photograph made with the 100-inch (2.5 m) Hooker telescope at the Mount Wilson Observatory in California.", + ], + more: [ + "Ananke is the largest member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. Ananke was probably an asteroid that was captured by Jupiter's gravity and then suffered a collision which broke off a number of pieces. Those pieces became the other 15 moons in the Ananke group. All of the Ananke moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and rather highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Ananke satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. Ananke's observed color is somewhere between gray and light red. Ananke was named for the mother of Adrastea by Zeus, the Greek equivalent of the Roman god Jupiter. In other accounts, Adrastea is described as a nymph of Crete who was one of the nursemaids of the infant Zeus. Ananke is the personification of fate or necessity in ancient Greek literature, who rewards or punishes people for their deeds.​", + ], + }, + related: [], + }, + anthe: { + title: "Anthe", + description: { + blurb: [ + "Anthe was discovered on May 30, 2007, although a check back revealed Anthe in Cassini images as early as June 2004. Anthe is the 60th confirmed moon of Saturn.", + ], + more: [ + "Anthe is a tiny moon with a mean radius of 0.6 miles (0.9 km) that orbits between Mimas and Enceladus at about of 122,800 miles (197,700 km) from Saturn. Anthe and two other tiny moons, Methone and Pallene, may have split from either Mimas or Enceladus, or all five moons may be the remains of a larger swarm that traveled in that area close to Saturn. Anthe circles Saturn in approximately 25 hours. Because these three tiny moons orbit at very similar distances from Saturn, they are in a dynamical relationship. The vastly more massive Mimas has the greatest effect on Anthe, causing the Methone orbit to vary by as much as 12.4 miles (20 km), and has a slightly smaller effect on Pallene. Together, these three moons may also be contributing particles to Saturn's E ring. Material blasted off Anthe by micrometeoroid impacts is believed to the source of the Anthe Ring Arc, a faint partial ring arout Saturn that is co-orbital with the moon first detected in June 2007. The name Anthe comes from the name in Greek mythology of one of seven Alkyonides—daughters of the god (or Titan) Alkyoneus. Astronomers also refer to Anthe as Saturn XLIX, and before it was confirmed, it was known as S/2007 S4.​", + ], + }, + related: ["sc_cassini"], + }, + aoede: { + title: "Aoede", + description: { + blurb: [ + "Aoede was discovered Feb. 8, 2003 at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Aoede is considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. Most or all of the Pasiphae satellites are thought to have begun as a single asteroid that, after being captured by Jupiter's gravity, suffered a collision which broke off a number of pieces. All of the Pasiphae moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Pasiphae satellites began as one or more captured asteroids, rather than forming as part of the original Jupiter system. Aoede has a mean radius of two km, assuming an albedo of 0.04. At a mean distance of about 14.9 million miles (24 million km) from Jupiter, the satellite takes about 761 Earth days to complete one orbit. Originally called S/2003 J7, Aoede was named for one of the Muses, who were daughters of Zeus, the Greek equivalent of the Roman god Jupiter. Aoede means song. A name ending in \"e\" was chosen for this moon in accordance with the International Astronomical Union's policy for designating outer moons with retrograde orbits.​", + ], + }, + related: [], + }, + arche: { + title: "Arche", + description: { + blurb: [ + "Arche was discovered Oct. 31, 2002, by Scott S. Sheppard at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Arche is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99 percent of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color—light red—except for Kalyke, which is considerably redder than the others. Arche has a mean radius of about 1 mile (1.5 km). At a mean distance of about 14.5 million miles (23.4 million) km from Jupiter, the satellite takes about 732 Earth days to complete one orbit. Originally called S/2002 J1, Arche was named for one of the Muses, who were daughters of Zeus, the Greek equivalent of the Roman god Jupiter. Her name means \"beginning.\"​", + ], + }, + related: [], + }, + atlas: { + title: "Atlas", + description: { + blurb: [ + "Atlas was discovered in 1980 by R. Terrile and the Voyager 1 team from photographs taken during its encounter with Saturn.", + ], + more: [ + "Atlas is an inner moon of Saturn, orbiting around the outer edge of Saturn's A Ring. Like Pan, Atlas has a distinctive flying saucer shape created by a prominent equatorial ridge not seen on the other small moons of Saturn. Cassini images revealed in 2004 that a temporary faint ring of material with the orbit of Atlas. The small, pointy moon has a mean radius of 9.4 miles (15.1 km). It orbits 85,544 miles (137,670 km) away from, taking 14.4 hours to complete its trip around the planet. Moons of Saturn were originally named for Greco-Roman Titans and descendants of the Titans. But as many new moons were discovered, scientists began selecting names from more mythologies including Gallic, Inuit, and Norse stories. Originally designated S/1980 S28, this moon is named after Atlas, a Titan, and a son of Iapetus. Atlas was ordered by Zeus to uphold the vault of the sky after the defeat of the Titans. Atlas was so strong that he supported the weight of the Universe on his shoulders.", + ], + }, + related: ["sc_voyager_1"], + }, + autonoe: { + title: "Autonoe", + description: { + blurb: [ + "Autonoe was discovered Dec. 10, 2001 by Scott S. Sheppard, David C. Jewitt, and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Autonoe is considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. Most or all of the Pasiphae satellites are thought to have begun as a single asteroid that, after being captured by Jupiter's gravity, suffered a collision which broke off a number of pieces. The bulk of the original asteroid survived as the moon called Pasiphae, and the other pieces became some or all of the other moons in the group. All of the Pasiphae moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Pasiphae satellites began as one or more captured asteroids, rather than forming as part of the original Jupiter system. Autonoe has a mean radius of 1.2 miles (2 km), assuming an albedo of 0.04. At a mean distance of about 14.9 million miles (24 million km) from Jupiter, the satellite takes about 761 Earth days to complete one orbit. Originally called S/2001 J1, Autonoe was named for the mother of the Graces by Jupiter, according to some authors.", + ], + }, + related: [], + }, + bebhionn: { + title: "Bebhionn", + description: { + blurb: [ + "Bebhionn was discovered on Dec. 12, 2004 using the wide-field camera on the 8.2-m Subaru telescope on Mauna Kea, Hawaii, with orbital elements computed by Brian Marsden.", + ], + more: [ + "Bebhionn has a mean radius of 1.9 miles (3 km), assuming an albedo (a measure of how reflective the surface is) of 0.04. At a mean distance of 10.6 million miles (17.1 million km) from Saturn, the moon takes about 835 Earth days to complete one orbit. Bebhionn is one of the four known members of the Gallic group of moons. These moons have prograde orbits (they travel around Saturn in the same direction as the planet's rotation), but their egg-shaped, angled orbits classify them as \"irregular\" moons. Like Saturn's other irregular moons, they are thought to be objects that were captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet, as the regular moons are thought to have done. The similarities among the orbits of moons in the Gallic group suggest a common origin—they may be fragments of a single object that shattered in a collision. The other members of this group are Albiorix, Erriapus, and Tarvos. Originally called S/2004 S11, Bebhionn was named for a beautiful giantess in Celtic mythology. In one story, she escapes from Maidens' Land—which was populated entirely by women except for the king and his three sons—only to be slain by her giant husband, who was the son of the king of the Isle of Men.​", + ], + }, + related: [], + }, + belinda: { + title: "Belinda", + description: { + blurb: [ + "Belinda was discovered on Jan. 13, 1986 in images taken by Voyager 2. It is one of the 10 Uranian satellites discovered by the Voyager science team.", + ], + more: [ + "Little is known about Belinda other than its size and orbital characteristics. Based on its low albedo, its surface probably consists of the dark, unprocessed, carbon-rich material found on the C-class of asteroids.", + ], + }, + related: ["sc_voyager_2"], + }, + bergelmir: { + title: "Bergelmir", + description: { + blurb: [ + "Bergelmir was discovered on Dec. 12, 2004, one of 12 Saturnian moons found that day using wide-field camera on the Subaru 8.3-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Bergelmir has a mean radius of 1.9 miles (3 km), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 159 degrees and an eccentricity of about 0.1. At a mean distance of 12 million miles (19.3 million km) from Saturn, the moon takes about 1,006 Earth days to complete one orbit. Bergelmir is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn—traveling around in the opposite direction from the planet's rotation. Bergelmir and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Bergelmir is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2004 S15, Bergelmir was named for the frost giant who, with his wife, escaped drowning in the flood of Ymir's blood that ensued when Ymir was slain by Odin and his brothers in the Norse tale of creation.​", + ], + }, + related: [], + }, + bestla: { + title: "Bestla", + description: { + blurb: [ + "Bestla was discovered on Dec. 12, 2004, one of 12 Saturnian moons found that day using wide-field camera on the Subaru 8.3-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Bestla has a mean radius of 2.2 miles (3.5 km), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 142 degrees and an eccentricity of about 0.5. At a mean distance of 12.6 million miles (20.3 million km) from Saturn, the moon takes about 1,087 Earth days to complete one orbit. Bestla is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn—traveling around in the opposite direction from the planet's rotation. Bestla and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Bestla is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Bestla appears to be a member of a subgroup with Narvi. Originally called S/2004 S18, Bestla is named for a giantess and the mother of Odin, who is the supreme god in Norse mythology.​", + ], + }, + related: [], + }, + bianca: { + title: "Bianca", + description: { + blurb: [ + "Bianca was discovered Jan. 23, 1986 in images taken by Voyager 2. It is one of the 10 Uranian satellites discovered by the Voyager science team.", + ], + more: [ + 'Bianca is one of the small, inner moons of Uranus. Little is known about it other than its size and orbital characteristics. Neither its size or albedo have been measured directly, but by analogy with Belinda and Puck, its surface probably consists of the dark, unprocessed, carbon-rich material found on the C-class of asteroids. Originally called S/1986 U9, Bianca was named after the sister of Katharina (Kate) in Shakespeare\'s play, "The Taming of the Shrew."​', + ], + }, + related: ["sc_voyager_2"], + }, + c_2010_x1: { + title: "Elenin", + description: { + blurb: [ + "Comet C/2010 X1 (Elenin) is an Oort cloud comet discovered on December 10, 2010.", + ], + more: [ + "Comet Elenin was hit by a coronal mass ejection from the sun and started disintegrating in August of 2011, and as of mid-October 2011 was not visible even using large ground-based telescopes.", + ], + }, + related: [], + }, + c_2012_s1: { + title: "ISON", + description: { + blurb: [ + "C/2012 S1 (ISON) bears the name of the night-sky survey program that discovered it, the International Scientific Optical Network, in 2012.", + ], + more: [ + "C/2012 S1 (ISON) was the subject of the most coordinated comet observing campaign in history. Over the course of a year, more than a dozen spacecraft and numerous ground-based observers collected what is believed to be the largest single cometary dataset in history as ISON plunged toward a close encounter with the Sun.Just prior to its closest approach to the sun on Nov. 28, 2013, Comet ISON went through a major heating event, and was torn to pieces. What remained of Comet ISON appeared to brighten and spread out, then fade.", + ], + }, + related: ["sc_deep_impact"], + }, + caliban: { + title: "Caliban", + description: { + blurb: [ + "Caliban orbits Uranus in the opposite direction from the regular moons and the rotation of the planet itself (called a retrograde orbit). Its orbit is also somewhat inclined and eccentric, and very far from the planet -- more than 10 times farther than Oberon, the farthest regular moon. These characteristics suggest that Caliban was an independent body that was captured by Uranus' gravity. It is thought to be about 72 km in diameter, and to be the second largest irregular satellite of Uranus (about half the size of Sycorax). The size estimate is based on the brightness of the moon and an assumed albedo of 0.04, typical of captured asteroids in the outer solar system.", + ], + }, + related: [], + }, + callirrhoe: { + title: "Callirrhoe", + description: { + blurb: [ + "Callirrhoe was discovered Oct. 19, 1999 via the 36-inch telescope on Kitt Peak, in the course of observations by the Spacewatch program of the University of Arizona.", + ], + more: [ + "Initially thought to be an asteroid, Callirrhoe is considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. All of the Pasiphae moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Pasiphae satellites began as one or more captured asteroids, rather than forming as part of the original Jupiter system. Compared to Jupiter's other satellite groups, confidence is lower that all the moons in the Pasiphae group originated in a single collision. This is due to differences in color (varying from red to gray), and differences in orbital eccentricity and inclination among the members of the Pasiphae group. Sinope, in particular, is suspected of starting out as an independent asteroid. Callirrhoe has a mean radius of 2.7 miles (4.3 km), assuming an albedo of 0.04. At a mean distance of about 15 million miles (24.1 million km) from Jupiter, the satellite takes about 759 Earth days to complete one orbit. This object was originally called asteroid 1999 UX18 and then renamed S/1999 J1 upon discovery that it is a satellite of Jupiter. Ultimately, it was named \"Callirrhoe\" after the daughter of the river god, Achelous, who persuaded Zeus (the Greek equivalent of the Roman god Jupiter) to instantly change her young sons into grown men so they could avenge the murder of their father.", + ], + }, + related: [], + }, + calypso: { + title: "Calypso", + description: { + blurb: [ + "Calypso was discovered by D. Pascu, P.K. Seidelmann, W. Baum, and D. Currie in March 1980 using a ground-based telescope.", + ], + more: [ + 'Calypso is a Trojan (trailing moon) of the larger moon Tethys, orbiting 183,000 miles (295,000 km) from Saturn, completing one orbit in 45 hours. Calypso follows Tethys in its orbit by 60 degrees. (Telesto is the other Tethys Trojan, orbiting Saturn 60 degrees ahead of Tethys.) Together, Calypso and Telesto are known as the "Tethys Trojans" and were discovered in the same year. Calypso has a mean radius of 6.6 miles (10.7 km) across. Like many other small Saturnian moons and small asteroids, Calypso is irregularly shaped by overlapping large craters. This moon appears to also have loose surface material capable of smoothing the appearance of craters. Its surface is one of the most reflective (at visual wavelengths) in the solar system, with a visual geometric albedo (a measure of how reflective the surface is) of 1.34. This very high reflectiveness could be the result of particles from Saturn\'s E-ring, which is composed of small ice particles generated by Enceladus\' south polar geysers. Moons of Saturn were originally named for Greco-Roman Titans and descendants of the Titans. But as many new moons were discovered, scientists began selecting names from more mythologies, including Gallic, Inuit, and Norse stories. Originally called S/1980 S25, Calypso is named for a nymph whose name means "I hide." A daughter of the Titans, Oceanus and Tethys, she lived alone on her island until she fell in love with the explorer Odysseus (called Ulysses by the Romans; his name means "one who suffers"). Calypso helped Odysseus find his way home after his long voyage and dangerous adventures.​', + ], + }, + related: [], + }, + carme: { + title: "Carme", + description: { + blurb: [ + "Carme was discovered on July 30, 1938 by Seth Barnes Nicholson with the 100-inch (2.5 m) Hooker telescope at the Mount Wilson Observatory in California.", + ], + more: [ + "With a mean radius of 14 miles (23 km), Carme is the largest member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. Carme was probably a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. Those pieces became the other 16 moons in the Carme group. Carme still retains 99 percent of the total mass of the group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color—light red—except for Kalyke, which is considerably redder than the others. All of these characteristics support the idea that the Carme satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Carme members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. At a mean distance of about 14.5 million miles (23.4 million km) from Jupiter, the satellite takes about 734 Earth days to complete one orbit. Carme is named for the mother of Britomartis by the Roman god Jupiter (or Zeus in the Greek version of the myth), who became a goddess of Crete. A name ending in \"e\" was chosen in accordance with the International Astronomical Union's policy for designating outer moons with retrograde orbits.​", + ], + }, + related: [], + }, + carpo: { + title: "Carpo", + description: { + blurb: [ + "Carpo was discovered on Feb. 26, 2003 using the 12-ft. (3.6-m) Canada-France-Hawaii telescope at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Carpo, some 1.9 miles (3 km) across (assuming an albedo of 0.04), orbits Jupiter at a distance of about 10.5 million miles (17 million km). It takes a little over 456 Earth days to complete one orbit. The orbit is somewhat inclined with respect to Jupiter's equatorial plane, and the direction of travel is the same as that of Jupiter's rotation (a \"prograde\" orbit). It is Jupiter's most distant known moon with a prograde orbit. There are many moons known to be further out, but they all travel around Jupiter in the opposite direction. Originally designated S/2003 J20, Carpo was named for one of the three Athenian goddesses of the flowers of spring and the fruits of summer and autumn. An annual festival in their honor was called the Horaea. According to Hesoid, a group of goddesses collectively called the Horae (with different names, which did not include Carpo) were daughters of Zeus, the Greek equivalent of the Roman god Jupiter.​", + ], + }, + related: [], + }, + chaldene: { + title: "Chaldene", + description: { + blurb: [ + "Chaldene was discovered Nov. 23, 2000 by Scott S. Sheppard, David C. Jewitt, Yange R. Fernandez, and Eugene Magnier at an observatory on Mauna Kea in Hawaii.", + ], + more: [ + "Chaldene is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99 percent of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color—light red—except for Kalyke, which is considerably redder than the others. All of these characteristics support the idea that the Carme satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Carme members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Chaldene has a mean radius of about 1 mile (1.9 km). At a mean distance of about 14.3 million miles (23.1 million km) from Jupiter, the satellite takes about 724 Earth days to complete one orbit. Originally called S/2000 J10, Chaldene was named for the mother of Solymos by Zeus, the Greek equivalent of the Roman god Jupiter. A name ending in \"e\" was chosen in accordance with the International Astronomical Union's policy for designating outer moons with retrograde orbits.​", + ], + }, + related: [], + }, + cordelia: { + title: "Cordelia", + description: { + blurb: [ + "Cordelia was discovered on Jan. 20, 1986 in images taken by Voyager 2. It is one of the 10 Uranian satellites discovered by the Voyager science team.", + ], + more: [ + "Of the moons known to orbit Uranus, Cordelia is closest to the planet. It and Ophelia are shepherd moons whose gravity keeps the particles that constitute Uranus' Epsilon ring from dispersing. Neither its size nor its albedo have been measured directly, but assuming an albedo of 0.07 like Puck, its surface probably consists of the dark, unprocessed, carbon-rich material found on the C-class of asteroids. Originally called S/1986 U7, Cordelia was named for one of the youngest daughters of King Lear in William Shakespeare's play of the same name. King Lear disowns Cordelia for her refusal to flatter him. Others think highly of her, and the King of France marries her for her virtue alone. Cordelia forgives her father in spite of his cruelty toward her and remains loyal to him.", + ], + }, + related: ["sc_voyager_2"], + }, + cressida: { + title: "Cressida", + description: { + blurb: [ + "Cressida was discovered on Jan. 9, 1986 in images taken by Voyager 2. It is one of the 10 Uranian satellites discovered by the Voyager science team.", + ], + more: [ + 'Cressida is one of the small, inner moons of Uranus. Little is known about it other than its size and orbital characteristics. Based on its low albedo, its surface probably consists of the dark, unprocessed, carbon-rich material found on the C-class of asteroids. Originally called S/1986 U3, Cressida was named for the title character in William Shakespeare\'s play, "Troilus and Cressida."', + ], + }, + related: ["sc_voyager_2"], + }, + cupid: { + title: "Cupid", + description: { + blurb: [ + "Cupid was discovered on Aug. 25, 2003 by M.R. Showalter and J.J. Lissauer, using the Hubble Space Telescope.", + ], + more: [ + "Cupid is one of the inner moons of Uranus, so small and dark that it escaped the notice of Voyager 2 during the spacecraft's visit in 1986. Originally called S/2003 U2, Cupid was named for the Roman god of love, who appears in William Shakespeare's play, \"Timon of Athens\" (in keeping with the custom of naming most of Uranus' moons after Shakespearean characters).", + ], + }, + related: [], + }, + cyllene: { + title: "Cyllene", + description: { + blurb: [ + "Cyllene was discovered Feb. 9, 2003 by Scott S. Sheppard and his team from the University of Hawaii at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Cyllene is considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. Most or all of the Pasiphae satellites are thought to have begun as a single asteroid that, after being captured by Jupiter's gravity, suffered a collision which broke off a number of pieces. The bulk of the original asteroid survived as the moon called Pasiphae, and the other pieces became some or all of the other moons in the group. All of the Pasiphae moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Pasiphae satellites began as one or more captured asteroids, rather than forming as part of the original Jupiter system. Compared to Jupiter's other satellite groups, confidence is lower that all the moons in the Pasiphae group originated in a single collision. This is due to differences in color (varying from red to gray), and differences in orbital eccentricity and inclination among the members of the Pasiphae group. Sinope, in particular, is suspected of starting out as an independent asteroid. Cyllene has a mean radius of one kilometer, assuming an albedo of 0.04. At a mean distance of about 14.8 million miles (23.8 million km) from Jupiter, the satellite takes about 752 Earth days to complete one orbit. Originally called S/2003 J13, Cyllene was named for a nymph in Greek mythology who was a daughter of Zeus, the Greek equivalent of the Roman god Jupiter. She is associated with a mountain in Arcadia on which, legend has it, the blackbirds become white and are impossible to shoot during the daytime.", + ], + }, + related: [], + }, + dactyl: { + title: "Dactyl", + description: { + blurb: [ + "Dactyl is a moon of the asteroid 243 Ida, discovered by the Galileo spacecraft in 1993.", + ], + more: [ + "Dactyl is heavily cratered, like Ida, and consists of similar materials. Its origin is uncertain. Dactyl was found on 17 February 1994 by Galileo mission member Ann Harch, while examining delayed image downloads from the spacecraft. Galileo recorded 47 images of Dactyl over an observation period of 5.5 hours in August of 1993. Dactyl's orbit around Ida is not precisely known.", + ], + }, + related: ["sc_galileo"], + }, + daphnis: { + title: "Daphnis", + description: { + blurb: [ + "Daphnis was discovered by the Cassini mission team on 1 May 2005. Prior to its discovery, scientists posited the existence of a moon in Daphnis' position due to the ripples observed along the edge of the Keeler Gap.", + ], + more: [ + "Known as the wavemaker moon, scientists posited the existence of a moon in Daphnis' position due to the ripples observed along the edge of the Keeler Gap. Daphnis has a mean radius of 2.4 miles (3.8 km) and orbits 85,000 miles (136,500 km) from Saturn, completing one orbit in 14 hours. The gravitational pull of tiny inner Saturnian moon Daphnis perturbs the orbits of particles of Saturn's A ring—and sculpting the edge of the Keeler Gap into waves. Material on the inner edge of the gap orbits faster than the moon, so the waves there lead the moon in its orbit. Material on the outer edge moves slower than the moon, so waves there trail the moon. The waves Daphnis causes cast shadows on Saturn during its equinox when the sun is in line with the plane of the rings. Formerly known as S/2005 S1, Daphnis is named for a shepherd, and pipes player who is a pastoral poet in Greek mythology. Daphnis was the son of Hermes, the brother of Pan and a descendent of the Titans.​", + ], + }, + related: ["sc_cassini"], + }, + deimos: { + title: "Deimos", + description: { + blurb: [ + "Deimos is the smaller of Mars' two moons. Being only 9 by 7 by 6.8 miles in size (15 by 12 by 11 kilometers), Deimos whirls around Mars every 30 hours.", + ], + more: [ + "Deimos is a small and lumpy, heavily cratered object. Its craters are generally smaller than 1.6 miles (2.5 kilometers) in diameter, however, and it lacks the grooves and ridges seen on Phobos. Typically when a meteorite hits a surface, surface material is thrown up and out of the resulting crater. The material usually falls back to the surface surrounding the crater. However, these ejecta deposits are not seen on Deimos, perhaps because the moon's gravity is so low that the ejecta escaped to space. Material does appear to have moved down slopes. Deimos also has a thick regolith, perhaps as deep as 328 feet (100 meters), formed as meteorites pulverized the surface. Deimos is a dark body that appears to be composed of C-type surface materials, similar to that of asteroids found in the outer asteroid belt.", + ], + }, + related: [], + }, + desdemona: { + title: "Desdemona", + description: { + blurb: [ + "Desdemona was discovered on Jan. 13 1986 in images taken by Voyager 2. It is one of the 10 Uranian satellites discovered by the Voyager science team.", + ], + more: [ + 'Desdemona is one of the small, inner moons of Uranus. Little is known about it other than its size and orbital characteristics. Neither its size nor its albedo have been measured directly, but assuming an albedo of 0.07 like Puck, its surface probably consists of the dark, unprocessed, carbon-rich material found on the C-class of asteroids. Originally called S/1986 U6, Desdemona was named after the wife of Othello in William Shakespeare\'s play, "Othello, the Moor of Venice." Desdemona is the daughter of a Venetian senator.', + ], + }, + related: ["sc_voyager_2"], + }, + despina: { + title: "Despina", + description: { + blurb: [ + "Despina is a tiny moon located within Neptune's faint ring system. The irregularly-shaped moon orbits Neptune every eight hours, circling in the same direction as Neptune's own rotation. Despina remains close to Neptune's equatorial plane.", + ], + }, + related: ["sc_voyager_2"], + }, + dia: { + title: "Dia", + description: { + blurb: [ + "Dia was discovered in 2000 by using the University of Hawaii's 2.2 m (88 inch) telescope atop Mauna Kea. The moon was then lost in Jupiter's bright glare for several years. Dia was rediscovered in images obtained by the Magellan Telescope in 2010 and 2011.", + ], + more: [ + 'With a prograde orbit and a radius of about 1.2 miles (2 km), Dia is among the smallest member of the Himalia group (made up of Himalia, Leda, Lysithea, and Elara). Dia is a Greek name meaning "she who belongs to Zeus" (who became Jupiter in Roman mythology). Dia was the divine daughter of the seashore. The tiny moon was originally called S/2000 J11 because it is a satellite that was discovered in 2000, and was the 11th satellite of Jupiter to be found that year.​', + ], + }, + }, + dimorphos: { + title: "Dimorphos", + description: { + blurb: [ + "Dimorphos is an asteroid that is part of a binary system with the larger asteroid Didymos, and has an orbital period of 11.9 hours.", + ], + more: [ + "Discovered in 2003, It measures approximately 160 metres (520 ft) in diameter compared to the larger Didymos, at 780 metres (2,560 ft). The DART mission successfully impacted Dimorphos on September 26th, 2022, in order to test the viability of redirecting the orbit of an asteroid. The orbital period of Dimorphos around Didymos was changed by approximately half an hour.", + ], + }, + related: ["sc_dart"], + stats: { + discovery: + "First observed in 2003 (7 years after the discovery of Didymos), Dimorphos is the smaller twin of the Didymos binary asteroid system. The DART mission intentionally crashed into Dimorphos on September 26th, 2022, and successfully altered its orbit.", + rotation: 11.92, + }, + approach: { + fact: "Dimorphos and its binary system are classifed as a PHO (potentially hazardous object), and approached Earth at a distance of 0.07123 AU (astronomical units) on October 4th, 2022.", + }, + }, + dione: { + title: "Dione", + description: { + blurb: [ + "Dione is a small moon orbiting Saturn every 2.7 days at a distance roughly the same as our moon orbits around the Earth.", + ], + more: [ + "About 700 miles (1,100 kilometers) in diameter, Dione's density is 1.48 times that of liquid water, suggesting that about a third of Dione is made up of a dense core (probably silicate rock) with the remainder of its composition being ice. At Dione's average temperature of minus 121 degrees Fahrenheit (minus 186 degrees Celsius or 87 Kelvin), ice is hard as rock. Ice particles as fine as smoke constantly bombard Dione from Saturn's E ring, which is produced by the jets of icy material spraying from Enceladus. So while Enceladus is less than half the diameter of Dione, the smaller moon is altering the surface of the larger moon, painting it with fresh ice dust.", + ], + }, + related: ["sc_cassini", "sc_voyager_1", "saturn"], + }, + sc_dscovr: { + title: "DSCOVR", + description: { + blurb: [ + "DSCOVR (Deep Space Climate Observatory) is an American space weather station that monitors changes in the solar wind, providing space weather alerts and forecasts for geomagnetic storms that could disrupt power grids, satellites, telecommunications, aviation and GPS.", + ], + more: [ + "DSCOVR was launched on Feb.11, 2015, and 100 days later it reached the Sun–Earth L1 Lagrange point and began orbiting about 1 million miles (1.5 million kilometers) from Earth.", + "The satellite has a continuous view of the Sun and the sunlit side of Earth. It takes full Earth pictures about every 2 hours using the Earth Polychromatic Imaging Camera (EPIC) instrument. In October 2015, a website was launched that posts at least a dozen new color images every day from EPIC.", + ], + }, + dates: { + start: "2015-02-11T23:03:02", + end: "", + landing: "", + }, + related: ["sun", "earth"], + }, + eirene: { + title: "Eirene", + description: { + blurb: [ + "Eirene was discovered in February 2003 by Scott Sander Sheppard at the Mauna Kea Observatory in Hawaii, and originally designated S/2003 J5.", + ], + more: [ + "Eirene is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Eirene has a mean radius of about 1.2 miles (2 kilometers). At a mean distance of about 15 million miles (23.5 million kilometers) from Jupiter, the satellite takes about 739 Earth days to complete one orbit. In mythology, Eirene is the goddess of peace and the daughter of Zeus and Themis.​", + ], + }, + }, + elara: { + title: "Elara", + description: { + blurb: [ + "Elara was discovered on Jan. 5, 1905 in photographs taken with the Crossley 36-inch (0.9 meter) reflector of the Lick Observatory on Mount Hamilton at the University of California, San Jose.", + ], + more: [ + "Elara is the eighth largest moon of Jupiter. With a mean radius of 26.7 miles (43 km) assuming an albedo of 0.04, it's only about 2 percent the size of Europa, the smallest of the four Galilean moons. But it's about half as big as Himalia, which makes it the second biggest in the Himalia group, a family of Jovian satellites which have similar orbits and appearance, and are therefore thought to have a common origin. Elara may be a chunk of an asteroid (a C- or D-class asteroid, judging by the fact that it reflects only about 4 percent of the light it receives), which was broken apart in a collision either before or after being captured by Jupiter's gravity. In this scenario, the other pieces became the other moons in the Himalia group: Leda, Himalia (the largest), and Lysithea. A fifth moon, called S/2000 J11, only about 1.2 miles (2 km) in radius, was considered a candidate for this group. However, it was lost before its orbit could be definitively determined. It may have crashed into Himalia, reuniting two pieces of the former asteroid, and perhaps creating a faint temporary ring of Jupiter near the orbit of Himalia. At a distance of about 7.3 million miles (11.7 million km) from Jupiter, Elara takes nearly 260 Earth days to complete one orbit. Elara is named for one of the lovers of Zeus, the Greek equivalent of the Roman god Jupiter. In Greek mythology, Zeus hid her from his wife, Hera, by placing Elara deep beneath the Earth, where she gave birth to their son, a giant called Tityas.", + ], + }, + related: [], + }, + enceladus: { + title: "Enceladus", + description: { + blurb: [ + "One of Saturn's most surprising moons, Enceladus has altered views about where life might exist.", + ], + more: [ + "Few worlds in our solar system are as compelling as Saturn’s icy ocean moon Enceladus. A handful of worlds are thought to have liquid water oceans beneath their frozen shell, but Enceladus sprays its ocean out into space where a spacecraft can sample it. From these samples, scientists have determined that Enceladus has most of thechemical ingredients needed for life, and likely has hydrothermal vents spewing out hot, mineral-rich water into its ocean. About as wide as Arizona, Enceladus also has the whitest,most reflective surface in the solar system. The moon creates a ring of its own as it orbits Saturn—its spray of icy particles spreads out into the space around its orbit, circling the planet to form Saturn’s E ring. In 2005, NASA’s Cassini spacecraft discovered that icy water particles and gas gush from the moon’s surface at approximately 800 miles per hour (400 meters per second). The eruptions appear to be continuous, generating an enormous halo of fine ice dust around Enceladus, which supplies material to Saturn's E-ring. Only a small fraction of the material ends up in the ring, however, with most of it falling like snow back to the moon’s surface, which helps keep Enceladus bright white.The water jets come from relatively warm fractures in the crust, which scientists informally call the “tiger stripes.” Several gases, including water vapor, carbon dioxide, methane, perhaps a little ammonia and either carbon monoxide or nitrogen gas make up the gaseous envelope of the plume, along with salts and silica. And the density of organic materials in the plume was about 20 times denser than scientists expected. From gravity measurements based on the Doppler effect and the magnitude of the moon’s very slight wobble as it orbits Saturn, scientists determined that the jets were being supplied by a global ocean inside the moon. Scientists think that the moon’s ice shell may be as thin as half a mile to 3 miles (1 to 5 kilometers) at the south pole. The average global thickness of the ice is thought to be about 12 to 16 miles (20 to 25 kilometers). Since the ocean in Enceladus supplies the jets, and the jets produce Saturn’s E ring, to study material in the E ring is to study Enceladus’ ocean. The E ring is mostly made of ice droplets, but among them are peculiar nanograins of silica, which can only be generated where liquid water and rock interact at temperatures above about 200 degrees Fahrenheit (90 degrees Celsius). This, among other evidence, points to hydrothermal vents deep beneath Enceladus’ icy shell, not unlike the hydrothermal vents that dot Earth’s ocean floor. With its global ocean, unique chemistry and internal heat, Enceladus has become a promising lead in our search for worlds where life could exist.", + ], + }, + related: ["sc_cassini"], + }, + epimetheus: { + title: "Epimetheus", + description: { + blurb: [ + 'Audouin Dollfus observed a moon on Dec. 15, 1966, for which he proposed the name "Janus." On Dec. 18 of the same year, Richard Walker made a similar observation, now credited as the discovery of Epimetheus.', + ], + more: [ + "Epimetheus is a potato-shaped moon with a mean radius of 36 miles (58 km) and dimensions of 84 x 65 x 65 miles (135 x 108 x 105 km, respectively). Its shape reflects pronounced flattening at the Epimethean South Pole associated with the remains of a large crater. Epimetheus has several craters larger than 19 miles (30 km), including Hilairea and Pollux. This oblong moon orbits 94,000 miles (151,000 km) away from Saturn, taking 17 hours to circle the planet, in the gap between the F and G rings, but it doesn't do this alone. It actually shares its orbit with a sister moon named Janus, in what is called a co-orbital condition or 1:1 resonance. Epimetheus and Janus may have formed by the break-up of one moon. If so, it would have happened early in the life of the Saturn system since both moons have ancient cratered surfaces, many with soft edges because of dust. They also have some grooves (similar to grooves on the Martian moon Phobos) suggesting some glancing blows from other bodies. Together, the moons trail enough particles to generate a faint ring. However, except for very powerful telescopes, the region of their common orbit appears as a gap between Saturn's prominent F and G rings. Epimetheus and Janus are the fifth and sixth moons in distance from Saturn. Both are phase locked with their parent; one side always faces toward Saturn. Being so close, they orbit in less than 17 hours. They are both thought to be composed of largely of water ice, but their density of less than 0.7 is much less than that of water. Thus, they are probably \"rubble piles\" — each a collection of numerous pieces held together loosely by gravity. Each moon has dark, smoother areas, along with brighter areas of terrain. One interpretation of this is that the darker material evidently moves down slopes, leaving shinier material such as water ice on the walls of fractures. Their temperature is approximately -195 degrees Celsius (-319 degrees Fahrenheit). Their reflectivity (or albedo) of 0.7 to 0.8 in the visual range again suggests a composition largely of water ice. Janus and Epimetheus share their orbits with a faint dust ring around Saturn, now called the Janus/Epimetheus Ring. This ring may be made of particles blasted off their surfaces by meteoroid impacts. The name Epimetheus comes from the Greek god (or titan) Epimetheus (or hindsight) who was the brother of Prometheus (foresight). Together, they represented humanity.", + ], + }, + related: ["sc_cassini"], + }, + erinome: { + title: "Erinome", + description: { + blurb: [ + "Erinome was discovered on Nov. 23, 2000 at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Erinome is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99% of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color—light red—except for Kalyke, which is considerably redder than the others. All of these characteristics support the idea that the Carme satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Carme members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped.vErinome has a mean radius of about one mile (1.6 km). At a mean distance of about 14.4 million miles (23.2 million km) from Jupiter, the satellite takes about 728 Earth days to complete one orbit. Originally called S/2000 J4, Erinome was named for a chaste young woman in Roman mythology whom Venus causes to fall in love with Jupiter. She loses her virginity to Adonis, however, after Venus throws a fog on her. This displeases the goddess Diana, who turns Erinome into a peacock. Adonis, realizing he has assaulted a love of Jupiter, flees into the woods, but is driven out by Mercury. Just as Adonis is about to defeat Mercury in a violent fight, Jupiter throws a lightning bolt and kills him.", + ], + }, + related: [], + }, + erriapus: { + title: "Erriapus", + description: { + blurb: [ + "Erriapus was discovered on Sept. 23, 2000 at the Mauna Kea Observatory on the island of Hawaii.", + ], + more: [ + "Erriapus has a mean radius of 3.1 miles (5 kilometers) assuming an albedo (a measure of how reflective the surface is) of 0.06. At a mean distance of 10.9 million miles (17.6 million kilometers) from Saturn, the moon takes about 871 Earth days to complete one orbit. Erriapus is one of the four known members of the Gallic group of moons. These moons have prograde orbits (they travel around Saturn in the same direction as the planet's rotation), but their egg-shaped, angled orbits classify them as \"irregular\" moons. Like Saturn's other irregular moons, they are thought to be objects that were captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet, as the regular moons are thought to have done. The similarities among the orbits of moons in the Gallic group suggest a common origin—they may be fragments of a single object that shattered in a collision. The other members of this group are Albiorix, Bebhionn and Tarvos. Observations by Tommy Grav and James Bauer using telescopes on Mauna Kea, Hawaii in 2006 found that the color of Albiorix varies over its surface. They hypothesize that Tarvos and Erriapus, which were both seen to be light red, are the largest fragments from an impact on Albiorix, leaving a less-red crater. (These observations did not include Bebhionn.) Moons of Saturn were originally named for Greco-Roman Titans and descendants of the Titans. But as many new moons were discovered scientists began selecting names from more mythologies, including Gallic, Inuit and Norse stories. Erriapus, originally designated S/2000 10, is named for a Gallic giant. It was named Erriapo in August 2003, but the name was changed from Erriapo to the nominative Erriapus per International Astronomical Union conventions in late 2007.​", + ], + }, + related: [], + }, + ersa: { + title: "Ersa", + description: { + blurb: [ + "This tiny moon of Jupiter was first spotted in 2017 and originally designated S/2018 J1.", + ], + more: [ + "The discovery announcement was made in July 2018. In mythology, Ersa is the sister of Pandia and, as such, also the daughter of Zeus and the Moon goddess Selene. Ersa is the goddess of dew.​", + ], + }, + }, + euanthe: { + title: "Euanthe", + description: { + blurb: [ + "Euanthe was discovered on Dec. 11, 2001 by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Euanthe is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter's gravity and then suffered a collision, which broke off a number of pieces. The largest remaining chunk was named \"Ananke,\" and the smaller pieces became the other 15 moons in the Ananke group. All of the Ananke moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and rather highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Ananke satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Ananke members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Euanthe has a mean radius of just under one mile (about 1.5 kilometers), assuming an albedo of 0.04. At a mean distance of about 13 million miles (21 million kilometers) from Jupiter, it takes about 620 Earth days to complete one orbit. Originally called S/2001 J7, Euanthe was given one of the names in Greek mythology for the mother of the Graces by Zeus, the Greek equivalent of the Roman god Jupiter.", + ], + }, + related: [], + }, + eukelade: { + title: "Eukelade", + description: { + blurb: [ + "Eukelade was discovered on Feb. 6, 2003, by Scott S. Sheppard at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Eukelade is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99% of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color—light red —except for Kalyke, which is considerably redder than the others. All of these characteristics support the idea that the Carme satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Carme members are massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Eukelade has a mean radius of about 1.2 miles (2 kilometers). At a mean distance of about 14.4 million miles (23.3 million kilometers) from Jupiter, the satellite takes about 730 Earth days to complete one orbit. Originally called S/2003 J1, Eukelade was named for one of the Muses, who were daughters of Zeus, the Greek equivalent of the Roman god Jupiter. Her name means \"well sounding.\"", + ], + }, + related: [], + }, + eupheme: { + title: "Eupheme", + description: { + blurb: [ + "Eupheme was discovered Mar. 4, 2003 at the Mauna Kea Observatory in Hawaii, and originally designated S/2003 J3.", + ], + more: [ + "Eupheme has a mean radius of about less than a mile or about one kilometer, (assuming an albedo of 0.04). At a mean distance of about 13 million miles (20.2 million kilometers) from Jupiter, it takes about 584 Earth days to complete one orbit. In mythology, Eupheme is the spirit of praise and good omen, the granddaughter of Zeus, and the sister of Philophrosyne.​", + ], + }, + }, + euporie: { + title: "Euporie", + description: { + blurb: [ + "Euporie was discovered on Dec. 11, 2001 by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Euporie is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter's gravity and then suffered a collision, which broke off a number of pieces. The largest remaining chunk was named \"Ananke,\" and the smaller pieces became the other 15 moons in the Ananke group. All of the Ananke moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and rather highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Ananke satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Ananke members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Euporie has a mean radius of about 0.6 miles (one kilometer), assuming an albedo of 0.04. At a mean distance of about 11.9 million miles (19.3 million kilometers) from Jupiter, it takes about 551 Earth days to complete one orbit. Originally called S/2001 J10, Euporie was named for one of the Horae (seasons), who were daughters of the Roman god Jupiter, and a Titaness named Themis. Euporie means plenty.", + ], + }, + related: [], + }, + europa: { + title: "Europa", + description: { + blurb: [ + "Europa may be the most promising place in our solar system to find present-day environments suitable for some form of life beyond Earth.", + ], + more: [ + "Scientists are almost certain that hidden beneath the icy surface of Europa is a salty-water ocean thought to contain twice as much water as Earth’s oceans combined. Slightly smaller than Earth's Moon, Europa’s water-ice surface is crisscrossed by long, linear fractures, cracks, ridges, and bands. The moon’s ice shell is probably 10 to 15 miles (15 to 25 kilometers) thick, beneath which the ocean is estimated to be 40 to 100 miles (60 to 150 kilometers) deep. Like Earth, Europa is thought to also contain a rocky mantle and iron core. Europa’s water-ice surface is crisscrossed by long, linear fractures. Based on the small number of observable craters, the surface of this moon appears to be no more than 40 to 90 million years old, which is youthful in geologic terms (the surface of Callisto, another of Jupiter’s moons, is estimated to be a few billion years old). Along Europa's many fractures, and in splotchy patterns across its surface, is a reddish-brown material whose composition is not known for certain, but likely contains salts and sulfur compounds that have been mixed with the water ice and modified by radiation. This surface composition may hold clues to the moon's potential as a habitable world.", + ], + }, + related: [ + "sc_pioneer_10", + "sc_pioneer_11", + "sc_voyager_1", + "sc_voyager_2", + "sc_galileo", + ], + }, + eurydome: { + title: "Eurydome", + description: { + blurb: [ + "Eurydome was discovered on Dec. 9, 2001 by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Eurydome is considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. Most or all of the Pasiphae satellites are thought to have begun as a single asteroid that, after being captured by Jupiter's gravity, suffered a collision which broke off a number of pieces. The bulk of the original asteroid survived as the moon called Pasiphae, and the other pieces became some or all of the other moons in the group. All of the Pasiphae moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Pasiphae satellites began as one or more captured asteroids, rather than forming as part of the original Jupiter system. Eurydome has a mean radius of about 0.9 miles (1.5 kilometers), assuming an albedo of 0.04. At a mean distance of about 14.3 million miles (23.1 million kilometers) from Jupiter, the satellite takes about 717 Earth days to complete one orbit. Originally called S/2001 J4, Eurydome was named for a character in Greek mythology who, according to some sources, was the mother of the Graces by Zeus, the Greek equivalent of the Roman god Jupiter.", + ], + }, + related: [], + }, + farbauti: { + title: "Farbauti", + description: { + blurb: [ + "Farbauti was discovered on Dec. 12, 2004, one of 12 Saturnian moons found that day using wide-field camera on the Subaru 8.3-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Farbauti has a mean radius of about 1.6 miles (2.5 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 158 degrees and an eccentricity of about 0.2. At a mean distance of 12.7 million miles (20.4 million kilometers) from Saturn, the moon takes about 1,087 Earth days to complete one orbit. Farbauti is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn—traveling around in the opposite direction from the planet's rotation. Farbauti and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Farbauti is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Farbauti appears to be a member of a subgroup that also includes Skoll, Hyrrokkin, S/2006 S1, Bergelmir, Skathi, S/2006 S3, and Kari. Originally called S/2004 S9, Farbauti was named for a giant in Norse mythology who was the father of Loki, who was known as the disgrace of the gods.", + ], + }, + related: [], + }, + fenrir: { + title: "Fenrir", + description: { + blurb: [ + "Fenrir was discovered on Dec. 12, 2004, one of 12 Saturnian moons found that day using a wide-field camera on the Subaru 8.2-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Fenrir has a mean radius of 1.2 miles (2.0 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 164 degrees and an eccentricity of about 0.1. At a mean distance of 14 million miles (22.5 million kilometers) from Saturn, the moon takes about 1,260 Earth days to complete one orbit. Fenrir is a member of the Norse group of moons. Thes \"irregular\" moons have retrograde orbits around Saturn—traveling around in the opposite direction from the planet's rotation. Fenrir and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Saturn's other irregular moons, Fenrir is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2004 S16, Fenrir was named for a monstrous wolf in Norse mythology who was the offspring of Loki, the disgrace of the gods, and Angrboda, a disagreeable giantess. The gods managed to bind Fenrir using a dwarf-manufactured fetter made of the sound of a cat's footfall, a woman's beard and other hard-to-find components. According to the mythology, Fenrir is destined to break free at doomsday (the time known as Ragnarok) and kill Odin, the supreme Norse god.", + ], + }, + related: [], + }, + galatea: { + title: "Galatea", + description: { + blurb: [ + "Galatea is another of Neptune's tiny moons. Small and irregularly-shaped like Despina, Galatea orbits in the same direction as Neptune and is relatively close to the gas giant's equatorial plane. The small moon's gravity is believed to cause disturbances in Neptune's ring system. It was found in the same month scientists discovered ring arcs, or partial rings, that were suspected to exist around Neptune.", + "Galatea circles Neptune every 10 hours and 18 minutes.", + ], + }, + related: ["sc_voyager_2"], + }, + ganymede: { + title: "Ganymede", + description: { + blurb: [ + "Jupiter's moon Ganymede is the largest moon in our solar system and the only moon with its own magnetic field.", + ], + more: [ + "The magnetic field of Ganymede causes auroras, which are ribbons of glowing, electrified gas, in regions circling the moon’s north and south poles. Ganymede has large, bright regions of ridges and grooves that slice across older, darker terrains. These grooved regions are a clue that the moon experienced dramatic upheavals in the distant past. Scientists have also found strong evidence of an underground ocean on Ganymede. Ganymede was discovered by Galileo Galilei on Jan. 7, 1610. The discovery, along with three other Jovian moons, was the first time a moon was discovered orbiting a planet other than Earth. The discovery of the four Galilean satellites eventually led to the understanding that planets in our solar system orbit the sun, instead of our solar system revolving around Earth.", + ], + }, + related: [ + "sc_pioneer_10", + "sc_pioneer_11", + "sc_voyager_1", + "sc_voyager_2", + "sc_galileo", + "sc_juno", + ], + }, + greip: { + title: "Greip", + description: { + blurb: [ + "Greip was discovered on March 6, 2006 by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna using the Subaru 8.3-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Greip has a mean radius of 1.9 miles (3 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 173 degrees and an eccentricity of about 0.3. At a mean distance of 11.5 million miles (18.4 million kilometers) from Saturn, the moon takes about 936 Earth days to complete one orbit. Greip is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn—traveling around in the opposite direction from the planet's rotation. Greip and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Greip is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2006 S4, Greip was named for one of the nine giantesses who gave birth to Heimdall, the guard of the rainbow bridge that links our world to Asgard, home of the Norse gods.", + ], + }, + related: [], + }, + c_1995_o1: { + title: "Hale-Bopp", + description: { + blurb: [ + "Comet Hale-Bopp was visible to the naked eye for 18 months in 1996 and 1997. It has a large nucleus of 37 miles (60 km) and orbits the sun every 2,534 years.", + ], + more: [ + "On July 23, 1995, an unusually bright comet outside of Jupiter's orbit (7.15 AU) was discovered independently by Alan Hale, New Mexico and Thomas Bopp, Arizona. The new comet, designated C/1995 O1, is the farthest comet ever discovered by amateurs and appeared 1000 times brighter than Comet Halley did at the same distance. Normally, comets are inert when they are beyond the orbit of Jupiter, so it has been speculated that Comet Hale-Bopp is either a rather large comet or experienced a bright outburst (or both). The comet is the brightest comet since Comet West in 1976.", + ], + }, + related: [], + }, + ferdinand: { + title: "Ferdinand", + description: { + blurb: [ + "Ferdinand is a very small, dark moon which orbits Uranus at a greater distance than any other known satellite of that planet.", + ], + }, + related: [], + }, + fornjot: { + title: "Fornjot", + description: { + blurb: [ + "Fornjot was discovered on Dec. 12 2004, one of 12 Saturnian moons found that day using a wide-field camera on the Subaru 8.2-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Fornjot has a mean radius of 1.9 miles (3 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 170 degrees and an eccentricity of about 0.2. At a mean distance of 15.6 million miles (25.2 million kilometers) from Saturn, the moon takes about 1,494 Earth days to complete one orbit. Fornjot is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn—traveling around in the opposite direction from the planet's rotation. Fornjot and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Fornjot is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2004 S8, Fornjot was named for the giant (also called Forniot) in Norse mythology who was father to the giants and commanded the wind, the sea and fire.", + ], + }, + related: [], + }, + francisco: { + title: "Francisco", + description: { + blurb: [ + "Francisco is a very small, dark moon which orbits Uranus in the opposite direction from the regular moons and the planet's own rotation (a retrograde orbit).", + ], + }, + related: [], + }, + halimede: { + title: "Halimede", + description: { + blurb: [ + "Halimede is one of three tiny moons (ranging in size from 30 to 40 km -- or 18 to 24 miles) of Neptune discovered in 2002 using innovative ground-based telescope techniques. (The other moons discovered were Laomedeia and Sao.) The moons are so distant and so small they are about 100 million times fainter than can be seen with the unaided eye. The moons were missed by the Voyager 2 spacecraft in 1989 because they are so faint and distant from Neptune.", + "Halimede is considered an irregular satellite because of its distant, eccentric orbit around Neptune. Like most irregular satellites of the giant planets in our outer solar system, Halimede most likely formed after a collision between a larger moon and a comet or an asteroid. Sao and Laomedeia have prograde orbits, which means they orbit in the same direction as Neptune's rotation. Halimede has a retrograde orbit, which means Halimede orbits in the opposite direction of Neptune's rotation.", + "Very little is known about Halimede. Scientists are trying to learn more about it and its irregular sisters because they offer a glimpse of the conditions at the time the planets in our solar system were forming billions of years ago.", + ], + }, + related: [], + }, + harpalyke: { + title: "Harpalyke", + description: { + blurb: [ + "Harpalyke was discovered Nov. 23, 2000 by Scott S. Sheppard, David C. Jewitt, Yanga R. Fernandez, and Eugene Magnier at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Harpalyke is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter's gravity and then suffered a collision, which broke off a number of pieces. The largest remaining chunk was named \"Ananke,\" and the smaller pieces became the other 15 moons in the Ananke group. All of the Ananke moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and rather highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Ananke satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Ananke members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Harpalyke has a mean radius of about 1.3 miles (2.2 kilometers), assuming an albedo of 0.04. It is colored a similar gray to two other moons in the Ananke family: Praxidike and Iocaste. At a mean distance of about 13.1 million miles (21.1 million kilometers) from Jupiter, Harpalyke takes about 623 Earth days to complete one orbit. Originally called S/2000 J5, Harpalyke was named for a woman in Greek mythology who was transformed into a night bird called Chalcis. According to one version of the story, this transformation happened after she had intercourse with Zeus, the Greek equivalent of the Roman god Jupiter. In another version, she had incestuous relations with her father. In revenge, she killed her younger brother or her son (depending on the account), carved him up, cooked the meat and served it to her father, who ultimately kills himself.", + ], + }, + related: [], + }, + hati: { + title: "Hati", + description: { + blurb: [ + "Hati was discovered on Dec. 12, 2004, one of 12 Saturnian moons found that day using a wide-field camera on the Subaru 8.2-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Hati has a mean radius of 1.9 miles (3 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 165 degrees and an eccentricity of about 0.4. At a mean distance of 12.3 million miles (19.8 million kilometers) from Saturn, the moon takes about 1,039 Earth days to complete one orbit. Its rotational period is just 5.5 hours, the fastest known rotation of all of Saturn's moons. Hati is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn—traveling around in the opposite direction from the planet's rotation. Hati and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Hati is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2004 S14, Hati was named for a giant wolf in Norse mythology who pursues the Moon (that is, the Moon chariot and the boy who drives it—see Mundilfari for an explanation) across the sky. According to the mythology, Hati is destined to catch and devour them at the doomsday time known as Ragnarok.", + ], + }, + related: [], + }, + hegemone: { + title: "Hegemone", + description: { + blurb: [ + "Hegemone was discovered on Feb. 8, 2003 by Scott S. Sheppard, David C. Jewitt, Jan T. Kleyna, Yanga R. Fernandez, and Henry H. Hsieh at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Hegemone is considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. Most or all of the Pasiphae satellites are thought to have begun as a single asteroid that, after being captured by Jupiter's gravity, suffered a collision which broke off a number of pieces. The bulk of the original asteroid survived as the moon called Pasiphae, and the other pieces became some or all of the other moons in the group. All of the Pasiphae moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Pasiphae satellites began as one or more captured asteroids, rather than forming as part of the original Jupiter system. Hegemone has a mean radius of about 0.93 miles (1.5 kilometers), assuming an albedo of 0.04. At a mean distance of about 14.6 million miles (23.6 million kilometers) from Jupiter, the satellite takes about 740 Earth days to complete one orbit. Originally called S/2003 J8, Hegemone was named for one of the Graces (according to the Athenians), who were daughters of Zeus, the Greek equivalent of the Roman god Jupiter. The name means \"female leader.\"", + ], + }, + related: [], + }, + helene: { + title: "Helene", + description: { + blurb: [ + "Helene was discovered on March 1, 1980 during the Earth ring-plane crossing by J. Lecacheux and others.", + ], + more: [ + 'Helene, a small and faint moon of Saturn, is referred to as a Trojan moon because it shares its orbit with another moon—Dione, a moon hundreds of times larger than Helene. This complex orbital arrangement is held steady by gravity: Helene is located at a Lagrange point, where it feels the tug of gravity equally from distant Saturn and nearby Dione. For this reason, soon after it was discovered in 1980 it was called Dione B. This irregularly shaped moon has a mean radius of 10.9 miles (17.6 kilometers) with dimensions 22 x 19 x 18.6 miles (36 x 32 x 30 km). It orbits 234,505 miles (377,400 kilometers) away from Saturn, taking 2.7 Earth days to complete one orbit. John Herschel suggested that the moons of Saturn be associated with mythical brothers and sisters of Kronus. (Kronus is the equivalent of the Roman god Saturn in Greek mythology.) The International Astronomical Union now controls the official naming of astronomical bodies. Originally designated S/1980 S6, Helene is named after the granddaughter of Kronus and is the sister of Polydeuces. Helene was born out of an egg since Zeus took the shape of a swan when he raped her mother Leda. The account of this engendering is retold in the poem "Leda and the Swan" by William Butler Yeats. This same figure in Greek mythology was the cause of the Trojan War.', + ], + }, + related: ["sc_cassini"], + }, + helike: { + title: "Helike", + description: { + blurb: [ + "Helike was discovered on Feb. 6, 2003 by Scott S. Sheppard at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Helike is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter's gravity and then suffered a collision, which broke off a number of pieces. The largest remaining chunk was named \"Ananke,\" and the smaller pieces became the other 15 moons in the Ananke group. All of the Ananke moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and rather highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Ananke satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Ananke members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Helike has a mean radius of about 1.2 miles (2 kilometers), assuming an albedo of 0.04. At a mean distance of about 13.1 million miles (21.1 million kilometers) from Jupiter, it takes about 626 Earth days to complete one orbit. Originally called S/2003 J6, Helike was named for one of the Muses, who were daughters of Zeus, the Greek equivalent of the Roman god Jupiter. Helike is also the name of a nymph in Greek mythology who helped to nurse Zeus and was transferred to the stars as a reward. There, she became the constellation, the Great Bear.", + ], + }, + related: [], + }, + hermippe: { + title: "Hermippe", + description: { + blurb: [ + "Hermippe was discovered in Dec. 9, 2001 by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Hermippe is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter's gravity and then suffered a collision, which broke off a number of pieces. The largest remaining chunk was named \"Ananke,\" and the smaller pieces became the other 15 moons in the Ananke group. All of the Ananke moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and rather highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Ananke satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Ananke members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Hermippe has a mean radius of about 1.2 miles (2 kilometers). At a mean distance of about 13.2 million miles (21.3 million kilometers) from Jupiter, it takes about 634 Earth days to complete one orbit. Originally called S/2001 J3, Hermippe was named for one of the many lovers of Zeus, the Greek equivalent of the Roman god Jupiter. She bore him a son named Orchomenos.", + ], + }, + related: [], + }, + herse: { + title: "Herse", + description: { + blurb: [ + "Herse was discovered on Feb. 27, 2003 by Brett J. Gladman, John J. Kavelaars, Jean-Marc Petit, and Lynne Allen.", + ], + more: [ + "Herse is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99% of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color -- light red -- except for Kalyke, which is considerably redder than the others. All of these characteristics support the idea that the Carme satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Carme members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Herse has a mean radius of about 0.62 miles (one kilometer). At a mean distance of about 14.5 million miles (23.4 million kilometers) from Jupiter, the satellite takes more than 734 Earth days to complete one orbit. Originally called S/2003 J17, Herse was named for a daughter of Selene (goddess of the moon) and Zeus, the Greek equivalent of the Roman god Jupiter.", + ], + }, + related: [], + }, + hiiaka: { + title: "Hi'iaka", + description: { + blurb: ["Hi'iaka is a moon of the dwarf planet Haumea."], + more: [""], + }, + related: [], + }, + himalia: { + title: "Himalia", + description: { + blurb: [ + "Himalia was discovered on December 3, 1904 in photographs taken with the Crossley 36-inch (0.9 meter) reflector of the Lick Observatory on Mount Hamilton at the University of California, San Jose.", + ], + more: [ + "Himalia is the fifth largest moon orbiting Jupiter. With a mean radius of 85 km assuming an albedo of 0.04), it's only about 5% the size of the fourth largest moon, Europa. But it's by far the largest member of the Himalia group, a family of Jovian satellites which have similar orbits and appearance, and are therefore thought to have a common origin. Himalia may be the largest remaining chunk of an asteroid (a C- or D-class asteroid, judging by the fact that it reflects only about 4% of the light it receives), which had several pieces broken off in a collision either before or after being captured by Jupiter's gravity. In this scenario, those pieces became the other moons in the Himalia group: Leda, Lysithea and Elara. A fifth moon, called S/2000 J11, only about 1.2 miles (2 kilometers) in radius, was considered a candidate for this group. However, it was lost before its orbit could be definitively determined. It may have crashed into Himalia, reuniting two pieces of the former asteroid, and perhaps creating a faint temporary ring of Jupiter near the orbit of Himalia. At a distance of about 7.1 million miles (11.5 million kilometers) from Jupiter, Himalia takes about 251 Earth days to complete one orbit. Himalia was named for a nymph of the island of Rhodes in Greek mythology who was one of the lovers of Zeus (the Greek equivalent of the Roman god Jupiter). She bore him three sons: Spartaeus, Cronios and Cytus.", + ], + }, + related: ["sc_cassini"], + }, + hippocamp: { + title: "Hippocamp", + description: { + blurb: [ + "Hippocamp, originally designated S/2004 N1, was discovered by Mark Showalter on July 1, 2013 using Hubble Space Telescope images taken of the Neptune system between 2004 and 2009.", + ], + more: [ + "Hippocamp is unusually close to a much larger Neptunian moon called Proteus. Normally, a moon like Proteus should have gravitationally swept aside or swallowed the smaller moon while clearing out its orbital path. Scientists think Hippocamp is likely a chipped-off piece of the larger moon that resulted from a collision with a comet billions of years ago. The diminutive moon, only 20 miles (about 34 kilometers) across, is 1/1000th the mass of Proteus (which is 260 miles [about 418 kilometers] across). Hippocamp is much smaller than any of Neptune's previously known satellites, and below the detection threshold of the Voyager cameras sent there in 1989. The moon is so small and dim that itis roughly 100 million times fainter than the faintest star that can be seen with the naked eye. The moon orbits Neptune every 23 hours. It is nestled between the orbits of Larissa and Proteus.", + ], + }, + related: [], + }, + hydra: { + title: "Hydra", + description: { + blurb: [ + "Hydra was discovered in June, 2005 by Hal Weaver and a large team of astronomers using the Hubble Space Telescope.", + ], + more: [ + "Hydra is the outer of the two moons discovered orbiting Pluto in 2005. Nix and Hydra are roughly 5,000 times fainter than Pluto and are about two to three times farther from Pluto than its large moon, Charon, which was discovered in 1978. Nix and Hydra are roughly 20 to 70 miles (32 to 113 km) wide. They are so faint so small and so faint that scientists combined a short exposure of Pluto and Charon and a long exposure of Nix and Hydra to create images of them all together. Hydra was named for the nine-headed serpent that Hercules fought in Greek and Roman mythology.", + ], + }, + related: ["sc_new_horizons"], + }, + hyperion: { + title: "Hyperion", + description: { + blurb: [ + "Hyperion is the largest of Saturn's irregular, nonspherical moons.", + ], + more: [ + "Hyperion's mean radius is 83.9 miles (135 kilometers), but since Hyperion is rather potato-shaped, its shape can be described in terms of its diameter along its three axes: 255 x 163 x 137 miles (410 x 260 x 220 kilometers, respectively). Considering its odd shape, Hyperion is probably a remnant of a larger moon that was destroyed by a major impact. Hyperion's density is slightly more than half that of water. This could be due to water ice with gaps (porosity) of more than 40 percent. Also, lighter materials, such as frozen methane or carbon dioxide, could make up part of Hyperion. This is consistent with the concept of Hyperion accreting from a number of smaller ice and rock bodies, but not having enough gravity to compact them. Thus, Hyperion might be similar to a large rubble pile. Hyperion rotates chaotically, tumbling unpredictably through space as it orbits Saturn. The most noticeable close-up feature of Hyperion is its deeply cratered surface. Hyperion and its sister outer moons, Phoebe and Iapetus, all show extensive cratering because they are Saturn's most distant moons and have experienced very little tidal warming that might blur or erase earlier features. However, the Hyperion craters are particularly deep and do not have significant rays of ejecta (although there appears to have been slumping or landslides inside many of the bigger craters). The result is a curiously punched-in look, somewhat like the surface of a sponge or a wasp nest. Planetary geologists have theorized that Hyperion's high-porosity and low density would crater more by compression than excavation.", + ], + }, + related: ["sc_cassini"], + }, + hyrrokkin: { + title: "Hyrrokkin", + description: { + blurb: [ + "Hyrrokkin was discovered on Dec. 12, 2004 using the Subaru 8.3-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Hyrrokkin has a mean radius of 1.9 miles (3 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 151 degrees and an eccentricity of about 0.3. At a mean distance of 11.5 million miles (18.4 million kilometers) from Saturn, the moon takes about 932 Earth days to complete one orbit. Hyrrokkin is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn -- traveling around in the opposite direction from the planet's rotation. Hyrrokkin and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Hyrrokkin is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Hyrrokkin appears to be a member of a subgroup that also includes Skathi, Skoll, S/2006 S1, Bergelmir, Farbauti, S/2006 S3, and Kari. Originally called S/2004 S19, Hyrrokkin was named for giantess in Norse mythology who launched Baldur's enormous funeral ship with one mighty push when the gods, themselves, were unable to budge it", + ], + }, + related: ["sc_cassini"], + }, + iapetus: { + title: "Iapetus", + description: { + blurb: [ + "Iapetus, the third largest moon of Saturn, is known for having a bright half and a dark half, with the leading hemisphere being dark.", + ], + more: [ + "Iapetus has been called the yin and yang of the Saturn moons because its leading hemisphere has a reflectivity (or albedo) as dark as coal (albedo 0.03-0.05 with a slight reddish tinge) and its trailing hemisphere is much brighter at 0.5-0.6.", + "Saturn's third largest moon, Iapetus has a mean radius of 457 miles (736 kilometers) and a density only 1.2 times that of liquid water. It has been suggested that Iapetus (like Rhea) is three quarters ice and one quarter rock.Iapetus orbits at 2,213,000 miles (3,561,000 kilometers) from Saturn. The great distance from Saturn's tidal forces and from most of the other moons and ring particles has probably allowed the Iapetus surface to be largely unaffected by any melting episodes that could have caused some smoothing or \"resurfacing\" as on some of the moons closer to Saturn.", + "However, despite the great distance, Saturn has tidally locked Iapetus. The moon always presents the same face toward Saturn. With its distant, inclined orbit, Iapetus is the only large moon from which there is a nice view of the rings of Saturn.Giovanni Cassini observed the dark-light difference of this moon's surface when he discovered Iapetus in 1671. He noted that he could only see Iapetus on the west side of Saturn. He correctly concluded that Iapetus had one side much darker than the other side, and that Iapetus was tidally locked with Saturn.", + "Scientists have long wondered why one hemisphere of Iapetus is so dark in comparison to its other hemisphere, and in comparison to other surfaces in the Saturn system. Iapetus may be sweeping up particles from the more-distant dark moon, Phoebe. If that is the darkening mechanism, it should be steadily renewing the dark surface because very few fresh bright craters are detected within the dark terrain. An alternate theory is that there might be ice volcanism distributing darker material to the surface. Volcano-like eruptions of hydrocarbons might form the dark surfaces, particularly after chemical reactions caused by solar radiation.", + "The September 2007 Cassini flyby of Iapetus showed that a third process, thermal segregation, is probably the most responsible for Iapetus' dark hemisphere. Iapetus has a very slow rotation, longer than 79 days. Such a slow rotation means that the daily temperature cycle is very long, so long that the dark material can absorb heat from the sun and warm up. (The dark material absorbs more heat than the bright icy material.) This heating will cause any volatile, or icy, species within the dark material to sublime out, and retreat to colder regions on Iapetus. This sublimation of volatiles causes the dark material to become even darker -- and causes neighboring bright, cold regions to become even brighter. Iapetus may have experienced a (possibly small) influx of dark material from an external source, which could have warmed up and triggered this thermal segregation process.", + 'The second most notable feature of Iapetus is its "equatorial ridge", a chain of 6-mile (10-km) high mountains girdling the moon\'s equator. On the anti-Saturnian side of Iapetus, the ridge appears to break up and distinct, partially bright mountains are observed. The Voyager I and Voyager II encounters provided the first knowledge of these mountains, and they are informally referred to as the Voyager Mountains.', + "There are two theories on how the ridge formed. Some scientists think the ridge was formed at an earlier time when Iapetus rotated much faster than it does today; others think the ridge is made of material left from the collapse of a ring.", + ], + }, + related: ["sc_cassini"], + }, + io: { + title: "Io", + description: { + blurb: [ + "Jupiter's moon Io is the most volcanically active world in the Solar System, with hundreds of volcanoes, some erupting lava fountains dozens of miles (or kilometers) high.", + ], + more: [ + "Io’s remarkable activity is the result of a tug-of-war between Jupiter's powerful gravity and smaller but precisely timed pulls from two neighboring moons that orbit farther from Jupiter – Europa and Ganymede. A bit larger than Earth's Moon, Io is the third largest of Jupiter's moons, and the fifth one in distance from the planet. Although Io always points the same side toward Jupiter in its orbit around the giant planet, the large moons Europa and Ganymede perturb Io's orbit into an irregularly elliptical one. Thus, in its widely varying distances from Jupiter, Io is subjected to tremendous tidal forces.", + "These forces cause Io's surface to bulge up and down (or in and out) by as much as 330 feet (100 meters). Compare these tides on Io's solid surface to the tides on Earth's oceans. On Earth, in the place where tides are highest, the difference between low and high tides is only 60 feet (18 meters), and this is for water, not solid ground.", + "Io's orbit, keeping it at more or less a cozy 262,000 miles (422,000 kilometers) from Jupiter, cuts across the planet's powerful magnetic lines of force, thus turning Io into an electric generator. Io can develop 400,000 volts across itself and create an electric current of 3 million amperes. This current takes the path of least resistance along Jupiter's magnetic field lines to the planet's surface, creating lightning in Jupiter's upper atmosphere.", + ], + }, + related: [ + "sc_pioneer_10", + "sc_pioneer_11", + "sc_voyager_1", + "sc_voyager_2", + "sc_galileo", + "sc_cassini", + ], + }, + ijiraq: { + title: "Ijiraq", + description: { + blurb: [ + "Ijiraq is a minor moon of Saturn and was discovered on Sept. 23, 2000.", + ], + more: [ + "Ijiraq has a mean radius of 3.7 miles (6 kilometers) and it takes about 452 Earth days to complete one orbit. Ijiraq is one of five known members of the Inuit group of moons, which orbit Saturn at a mean distance of 7 to 11 million miles. The Inuit moons all have prograde orbits (they travel around Saturn in the same direction as the planet's rotation), but their deviations from circular orbits and from the plane of Saturn's equator classify them as \"irregular\" moons. The similarities among the Inuit group's orbits suggest a common origin -- they may be fragments of a single object that shattered in a collision. The other members of this group are Kiviuq, Paaliaq, Siarnaq, and Tarqeq. Ijiraq is redder than Kiviuq, Siarnaq and Paaliaq, and lacks the feature these other moons display at the deep red wavelength of 0.7 micrometers. Originally called S/2000 S6, Ijiraq was named for a fictional character in the children's book, \"Hide and Sneak\" by Michael Arvaarluk Kusugak.", + ], + }, + related: [], + }, + iocaste: { + title: "Iocaste", + description: { + blurb: [ + "Iocaste was discovered Nov. 23, 2000 by Scott S. Sheppard, David C. Jewitt, Yanga R. Fernandez, and Eugene Magnier at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Iocaste is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter's gravity and then suffered a collision, which broke off a number of pieces. The largest remaining chunk was named \"Ananke,\" and the smaller pieces became the other 15 moons in the Ananke group. All of the Ananke moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and rather highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Ananke satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Ananke members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Iocaste has a mean radius of about 1.6 miles (2.6 kilometers), assuming an albedo of 0.04. It is colored a similar gray to two other moons in the Ananke family: Praxidike and Harpalyke. At a mean distance of about 13.2 million miles (21.3 million kilometers) from Jupiter, Iocaste takes about 632 Earth days to complete one orbit. Originally called S/2000 J3, Iocaste was named for the mother of Agamedes by the Roman god, Jupiter.", + ], + }, + related: [], + }, + isonoe: { + title: "Isonoe", + description: { + blurb: [ + "Isonoe was discovered Nov. 23, 2000, by Scott S. Sheppard, David C. Jewitt, Yanga R. Fernandez, and Eugene Magnier at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Isonoe is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99% of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. None of the Carme members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Isonoe has a mean radius of about 1.1 miles (1.9 kilometers). At a mean distance of about 14.4 million miles (23.2 million kilometers) from Jupiter, the satellite takes about 726 Earth days to complete one orbit. Originally called S/2000 J6, Isonoe was named for the mother of Orchomenus by Zeus, the Greek equivalent of the Roman god Jupiter. Isonoe was one of the 50 daughters of Danaus in Greek legend. Danaus agreed to the marriage of his 50 daughters to the 50 sons of Aegyptus, his twin brother, but commanded his daughters to kill their new husbands in their sleep on their wedding night. All but one complied. For some reason, Danaus had difficulty finding suitors for his daughters after that, so he offered them as prizes in a foot race. Danaus' daughters were ultimately condemned in Hades to endlessly attempt to fill a bottomless water vessel.", + ], + }, + related: [], + }, + janus: { + title: "Janus", + description: { + blurb: [ + 'Audouin Dollfus observed a moon on Dec. 15, 1966, for which he proposed the name "Janus."', + ], + more: [ + "Janus is a potato-shaped moon with a mean radius of 55.6 miles (89.5 kilometers) and dimensions of 122 x 119 x 93 miles (196 x 192 x 150 kilometers, respectively). Janus is extensively cratered with several craters larger than 19 miles (30 kilometers). Janus' prominent craters are named Castor, Phoebe, Idas and Lynceus. This oblong moon orbits 94,000 miles (151,000 kilometers) away from Saturn, taking 17 hours to complete one orbit, in the gap between the F and G rings, but it doesn't do this alone. It actually shares its orbit with a sister moon named Epimetheus, in what is called a co-orbital condition or 1:1 resonance. One moon orbits 31 miles (50 km) farther away from the planet than the other, taking more time to complete one turn around Saturn. This slight difference means the inner, faster moving moon starts to catch up to the other approximately every four Earth years. Interestingly, when this happens, the gravity interaction between the moons causes them to trade places between these inner and outer orbits. Together, the moons trail enough particles to generate a faint ring. However, except for very powerful telescopes, the region of their common orbit appears as a gap between Saturn's prominent F and G rings. Janus and Epimetheus are the fifth and sixth moons in distance from Saturn. Both are phase locked with their parent; one side always faces toward Saturn. Being so close, they orbit in less than 17 hours. They are both thought to be composed of largely of water ice, but their density of less than 0.7 is much less than that of water. Thus, they are probably \"rubble piles\" -- each a collection of numerous pieces held together loosely by gravity. Each moon has dark, smoother areas, along with brighter areas of terrain. One interpretation of this is that the darker material evidently moves down slopes, leaving shinier material such as water ice on the walls of fractures. Their temperature is approximately -195 degrees Celsius (-319 degrees Fahrenheit). Their reflectivity (or albedo) of 0.7 to 0.8 in the visual range again suggests a composition largely of water ice. Janus and Epimetheus share their orbits with a faint dust ring around Saturn, now called the Janus/Epimetheus Ring. This ring may be made of particles blasted off their surfaces by meteoroid impacts. The name Janus comes from the Roman god of gates, doors, doorways, beginnings, and endings.", + ], + }, + related: ["sc_pioneer_11", "sc_voyager_2", "sc_cassini"], + }, + jarnsaxa: { + title: "Jarnsaxa", + description: { + blurb: [ + "Jarnsaxa was discovered on March 6, 2006 using the Subaru 8.3-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Jarnsaxa has a mean radius of 1.9 miles (3 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 163 degrees and an eccentricity of about 0.2. At a mean distance of 12.0 million miles (19.4 million kilometers) from Saturn, the moon takes about 1,007 Earth days to complete one orbit. Jarnsaxa is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn -- traveling around in the opposite direction from the planet's rotation. Jarnsaxa and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Jarnsaxa is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2006 S6, Jarnsaxa was named for one of the nine giantesses in Norse mythology who gave birth to Heimdall, the guard of the rainbow bridge that links our world to Asgard, home of the gods.", + ], + }, + related: [], + }, + juliet: { + title: "Juliet", + description: { + blurb: [ + "Juliet was discovered on Jan. 3, 1986 in images taken by Voyager 2. It is one of the 10 Uranian satellites discovered by the Voyager science team.", + ], + more: [ + 'Juliet is one of the small, inner moons of Uranus. Little is known about it other than its size and orbital characteristics. Neither its size nor its albedo have been measured directly, but assuming an albedo of 0.07 like Puck, its surface probably consists of the dark, unprocessed, carbon-rich material found on the C-class of asteroids. Originally called S/1986 U2, Juliet was named for the title character in William Shakespeare\'s play, "Romeo and Juliet." Juliet is the daughter of the Capulets, who are sworn enemies to the Montagues. Nevertheless, she falls in love with Romeo, son of the Montagues.', + ], + }, + related: ["sc_voyager_2"], + }, + jupiter_li: { + title: "Jupiter LI", + description: { + blurb: [ + "This tiny moon is one of several discovered from Earth-based telescopes with improved search techniques. It is a little bigger than a mile (2 kilometers) across.", + ], + more: [ + "This moon is still awaiting an official name. Since its discovery is now confirmed, it is temporarily being called Jupiter LI, which means it is the 51st confirmed moon discovered at Jupiter. It was originally called S/2010 J1.", + ], + }, + related: [], + }, + jupiter_lii: { + title: "Jupiter LII", + description: { + blurb: [ + "This moon of Jupiter was discovered on Sept. 8, 2010 at the Palomer 5-m Hale telescope in California.", + ], + more: [ + "This tiny moon is one of several discovered from Earth-based telescopes with improved search techniques. It is a little bigger than a mile (2 kilometers) across.", + ], + }, + related: [], + }, + jupiter_liv: { + title: "Jupiter LIV", + description: { + blurb: [ + "Jupiter LIV, originally known as S/2016 J 1, is an outer natural satellite of Jupiter.", + ], + more: [ + "It was discovered by Scott S. Sheppard in 2016, but not announced until June 2, 2017 via a Minor Planet Electronic Circular from the Minor Planet Center. It is about 1 kilometer in diameter and orbits at a semi-major axis of about 20,650,845 km with an inclination of about 139.8°. It belongs to the Ananke group.", + ], + }, + related: [], + }, + jupiter_lv: { + title: "Jupiter LV", + description: { + blurb: [ + "Jupiter LV, originally known as S/2003 J 18, is an outer natural satellite of Jupiter.", + ], + more: ["Jupiter LV is about 2 kilometres in diameter."], + }, + related: [], + }, + jupiter_lvi: { + title: "Jupiter LVI", + description: { + blurb: [ + "Jupiter LVI, provisionally known as S/2011 J 2, is a natural satellite of Jupiter. It was discovered in 2011.", + ], + more: [ + "The moon was lost following its discovery in 2011, but was subsequently re-discovered in 2017. It is an irregular moon with a retrograde orbit, like so many of the smaller Jupiter moons.", + ], + }, + related: [], + }, + jupiter_lxi: { + title: "Jupiter LXI", + description: { + blurb: [ + "Jupiter LXI, provisionally known as S/2003 J 19, is a natural satellite of Jupiter, discovered in 2003.", + ], + more: [ + "S/2003 J 19 is about 2 kilometres in diameter, and orbits Jupiter every 699.125 days, at an inclination of 165° to the ecliptic (164° to Jupiter's equator), in a retrograde direction and with an eccentricity of 0.1961. It belongs to the Carme group, made up of irregular retrograde moons orbiting Jupiter at an inclination of about 165°.This moon was lost following its discovery in 2003 but then re-discovered in 2018.", + ], + }, + related: [], + }, + jupiter_lxiii: { + title: "Jupiter LXIII", + description: { + blurb: [ + "Jupiter LXIII, provisionally known as S/2017 J 2, is an outer natural satellite of Jupiter. It was discovered in 2017.", + ], + more: [ + "It is a member of the Carme group, and is about 2 kilometers in diameter.", + ], + }, + related: [], + }, + jupiter_lxiv: { + title: "Jupiter LXIV", + description: { + blurb: [ + "Jupiter LXIV, originally known as S/2017 J 3, is an outer natural satellite of Jupiter.", + ], + more: [ + "It was discovered in 2017, is about two kilometers in diameter, and is a member of the Ananke group.", + ], + }, + related: [], + }, + jupiter_lxix: { + title: "Jupiter LXIX", + description: { + blurb: [ + "Jupiter LXIX, originally known as S/2017 J 8, is an outer natural satellite of Jupiter.", + ], + more: [ + "It was discovered in 2017, is about two kilometers in diameter, and is a member of the Ananke group.", + ], + }, + related: [], + }, + jupiter_lxvi: { + title: "Jupiter LXVI", + description: { + blurb: [ + "Jupiter LXVI, originally known as S/2017 J 5, is an outer natural satellite of Jupiter.", + ], + more: [ + "It was discovered in 2017, is about two kilometers in diameter, and is a member of the Carme group.", + ], + }, + related: [], + }, + jupiter_lxvii: { + title: "Jupiter LXVII", + description: { + blurb: [ + "Jupiter LXVII, originally known as S/2017 J 6, is an outer natural satellite of Jupiter.", + ], + more: [ + "It was discovered in 2017, is about two kilometers in diameter, and is a member of the Pasiphae group.", + ], + }, + related: [], + }, + jupiter_lxviii: { + title: "Jupiter LXVIII", + description: { + blurb: [ + "Jupiter LXVIII, provisionally known as S/2017 J 7, is an outer natural satellite of Jupiter.", + ], + more: [ + "It was discovered in 2017, is about two kilometers in diameter, and is a member of the Pasiphae group.", + ], + }, + related: [], + }, + jupiter_lxx: { + title: "Jupiter LXX", + description: { + blurb: [ + "Jupiter LXX, originally known as S/2017 J 9, is an outer natural satellite of Jupiter.", + ], + more: [ + "It was discovered in 2017, is about two kilometers in diameter, and is a member of the Ananke group.", + ], + }, + related: [], + }, + jupiter_lxxii: { + title: "Jupiter LXXII", + description: { + blurb: [ + "Jupiter LXXII, originally known as S/2011 J 1, is a natural satellite of Jupiter.", + ], + more: [ + "It was discovered in 2017, is about three kilometers in diameter, and is a member of the Ananke group.", + ], + }, + related: [], + }, + kale: { + title: "Kale", + description: { + blurb: [ + "Kale was discovered Dec. 9, 2001 by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Kale is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99% of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color -- light red -- except for Kalyke, which is considerably redder than the others. All of these characteristics support the idea that the Carme satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Carme members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Kale has a mean radius of about 0.6 miles (one kilometer). At a mean distance of about 14.4 million miles (23.2 million kilometers) from Jupiter, the satellite takes about 729 Earth days to complete one orbit. Originally called S/2001 J8, Kale was named for one of the Graces, who were daughters of Zeus, the Greek equivalent of the Roman god Jupiter.", + ], + }, + related: [], + }, + kallichore: { + title: "Kallichore", + description: { + blurb: [ + "Kallichore was discovered on Feb. 6, 2003 by Scott S. Sheppard at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Kallichore is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99% of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color – light red – except for Kalyke, which is considerably redder than the others. All of these characteristics support the idea that the Carme satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Carme members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Kallichore has a mean radius of about 0.6 miles (one kilometer). At a mean distance of about (23.3 million kilometers) from Jupiter, the satellite takes about 728 Earth days to complete one orbit. Originally called S/2003 J11, Kallichore was named for one of the Muses, who were daughters of Zeus, the Greek equivalent of the Roman god Jupiter. Her name means \"beautiful in dance.\"", + ], + }, + related: [], + }, + kalyke: { + title: "Kalyke", + description: { + blurb: [ + "Kalyke was discovered on Nov. 23, 2000 by Scott S. Sheppard, David C. Jewitt, Yanga R. Fernandez, and Eugene Magnier at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Kalyke is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99% of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color – light red – except for Kalyke, which is considerably redder than the others. All of these characteristics support the idea that the Carme satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Carme members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Kalyke has a mean radius of about 1.6 miles (2.6 kilometers). At a mean distance of about 14.6 million miles (23.5 million kilometers) from Jupiter, the satellite takes about 742 Earth days to complete one orbit. Originally called S/2000 J2, Kalyke was named for the mother of Endymion by Zeus (the Greek equivalent of the Roman god Jupiter) according to some accounts in Greek mythology.", + ], + }, + related: [], + }, + kari: { + title: "Kari", + description: { + blurb: [ + "Kari was discovered on March 6, 2006 based on data obtained with the Subaru 8.3-m reflector telescope on Mauna Kea, Hawaii, during the months of January to April, 2006.", + ], + more: [ + "Kari has a mean radius of 1.9 miles (3 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 156 degrees and an eccentricity of about 0.5. At a mean distance of 13.7 million miles (22.1 million kilometers) from Saturn, the moon takes about 1,231 Earth days to complete one orbit. Its rotation period is 7 hours and 42 minutes. Kari is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn -- traveling around in the opposite direction from the planet's rotation. Kari and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Kari is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Kari appears to be a member of a subgroup that also includes Skathi, Skoll, Hyrrokkin, S/2006 S1, Farbauti, Bergelmir, and S/2006 S3. Originally called S/2006 S2, Kari was named for a wind giant in Norse mythology", + ], + }, + related: ["sc_cassini"], + }, + kerberos: { + title: "Kerberos", + description: { + blurb: [ + "Kerberos was discovered on June 28, 2011 by a large team led by Mark Showalter using the Hubble Space Telescope.", + ], + more: [ + "Pluto's tiny moon Kerberos appears to be smaller than scientists expected and has a highly-reflective surface, counter to predictions prior to the July 2015 flyby of the NASA's New Horizons spacecraft. The new data show that Kerberos appears to have a double-lobed shape, with the larger lobe approximately 5 miles (8 kilometers) across and the smaller lobe approximately 3 miles (5 kilometers) across. Scientists speculate from its unusual shape that Kerberos could have been formed by the merger of two smaller objects. The reflectivity of Kerberos' surface is similar to that of Pluto's other small moons (approximately 50 percent) and strongly suggests Kerberos, like the others, is coated with relatively clean water ice. Kerberos is located between the orbits of Nix and Hydra, which Hubble discovered in 2005. Charon was discovered in 1978 at the U.S. Naval Observatory and first resolved using Hubble in 1990 as a separate body from Pluto. Originally designated S/2011 (134340) 1 (and sometime referred to as P4), Kerberos is named after the three-headed dog of Greek mythology.", + ], + }, + related: ["sc_new_horizons"], + }, + kiviuq: { + title: "Kiviuq", + description: { + blurb: [ + "Kiviuq was discovered on Aug. 7, 2000 at the European Southern Observatory in La Silla, Chile.", + ], + more: [ + "Kiviuq has a mean radius of about 5 miles (8 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.06. This small, light red, irregular moon, is a dark object in a highly inclined orbit around Saturn. At a mean distance of 7.0 million miles (11.3 million kilometers) from Saturn, the moon takes about 449 Earth days to complete one orbit, while it rotates once every 21 hours and 49 minutes. Kiviuq is one of five known members of the Inuit group of moons, which orbit Saturn at a mean distance of 7 to 11 million miles (11 to 18 million kilometers), at inclinations between 40 and 50 degrees from the plane of Saturn's equator, and with eccentricities of 0.15 to 0.48. (A moon's eccentricity is a number between 0 and 1 which describes the shape of the orbit. The closer to 0, the more circular it is; the closer to 1, the more elongated.) The Inuit moons all have prograde orbits (they travel around Saturn in the same direction as the planet's rotation), but their deviations from circular orbits and from the plane of Saturn's equator classify them as \"irregular\" moons. Like Saturn's other irregular moons, they are thought to be objects that were captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet, as the regular moons are thought to have done. Originally called S/2000 S5, Kiviuq was named for the wandering hero of epic stories told by the Inuit people.", + ], + }, + related: [], + }, + kore: { + title: "Kore", + description: { + blurb: [ + "Kore was discovered on Feb. 8, 2003 by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Kore is considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. Most or all of the Pasiphae satellites are thought to have begun as a single asteroid that, after being captured by Jupiter's gravity, suffered a collision which broke off a number of pieces. The bulk of the original asteroid survived as the moon called Pasiphae, and the other pieces became some or all of the other moons in the group. All of the Pasiphae moons are retrograde, so they orbit Jupiter in the opposite direction from the planet's rotation. Compared to Jupiter's other satellite groups, confidence is lower that all the moons in the Pasiphae group originated in a single collision. Kore has a mean radius of 0.6 miles (one kilometer), assuming an albedo of 0.04. At a mean distance of about 15.2 million miles (24.5 million kilometers) from Jupiter, the satellite takes about 777 Earth days to complete one orbit. Originally called S/2003 J14, Kore was named for a character in Greek mythology who was the daughter of Zeus (the Greek equivalent of the Roman god Jupiter) and Demeter, the goddess of agriculture.", + ], + }, + related: [], + }, + laomedeia: { + title: "Laomedeia", + description: { + blurb: [ + "Laomedeia is one of three tiny moons (ranging in size from 30 to 40 km -- or 18 to 24 miles) of Neptune discovered in 2002 using innovative ground-based telescope techniques. (The other moons discovered were Sao and Halimede.) The moons are so distant and so small they are about 100 million times fainter than can be seen with the unaided eye. The moons were missed by the Voyager 2 spacecraft in 1989 because they are so faint and distant from Neptune.", + "Laomedeia is considered an irregular satellite because of its distant, eccentric orbit around Neptune. Like most irregular satellites of the giant planets in our outer solar system, Laomedeia most likely formed after a collision between a larger moon and a comet or an asteroid. Laomedeia and Sao have prograde orbits, which means they orbit in the same direction as Neptune's rotation. Halimede has a retrograde orbit, which means Halimede orbits in the opposite direction of Neptune's rotation.", + "Very little is known about Laomedeia. Scientists are trying to learn more about it and its irregular sisters because they offer a glimpse of the conditions at the time the planets in our solar system were forming billions of years ago.", + ], + }, + related: [], + }, + larissa: { + title: "Larissa", + description: { + blurb: [ + "Larissa is another of the small moons found near Neptune's faint ring system in 1989. Like Despina and Galatea, Larissa is irregularly shaped and heavily cratered.", + "Larissa's orbit is mostly circular, but it is slowly spiraling inward and may eventually impact Neptune's atmosphere, or the gas giant's tidal forces may break Larissa apart to form a planetary ring. The moon orbits Neptune in about 13 hours and 20 minutes.", + ], + }, + related: ["sc_voyager_2"], + }, + leda: { + title: "Leda", + description: { + blurb: [ + "Leda was discovered on Sept. 14, 1974 by Charles Thomas Kowal on plates taken from Sept. 11 through 13, 1974 with the 122-cm Schmidt telescope at Mount Palomar.", + ], + more: [ + "With a mean radius of 6.2 miles (10 kilometers), assuming an albedo of 0.04, Leda is the smallest moon in the Himalia group, a family of Jovian satellites which have similar orbits and appearance, and are therefore thought to have a common origin. Leda may be a chunk of an asteroid (a C- or D-class asteroid, judging by the fact that it reflects only about 4% of the light it receives), which was broken apart in a collision either before or after being captured by Jupiter's gravity. In this scenario, the other pieces became the other moons in the Himalia group: Himalia (the largest), Lysithea and Elara. A fifth moon, called S/2000 J11, only about 2 km in radius, was considered a candidate for this group. However, it was lost before its orbit could be definitively determined. It may have crashed into Himalia, reuniting two pieces of the former asteroid, and perhaps creating a faint temporary ring of Jupiter near the orbit of Himalia. At a distance of about 6.9 million miles (11.2 million kilometers) from Jupiter, Leda takes nearly 241 Earth days to complete one orbit. Leda was named for a woman in Greek mythology. According to one legend, she was seduced by Zeus (the Greek equivalent of the Roman god, Jupiter), who had taken the form of a swan.", + ], + }, + related: [], + }, + loge: { + title: "Loge", + description: { + blurb: [ + "Loge was discovered on March 6, 2006 by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna using the Subaru 8.3-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Loge has a mean radius of 1.9 miles (3 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 167 degrees and an eccentricity of about 0.2. At a mean distance of 14.3 million miles (23.0 million kilometers) from Saturn, the moon takes about 1,311 Earth days to complete one orbit. Loge is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn -- traveling around in the opposite direction from the planet's rotation. Loge and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Loge is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2006 S5, Loge was named for Logi, a god who was the personification of fire in Norse mythology.", + ], + }, + related: [], + }, + lysithea: { + title: "Lysithea", + description: { + blurb: [ + "Lysithea was discovered on July 6, 1938 by Seth Barnes Nicholson with the 100-inch (2.5 m) Hooker telescope at the Mount Wilson Observatory.", + ], + more: [ + "With a mean radius of 11.1 miles (18 kilometers), assuming an albedo of 0.04, Lysithea is the second smallest moon in the Himalia group, a family of Jovian satellites which have similar orbits and appearance, and are therefore thought to have a common origin. Lysithea may be a chunk of an asteroid (a C- or D-class asteroid, judging by the fact that it reflects only about 4% of the light it receives), which was broken apart in a collision either before or after being captured by Jupiter's gravity. In this scenario, the other pieces became the other moons in the Himalia group: Leda, Himalia (the largest) and Elara. A fifth moon, called S/2000 J11, only about 1.2 miles, (2 kilometers) in radius, was considered a candidate for this group. However, it was lost before its orbit could be definitively determined. It may have crashed into Himalia, reuniting two pieces of the former asteroid, and perhaps creating a faint temporary ring of Jupiter near the orbit of Himalia. At a distance of about 7.2 million miles (11.7 million kilometers) from Jupiter, Lysithea takes about 259 Earth days to complete one orbit. Lysithea was named for one of the lovers of the Roman god Jupiter, or the Greek equivalent, Zeus.", + ], + }, + related: [], + }, + mab: { + title: "Mab", + description: { + blurb: [ + "Mab was discovered on Aug. 23, 2003 by Mark R. Showalter and Jack J. Lissauer, using the Hubble Space Telescope.", + ], + more: [ + "Mab is a small, inner moon of Uranus. It orbits at the same distance as one of the planet's rings, the Mu ring, and in fact may provide dust for that ring when the moon is struck by small meteoroids or ring particles. Because of its small size and dark color, it was overlooked in the Voyager 2 images until after it was spotted with a ground-based telescope in 2003. Mab is queen of the fairies in English folklore. She is mentioned in a speech given in William Shakespeare's play, \"Romeo and Juliet,\" so the name is at least somewhat in keeping with the practice of naming most Uranian moons after characters in Shakespeare's plays. The original designation for this moon was S/2003 U1.​", + ], + }, + related: [], + }, + margaret: { + title: "Margaret", + description: { + blurb: [ + "Margaret is considered an irregular moon of Uranus because of the eccentricity and inclination of its orbit, but it is the only such moon that travels in a prograde direction -- that is, in the same direction as the regular moons and the planet's rotation about its axis. Only about 20 km in diameter and very dark, it is likely an object that was captured by Uranus' gravity.", + ], + }, + related: [], + }, + megaclite: { + title: "Megaclite", + description: { + blurb: [ + "Megaclite was discovered on Nov. 25, 2000 by Scott S. Sheppard, David C. Jewitt, Yanga R. Fernandez, and Eugene A. Magnier at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Megaclite is considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. Most or all of the Pasiphae satellites are thought to have begun as a single asteroid that, after being captured by Jupiter's gravity, suffered a collision which broke off a number of pieces. The bulk of the original asteroid survived as the moon called Pasiphae, and the other pieces became some or all of the other moons in the group. Compared to Jupiter's other satellite groups, confidence is lower that all the moons in the Pasiphae group originated in a single collision. This is due to differences in color (varying from red to gray), and differences in orbital eccentricity and inclination among the members of the Pasiphae group. Sinope, in particular, is suspected of starting out as an independent asteroid. Megaclite has a mean radius of 1.6 miles (2.7 kilometers), assuming an albedo of 0.04. At a mean distance of about 14.7 million (23.8 million kilometers) from Jupiter, the satellite takes about 753 Earth days to complete one orbit. Originally called S/2000 J8, Megaclite was named for one of the adulterous conquests of the Roman god Jupiter.", + ], + }, + related: [], + }, + menoetius: { + title: "Menoetius", + description: { + blurb: [ + 'Menoetius is part of a large binary asteroid located in the orbit of Jupiter, always "trailing" the planet by 60 degrees. It is in a binary system with its larger twin, Patroclus. Referred to as a Trojan asteroid, It will be visited by the Lucy mission in 2033.', + ], + more: [ + "This asteroid will be the final encounter of Lucy's primary mission, in March of 2033. After a long journey from the Greek L4 swarm to the Trojan L5 swarm, Lucy will fly by the binary pair of asteroids (617) Patroclus and Menoetius. They are large P-type Trojans, with average diameters of 113 km and 104 km (about 70 and 65 miles), respectively. Scientists hypothesize that they may be primordial asteroids left over from the very early Solar System.", + ], + }, + related: ["sc_lucy", "617_patroclus"], + }, + methone: { + title: "Methone", + description: { + blurb: [ + "The Cassini Imaging Team discovered Methone on June 1, 2004. Methone and nearby Pallene were the first moons discovered in Cassini images.", + ], + more: [ + "Methone is a tiny 1-mile (1.6-kilometer) mean radius moon that orbits between Mimas and Enceladus at a radius of 120,546 miles (194,000 kilometers) from Saturn. Scientists have two theories to explain the presence of Methone and two other tiny sister moons, Pallene and Anthe. First, the three moons may have split from either Mimas or Enceladus. Second, all five moons may be the remains of a larger swarm that traveled in that area close to Saturn. Methone orbits Saturn in 24 hours. Methone, Pallene and Anthe, all orbit at very similar distances from Saturn – they are in a dynamical relationship. Mimas strongly perturbs the three moons, all of which orbit between Mimas and Enceladus. The vastly more massive Mimas causes the Methonean orbit to vary by as much as 12.4 miles (20 km), it causes Pallene to vary by a slightly smaller amount and it has the greatest effect on Anthe. Because these three tiny moons (Methone, Pallene and Anthe) orbit at very similar distances from Saturn, they are in a dynamical relationship. The vastly more massive Mimas causes the Methone orbit to vary by as much as 12.4 miles (20 km), causes Pallene to vary by a slightly smaller amount, and has the greatest effect on Anthe. These three moons may also be contributing particles to Saturn's E-ring. John Herschel suggested that the moons of Saturn be associated with the mythical brothers and sisters of Kronus.", + ], + }, + related: ["sc_cassini"], + }, + metis: { + title: "Metis", + description: { + blurb: [ + "Metis was discovered in March 1979 by the Voyager science team.", + ], + more: [ + "Orbiting within Io's orbit, which is the innermost of the four largest moons of Jupiter (called the Galilean moons), are four smaller moons named Metis, Adrastea, Amalthea, and Thebe. Metis is the third largest within this grouping and it has a mean radius of about 13.3 miles (21.5 kilometers). Metis orbits 128,000 km from its parent planet Jupiter and it takes 0.295 Earth days to complete one orbit. We do not know the rotational period for Metis, but its orbital period is 5 hours, and it is likely to be in synchronous orbit, keeping the same face pointing towards Jupiter. Since Io orbits about 262,000 miles (422,000) kilometers above Jupiter and, at this close distance, is subjected to extreme tidal flexing from Jupiter's gravity, one would imagine that this even closer satellite would be pulled to pieces. However, because it is so small Metis is relatively immune to the effects of tidal forces. Metis is one of the two closest moons (the other is Adrastea) that orbit inside what is called the synchronous orbit radius of Jupiter. That is, Metis orbits Jupiter faster than Jupiter rotates on its axis. At this distance, Metis' orbit will eventually decay and it will fall into the planet. Metis and Adrastea also orbit inside Jupiter's main ring and are undoubtedly the source of the material for this ring. Amalthea and Thebe provide the material for the Gossamer ring. Originally designated S/1979 J 1, Metis is named for the first wife of Zeus who was swallowed by Zeus while pregnant with their first child.", + ], + }, + related: ["sc_voyager_1"], + }, + mimas: { + title: "Mimas", + description: { + blurb: [ + "Crater-covered Mimas is the smallest and innermost of Saturn's major moons.", + ], + more: [ + 'Its most distinguishing feature is a giant impact crater – named Herschel after the moon\'s discoverer – which stretches a third of the way across the face of the moon, making it look like the Death Star from "Star Wars" The Herschel Crater is 80 miles (130 kilometers) across – one third of the diameter of the moon itself – with outer walls about 3 miles (5 kilometers) high and a central peak 3.5 miles (6 km) high. The impact that blasted this crater out of Mimas probably came close to breaking the moon apart. Shock waves from the Herschel impact may have caused the fractures, also called chasmata, on the opposite side of Mimas. That Mimas appears to be frozen solid is puzzling because Mimas is closer to Saturn and has a much more eccentric (elongated) orbit than Enceladus, which should mean that Mimas has more tidal heating than Enceladus. Yet Enceladus displays geysers of water, which implies internal heat, while Mimas has one of the most heavily cratered surfaces in the solar system, which suggests a frozen surface that has persisted for enough time to preserve all those craters. This paradox has prompted the "Mimas Test" by which any theory that claims to explain the partially thawed water of Enceladus must also explain the entirely frozen water of Mimas.', + ], + }, + related: ["sc_cassini", "sc_voyager_1", "sc_voyager_2"], + }, + miranda: { + title: "Miranda", + description: { + blurb: [ + "Miranda, a moon of Uranus, looks like it was pieced together from parts that didn't quite merge properly.", + ], + more: [ + "At about 500 km in diameter, it's only one-seventh as large as Earth's moon, a size that seems unlikely to support much tectonic activity.", + "Yet Miranda sports one of the strangest and most varied landscapes among extraterrestrial bodies, including three large features known as \"coronae,\" which are unique among known objects in our solar system. They are lightly cratered collections of ridges and valleys, separated from the more heavily cratered (and presumably older) terrain by sharp boundaries like mismatched patches on a moth-eaten coat. Miranda's giant fault canyons are as much as 12 times as deep as the Grand Canyon. Due to Miranda's low gravity and large cliffs, a rock dropped off the edge of the highest cliff would take a full 10 minutes to reach the foot of the cliff. All of Uranus' larger moons, including Miranda, are thought to consist mostly of roughly equal amounts of water ice and silicate rock. Unlike the other four main Uranian satellites, Miranda's orbit is slightly inclined. Miranda was named for the daughter of Prospero in William Shakespeare's play, \"The Tempest.\"", + ], + }, + related: ["sc_voyager_2"], + }, + mneme: { + title: "Mneme", + description: { + blurb: [ + "Mneme was discovered on Feb. 9, 2003 by Scott S. Sheppard and Brett Joseph Gladman at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Mneme is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter's gravity and then suffered a collision, which broke off a number of pieces. The largest remaining chunk was named \"Ananke,\" and the smaller pieces became the other 15 moons in the Ananke group. All of the Ananke moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and rather highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Ananke satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Ananke members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Mneme has a mean radius of about 0.6 miles (one kilometer), assuming an albedo of 0.04. At a mean distance of about 13 million miles (21 million kilometers) from Jupiter, it takes about 620 Earth days to complete one orbit. Originally called S/2003 J21, Mneme was named for one of the Muses, who were daughters of Zeus, the Greek equivalent of the Roman god Jupiter. Mneme means memory.", + ], + }, + related: [], + }, + moon: { + title: "Moon", + description: { + blurb: [ + "Earth's Moon is the only place beyond Earth where humans have set foot.", + ], + more: [ + "The brightest and largest object in our night sky, the Moon makes Earth a more livable planet by moderating our home planet's wobble on its axis, leading to a relatively stable climate. It also causes tides, creating a rhythm that has guided humans for thousands of years.", + "Our moon is the fifth largest of the 190+ moons orbiting planets in our solar system.", + "Earth's only natural satellite is simply called \"the Moon\" because people didn't know other moons existed until Galileo Galilei discovered four moons orbiting Jupiter in 1610. With a radius of 1,079.6 miles (1,737.5 kilometers), the Moon is less than a third the width of Earth. If Earth were the size of a nickel, the Moon would be about as big as a coffee bean.", + "The Moon is farther away from Earth than most people realize. The Moon is an average of 238,855 miles (384,400 kilometers) away. That means 30 Earth-sized planets could fit in between Earth and the Moon.", + ' The Moon is slowly moving away from Earth, getting about an inch farther away each year. The leading theory of the Moon\'s origin is that a Mars-sized body collided with Earth about 4.5 billion years ago. The resulting debris from both Earth and the impactor accumulated to form our natural satellite. The newly formed Moon was in a molten state, but within about 100 million years, most of the global "magma ocean" had crystallized, with less-dense rocks floating upward and eventually forming the lunar crust.', + ], + }, + related: [ + "sc_lcross", + "sc_grail_a", + "sc_grail_b", + "sc_ladee", + "sc_clementine", + "sc_lunar_prospector", + ], + }, + mundilfari: { + title: "Mundilfari", + description: { + blurb: [ + "Mundilfari was discovered in 2000 using the 3.6-m Canada-France-Hawaii reflector on Mauna Kea in Hawaii, with adaptive optics.", + ], + more: [ + 'Mundilfari has a mean radius of 2.2 miles (3.5 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.06. It orbits Saturn at an inclination of about 169 degrees and an eccentricity of about 0.2. At a mean distance of 11.6 million miles (18.7 million kilometers) from Saturn, the moon takes about 953 Earth days to complete one orbit. Mundilfari is a member of the Norse group of moons. These "irregular" moons have retrograde orbits around Saturn -- traveling around in the opposite direction from the planet\'s rotation. Mundilfari and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn\'s other irregular moons, Mundilfari is thought to be an object that was captured by Saturn\'s gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2000 S9, Mundilfari was named for the father of two beautiful children in Norse mythology, a son whom he named "Moon" and a daughter whom he named "Sun."', + ], + }, + related: [], + }, + naiad: { + title: "Naiad", + description: { + blurb: [ + "Potato-shaped Naiad is most likely made up of fragments of Neptune's original satellites, which were smashed up by disturbances when the ice giant captured its largest moon, Triton. It is probable that Naiad has not been modified by any internal geological processes since its formation.", + "Naiad orbits close to Neptune. The small moon circles the planet every seven hours and six minutes in a decaying orbit; Naiad may eventually crash into Neptune's atmosphere or be torn apart and form a planetary ring.", + ], + }, + related: ["sc_voyager_2"], + }, + namaka: { + title: "Namaka", + description: { + blurb: ["Namaka is the smaller, inner moon of the dwarf planet Haumea."], + more: [ + "Namaka was discovered on 30 June 2005 and announced on 29 November 2005, and is named after the goddess of the sea in Hawaiian mythology and one of the daughters of Haumea.", + ], + }, + related: [], + }, + narvi: { + title: "Narvi", + description: { + blurb: [ + "Narvi was discovered on April 8, 2003 by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna, from photos taken from Feb. 5 to 3 April 3.", + ], + more: [ + "Narvi has a mean radius of 2.2 miles (3.5 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 143 degrees and an eccentricity of about 0.4. At a mean distance of 12.1 million miles (19.4 million kilometers) from Saturn, the moon takes about 1,004 Earth days to complete one orbit. Narvi is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn -- traveling around in the opposite direction from the planet's rotation. Narvi and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Narvi is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Narvi appears to be a member of a subgroup with Bestla. Originally called S/2003 S1, Narvi was named for a son of Loki in Norse mythology.", + ], + }, + related: [], + }, + nix: { + title: "Nix", + description: { + blurb: [ + "Nix is the inner of the two moons discovered orbiting Pluto in 2005 by the Hubble Space Telescope.", + ], + more: [ + "Nix and Hydra are roughly 5,000 times fainter than Pluto and are about two to three times farther from Pluto than its large moon, Charon, which was discovered in 1978. Nix and Hydra are roughly 20 to 70 miles (32 to 113 km) wide.They are so small and so faint that scientists combined a short exposure of Pluto and Charon and a long exposure of Nix and Hydra to create images of them all together. Nix was named for the Greek goddess of darkness and night and mother of Charon.", + ], + }, + related: ["sc_hubble_space_telescope", "sc_new_horizons"], + }, + nereid: { + title: "Nereid", + description: { + blurb: [ + "Nereid is one of the outermost of Neptune's known moons and is among the largest.", + ], + more: [ + "Nereid is unique because it has one of the most eccentric orbits of any moon in our solar system. Nereid is so far from Neptune that it requires 360 Earth days to make one orbit. This odd orbit suggests that Nereid may be a captured asteroid or Kuiper Belt object or that it was greatly disturbed during the capture of Neptune's largest moon Triton.", + ], + }, + related: ["sc_voyager_2"], + }, + neso: { + title: "Neso", + description: { + blurb: [ + "Very little is known about Neso, another of Neptune's extremely distant irregular moons. Neso's eccentric orbit takes it millions of kilometers from the ice giant. The moon's orbit is among the most distant from its planet than any other known moon in our solar system.", + "The small moon shares similar orbital parameters with another moon of Neptune -- Psamathe. Both Neso and Psamathe may be fragments from the break-up of a larger moon billions of years ago.", + ], + }, + related: [], + }, + oberon: { + title: "Oberon", + description: { + blurb: ["Oberon is the second largest moon of Uranus."], + more: [ + "Discovered in 1787, little was known about this moon until Voyager 2 passed it during its flyby of Uranus in January 1986. Oberon is heavily cratered―similar to Umbriel―especially when compared to three other moons of Uranus: Ariel, Titania and Miranda. Like all of Uranus' large moons, Oberon is composed of roughly half ice and half rock. Oberon has at least one large mountain that rises about 6 km off the surface. The moon was named for the king of the fairies in Shakespeare's \"A Midsummer Night's Dream.\"", + ], + }, + related: ["sc_voyager_2"], + }, + ophelia: { + title: "Ophelia", + description: { + blurb: [ + "Ophelia was discovered in January 1986 in images sent back by the Voyager 2 spacecraft during its flyby of Uranus.", + ], + more: [ + "Ophelia is one of the small inner moons of Uranus. Ophelia appears to be the outer satellite straddling Uranus' bright Epsilon ring. Ophelia and Cordelia are believed to herd the ring material into shape and keep it from drifting into space. All of Uranus' inner moons (those observed by Voyager 2) appear to be roughly half water ice and half rock. This moon was originally designated S/1986 U8, but was later renamed for the character of Ophelia in Shakespeare's \"Hamlet.\" Ophelia is the daughter of Polonius and fiance of Hamlet in the play.", + ], + }, + related: ["sc_voyager_2"], + }, + orthosie: { + title: "Orthosie", + description: { + blurb: [ + "Orthosie is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin", + ], + more: [ + "The group probably began as an asteroid that was captured by Jupiter's gravity and then suffered a collision which broke off a number of pieces. The largest remaining chunk was named \"Ananke,\" and the smaller pieces became the other 15 moons in the Ananke group. All of the Ananke moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and rather highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Ananke satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Ananke members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Orthosie has a mean radius of about 0.6 miles (one kilometer), assuming an albedo of 0.04. At a mean distance of about 13.1 million miles (21.2 million kilometers) from Jupiter, it takes about 623 Earth days to complete one orbit. Originally called S/2001 J9, Orthosie was named for one of the Horae, who were daughters of Jupiter and Themis, a Titaness, in Roman mythology. Orthosie means luck.", + ], + }, + related: [], + }, + paaliaq: { + title: "Paaliaq", + description: { + blurb: [ + "Paaliaq was discovered on Aug. 7, 2000 at the European Southern Observatory in La Silla, Chile.", + ], + more: [ + "Paaliaq has a mean radius of 6.8 miles (11 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.06. At a mean distance of 9.3 million miles (15.0 million kilometers) from Saturn, the moon takes about 688 Earth days to complete one orbit. It has the most eccentric orbit around Saturn, meaning that its orbit is shaped like an oval. Paaliaq is one of five known members of the Inuit group of moons, which orbit Saturn at a mean distance of 7 to 11 million miles (11 to 18 million kilometers), at inclinations between 40 and 50 degrees from the plane of Saturn's equator, and with eccentricities of 0.15 to 0.48. (A moon's eccentricity is a number between 0 and 1 which describes the shape of the orbit. The closer to 0, the more circular it is; the closer to 1, the more elongated.) Observations by Tommy Grav and James Bauer using telescopes on Mauna Kea, Hawaii in 2006 (before the discovery of Tarqeq) found that Kiviuq, Siarnaq and Paaliaq all are light red with similar infrared features, further supporting the idea of a common origin. Originally called S/2000 S2, Paaliaq was named for a fictional Inuit shaman in the book, \"The Curse of the Shaman,\" by Michael Arvaarluk Kusugak and Vladyana Langer Krykorka.", + ], + }, + related: [], + }, + pallene: { + title: "Pallene", + description: { + blurb: [ + "The Cassini imaging team discovered Pallene on June 1, 2004. Pallene and nearby Methone were the first moons discovered in Cassini images.", + ], + more: [ + "Pallene (pronounced pal-lee-nee, adjective: Pallenean) is a tiny moon, with a mean radius of 1.6 miles (2.5 kilometers), that orbits between Mimas and Enceladus at about 132,000 miles (212,000 kilometers) from Saturn. Scientists have two theories to explain the presence of Pallene and two other tiny sister moons, Methone and Anthe. First, the three moons may have split from either Mimas or Enceladus. Second, all five moons may be the remains of a larger swarm that traveled in that area close to Saturn. Pallene circles Saturn in approximately 27.7 hours. Because Pallene and its two sister moons orbit at very similar distances from Saturn, they are in a dynamical relationship. Mimas strongly perturbs Pallene, the 2-mile (3-kilometer) diameter moon Methone and the 1-mile (2-kilometer) diameter moon Anthe, all of which orbit between Mimas and the next major moon, Enceladus. The vastly more massive Mimas causes the orbits of the tiny moons to vary by as much as 12.4 miles (20 kilometers). Together, these three moons may also be contributing particles to Saturn's E-ring. Pallene shares its orbit with a faint dust ring around Saturn, now called the Pallene Ring. This ring may be made of particles blasted off Pallene's surface by meteoroid impacts. The name Pallene comes from the name in Greek mythology of one of seven Alkyonides, daughters of the god (or Titan) Alkyoneus who was born of Gaia and the blood of Uranus.", + ], + }, + related: ["sc_cassini"], + }, + pan: { + title: "Pan", + description: { + blurb: [ + "Pan was discovered by M.R. Showalter in 1990 using images taken by the Voyager 2 spacecraft nine years earlier.", + ], + more: [ + "Pan, the innermost of Saturn's known moons, has a mean radius of 8.8 miles (14.1 kilometers) and orbits 83,000 miles (134,000 kilometers) away from Saturn, within the Encke Gap of Saturn's A-ring. As it orbits Saturn every 13.8 hours, it acts as a shepherd moon and is responsible for keeping the Encke Gap open. The gap is a 200 mile (325 kilometer) opening in Saturn's A ring. Pan creates stripes, called \"wakes,\" in the ring material on either side of it. Since ring particles closer to Saturn than Pan move faster in their orbits, these particles pass the moon and receive a gravitational \"kick\" from Pan as they do. This kick causes waves to develop in the gap and also throughout the ring, extending hundreds of miles into the rings. These waves intersect downstream to create the wakes, places where ring material has bunched up in an orderly manner thanks to Pan's gravitational kick. Pan, like Saturn's moon Atlas, has a prominent equatorial ridge that gives it a distinctive flying saucer shape. Moons of Saturn were originally named for Greco-Roman Titans and descendants of the Titans. But as many new moons were discovered scientists began selecting names from more mythologies, including Gallic, Inuit and Norse stories. Pan, a satyr (a creature resembling a man with the hind legs and hooves of a goat), is a Greek god of nature and the forest.", + ], + }, + related: ["sc_cassini"], + }, + pandia: { + title: "Pandia", + description: { + blurb: [ + "This tiny moon of Jupiter was first spotted in 2017 and originally designated S/2017 J4.", + ], + more: [ + "The discovery announcement was made in July 2018. Pandia is the daughter of Zeus and the Moon goddess Selene. Pandia is the goddess of the full moon and the sister of Ersa.", + ], + }, + related: [], + }, + pandora: { + title: "Pandora", + description: { + blurb: [ + "Pandora was discovered in October 1980 by the Voyager 1 science team.", + ], + more: [ + 'Pandora, a potato-shaped moon, is coated in a fine (dust-sized) icy material. Even the craters on Pandora are coated in debris, a stark contrast to the crisply-defined craters of other moons, such as Hyperion. Curious grooves and ridges also appear to cross the surface of the small moon. Pandora is interesting because it tends to disrupt the F ring, while Prometheus helps to keep the primary ring in place. Pandora is about 25.3 miles (40.7 kilometers) in mean radius. It orbits 88,000 miles (142,000 kilometers) away from Saturn, near the F ring, taking 15.1 hours to go around Saturn. Moons of Saturn were originally named for Greco-Roman Titans and descendants of the Titans. But as many new moons were discovered scientists began selecting names from more mythologies, including Gallic, Inuit and Norse stories. Originally called S/1980 S26, Pandora was renamed in 1985. In mythology, Pandora (pan-DOR-uh) was a work of art who was transformed into a human by the gods. Her curiosity was said to have loosed all manner of ills upon the world when she let evil creatures out of a locked box; however, she is also responsible for hope entering the world ("hope" had been the last "creature" in the box).', + ], + }, + related: ["sc_voyager_1", "sc_voyager_2", "sc_cassini"], + }, + pasiphae: { + title: "Pasiphae", + description: { + blurb: [ + "Pasiphae was discovered on Jan. 27, 1908, by Philibert Jacques Melotte with the Greenwich Observatory's 30-inch Cassegrain telescope.", + ], + more: [ + "With a mean radius of 18.6 miles (30 kilometers), Pasiphae is the largest member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. Pasiphae was probably an asteroid that was captured by Jupiter's gravity and then suffered a collision which broke off a number of pieces. Those pieces became at least some, and perhaps all, of the other moons commonly categorized as members of the Pasiphae group. All of the Pasiphae moons are retrograde, which means they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. All of these characteristics support the idea that the Pasiphae satellites began as one or more captured asteroids, rather than forming as part of the original Jupiter system. Both Pasiphae and Sinope are locked in secular resonances with Jupiter, which means that Jupiter's gravity tugs at them at regular intervals in a way that can modify their orbits over time. This could account for the differences in their orbits compared to each other and to other presumed members of the Pasiphae group. Pasiphae has a mean radius of 18.6 miles (30 kilometers), assuming an albedo of 0.04. At a mean distance of about 14.6 million miles (23.6 million kilometers) from Jupiter, the satellite takes about 744 Earth days to complete one orbit. Pasiphae was named for the wife of Minos, who was king of Crete.", + ], + }, + related: [], + }, + pasithee: { + title: "Pasithee", + description: { + blurb: [ + "Pasithee was discovered on Dec. 11, 2001, by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Pasithee is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99 percent of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. All of the Carme moons are retrograde, which means that they orbit Jupiter in the opposite direction from the planet's rotation. Their orbits are also eccentric (elliptical rather than circular) and highly inclined with respect to Jupiter's equatorial plane. They all are very similar in color -- light red -- except for Kalyke, which is considerably redder than the others. All of these characteristics support the idea that the Carme satellites began as a captured asteroid, rather than forming as part of the original Jupiter system. None of the Carme members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Pasithee has a mean radius of about one kilometer. At a mean distance of about 14 million miles (23 million kilometers) from Jupiter, the satellite takes about 719 Earth days to complete one orbit. Originally called S/2001 J6, Pasithee was named for one of the Graces, who were daughters of Zeus, the Greek equivalent of the Roman god Jupiter.", + ], + }, + related: [], + }, + perdita: { + title: "Perdita", + description: { + blurb: [ + "Perdita was discovered 13 years after its picture was taken by Voyager 2 during the spacecraft's flyby in 1986.", + ], + more: [ + "Perdita's orbit lies between those of Belinda and Puck, about 76,400 km from Uranus. It is believed to be about 30 km in diameter and very dark (albedo of about 0.08). Little else is known. University of Arizona's Erich Karkoschka found the moon in the public archive of Voyager 2 images when he compared them with those of the Hubble Space Telescope. The International Astronomical Union (IAU) recognized it as a moon of Uranus, but withdrew its designation as premature when subsequent efforts failed to observe it. Its existence was finally confirmed, however, in 2003, when the Hubble imaged an object right in Perdita's predicted location. Originally called S/1986 U10, Perdita was named for the daughter of Leontes and Hermione in William Shakespeare's play, \"The Winter's Tale.\" In the play Leontes initially refuses to believe that Perdita is his daughter because he thinks that his wife has had an affair with king Polixenes of Bohemia. Circumstances lead to Perdita being abandoned by her father and later found and raised by a Bohemian shepherd. 16 years later Bohemian Prince Florizel meets and falls in love with Perdita and it is revealed that she is the princess of Sicily. Perdita's father Leontes reconciles his differences with king Polixenes, and the marriage is ratified.", + ], + }, + related: ["sc_voyager_2"], + }, + philophrosyne: { + title: "Philophrosyne", + description: { + blurb: [ + "Philophrosyne was discovered in April 2003 by Scott S. Sheppard at the Mauna Kea Observatory in Hawaii, and originally designated S/2003 J15.", + ], + more: [ + 'Philophrosyne is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter\'s gravity and then suffered a collision which broke off a number of pieces. The largest remaining chunk was named "Ananke," and the smaller pieces became the other 15 moons in the Ananke group. Philophrosyne has a mean radius of less than a mile (about one kilometer), assuming an albedo of 0.04. At a mean distance of about 14 million miles (22.6 million kilometers) from Jupiter, it takes about 690 Earth days to complete one orbit.', + ], + }, + related: [], + }, + phobos: { + title: "Phobos", + description: { + blurb: [ + "Phobos is the larger of Mars' two moons. It orbits Mars three times a day, and is so close to the planet's surface that in some locations on Mars it cannot always be seen.", + ], + more: [ + "Phobos, gouged and nearly shattered by a giant impact crater and beaten by thousands of meteorite impacts, is on a collision course with Mars. Phobos is the larger of Mars' two moons and is 17 x 14 x 11 miles (27 by 22 by 18 kilometers) in diameter. Phobos is nearing Mars at a rate of six feet (1.8 meters) every hundred years; at that rate, it will either crash into Mars in 50 million years or break up into a ring. Its most prominent feature is the 6-mile (9.7 kilometer) crater Stickney, its impact causing streak patterns across the moon's surface. Stickney was seen by Mars Global Surveyor to be filled with fine dust, with evidence of boulders sliding down its sloped surface.", + ], + }, + related: [], + }, + phoebe: { + title: "Phoebe", + description: { + blurb: ["Phoebe is one of the furthest moons from Saturn."], + more: [ + "Phoebe is one of Saturn's most intriguing moons, orbiting at a distance of 8,049,668 miles (12,952,000 kilometers) from the planet, almost four times the distance from Saturn than its nearest neighbor, the moon Iapetus. Phoebe and Iapetus are the only major moons in the Saturnian system that do not orbit closely to the plane of Saturn's equator. Phoebe is also located near a very faint ring of Saturn that was only discovered in 2009, called the Phoebe ring.", + "Phoebe is roughly spherical and has a mean radius of about 66.2 miles (106.5 kilometers), about one-sixteenth the radius of Earth's Moon. Phoebe rotates on its axis every nine hours, and it completes a full orbit around Saturn in about 18 Earth months. Its irregular, elliptical orbit is inclined about 175 degrees to Saturn's equator. Phoebe's orbit is also retrograde, which means it goes around Saturn in the opposite direction than most other moons — as well as most objects in the solar system.", + "Unlike most major moons orbiting Saturn, Phoebe is very dark and reflects only 6 percent of the sunlight it receives. Its darkness and irregular, retrograde orbit suggest Phoebe is most likely a captured object. A captured object is a celestial body that is trapped by the gravitational pull of a much bigger body, generally a planet. Phoebe's darkness, in particular, suggests that the small moon comes from the outer solar system, an area where there is plenty of dark material.", + "Some scientists think Phoebe could be a captured Centaur. Centaurs are believed to be Kuiper Belt bodies that migrated into the inner solar system. Centaurs are found between the asteroid belt and the Kuiper Belt, and are considered a kind of intermediate type of small body, neither an asteroid nor a Kuiper Belt object. If Phoebe is indeed a captured Centaur, images and scientific data of Phoebe taken by the Cassini spacecraft will give scientists the first opportunity to study a Centaur. Centaurs are of extreme interest to scientists because they are believed to be primordial; that is, they appear to date from the formation of the solar system. These objects are the building blocks of the solar system, the leftovers that never pulled into a planet. And because of its relative small size, Phoebe might never have heated up enough to change its chemical composition — which increases the scientific value of its study.", + ], + }, + related: ["sc_voyager_2", "sc_cassini"], + }, + polydeuces: { + title: "Polydeuces", + description: { + blurb: [ + "Polydeuces was discovered by the Cassini mission team on Oct. 21, 2004, and upon further review of Cassini images, scientists found it in images from April 9 of the same year.", + ], + more: [ + 'Polydeuces is a small moon with a mean radius of just 0.8 miles (1.3 kilometers) orbiting Saturn at a distance of about 234,000 miles (377,000 kilometers), taking 2.7 Earth days to go around the planet. Polydeuces is an example of a so-called "Trojan" moon — it follows a larger moon in orbit around the planet (in the case of Polydeuces, the larger moon is Dione). Polydeuces is a trailing co-orbital of Dione, while the moon Helene is the leading co-orbital. Trojan moons are found near stable "Lagrangian points" — places where the gravitational pull of the planet and the larger moon become balanced. The Trojans are situated 60 degrees ahead or behind the larger moon in its orbit. It is believed that Polydeuces can get as close as 39 degrees to Dione and then drift as far as 92 degrees from it, taking over two years to complete its journey around the Lagrange point. If verified, the extent of this wandering is the largest detected so far for any Trojan moon. Originally designated S/2004 S5, Polydeuces (another name for Pollux) is named for the son of Leda and Zeus.', + ], + }, + related: ["sc_cassini"], + }, + portia: { + title: "Portia", + description: { + blurb: [ + "Portia was discovered January 1986 in images sent back by the Voyager 2 spacecraft during its flyby of Uranus.", + ], + more: [ + "Very little is known about Uranus' small and fast-moving moon Portia. It is known that Portia has a diameter of 140 km, making it one of the largest of Uranus' lesser satellites. It is also known that Portia orbits Uranus in less than one Earth day. This moon is named after Portia, the heroine of William Shakespeare's 16th century play \"The Merchant of Venice.\" It was originally designated S/1986 U 1", + ], + }, + related: ["sc_voyager_2"], + }, + praxidike: { + title: "Praxidike", + description: { + blurb: [ + "Praxidike was discovered on Nov. 23, 2000, by Scott S. Sheppard, David C. Jewitt, Yanga R. Fernandez, and Eugene Magnier at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + 'Praxidike is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter\'s gravity and then suffered a collision which broke off a number of pieces. The largest remaining chunk was named "Ananke," and the smaller pieces became the other 15 moons in the Ananke group. If Ananke, with a mean radius of 8.7 miles (14 kilometers), is considered the slightly diminished original asteroid, then Praxidike, with a mean radius of 2 miles (3.4 kilometers), assuming an albedo of 0.04, is the largest chip that was knocked off the asteroid. Praxidike is colored a similar gray to two other moons in the Ananke family: Harpalyke and Iocaste. At a mean distance of about 13 million miles (21.1 million kilometers) from Jupiter, Praxidike takes about 625 Earth days to complete one orbit. Originally called S/2000 J7, Praxidike was named for the Greek goddess of justice or punishment. She was the mother of Klesios, Harmonia and Arete by Zeus, the Greek equivalent of the Roman god Jupiter.', + ], + }, + related: [], + }, + prometheus: { + title: "Prometheus", + description: { + blurb: [ + "The Voyager 1 science team discovered Prometheus in October 1980.", + ], + more: [ + "Prometheus acts as a shepherding moon, constraining the extent of the inner edge of Saturn's F Ring. Prometheus is extremely irregular and has visible craters — some up to 12.4 miles (20 kilometers) in diameter. However, it is much less cratered than its nearby neighbors Pandora, Janus and Epimetheus. The density of Prometheus has been estimated to be low; it is probably a porous, icy body. The potato-shaped moon is about 26.8 miles (43.1 kilometers) in mean radius, orbiting Saturn at a distance of 87,000 miles (139,000 kilometers), taking 14.7 hours to go around the planet. Moons of Saturn were originally named for Greco-Roman Titans and descendants of the Titans. But as many new moons were discovered scientists began selecting names from more mythologies, including Gallic, Inuit and Norse stories. Originally designated S/1980 S27, Prometheus [pro-MEE-thee-us] is named for the son of the Titan Iapetus and brother of Atlas and Epimetheus. He is best known in Greek mythology for stealing fire from the gods and giving it to humanity.", + ], + }, + related: ["sc_voyager_1", "sc_cassini"], + }, + prospero: { + title: "Prospero", + description: { + blurb: [ + "Prospero is a small, dark, irregular moon that orbits Uranus in the opposite direction from the regular satellites and the rotation of the planet, itself (known as a retrograde orbit).", + ], + }, + related: [], + }, + proteus: { + title: "Proteus", + description: { + blurb: ["Proteus was discovered in 1989 by the Voyager 2 spacecraft."], + more: [ + "Proteus is one of the largest of Neptune's known moons, although it is not as big as Triton. The moon has an odd box-like shape and if it had just a little more mass it would be able to transform into a sphere. Proteus orbits Neptune about every 27 hours.", + ], + }, + related: ["sc_voyager_2"], + }, + psamathe: { + title: "Psamathe", + description: { + blurb: [ + "Psamathe is so distant from Neptune it takes almost 26 Earth years to make a single orbit around the ice giant. The moon's orbit is among the most distant from its planet than any other known moon in our solar system.", + "The small moon shares similar orbital parameters with with another moon of Neptune -- Neso. Both Psamathe and Neso may be fragments from the break-up of a larger moon billions of years ago.", + ], + }, + related: [], + }, + puck: { + title: "Puck", + description: { + blurb: [ + "Puck was discovered December 1985 in images sent back by the Voyager 2 spacecraft during its flyby of Uranus.", + ], + more: [ + "Puck is one of the small inner moons of Uranus. With a diameter of about 150 km (about 90 miles), Puck is the largest of Uranus' known lesser satellites. Puck orbits Uranus in less than one Earth day. Originally designated S/1985 U1, Puck is named for a mischievous sprite in William Shakespeare's \"A Midsummer Night's Dream.\"​", + ], + }, + related: ["sc_voyager_2"], + }, + rhea: { + title: "Rhea", + description: { + blurb: ["Rhea is the second largest moon of Saturn"], + more: [ + "Rhea is a small, cold, airless body that is very similar to sister moons Dione and Tethys. As with the other two moons, Rhea is tidally locked in phase with its parent — one side always faces toward Saturn — as it completes its 4.5-Earth-day orbit around the planet. Rhea's surface temperatures are also similar to Dione and Tethys, being roughly as warm as -281 degrees Fahrenheit (-174 degrees Celsius) in sunlit areas and ranging down to -364 degrees Fahrenheit (-220 degrees Celsius) in shaded areas. Also like Dione and Tethys, Rhea has a high reflectivity (or geometric albedo) suggesting a surface composition largely of water ice, which behaves like rock in Rhea's temperature range. In 2008, the Cassini spacecraft found evidence of material orbiting Rhea — the first time rings had been found around a moon. A broad debris disk and at least one ring appear to have been detected by a suite of six instruments on Cassini specifically designed to study the atmospheres and particles around Saturn and its moons.", + ], + }, + related: ["sc_cassini", "sc_voyager_1", "sc_voyager_2"], + }, + rosalind: { + title: "Rosalind", + description: { + blurb: [ + "Rosalind was discovered by the Voyager 2 science team on 13 January 1986.", + ], + more: [ + "Little is known about Rosalind, one of several satellites discovered by Voyager 2 as it flew by Uranus in 1986. Rosalind is one of Uranus' inner moons and has a radius of about 22 miles (36 kilometers). Originally designated S/1986 U4, Rosalind was named for the daughter of a banished Duke in Shakespeare's play \"As You Like It.\"​", + ], + }, + related: ["sc_voyager_2"], + }, + s_2003_j_10: { + title: "S/2003 J 10", + description: { + blurb: [ + "S/2003 J 10 was discovered in February 2003 at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "S/2003 J 10 has a mean radius of less than a mile, or about one kilometer. At a mean distance of about 14 million miles (23 million kilometers) from Jupiter, the satellite takes about 716 Earth days to complete one orbit. S/2003 J10 was so designated because it is a satellite (S) that was discovered in 2003, and was the 10th satellite of Jupiter (J) to be found that year.", + ], + }, + related: [], + }, + s_2003_j_12: { + title: "S/2003 J 12", + description: { + blurb: [ + 'The name "S/2003 J 12" means that it is a satellite (S) that was discovered in 2003 orbiting Jupiter (J), and that it was the 12th satellite of Jupiter discovered that year.', + ], + more: [ + "At a distance of about 11 million miles (17.8 million kilometers) from Jupiter, S/2003 J12 is the innermost of the known retrograde satellites (those which orbit Jupiter in the opposite direction from the planet's rotation). It takes almost 490 Earth days tocomplete one orbit, and its orbit is highly inclined with respect to Jupiter's equatorial plane. S/2003 J12 is less than a mile across ( about one kilometer), assuming an albedo of 0.04).", + ], + }, + related: [], + }, + s_2003_j_16: { + title: "S/2003 J 16", + description: { + blurb: [ + "S/2003 J 16 was discovered in April 2003 by Brett J. Gladman at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "S/2003 J 16 is a member of the Ananke group. S/2003 J16 has a mean radius of about one kilometer (assuming an albedo of 0.04). At a mean distance of about 13 million miles (20.9 million kilometers) from Jupiter, it takes about 616 Earth days to complete one orbit.", + ], + }, + related: [], + }, + s_2003_j_2: { + title: "S/2003 J 2", + description: { + blurb: [ + "This moon of Jupiter, like many others, was discovered in February or March 2003 at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "This satellite has a mean radius of 1 km, assuming an albedo of 0.04. At a mean distance of about 18 million miles (28.3 million kilometers) from Jupiter, the satellite takes about 979 Earth days to complete one orbit.", + ], + }, + related: [], + }, + s_2003_j_23: { + title: "S/2003 J 23", + description: { + blurb: [ + "This moon of Jupiter, like many others, was discovered in 2003 at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "S/2003 J 23 is considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. S/2003 J 23 has a mean radius of less than a mile (about one kilometer), assuming an albedo of 0.04. At a mean distance of about 15 million miles (23.5 million kilometers) from Jupiter, the satellite takes about 732 Earth days to complete one orbit.", + ], + }, + related: [], + }, + s_2003_j_24: { + title: "S/2003 J 24", + description: { + blurb: [ + "This moon of Jupiter was independently discovered in 2021 using data from 2003.", + ], + more: [ + "S/2003 J 24 orbits Jupiter at an average distance of 23,088,000 km (0.15433 AU) in 715.4 days, at an inclination of 162° to the ecliptic, in a retrograde direction and with an eccentricity of 0.25. It belongs to the Carme group, made up of irregular retrograde moons orbiting Jupiter at a distance ranging between 23 and 24 Gm and at an inclination of about 165°.", + ], + }, + related: [], + }, + s_2003_j_4: { + title: "S/2003 J 4", + description: { + blurb: [ + "This moon of Jupiter, like many others, was discovered in 2003 at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "S/2003 J 4 is a member of the Pasiphae group, and has a mean radius of less than a mile (about 1 kilometer), assuming an albedo of 0.04. At a mean distance of about 15 million miles (23.9 million kilometers) from Jupiter, the satellite takes about 755 Earth days to complete one orbit.", + ], + }, + related: [], + }, + s_2003_j_9: { + title: "S/2003 J 9", + description: { + blurb: [ + "This moon of Jupiter, like many others, was discovered in 2003 at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "S/2003 J 9 is a member of the Carme group, and has a mean radius of about 1,600 feet (half a kilometer). At a mean distance of about 15 million miles (23.4 million kilometers) from Jupiter, the satellite takes about 733 Earth days to complete one orbit.", + ], + }, + related: [], + }, + s_2004_s_7: { + title: "S/2004 S 7", + description: { + blurb: [ + "S/2004 S 7 is a natural satellite of Saturn discovered in 2004. It was considered lost but was later recovered when observed again in 2022.", + ], + more: [ + "S/2004 S 7 is about 6 kilometres in diameter, and orbits Saturn in 1173.932 days.​", + ], + }, + }, + s_2004_s_12: { + title: "S/2004 S 12", + description: { + blurb: [ + "S/2004 S 12 is a natural satellite of Saturn discovered in 2004. It was considered lost but was later recovered when observed again in 2022.", + ], + more: [ + "S/2004 S 12 is about 5 kilometres in diameter, and orbits Saturn in 1048.567 days.​", + ], + }, + }, + s_2004_s_13: { + title: "S/2004 S 13", + description: { + blurb: [ + "S/2004 S 13 is a natural satellite of Saturn discovered in 2004. It was considered lost but was later recovered when observed again in 2022.", + ], + more: [ + "S/2004 S 13 is about 6 kilometres in diameter, and orbits Saturn in 905.848 days.​", + ], + }, + }, + s_2004_s_17: { + title: "S/2004 S 17", + description: { + blurb: [ + "S/2004 S 17 is a natural satellite of Saturn discovered in 2004. It was considered lost but was later recovered when observed again in 2022.", + ], + more: [ + "S/2004 S 17 is about 4 kilometres in diameter, and orbits Saturn in 985.453 days, at an inclination of 167° to the ecliptic.​", + ], + }, + }, + s_2004_s_21: { + title: "S/2004 S 21", + description: { + blurb: [ + "S/2004 S 21 is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "S/2004 S 21 is about 3 kilometres in diameter, and orbits Saturn at an average distance of 22,645 Gm in 1272.61 days, at an inclination of 160° to the ecliptic, in a retrograde direction and with an eccentricity of 0.318.​", + ], + }, + }, + s_2004_s_24: { + title: "S/2004 S 24", + description: { + blurb: [ + "S/2004 S 24 is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "S/2004 S 24 is about 3 kilometres in diameter, and orbits Saturn in 1294.25 days, at an inclination of 35.5° to the ecliptic, in a prograde direction and with an eccentricity of 0.085.", + ], + }, + }, + s_2004_s_28: { + title: "S/2004 S 28", + description: { + blurb: [ + "S/2004 S 28 is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "S/2004 S 28 is about 4 kilometres in diameter, and orbits Saturn in 1220.31 days, at an inclination of 170° to the ecliptic.", + ], + }, + }, + s_2004_s_31: { + title: "S/2004 S 31", + description: { + blurb: [ + "S/2004 S 31 is a natural satellite of Saturn and a member of the Inuit group. It was announced in 2019 from observations made from 2004 to 2007.", + ], + more: [ + "S/2004 S 31 is about 4 kilometres in diameter, and orbits Saturn in 869.65 days.", + ], + }, + }, + s_2004_s_36: { + title: "S/2004 S 36", + description: { + blurb: [ + "S/2004 S 36 is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "S/2004 S 36 is about 3 kilometres in diameter, and orbits Saturn in 1319.07 days, at an inclination of 155° to the ecliptic, in a retrograde direction and with an eccentricity of 0.748, the highest of any of Saturn's moons.", + ], + }, + }, + s_2004_s_37: { + title: "S/2004 S 37", + description: { + blurb: [ + "S/2004 S 37 is a natural satellite of Saturn. Its discovery was announced by Scott S. Sheppard, David C. Jewitt, and Jan Kleyna on October 8, 2019 from observations taken between December 12, 2004 and February 2, 2006.", + ], + more: [ + "S/2004 S 37 is about 4 kilometres in diameter, and orbits Saturn in 748.18 days.", + ], + }, + }, + s_2004_s_39: { + title: "S/2004 S 39", + description: { + blurb: [ + "S/2004 S 39 is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "S/2004 S 39 is about 3 kilometres in diameter, and orbits Saturn in 1351.83 days, at an inclination of 167° to the ecliptic, in a retrograde direction and with an eccentricity of 0.080.", + ], + }, + }, + s_2004_s_40: { + title: "S/2004 S 40", + description: { + blurb: [ + "S/2004 S 40 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 40 is about 4 kilometers in diameter and orbits Saturn at an average distance of 16.1 million km in 764.6 days. It has an inclination of 169.2° to the ecliptic in a retrograde direction with an eccentricity of 0.297.", + ], + }, + related: [], + }, + s_2004_s_41: { + title: "S/2004 S 41", + description: { + blurb: [ + "S/2004 S 41 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 41 is about 4 kilometers in diameter and orbits Saturn at an average distance of 18.1 million km in 914.61 days. It has an inclination of 165.7° to the ecliptic in a retrograde direction with an eccentricity of 0.300.", + ], + }, + related: [], + }, + s_2004_s_42: { + title: "S/2004 S 42", + description: { + blurb: [ + "S/2004 S 42 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 42 is about 4 kilometers in diameter and orbits Saturn at an average distance of 18.2 million km in 925.91 days. It has an inclination of 165.7° to the ecliptic in a retrograde direction with an eccentricity of 0.158.", + ], + }, + related: [], + }, + s_2004_s_43: { + title: "S/2004 S 43", + description: { + blurb: [ + "S/2004 S 43 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 43 is about 4 kilometers in diameter and orbits Saturn at an average distance of 18.9 million km in 980.08 days. It has an inclination of 171.1° to the ecliptic in a retrograde direction with an eccentricity of 0.432.", + ], + }, + related: [], + }, + s_2004_s_44: { + title: "S/2004 S 44", + description: { + blurb: [ + "S/2004 S 44 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 44 is about 5 kilometers in diameter and orbits Saturn at an average distance of 19.5 million km in 1026.16 days. It has an inclination of 167.7° to the ecliptic in a retrograde direction with an eccentricity of 0.129.", + ], + }, + related: [], + }, + s_2004_s_45: { + title: "S/2004 S 45", + description: { + blurb: [ + "S/2004 S 45 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 45 is about 4 kilometers in diameter and orbits Saturn at an average distance of 19.7 million km in 1038.7 days. It has an inclination of 154.0° to the ecliptic in a retrograde direction with an eccentricity of 0.551.", + ], + }, + related: [], + }, + s_2004_s_46: { + title: "S/2004 S 46", + description: { + blurb: [ + "S/2004 S 46 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 46 is about 3 kilometers in diameter and orbits Saturn at an average distance of 20.5 million km in 1107.58 days. It has an inclination of 177.2° to the ecliptic in a retrograde direction with an eccentricity of 0.249.", + ], + }, + related: [], + }, + s_2004_s_47: { + title: "S/2004 S 47", + description: { + blurb: [ + "S/2004 S 47 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 47 is about 4 kilometers in diameter and orbits Saturn at an average distance of 16.1 million km in 762.49 days. It has an inclination of 160.9° to the ecliptic in a retrograde direction with an eccentricity of 0.291.", + ], + }, + related: [], + }, + s_2004_s_48: { + title: "S/2004 S 48", + description: { + blurb: [ + "S/2004 S 48 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 48 is about 4 kilometers in diameter and orbits Saturn at an average distance of 22.1 million km in 1242.4 days. It has an inclination of 161.9° to the ecliptic in a retrograde direction with an eccentricity of 0.374.", + ], + }, + related: [], + }, + s_2004_s_49: { + title: "S/2004 S 49", + description: { + blurb: [ + "S/2004 S 49 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 49 is about 4 kilometers in diameter and orbits Saturn at an average distance of 22.4 million km in 1264.25 days. It has an inclination of 159.7° to the ecliptic in a retrograde direction with an eccentricity of 0.453.", + ], + }, + related: [], + }, + s_2004_s_50: { + title: "S/2004 S 50", + description: { + blurb: [ + "S/2004 S 50 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 50 is about 3 kilometers in diameter and orbits Saturn at an average distance of 22.3 million km in 1260.44 days. It has an inclination of 164.0° to the ecliptic in a retrograde direction with an eccentricity of 0.450.", + ], + }, + related: [], + }, + s_2004_s_51: { + title: "S/2004 S 51", + description: { + blurb: [ + "S/2004 S 51 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 51 is about 4 kilometers in diameter and orbits Saturn at an average distance of 25.2 million km in 1519.43 days. It has an inclination of 171.2° to the ecliptic in a retrograde direction with an eccentricity of 0.201.", + ], + }, + related: [], + }, + s_2004_s_52: { + title: "S/2004 S 52", + description: { + blurb: [ + "S/2004 S 52 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 52 is about 3 kilometers in diameter and orbits Saturn at an average distance of 26.4 million km in 1633.98 days. It has an inclination of 165.3° to the ecliptic in a retrograde direction with an eccentricity of 0.292.", + ], + }, + related: [], + }, + s_2004_s_53: { + title: "S/2004 S 53", + description: { + blurb: [ + "S/2004 S 53 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2004 S 53 is about 4 kilometers in diameter and orbits Saturn at an average distance of 23.3 million km in 1342.44 days. It has an inclination of 162.6° to the ecliptic in a retrograde direction with an eccentricity of 0.240.", + ], + }, + related: [], + }, + s_2005_s_4: { + title: "S/2005 S 4", + description: { + blurb: [ + "S/2005 S 4 is a natural satellite of Saturn, belonging to the Inuit group. It was discovered in 2005 and announced in 2023.", + ], + more: [ + "S/2005 S 4 is about 5 kilometers in diameter and orbits Saturn at an average distance of 11.3 million km in 450.22 days. It has an inclination of 48.0° to the ecliptic in a prograde direction with an eccentricity of 0.315.", + ], + }, + related: [], + }, + s_2005_s_5: { + title: "S/2005 S 5", + description: { + blurb: [ + "S/2005 S 5 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2005 and announced in 2023.", + ], + more: [ + "S/2005 S 5 is about 3 kilometers in diameter and orbits Saturn at an average distance of 21.4 million km in 1177.82 days. It has an inclination of 169.5° to the ecliptic in a retrograde direction with an eccentricity of 0.588.", + ], + }, + related: [], + }, + s_2006_s_1: { + title: "S/2006 S 1", + description: { + blurb: [ + "S/2006 S 1 is a natural satellite of Saturn, discovered in 2006.", + ], + more: [ + "S/2006 S 1 is about 6 kilometres in diameter, and orbits Saturn in 951.1 days, at an inclination of 154.6° to the ecliptic.", + ], + }, + }, + s_2006_s_10: { + title: "S/2006 S 10", + description: { + blurb: [ + "S/2006 S 10 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 10 is about 3 kilometers in diameter and orbits Saturn at an average distance of 19.0 million km in 983.14 days. It has an inclination of 161.6° to the ecliptic in a retrograde direction with an eccentricity of 0.151.", + ], + }, + related: [], + }, + s_2006_s_11: { + title: "S/2006 S 11", + description: { + blurb: [ + "S/2006 S 11 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2004 and announced in 2023.", + ], + more: [ + "S/2006 S 11 is about 3 kilometers in diameter and orbits Saturn at an average distance of 19.7 million km in 1042.28 days. It has an inclination of 174.1° to the ecliptic in a retrograde direction with an eccentricity of 0.144.", + ], + }, + related: [], + }, + s_2006_s_12: { + title: "S/2006 S 12", + description: { + blurb: [ + "S/2006 S 12 is a natural satellite of Saturn, belonging to the Gallic group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 12 is about 4 kilometers in diameter and orbits Saturn at an average distance of 19.6 million km in 1035.05 days. It has an inclination of 38.6° to the ecliptic in a prograde direction with an eccentricity of 0.542.", + ], + }, + related: [], + }, + s_2006_s_13: { + title: "S/2006 S 13", + description: { + blurb: [ + "S/2006 S 13 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 13 is about 4 kilometers in diameter and orbits Saturn at an average distance of 20.0 million km in 1060.63 days. It has an inclination of 162.0° to the ecliptic in a retrograde direction with an eccentricity of 0.313.", + ], + }, + related: [], + }, + s_2006_s_14: { + title: "S/2006 S 14", + description: { + blurb: [ + "S/2006 S 14 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 14 is about 3 kilometers in diameter and orbits Saturn at an average distance of 21.1 million km in 1152.68 days. It has an inclination of 166.7° to the ecliptic in a retrograde direction with an eccentricity of 0.060.", + ], + }, + related: [], + }, + s_2006_s_15: { + title: "S/2006 S 15", + description: { + blurb: [ + "S/2006 S 15 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 15 is about 4 kilometers in diameter and orbits Saturn at an average distance of 21.8 million km in 1213.96 days. It has an inclination of 161.1° to the ecliptic in a retrograde direction with an eccentricity of 0.117.", + ], + }, + related: [], + }, + s_2006_s_16: { + title: "S/2006 S 16", + description: { + blurb: [ + "S/2006 S 16 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 16 is about 3 kilometers in diameter and orbits Saturn at an average distance of 21.7 million km in 1207.52 days. It has an inclination of 164.1° to the ecliptic in a retrograde direction with an eccentricity of 0.204.", + ], + }, + related: [], + }, + s_2006_s_17: { + title: "S/2006 S 17", + description: { + blurb: [ + "S/2006 S 17 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 17 is about 4 kilometers in diameter and orbits Saturn at an average distance of 22.4 million km in 1264.58 days. It has an inclination of 168.7° to the ecliptic in a retrograde direction with an eccentricity of 0.425.", + ], + }, + related: [], + }, + s_2006_s_18: { + title: "S/2006 S 18", + description: { + blurb: [ + "S/2006 S 18 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 18 is about 4 kilometers in diameter and orbits Saturn at an average distance of 22.8 million km in 1298.4 days. It has an inclination of 169.5° to the ecliptic in a retrograde direction with an eccentricity of 0.131.", + ], + }, + related: [], + }, + s_2006_s_19: { + title: "S/2006 S 19", + description: { + blurb: [ + "S/2006 S 19 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 19 is about 4 kilometers in diameter and orbits Saturn at an average distance of 23.8 million km in 1389.33 days. It has an inclination of 175.5° to the ecliptic in a retrograde direction with an eccentricity of 0.467.", + ], + }, + related: [], + }, + s_2006_s_20: { + title: "S/2006 S 20", + description: { + blurb: [ + "S/2006 S 20 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 20 is about 5 kilometers in diameter and orbits Saturn at an average distance of 13.2 million km in 567.27 days. It has an inclination of 173.1° to the ecliptic in a retrograde direction with an eccentricity of 0.206.", + ], + }, + related: [], + }, + s_2006_s_3: { + title: "S/2006 S 3", + description: { + blurb: [ + "S/2006 S 3 is a natural satellite of Saturn, discovered in 2006.", + ], + more: [ + "S/2006 S 3 is about 6 kilometres in diameter, and orbits Saturn at an average distance of 21,308,400 km in 1160.7 days, at an inclination of 152.8° to the ecliptic.", + ], + }, + }, + s_2006_s_9: { + title: "S/2006 S 9", + description: { + blurb: [ + "S/2006 S 9 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2006 and announced in 2023.", + ], + more: [ + "S/2006 S 9 is about 3 kilometers in diameter and orbits Saturn at an average distance of 14.4 million km in 647.89 days. It has an inclination of 173.0° to the ecliptic in a retrograde direction with an eccentricity of 0.248.", + ], + }, + related: [], + }, + s_2007_s_2: { + title: "S/2007 S 2", + description: { + blurb: [ + "S/2007 S 2 is a natural satellite of Saturn, and was discovered in 2007.", + ], + more: [ + "S/2007 S 2 is about 6 kilometres in diameter, and orbits Saturn in 759.2 days.", + ], + }, + }, + s_2007_s_3: { + title: "S/2007 S 3", + description: { + blurb: [ + "S/2007 S 3 is a natural satellite of Saturn discovered in 2007. It has not been seen since and is considered to be lost.", + ], + more: [ + "S/2007 S 3 is about 5 kilometres in diameter, and orbits Saturn at an average distance of 20,518,500 kilometres in about 1100 days.", + ], + }, + }, + s_2007_s_5: { + title: "S/2007 S 5", + description: { + blurb: [ + "S/2007 S 5 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2007 and announced in 2023.", + ], + more: [ + "S/2007 S 5 is about 4 kilometers in diameter and orbits Saturn at an average distance of 15.8 million km in 746.88 days. It has an inclination of 158.4° to the ecliptic in a retrograde direction with an eccentricity of 0.104.", + ], + }, + related: [], + }, + s_2007_s_6: { + title: "S/2007 S 6", + description: { + blurb: [ + "S/2007 S 6 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2007 and announced in 2023.", + ], + more: [ + "S/2007 S 6 is about 3 kilometers in diameter and orbits Saturn at an average distance of 18.5 million km in 949.5 days. It has an inclination of 166.5° to the ecliptic in a retrograde direction with an eccentricity of 0.169.", + ], + }, + related: [], + }, + s_2007_s_7: { + title: "S/2007 S 7", + description: { + blurb: [ + "S/2007 S 7 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2007 and announced in 2023.", + ], + more: [ + "S/2007 S 7 is about 4 kilometers in diameter and orbits Saturn at an average distance of 15.9 million km in 754.29 days. It has an inclination of 169.2° to the ecliptic in a retrograde direction with an eccentricity of 0.217.", + ], + }, + related: [], + }, + s_2007_s_8: { + title: "S/2007 S 8", + description: { + blurb: [ + "S/2007 S 8 is a natural satellite of Saturn, belonging to the Gallic group. It was discovered in 2007 and announced in 2023.", + ], + more: [ + "S/2007 S 8 is about 4 kilometers in diameter and orbits Saturn at an average distance of 17.0 million km in 836.9 days. It has an inclination of 36.2° to the ecliptic in a prograde direction with an eccentricity of 0.490.", + ], + }, + related: [], + }, + s_2007_s_9: { + title: "S/2007 S 9", + description: { + blurb: [ + "S/2007 S 9 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2007 and announced in 2023.", + ], + more: [ + "S/2007 S 9 is about 4 kilometers in diameter and orbits Saturn at an average distance of 20.2 million km in 1078.07 days. It has an inclination of 159.3° to the ecliptic in a retrograde direction with an eccentricity of 0.360.", + ], + }, + related: [], + }, + s_2009_s_1: { + title: "S/2009 S 1", + description: { + blurb: [ + 'S/2009 S 1 is a "propeller moonlet" of Saturn orbiting at a distance of 117,000 km (73,000 mi), in the outer part of the B Ring, and with a diameter of 300 m (1,000 ft).', + ], + more: [ + "The moonlet was discovered by the Cassini Imaging Team on 26 July 2009, when it cast a shadow 36 km (22 mi) long onto the B Ring. S/2009 S 1 protrudes 150 m (500 ft) north of the ring.", + ], + }, + }, + s_2011_j_3: { + title: "S/2011 J 3", + description: { + blurb: [ + "This small moon of Jupiter was discovered in 2011 but only announced in late 2022.", + ], + more: [ + "S/2011 J 3 is part of the Himalia group, a tight cluster of prograde irregular moons of Jupiter that follow similar orbits to Himalia at semi-major axes between 11–12 million km (6.8–7.5 million mi) and inclinations between 26–31°.[3] With an estimated diameter of 3 km (1.9 mi) for an absolute magnitude of 16.3, it is among the smallest known members of the Himalia group.", + ], + }, + related: [], + }, + s_2016_j_3: { + title: "S/2016 J 3", + description: { + blurb: [ + "S/2016 J 3 is a small outer natural satellite of Jupiter discovered in 2016 but only announced and confirmed in early 2023.", + ], + more: [ + "S/2016 J 3 is part of the Carme group, a tight cluster of retrograde irregular moons of Jupiter that follow similar orbits to Carme at semi-major axes between 22–24 million km (14–15 million mi), orbital eccentricities between 0.2–0.3, and inclinations between 163–166°. It has a diameter of about 2 km (1.2 mi) for an absolute magnitude of 16.7.", + ], + }, + related: [], + }, + s_2016_j_4: { + title: "S/2016 J 4", + description: { + blurb: [ + "S/2016 J 4 is a small outer natural satellite of Jupiter discovered in 2016 but only announced and confirmed in early 2023.", + ], + more: [ + "S/2016 J 4 is part of the Pasiphae group, a dispersed cluster of distant retrograde irregular moons of Jupiter that follow similar orbits to Pasiphae at semi-major axes between 22–25 million km (14–16 million mi), orbital eccentricities between 0.2–0.6, and inclinations between 140–160°. It has a diameter of about 1 km (0.62 mi) for an absolute magnitude of 17.3, making it one of Jupiter's smallest known moons.", + ], + }, + related: [], + }, + s_2018_j_2: { + title: "S/2018 J 2", + description: { + blurb: [ + "S/2018 J 2 is a small outer natural satellite of Jupiter discovered in 2018 but only announced in late 2022.", + ], + more: [ + "S/2018 J 2 is part of the Himalia group, a tight cluster of prograde irregular moons of Jupiter that follow similar orbits to Himalia at semi-major axes between 11–12 million km (6.8–7.5 million mi) and inclinations between 26–31°. With an estimated diameter of 3 km (1.9 mi) for an absolute magnitude of 16.5, it is among the smallest known members of the Himalia group.", + ], + }, + related: [], + }, + s_2018_j_3: { + title: "S/2018 J 3", + description: { + blurb: [ + "S/2018 J 3 is a small outer natural satellite of Jupiter discovered in 2018 but only announced in early 2023.", + ], + more: [ + "S/2018 J 3 is part of the Carme group, a tight cluster of retrograde irregular moons of Jupiter that follow similar orbits to Carme at semi-major axes between 22–24 million km (14–15 million mi), orbital eccentricities between 0.2–0.3, and inclinations between 163–166°. It has a diameter of about 1 km (0.62 mi) for an absolute magnitude of 17.3, making it one of Jupiter's smallest known moons.", + ], + }, + related: [], + }, + s_2018_j_4: { + title: "S/2018 J 4", + description: { + blurb: [ + "S/2018 J 4 is a small outer natural satellite of Jupiter discovered in 2018 but only announced in early 2023.", + ], + more: [ + "S/2018 J 4 is an irregular moon of Jupiter on an highly inclined prograde orbit at an angle of 53° with respect to the ecliptic plane. It belongs to the same group as the similarly-inclined moon Carpo, which was long thought to be an outlier until the discovery of S/2018 J 4. S/2018 J 4's orbit is highly variable over time due to gravitational perturbations by the Sun and other planets. On average, S/2018 J 4's orbit has a semi-major axis of 16.3 million km (10.1 million mi), an eccentricity of 0.18, and a very high inclination of 50° with respect to the ecliptic.", + ], + }, + related: [], + }, + s_2019_s_1: { + title: "S/2019 S 1", + description: { + blurb: [ + "S/2019 S 1 is a natural satellite of Saturn, belonging to the Inuit group. It was discovered in 2019 and announced in 2021.", + ], + more: [ + "S/2019 S 1 is about 5 kilometers in diameter and orbits Saturn at an average distance of 11.2 million km in 445.513 days. It has an inclination of 49.5° to the ecliptic in a prograde direction and with an eccentricity of 0.623.", + ], + }, + related: [], + }, + s_2019_s_10: { + title: "S/2019 S 10", + description: { + blurb: [ + "S/2019 S 10 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 10 is about 3 kilometers in diameter and orbits Saturn at an average distance of 20.7 million km in 1123.04 days. It has an inclination of 163.9° to the ecliptic in a retrograde direction with an eccentricity of 0.249.", + ], + }, + related: [], + }, + s_2019_s_11: { + title: "S/2019 S 11", + description: { + blurb: [ + "S/2019 S 11 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 11 is about 4 kilometers in diameter and orbits Saturn at an average distance of 20.7 million km in 1115.0 days. It has an inclination of 144.6° to the ecliptic in a retrograde direction with an eccentricity of 0.513.", + ], + }, + related: [], + }, + s_2019_s_12: { + title: "S/2019 S 12", + description: { + blurb: [ + "S/2019 S 12 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 12 is about 4 kilometers in diameter and orbits Saturn at an average distance of 20.9 million km in 1138.85 days. It has an inclination of 167.1° to the ecliptic in a retrograde direction with an eccentricity of 0.476.", + ], + }, + related: [], + }, + s_2019_s_13: { + title: "S/2019 S 13", + description: { + blurb: [ + "S/2019 S 13 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 13 is about 3 kilometers in diameter and orbits Saturn at an average distance of 21.0 million km in 1144.92 days. It has an inclination of 177.3° to the ecliptic in a retrograde direction with an eccentricity of 0.318.", + ], + }, + related: [], + }, + s_2019_s_14: { + title: "S/2019 S 14", + description: { + blurb: [ + "S/2019 S 14 is a natural satellite of Saturn, belonging to the Inuit group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 14 is about 4 kilometers in diameter and orbits Saturn at an average distance of 17.9 million km in 893.14 days. It has an inclination of 46.2° to the ecliptic in a prograde direction with an eccentricity of 0.172.", + ], + }, + related: [], + }, + s_2019_s_15: { + title: "S/2019 S 15", + description: { + blurb: [ + "S/2019 S 15 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 15 is about 3 kilometers in diameter and orbits Saturn at an average distance of 21.2 million km in 1161.54 days. It has an inclination of 157.7° to the ecliptic in a retrograde direction with an eccentricity of 0.257.", + ], + }, + related: [], + }, + s_2019_s_16: { + title: "S/2019 S 16", + description: { + blurb: [ + "S/2019 S 16 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 16 is about 3 kilometers in diameter and orbits Saturn at an average distance of 23.3 million km in 1341.17 days. It has an inclination of 162.0° to the ecliptic in a retrograde direction with an eccentricity of 0.250.", + ], + }, + related: [], + }, + s_2019_s_17: { + title: "S/2019 S 17", + description: { + blurb: [ + "S/2019 S 17 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 17 is about 4 kilometers in diameter and orbits Saturn at an average distance of 22.7 million km in 1291.39 days. It has an inclination of 155.5° to the ecliptic in a retrograde direction with an eccentricity of 0.546.", + ], + }, + related: [], + }, + s_2019_s_18: { + title: "S/2019 S 18", + description: { + blurb: [ + "S/2019 S 18 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 18 is about 3 kilometers in diameter and orbits Saturn at an average distance of 23.1 million km in 1327.06 days. It has an inclination of 154.6° to the ecliptic in a retrograde direction with an eccentricity of 0.509.", + ], + }, + related: [], + }, + s_2019_s_19: { + title: "S/2019 S 19", + description: { + blurb: [ + "S/2019 S 19 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 19 is about 3 kilometers in diameter and orbits Saturn at an average distance of 23.0 million km in 1318.05 days. It has an inclination of 151.8° to the ecliptic in a retrograde direction with an eccentricity of 0.458.", + ], + }, + related: [], + }, + s_2019_s_2: { + title: "S/2019 S 2", + description: { + blurb: [ + "S/2019 S 2 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 2 is about 3 kilometers in diameter and orbits Saturn at an average distance of 16.6 million km in 799.82 days. It has an inclination of 173.3° to the ecliptic in a retrograde direction with an eccentricity of 0.279.", + ], + }, + related: [], + }, + s_2019_s_20: { + title: "S/2019 S 20", + description: { + blurb: [ + "S/2019 S 20 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 20 is about 3 kilometers in diameter and orbits Saturn at an average distance of 23.7 million km in 1375.45 days. It has an inclination of 156.1° to the ecliptic in a retrograde direction with an eccentricity of 0.354.", + ], + }, + related: [], + }, + s_2019_s_21: { + title: "S/2019 S 21", + description: { + blurb: [ + "S/2019 S 21 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 21 is about 4 kilometers in diameter and orbits Saturn at an average distance of 26.4 million km in 1636.32 days. It has an inclination of 171.9° to the ecliptic in a retrograde direction with an eccentricity of 0.155.", + ], + }, + related: [], + }, + s_2019_s_3: { + title: "S/2019 S 3", + description: { + blurb: [ + "S/2019 S 3 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 3 is about 4 kilometers in diameter and orbits Saturn at an average distance of 17.1 million km in 837.74 days. It has an inclination of 166.9° to the ecliptic in a retrograde direction with an eccentricity of 0.249.", + ], + }, + related: [], + }, + s_2019_s_4: { + title: "S/2019 S 4", + description: { + blurb: [ + "S/2019 S 4 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 4 is about 3 kilometers in diameter and orbits Saturn at an average distance of 18.0 million km in 904.26 days. It has an inclination of 170.1° to the ecliptic in a retrograde direction with an eccentricity of 0.409.", + ], + }, + related: [], + }, + s_2019_s_5: { + title: "S/2019 S 5", + description: { + blurb: [ + "S/2019 S 5 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 5 is about 3 kilometers in diameter and orbits Saturn at an average distance of 19.1 million km in 990.38 days. It has an inclination of 158.8° to the ecliptic in a retrograde direction with an eccentricity of 0.215.", + ], + }, + related: [], + }, + s_2019_s_6: { + title: "S/2019 S 6", + description: { + blurb: [ + "S/2019 S 6 is a natural satellite of Saturn, belonging to the Inuit group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 6 is about 4 kilometers in diameter and orbits Saturn at an average distance of 18.2 million km in 916.7 days. It has an inclination of 48.1° to the ecliptic in a prograde direction with an eccentricity of 0.084.", + ], + }, + related: [], + }, + s_2019_s_7: { + title: "S/2019 S 7", + description: { + blurb: [ + "S/2019 S 7 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 7 is about 4 kilometers in diameter and orbits Saturn at an average distance of 20.2 million km in 1080.29 days. It has an inclination of 174.2° to the ecliptic in a retrograde direction with an eccentricity of 0.232.", + ], + }, + related: [], + }, + s_2019_s_8: { + title: "S/2019 S 8", + description: { + blurb: [ + "S/2019 S 8 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 8 is about 4 kilometers in diameter and orbits Saturn at an average distance of 20.3 million km in 1088.68 days. It has an inclination of 172.8° to the ecliptic in a retrograde direction with an eccentricity of 0.311.", + ], + }, + related: [], + }, + s_2019_s_9: { + title: "S/2019 S 9", + description: { + blurb: [ + "S/2019 S 9 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2019 and announced in 2023.", + ], + more: [ + "S/2019 S 9 is about 4 kilometers in diameter and orbits Saturn at an average distance of 20.4 million km in 1093.11 days. It has an inclination of 159.5° to the ecliptic in a retrograde direction with an eccentricity of 0.433.", + ], + }, + related: [], + }, + s_2020_s_1: { + title: "S/2020 S 1", + description: { + blurb: [ + "S/2020 S 1 is a natural satellite of Saturn, belonging to the Inuit group. It was discovered in 2020 and announced in 2023.", + ], + more: [ + "S/2020 S 1 is about 4 kilometers in diameter and orbits Saturn at an average distance of 11.3 million km in 451.1 days. It has an inclination of 48.2° to the ecliptic in a prograde direction with an eccentricity of 0.337.", + ], + }, + related: [], + }, + s_2020_s_10: { + title: "S/2020 S 10", + description: { + blurb: [ + "S/2020 S 10 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2020 and announced in 2023.", + ], + more: [ + "S/2020 S 10 is about 3 kilometers in diameter and orbits Saturn at an average distance of 25.3 million km in 1527.22 days. It has an inclination of 165.6° to the ecliptic in a retrograde direction with an eccentricity of 0.295.", + ], + }, + related: [], + }, + s_2020_s_2: { + title: "S/2020 S 2", + description: { + blurb: [ + "S/2020 S 2 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2020 and announced in 2023.", + ], + more: [ + "S/2020 S 2 is about 3 kilometers in diameter and orbits Saturn at an average distance of 17.9 million km in 897.6 days. It has an inclination of 170.7° to the ecliptic in a retrograde direction with an eccentricity of 0.152.", + ], + }, + related: [], + }, + s_2020_s_3: { + title: "S/2020 S 3", + description: { + blurb: [ + "S/2020 S 3 is a natural satellite of Saturn, belonging to the Inuit group. It was discovered in 2020 and announced in 2023.", + ], + more: [ + "S/2020 S 3 is about 3 kilometers in diameter and orbits Saturn at an average distance of 18.1 million km in 907.99 days. It has an inclination of 46.1° to the ecliptic in a prograde direction with an eccentricity of 0.144.", + ], + }, + related: [], + }, + s_2020_s_4: { + title: "S/2020 S 4", + description: { + blurb: [ + "S/2020 S 4 is a natural satellite of Saturn, belonging to the Gallic group. It was discovered in 2020 and announced in 2023.", + ], + more: [ + "S/2020 S 4 is about 3 kilometers in diameter and orbits Saturn at an average distance of 18.2 million km in 926.92 days. It has an inclination of 40.1° to the ecliptic in a prograde direction with an eccentricity of 0.495.", + ], + }, + related: [], + }, + s_2020_s_5: { + title: "S/2020 S 5", + description: { + blurb: [ + "S/2020 S 5 is a natural satellite of Saturn, belonging to the Inuit group. It was discovered in 2020 and announced in 2023.", + ], + more: [ + "S/2020 S 5 is about 3 kilometers in diameter and orbits Saturn at an average distance of 18.4 million km in 933.88 days. It has an inclination of 48.2° to the ecliptic in a prograde direction with an eccentricity of 0.220.", + ], + }, + related: [], + }, + s_2020_s_6: { + title: "S/2020 S 6", + description: { + blurb: [ + "S/2020 S 6 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2020 and announced in 2023.", + ], + more: [ + "S/2020 S 6 is about 3 kilometers in diameter and orbits Saturn at an average distance of 21.3 million km in 1168.86 days. It has an inclination of 166.9° to the ecliptic in a retrograde direction with an eccentricity of 0.481.", + ], + }, + related: [], + }, + s_2020_s_7: { + title: "S/2020 S 7", + description: { + blurb: [ + "S/2020 S 7 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2020 and announced in 2023.", + ], + more: [ + "S/2020 S 7 is about 3 kilometers in diameter and orbits Saturn at an average distance of 17.4 million km in 861.7 days. It has an inclination of 161.5° to the ecliptic in a retrograde direction with an eccentricity of 0.500.", + ], + }, + related: [], + }, + s_2020_s_8: { + title: "S/2020 S 8", + description: { + blurb: [ + "S/2020 S 8 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2020 and announced in 2023.", + ], + more: [ + "S/2020 S 8 is about 3 kilometers in diameter and orbits Saturn at an average distance of 22.0 million km in 1228.12 days. It has an inclination of 161.8° to the ecliptic in a retrograde direction with an eccentricity of 0.252.", + ], + }, + related: [], + }, + s_2020_s_9: { + title: "S/2020 S 9", + description: { + blurb: [ + "S/2020 S 9 is a natural satellite of Saturn, belonging to the Norse group. It was discovered in 2020 and announced in 2023.", + ], + more: [ + "S/2020 S 9 is about 4 kilometers in diameter and orbits Saturn at an average distance of 25.4 million km in 1534.97 days. It has an inclination of 161.4° to the ecliptic in a retrograde direction with an eccentricity of 0.531.", + ], + }, + related: [], + }, + s_2021_j_1: { + title: "S/2021 J 1", + description: { + blurb: [ + "This small moon of Jupiter was discovered in 2021 and announced in early 2023.", + ], + more: [ + "S/2021 J 1 is part of the Ananke group, a cluster of retrograde irregular moons of Jupiter that follow similar orbits to Ananke at semi-major axes between 19–22 million km (12–14 million mi), orbital eccentricities between 0.1–0.4, and inclinations between 139–155°. It has a diameter of about 1 km (0.62 mi) for an absolute magnitude of 17.3, making it one of Jupiter's smallest known moons.", + ], + }, + related: [], + }, + s_2021_j_2: { + title: "S/2021 J 2", + description: { + blurb: [ + "This small moon of Jupiter was discovered in 2021 and announced in early 2023.", + ], + more: [ + "S/2021 J 2 is part of the Ananke group, a cluster of retrograde irregular moons of Jupiter that follow similar orbits to Ananke at semi-major axes between 19–22 million km (12–14 million mi), orbital eccentricities between 0.1–0.4, and inclinations between 139–155°. It has a diameter of about 1 km (0.62 mi) for an absolute magnitude of 17.3, making it one of Jupiter's smallest known moons.", + ], + }, + related: [], + }, + s_2021_j_3: { + title: "S/2021 J 3", + description: { + blurb: [ + "This small moon of Jupiter was discovered in 2021 and announced in early 2023.", + ], + more: [ + "S/2021 J 3 is part of the Ananke group, a cluster of retrograde irregular moons of Jupiter that follow similar orbits to Ananke at semi-major axes between 19–22 million km (12–14 million mi), orbital eccentricities between 0.1–0.4, and inclinations between 139–155°. It has a diameter of about 2 km (1.2 mi) for an absolute magnitude of 17.2.", + ], + }, + related: [], + }, + s_2021_j_4: { + title: "S/2021 J 4", + description: { + blurb: [ + "This small moon of Jupiter was discovered in 2021 and announced in early 2023.", + ], + more: [ + "S/2021 J 4 is part of the Carme group, a tight cluster of retrograde irregular moons of Jupiter that follow similar orbits to Carme at semi-major axes between 22–24 million km (14–15 million mi), orbital eccentricities between 0.2–0.3, and inclinations between 163–166°. It has a diameter of about 1 km (0.62 mi) for an absolute magnitude of 17.4, making it one of Jupiter's smallest known moons.", + ], + }, + related: [], + }, + s_2021_j_5: { + title: "S/2021 J 5", + description: { + blurb: [ + "This small moon of Jupiter was discovered in 2021 and announced in early 2023.", + ], + more: [ + "S/2021 J 5 is part of the Carme group, a tight cluster of retrograde irregular moons of Jupiter that follow similar orbits to Carme at semi-major axes between 22–24 million km (14–15 million mi), orbital eccentricities between 0.2–0.3, and inclinations between 163–166°. It has a diameter of about 2 km (1.2 mi) for an absolute magnitude of 16.8.", + ], + }, + related: [], + }, + s_2021_j_6: { + title: "S/2021 J 6", + description: { + blurb: [ + "This small moon of Jupiter was discovered in 2021 and announced in early 2023.", + ], + more: [ + "S/2021 J 6 is part of the Carme group, a tight cluster of retrograde irregular moons of Jupiter that follow similar orbits to Carme at semi-major axes between 22–24 million km (14–15 million mi), orbital eccentricities between 0.2–0.3, and inclinations between 163–166°. It has a diameter of about 1 km (0.62 mi) for an absolute magnitude of 17.3, making it one of Jupiter's smallest known moons.", + ], + }, + related: [], + }, + s_2022_j_1: { + title: "S/2022 J 1", + description: { + blurb: [ + "This small moon of Jupiter was discovered in 2022 and announced in early 2023.", + ], + more: [ + "S/2022 J 1 is part of the Carme group, a tight cluster of retrograde irregular moons of Jupiter that follow similar orbits to Carme at semi-major axes between 22–24 million km (14–15 million mi), orbital eccentricities between 0.2 and 0.3, and inclinations between 163 and 166°. It has a diameter of about 2 km (1.2 mi) for an absolute magnitude of 17.0.", + ], + }, + related: [], + }, + s_2022_j_2: { + title: "S/2021 J 2", + description: { + blurb: [ + "This small moon of Jupiter was discovered in 2022 and announced in early 2023.", + ], + more: [ + "S/2022 J 2 is part of the Carme group, a tight cluster of retrograde irregular moons of Jupiter that follow similar orbits to Carme at semi-major axes between 22–24 million km (14–15 million mi), orbital eccentricities between 0.2 and 0.3, and inclinations between 163 and 166°. With a diameter of about 1 km (0.62 mi) for an absolute magnitude of 17.6, it is one of Jupiter's smallest known moons with confirmed orbits.", + ], + }, + related: [], + }, + s_2022_j_3: { + title: "S/2021 J 3", + description: { + blurb: [ + "This small moon of Jupiter was discovered in 2022 and announced in early 2023.", + ], + more: [ + "S/2022 J 3 is part of the Ananke group, a cluster of retrograde irregular moons of Jupiter that follow similar orbits to Ananke at semi-major axes between 19–22 million km (12–14 million mi), orbital eccentricities between 0.1 and 0.4, and inclinations between 139 and 155°. It has a diameter of about 1 km (0.62 mi) for an absolute magnitude of 17.4.[", + ], + }, + related: [], + }, + sao: { + title: "Sao", + description: { + blurb: [ + "Sao is one of three tiny moons (ranging in size from 30 to 40 km -- or 18 to 24 miles) of Neptune discovered in 2002 using innovative ground-based telescope techniques. (The other moons discovered were Laomedeia and Halimede.) The moons are so distant and so small they are about 100 million times fainter than can be seen with the unaided eye. The moons were missed by the Voyager 2 spacecraft in 1989 because they are so faint and distant from Neptune.", + "Sao is considered an irregular satellite because of its distant, eccentric orbit around Neptune. Like most irregular satellites of the giant planets in our outer solar system, Sao most likely formed after a collision between a larger moon and a comet or an asteroid. Sao and Laomedeia have prograde orbits, which means they orbit in the same direction as Neptune's rotation. Halimede has a retrograde orbit, which means Halimede orbits in the opposite direction of Neptune's rotation.", + "Very little is known about Sao. Scientists are trying to learn more about it and its irregular sisters because they offer a glimpse of the conditions at the time the planets in our solar system were forming billions of years ago.", + ], + }, + related: [], + }, + gridr: { + title: "Gridr", + description: { + blurb: [ + "Gridr (formerly S/2004 S 20 and Saturn LIV) is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "In mythology, Gridr is a Norse giantess, and a consort of Odin who warned Thor of Geirrod's treachery and equipped Thor with her belt, iron glove, and staff. Gridr is about 4 kilometres in diameter, and orbits Saturn at an average distance of 19.418 Gm in 1010.55 days, at an inclination of 163° to the ecliptic, in a retrograde direction and with an eccentricity of 0.197.​", + ], + }, + }, + angrboda: { + title: "Angrboda", + description: { + blurb: [ + "Angrboda (formerly S/2004 S22 and Saturn LV) is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "In mythology, Angrboda is a Norse giantess, consort of Loki, and the mother of monsters. Angrboda is about 3 kilometres in diameter, and orbits Saturn in 1107.13 days, at an inclination of 177° to the ecliptic.​", + ], + }, + }, + skrymir: { + title: "Skrymir", + description: { + blurb: [ + "Skrymir (formerly S/2004 S23 and Saturn LVI) is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "In mythology, Skrymir is a Norse giant who is a master of illusions. Skrymir is about 4 kilometres in diameter, and orbits Saturn in 1149.82 days, at an inclination of 177° to the ecliptic.​", + ], + }, + }, + gerd: { + title: "Gerd", + description: { + blurb: [ + "Gerd (formerly S/2004 S25 and Saturn LVII) is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "In mythology, Gerd is a Norse giantess and a consort of Freyr. She is the personification of fertile soil. Gerd is about 4 kilometres in diameter, and orbits Saturn in 1150.69 days, at an inclination of 173° to the ecliptic.", + ], + }, + }, + eggther: { + title: "Eggther", + description: { + blurb: [ + "Eggther (formerly S/2004 S27 and Saturn LIX) is the outermost known natural satellite of Saturn, discovered in 2004 and announced in 2019.", + ], + more: [ + "In mythology, Eggther is a Norse giant and the watchman who announces the beginning of Ragnarok. Eggther is about 6 kilometres in diameter, and orbits Saturn in 1054.45 days, at an inclination of 168° to the ecliptic.", + ], + }, + }, + beli: { + title: "Beli", + description: { + blurb: [ + "Beli (formerly S/2004 S30 and Saturn LXI) is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "In mythology, Beli is a Norse giant killed by Freyr with a staghorn. Beli is about 4 kilometres in diameter, and orbits Saturn in 1087.84 days, at 157.5° to the ecliptic.", + ], + }, + }, + gunnlod: { + title: "Gunnlod", + description: { + blurb: [ + "Gunnlod (formerly S/2004 S32 and Saturn LXII) is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "In mythology, Gunnlod is a Norse giantess, and a daughter of Suttungr, for whom she guards the mead of poetry. Gunnlod is about 4 kilometres in diameter, and orbits Saturn in 1153.96 days, at an inclination of 159° to the ecliptic.", + ], + }, + }, + thiazzi: { + title: "Thiazzi", + description: { + blurb: [ + "Thiazzi (formerly S/2004 S33 and Saturn LXIII) is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "In mythology, Thiazzi is a Norse giant, and a son of Alvaldi who kidnapped Idun, guardian of the apples of the gods. Thiazzi is about 4 kilometres in diameter, and orbits Saturn in 1403.18 days, at an inclination of 160° to the ecliptic.", + ], + }, + }, + alvaldi: { + title: "Alvaldi", + description: { + blurb: [ + "Alvaldi (formerly S/2004 S35 and Saturn LXV) is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "In mythology, Alvaldi is a Norse giant and the father of Thiazzi. He was rich in gold, and his sons divided it amongst themselves by taking a mouthful of gold each. Alvaldi is about 5 kilometres in diameter, and orbits Saturn in 1253.08 days, at an inclination of 177° to the ecliptic.", + ], + }, + }, + geirrod: { + title: "Geirrod", + description: { + blurb: [ + "Geirrod (formerly S/2004 S38 and Saturn LXVI) is a natural satellite of Saturn discovered in 2004 and announced in 2019.", + ], + more: [ + "In mythology, Geirrod was a Norse giant killed by Thor. Geirrod is about 4 kilometres in diameter, and orbits Saturn in 1211.02 days, at an inclination of 154° to the ecliptic.", + ], + }, + }, + setebos: { + title: "Setebos", + description: { + blurb: [ + "Setebos is a small, dark moon (about 48 km in diameter, assuming an albedo of 0.04) which orbits Uranus in the opposite direction from the regular moons and the planet's rotation (known as a retrograde orbit).", + ], + }, + related: [], + }, + siarnaq: { + title: "Siarnaq", + description: { + blurb: [ + "Siarnaq was discovered on Sept. 23, 2000 using the 3.6-m Canada-France-Hawaii reflector on Mauna Kea, Hawaii, with adaptive optics.", + ], + more: [ + "Siarnaq has a mean radius of about 12.4 miles (20 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.06. At a mean distance of 11 million miles (18 million kilometers) from Saturn, the moon takes about 896 Earth days to complete one orbit. It rotates once every 10 hours and 9 minutes, which is this is the shortest rotation period of all prograde irregular moons of Saturn. Siarnaq is one of five known members of the Inuit group of moons, which orbit Saturn at a mean distance of 7 to 11 million miles (11 to 18 million kilometers), at inclinations between 40 and 50 degrees from the plane of Saturn's equator, and with eccentricities of 0.15 to 0.48. Like Saturn's other irregular moons, they are thought to be objects that were captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet, as the regular moons are thought to have done. The similarities among the Inuit group's orbits suggest a common origin — they may be fragments of a single object that shattered in a collision. The other members of this group are Kiviuq, Ijiraq, Paaliaq, and Tarqeq. Observations by Tommy Grav and James Bauer using telescopes on Mauna Kea, Hawaii in 2006 (before the discovery of Tarqeq) found that Kiviuq, Siarnaq and Paaliaq all are light red with similar infrared features, further supporting the idea of a common origin. Originally called S/2000 S3, Siarnaq was named for an Inuit goddess of sea creatures who was also queen of the underworld.", + ], + }, + related: ["sc_cassini"], + }, + sinope: { + title: "Sinope", + description: { + blurb: [ + "Sinope was discovered on July 21, 1914, by Seth Barnes Nicholson on photographic plates taken with the Lick Observatory's 36-inch (0.9 meter) telescope.", + ], + more: [ + "Sinope is generally considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. However, there is some uncertainty about whether Sinope belongs in this group or not. Most or all of the Pasiphae satellites are thought to have begun as a single asteroid that, after being captured by Jupiter's gravity, suffered a collision which broke off a number of pieces. The bulk of the original asteroid survived as the moon called Pasiphae, and the other pieces became some or all of the other moons in the group. If Sinope does not belong in the Pasiphae group, then the individual moon called Pasiphae retains 99 percent of the mass of the original asteroid. If Sinope is included, Pasiphae still retains the lion's share: 87 percent of the original mass. None of the Pasiphae members is massive enough to pull itself into a sphere, so they are probably all irregularly shaped. Sinope has a mean radius of 11.8 miles (19 kilometers), assuming an albedo of 0.04. At a mean distance of about 14.8 million miles (23.9 million kilometers) from Jupiter, the satellite takes about 759 Earth days to complete one orbit. Sinope was named for a nymph who outsmarted a smitten Zeus (the Greek equivalent of the Roman god Jupiter).", + ], + }, + related: [], + }, + skathi: { + title: "Skathi", + description: { + blurb: [ + "Skathi was discovered on Sept. 23, 2000 using the 3.6-m Canada-France-Hawaii reflector on Mauna Kea, Hawaii, with adaptive optics.", + ], + more: [ + "Skathi (formerly called Skadi) has a mean radius of 2.5 miles (4 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.06. It orbits Saturn at an inclination of about 151 degrees and an eccentricity of about 0.3. At a mean distance of 9.7 million miles (15.6 million kilometers) from Saturn, the moon takes about 728 Earth days to complete one orbit. Skathi is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn — traveling around in the opposite direction from the planet's rotation. Skathi and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Skathi is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Skathi appears to be a member of a subgroup that also includes Skoll, Hyrrokkin, S/2006 S1, Bergelmir, Farbauti, S/2006 S3, and Kari. Skathi, and another member of the Norse group, Ymir, may be the sources of material that coats the dark side of Iapetus and, to a lesser extent, the surface of Hyperion. Originally called S/2000 S8, Skathi was named for Skadi, a giantess in Norse mythology.", + ], + }, + related: [], + }, + skoll: { + title: "Skoll", + description: { + blurb: [ + "Skoll was discovered on March 6, 2006, by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna using the Subaru 8.3-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Skoll has a mean radius of 1.9 miles (3 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 160 degrees and an eccentricity of about 0.5. At a mean distance of 11.0 million miles (17.7 million kilometers) from Saturn, the moon takes about 878 Earth days to complete one orbit. Skoll is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn — traveling around in the opposite direction from the planet's rotation. Skoll and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Skoll is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Skoll appears to be a member of a subgroup that also includes Skathi, Hyrrokkin, S/2006 S1, Bergelmir, Farbauti, S/2006 S3, and Kari. Originally called S/2006 S8, Skoll was named for a giant wolf in Norse mythology, who pursues the sun across the sky. It is destined to catch and devour them at the doomsday time known as Ragnarok.", + ], + }, + related: [], + }, + sponde: { + title: "Sponde", + description: { + blurb: [ + "Sponde was discovered Dec. 9, 2001, by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Sponde is considered a member of the Pasiphae group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. Sponde has a mean radius of one kilometer, assuming an albedo of 0.04. At a mean distance of about 14.8 million miles (23.8 million kilometers) from Jupiter, the satellite takes about 748 Earth days to complete one orbit. Originally called S/2001 J5, Sponde was named for one of the Horae, who were daughters of Themis and Zeus, the Greek equivalent of the Roman god, Jupiter.", + ], + }, + related: [], + }, + stephano: { + title: "Stephano", + description: { + blurb: [ + "About 32 km in diameter (assuming an albedo of 0.04), Stephano is a small, dark moon which orbits Uranus in the opposite direction from the regular satellites and the planet's rotation (a retrograde orbit). Its orbital characteristics are similar to those of Caliban, suggesting a common origin.", + ], + }, + related: [], + }, + styx: { + title: "Styx", + description: { + blurb: [ + "Styx was discovered on June 26, 2012 by a large team led by Mark Showalter using the Hubble Space Telescope.", + ], + more: [ + "Pluto’s tiny moon Styx was uncovered in a Hubble survey searching for potential hazards in advance of the July 2015 New Horizons spacecraft Pluto flyby. It is intriguing that such a small planet can have such a complex collection of satellites. The discovery provides additional clues for unraveling how the Pluto system formed and evolved. The favored theory is that all the moons are relics of a collision between Pluto and another large Kuiper Belt Object billions of years ago. The moon is estimated to be 6 to 15 miles (10 to 24 kilometers) across. It is in a 58,000 mile (93,000 kilometer) diameter circular orbit around Pluto that is assumed to be on the same plane with the other satellites in the system. Originally designated S/2012 (134340) 1 (and sometime referred to as P5), Styx is named for the mythological river that separates the world of the living from the realm of the dead.", + ], + }, + related: ["sc_hubble_space_telescope", "sc_new_horizons"], + }, + surtur: { + title: "Surtur", + description: { + blurb: [ + "Surtur was discovered on March 6, 2006, by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna using the Subaru 8.3-m reflector telescope on Mauna Kea, Hawaii.", + ], + more: [ + "Surtur has a mean radius of 1.9 miles (3 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.04. It orbits Saturn at an inclination of about 169 degrees and an eccentricity of about 0.4. At a mean distance of 14.2 million miles (22.9 million kilometers) from Saturn, the moon takes about 1,296 Earth days to complete one orbit. Surtur is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn — traveling around in the opposite direction from the planet's rotation. Surtur and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Surtur is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2006 S7, Surtur was named for Surt, who guards Muspell, the land of fire in Norse mythology. At the doomsday time known as Ragnarok, he is destined to lead the fire giants in battle against the gods. The gods will be vanquished and Heaven and Earth will be consumed in fire.", + ], + }, + related: [], + }, + suttungr: { + title: "Suttungr", + description: { + blurb: [ + "Suttungr was discovered in 2000 using the 3.6-m Canada-France-Hawaii reflector on Mauna Kea, Hawaii, with adaptive optics.", + ], + more: [ + "Suttungr has a mean radius of 2.2 miles (3.5 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.06. It orbits Saturn at an inclination of about 174 degrees and an eccentricity of about 0.1. At a mean distance of 12.1 million miles (19.5 million kilometers) from Saturn, the moon takes about 1,017 Earth days to complete one orbit. Suttungr is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn — traveling around in the opposite direction from the planet's rotation. Suttungr and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Suttungr is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2000 S12, Suttungr was named for Suttungr (also spelled Suttung), a giant in Norse mythology.", + ], + }, + related: [], + }, + sycorax: { + title: "Sycorax", + description: { + blurb: [ + "Sycorax is the largest of the irregular moons which orbit Uranus in the opposite direction from the regular moons and the planet's rotation (known as a retrograde orbit).", + ], + }, + related: [], + }, + tarqeq: { + title: "Tarqeq", + description: { + blurb: [ + "Tarqeq was discovered on Jan. 16, 2007, by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Subaru 8.2-m reflector at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Tarqeq has a mean radius of 1.9 miles (3 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.06. At a mean distance of 11.1 million miles (17.9 million kilometers) from Saturn, the moon takes about 887 Earth days to complete one orbit. Tarqeq is one of five known members of the Inuit group of moons, which orbit Saturn at a mean distance of 7 to 11 million miles (11 to 18 million kilometers), at inclinations between 40 degrees and 50 degrees from the plane of Saturn's equator, and with eccentricities of 0.15 to 0.48. (A moon's eccentricity is a number between 0 and 1 which describes the shape of the orbit. The closer to 0, the more circular it is; the closer to 1, the more elongated.) Originally called S/2007 S1, Tarqeq was named for the Inuit spirit of Earth's Moon. This spirit is said to be a mighty hunter who watches over human behavior. In the mythology of the indigenous people of northern Alaska, he controls the animals.", + ], + }, + related: [], + }, + tarvos: { + title: "Tarvos", + description: { + blurb: [ + "Tarvos was discovered on Sept. 23, 2000 using the 3.6-m Canada-France-Hawaii reflector on Mauna Kea, Hawaii, with adaptive optics.", + ], + more: [ + "Tarvos has a mean radius of about 4.7 miles (7.5 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.06. At a mean distance of 11.4 million miles (18.3 million kilometers) from Saturn, the moon takes about 926 Earth days to complete one orbit. Tarvos is one of the four known members of the Gallic group of moons. These moons have prograde orbits (they travel around Saturn in the same direction as the planet's rotation), but their egg-shaped, angled orbits classify them as \"irregular\" moons. Like Saturn's other irregular moons, they are thought to be objects that were captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet, as the regular moons are thought to have done. Originally called S/2000 S4, Tarvos was named for a bull in Celtic mythology. It is known from two stone sculptures, found in Paris and Trier, of a bull with three cranes and a tree which is presumed to be a willow.", + ], + }, + related: [], + }, + taygete: { + title: "Taygete", + description: { + blurb: [ + "Taygete was discovered Nov. 25, 2000, by Scott S. Sheppard, David C. Jewitt, Yanga R. Fernandez, and Eugene Magnier at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + "Taygete is a member of the Carme group, a family of Jovian satellites which have similar orbits and appearance and are therefore thought to have a common origin. The group probably began as a D-type asteroid (possibly from the Hilda family or the Jupiter Trojans) that suffered a collision, which broke off a number of pieces, either before or after being captured by Jupiter's gravity. The largest remaining chunk (still retaining 99 percent of the group's mass) was named \"Carme,\" and the smaller pieces became the other 16 moons in the Carme group. Taygete has a mean radius of about 1.5 miles (2.5 kilometers). At a mean distance of about 14.4 million miles (23.3 million kilometers) from Jupiter, the satellite takes about 732 Earth days to complete one orbit. Originally called S/2000 J9, Taygete was named for one of the Pleiades, who were the seven daughters of Atlas. Taygete was impregnated by Zeus, the Greek equivalent of the Roman god Jupiter, and bore him a son called Lakedaemon. According to one account, that smooth-talking Zeus once attempted to mollify his wife, Hera, by telling her that he had never been so charmed as by Hera — not even when he had Taygete.", + ], + }, + related: [], + }, + telesto: { + title: "Telesto", + description: { + blurb: [ + "Telesto was discovered in 1980 using ground-based observations by Brad Smith, Harold Reitsema, Stephen Larson, and John Fountain.", + ], + more: [ + 'Telesto is known as a "Tethys Trojan" because, together with Calypso, it circles Saturn in the same orbit as the moon Tethys. At a distance of about 183,000 miles (295,000 kilometers) from Saturn, the moon takes 45.3 hours to make one trip around the planet. Telesto orbits about 60 degrees ahead of Tethys, while Calypso orbits behind Tethys by about 60 degrees. Because Telesto is in the front of this three-moon group, it is called the "leading Trojan." Telesto is 7.7 miles (12.4 kilometers) in mean radius and appears to have a smooth, icy surface. It does not show the signs of intense cratering seen on many of Saturn\'s other moons. Telesto is a daughter of the Titans Oceanus and Tethys in Greek mythology. It was originally designated S/1981 S13.', + ], + }, + related: ["sc_cassini"], + }, + tethys: { + title: "Tethys", + description: { + blurb: ["Tethys is Saturn's fifth largest moon."], + more: [ + "This cold, airless and heavily scarred body is very similar to sister moons Dione and Rhea except that Tethys is not as heavily cratered as the other two. Tethys appeared as a tiny dot to astronomers until the Voyager (1 and 2) encounters in 1980 and 1981. The Voyager images showed a major impact crater and a great chasm. The Cassini spacecraft has added details including a great variety of colors at small scales suggesting a variety of materials not seen elsewhere.", + ], + }, + related: ["sc_pioneer_11", "sc_voyager_1", "sc_voyager_2", "sc_cassini"], + }, + thalassa: { + title: "Thalassa", + description: { + blurb: [ + "Thalassa, like Naiad, most likely formed from fragments of Neptune's original moons, which were smashed by the disturbances caused when the ice giant Neptune captured Triton. Thalassa is unusual for an irregular moon because it is roughly disk-shaped.", + "Also like Naiad, Thalassa circles the planet in the same direction as Neptune rotates, and remains close to Neptune's equatorial plane. Thalassa's orbit is slowly decaying due to tidal deceleration and may eventually crash into Neptune's atmosphere or be torn apart and form a planetary ring.", + ], + }, + related: [], + }, + thebe: { + title: "Thebe", + description: { + blurb: [ + "Thebe was discovered in 1980 by the Voyager science team from images taken by Voyager 1.", + ], + more: [ + "Thebe is one of the four known small moons that orbit closer to Jupiter than the four vastly larger Galilean moons. These eight are the only known \"regular\" Jovian satellites, which means that they orbit Jupiter in the same direction as the planet's rotation (prograde orbits), and that their orbits are almost circular and in the same plane as Jupiter's equator. Thebe is the planet's seventh largest moon, with a mean radius of about 49 km. At a distance of about 138 thousand miles (222 thousand kilometers) from Jupiter, Thebe whips once around the planet in a little over 16 hours. The satellite originally called S/1979 J2 was ultimately named \"Thebe,\" a name associated with Jupiter — or his Greek equivalent, Zeus — in a variety of ways in different myths. In one, Thebe was a nymph who was a love of Zeus. In another, she was an Egyptian king's daughter and a love of Jupiter.", + ], + }, + related: ["sc_galileo", "sc_voyager_1", "sc_voyager_2"], + }, + thelxinoe: { + title: "Thelxinoe", + description: { + blurb: [ + "Thelxinoe was discovered on Feb. 9, 2003, by Scott S. Sheppard and Brett J. Gladman at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + 'Thelxinoe is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter\'s gravity and then suffered a collision which broke off a number of pieces. The largest remaining chunk was named "Ananke," and the smaller pieces became the other 15 moons in the Ananke group. Thelxinoe has a mean radius of about 0.62 miles (1 kilometer), assuming an albedo of 0.04. At a mean distance of about 13.1 million miles (21.2 million kilometers) from Jupiter, it takes about 628 Earth days to complete one orbit. Originally called S/2003 J22, Thelxinoe was named for one of the Muses, who were daughters of Zeus, the Greek equivalent of the Roman god Jupiter. Thelxinoe means charm.', + ], + }, + related: [], + }, + themisto: { + title: "Themisto", + description: { + blurb: [ + "Themisto was initially discovered on Sept. 30, 1975, by Charles Thomas Kowal and Elizabeth Roemer.", + ], + more: [ + "Themisto was subsequently lost until 2000, when it was rediscovered by Scott S. Sheppard, David C. Jewitt, Yanga Roland Fernandez and Eugene A. Magnier as part of a systematic search for small irregular Jovian moons. They used two CCD cameras — the largest in the world at the time — one mounted on the 8.3-m Subaru telescope and the other on the 3.6-m Canada-French-Hawaii telescope on Mauna Kea in Hawaii. It is a small satellite with a mean radius of 2.5 miles (4 kilometers) whose orbit is inclined with respect to Jupiter's equatorial plane. It travels in the same direction as Jupiter's rotation (a prograde orbit). At a distance of about 4.5 million miles (7.3 million kilometers) from Jupiter, Themisto takes about 130 Earth days to complete one orbit. Satellites in the Jovian system are named for Zeus/Jupiter's lovers and descendants. Themisto was originally called S/1975 J1 and then S/2000 J1 when it was rediscovered. Its current name comes from the Greek mythological character who was the mother of Ister by Zeus, the Greek equivalent of the Roman god Jupiter. She was changed into a bear by a jealous Hera, who was Zeus' wife and sister.", + ], + }, + related: [], + }, + thrymr: { + title: "Thrymr", + description: { + blurb: [ + "Thrymr was discovered in 2000 using the 3.6-m Canada-France-Hawaii reflector on Mauna Kea in Hawaii, with adaptive optics.", + ], + more: [ + "Thrymr has a mean radius of 2.2 miles (3.5 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.06. It orbits Saturn at an inclination of about 174 degrees and an eccentricity of about 0.5. At a mean distance of 12.7 million miles (20.4 million kilometers) from Saturn, the moon takes about 1,094 Earth days to complete one orbit. Thrymr is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn -- traveling around in the opposite direction from the planet's rotation. Thrymr and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Thrymr is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Originally called S/2000 S7, Thrymr was named for a giant in Norse mythology who stole Thor's hammer and offered to return it only if the gods gave him the very beautiful goddess Freyia to be his wife.", + ], + }, + related: [], + }, + thyone: { + title: "Thyone", + description: { + blurb: [ + "Thyone was discovered on Dec. 11, 2001, by Scott S. Sheppard, David C. Jewitt and Jan T. Kleyna at the Mauna Kea Observatory in Hawaii.", + ], + more: [ + 'Thyone is a member of the Ananke group, a family of Jovian satellites which have similar orbits and are therefore thought to have a common origin. The group probably began as an asteroid that was captured by Jupiter\'s gravity and then suffered a collision which broke off a number of pieces. The largest remaining chunk was named "Ananke," and the smaller pieces became the other 15 moons in the Ananke group. Thyone has a mean radius of about 1 mile (2 kilometers), assuming an albedo of 0.04. At a mean distance of about 13.2 million miles (21.2 million kilometers) from Jupiter, it takes about 627 Earth days to complete one orbit. Originally called S/2001 J2, Thyone was named for the mother (originally named Semele) of Dionysos by Zeus, the Greek equivalent of the Roman god Jupiter.', + ], + }, + related: [], + }, + titan: { + title: "Titan", + description: { + blurb: [ + "Saturn’s largest moon Titan is an extraordinary and exceptional world.", + ], + more: [ + "Among our solar system’s more than 150 known moons, Titan is the only one with a substantial atmosphere. And of all the places in the solar system, Titan is the only place besides Earth known to have liquids in the form of rivers, lakes and seas on its surface. Titan is larger than the planet Mercury and is the second largest moon in our solar system. Jupiter's moon Ganymede is just a little bit larger (by about 2 percent). Titan’s atmosphere is made mostly of nitrogen, like Earth’s, but with a surface pressure 50 percent higher than Earth’s. Titan has clouds, rain, rivers, lakes and seas of liquid hydrocarbons like methane and ethane. The largest seas are hundreds of feet deep and hundreds of miles wide. Beneath Titan’s thick crust of water ice is more liquid—an ocean primarily of water rather than methane. Titan’s subsurface water could be a place to harbor life as we know it, while its surface lakes and seas of liquid hydrocarbons could conceivably harbor life that uses different chemistry than we’re used to—that is, life as we don’t yet know it. Titan could also be a lifeless world.", + ], + }, + related: [ + "sc_pioneer_11", + "sc_voyager_1", + "sc_voyager_2", + "sc_cassini", + "sc_huygens", + ], + }, + titania: { + title: "Titania", + description: { + blurb: [ + "Titania is Uranus' largest moon. Images taken by Voyager 2 almost 200 years after Titania's discovery revealed signs that the moon was geologically active.", + ], + more: [ + "A prominent system of fault valleys, some nearly 1,000 miles (1,609 kilometers) long, is visible near the terminator (shadow line). The troughs break the crust in two directions, an indication of some tectonic extension of Titania's crust. Deposits of highly reflective material, which may represent frost, can be seen along the Sun-facing valley walls.", + "The moon is about 1,000 miles (1,600 kilometers) in diameter. The neutral gray color of Titania is typical of most of the significant Uranian moons. Titania is named for the queen of the fairies in William Shakespeare's 16th century play \"A Midsummer Night's Dream.\"", + ], + }, + related: ["sc_voyager_2"], + }, + trinculo: { + title: "Trinculo", + description: { + blurb: [ + "Trinculo is a small, dark moon orbiting Uranus in the opposite direction from the regular moons and the planet's rotation (called a retrograde orbit).", + ], + }, + related: [], + }, + triton: { + title: "Triton", + description: { + blurb: [ + "Triton is the largest of Neptune's 13 moons. It is unusual because it is the only large moon in our solar system that orbits in the opposite direction of its planet's rotation―a retrograde orbit.", + ], + more: [ + "Scientists think Triton is a Kuiper Belt Object captured by Neptune's gravity millions of years ago. It shares many similarities with Pluto, the best known world of the Kuiper Belt.", + "Like our own moon, Triton is locked in synchronous rotation with Neptune―one side faces the planet at all times. But because of its unusual orbital inclination both polar regions take turns facing the Sun. Triton's thin atmosphere is composed mainly of nitrogen with small amounts of methane. This atmosphere most likely originates from Triton's volcanic activity, which is driven by seasonal heating by the Sun. Triton, Io and Venus are the only bodies in the solar system besides Earth that are known to be volcanically active at the present time.", + "Triton is one of the coolest objects in our solar system. It is so cold that most of Triton's nitrogen is condensed as frost, giving its surface an icy sheen that reflects 70 percent of the sunlight that hits it.", + "NASA's Voyager 2―the only spacecraft to fly past Neptune and Triton―found surface temperatures of -391degrees Fahrenheit (-235 degrees Celsius). During its 1989 flyby, Voyager 2 also found Triton has active geysers, making it one of the few geologically active moons in our solar system.", + ], + }, + related: ["sc_voyager_2"], + }, + umbriel: { + title: "Umbriel", + description: { + blurb: [ + "Umbriel is the darkest of Uranus' largest moons. It reflects only 16 percent of the light that strikes its surface, a feature similar to the highland areas of Earth's Moon.", + ], + more: [ + "Other Uranian moons are much brighter. The process by which Umbriel's ancient cratered surface was darkened remains a mystery. Umbriel has a diameter of about 750 miles (1,200 kilometers). Images taken by Voyager 2 in 1986 revealed a curious bright ring about 90 miles (140 kilometers) in diameter on the moon's dark surface. It is unclear what created the distinctive ring, although it may be frost deposits associated with an impact crater.", + ], + }, + related: ["sc_voyager_2"], + }, + ymir: { + title: "Ymir", + description: { + blurb: [ + "Ymir was discovered in 2000 at the European Southern Observatory in La Silla, Chile.", + ], + more: [ + "Ymir has a mean radius of about 5.6 miles (9 kilometers), assuming an albedo (a measure of how reflective the surface is) of 0.06. It orbits Saturn at an inclination of about 172 degrees and an eccentricity of about 0.3. At a mean distance of 14.3 million miles (23.1 million kilometers) from Saturn, the moon takes about 1,316 Earth days to complete one orbit. Of the distant moons that take more than 3 Earth years to orbit Saturn, Ymir is by far the largest, nearly three times the size of its neighbors. Ymir is a member of the Norse group of moons. These \"irregular\" moons have retrograde orbits around Saturn -- traveling around in the opposite direction from the planet's rotation. Ymir and the other Norse moons also have eccentric orbits, meaning they are more elongated than circular. Like Saturn's other irregular moons, Ymir is thought to be an object that was captured by Saturn's gravity, rather than having accreted from the dusty disk that surrounded the newly formed planet as the regular moons are thought to have done. Ymir and another member of the Norse group, Skathi, may be the sources of material that coats the dark side of Iapetus and, to a lesser extent, the surface of Hyperion. Originally called S/2000 S1, Ymir was named for the first living being in Norse mythology, the first of a race of frost giants.", + ], + }, + related: [], + }, + sc_ace: { + title: "ACE", + description: { + blurb: [ + "NASA's Advanced Composition Explorer (ACE) collects and analyzes particles of solar, interplanetary, interstellar and galactic origins.", + ], + more: [ + "The ACE robotic spacecraft was launched August 25, 1997, and entered an orbit close to the L1 Lagrangian point (which lies between the Sun and the Earth at a distance of some 1.5 million km from the latter) on December 12, 1997. The data contributes to our understanding of the Sun, its interaction with Earth, and the evolution of the solar system. ACE continues to provide space weather reports and warnings of geomagnetic storms that can disrupt communications on Earth and harm astronauts in space.", + ], + }, + dates: { + start: "1997-08-25", + end: "", + landing: "", + }, + related: [], + }, + sc_acrimsat: { + title: "ACRIMSAT", + description: { + blurb: [ + "ACRIMSAT (Active Cavity Radiometer Irradiance Monitor Satellite) was a mission to monitor the levels of total solar irradiance, which is the power per square meter delivered by the sun.", + ], + more: [ + "Launched in December 1999, the mission lasted almost 14 years, until contact was lost on December 13th, 2013. Monitoring the sun's output over a long period can help separate climate change effects of the sun's variance from other effects such as the greenhouse effect.", + ], + }, + dates: { + start: "1999-12-21T00:00:00", + end: "2013-12-13T00:00:00", + landing: "", + }, + parent: "earth", + related: ["sun"], + }, + sc_aqua: { + title: "Aqua", + description: { + blurb: [ + "Aqua is a NASA Earth Science satellite mission named for the large amount of information that the mission is collecting about the Earth's water cycle.", + ], + more: [ + "The Aqua mission collects data about evaporation from the oceans, water vapor in the atmosphere, clouds, precipitation, soil moisture, sea ice, land ice, and snow cover on the land and ice. Additional variables also being measured by Aqua include radiative energy fluxes, aerosols, vegetation cover on the land, phytoplankton and dissolved organic matter in the oceans, and air, land, and water temperatures. Aqua was launched on May 4, 2002, and has six Earth-observing instruments on board, collecting a variety of global data sets. Aqua was originally developed for a six-year design life but has now far exceeded that original goal. It continues transmitting high-quality data from four of its six instruments, AIRS, AMSU, CERES, and MODIS, and reduced quality data from a fifth instrument, AMSR-E. The sixth Aqua instrument, HSB, collected approximately nine months of high quality data but failed in February 2003. Aqua was the first member launched of a group of satellites termed the Afternoon Constellation, or sometimes the A-Train.", + ], + }, + dates: { + start: "2002-05-04T09:54:58", + end: "", + landing: "", + }, + related: [], + }, + sc_artemis_1: { + title: "Artemis I", + description: { + blurb: [ + "Artemis I is an uncrewed flight test that is the first mission to use NASA's Space Launch System (SLS) and the Orion spacecraft. It will be followed by a crewed flight on Artemis II.", + ], + more: [ + "The first in a series of increasingly complex missions, Artemis I is an uncrewed flight test that will provide a foundation for human deep space exploration, and demonstrate our commitment and capability to extend human existence to the Moon and beyond. The spacecraft launched on the most powerful rocket in the world and flew farther than any spacecraft built for humans has ever flown, traveling thousands of miles past the moon, then entering a distant retrograde orbit of the moon before returning to Earth.", + ], + }, + dates: { + start: "2022-11-16T06:47:44", + end: "2022-11-17T06:47:44", + landing: "", + }, + parent: "earth", + related: ["sc_capstone"], + }, + sc_aura: { + title: "Aura", + description: { + blurb: [ + "Aura (Latin for breeze) obtains measurements of ozone, aerosols and key gases throughout the atmosphere using technologically innovative space instrumentation. Scientists use these data to gain revolutionary insights into the chemistry of our atmosphere.", + ], + more: [ + "Aura's instruments measure trace gases in the atmosphere by detecting their unique spectral signatures. MLS observes the faint microwave emissions from rotating and vibrating molecules. HIRDLS and TES observe the infrared thermal emissions also due to molecular vibrations and rotations. OMI detects the molecular absorption of backscattered sunlight in the visible and ultraviolet wavelengths.", + "Horizon viewing (limb) instruments (MLS, TES and HIRDLS slice through the atmosphere, profiling gases. Down-looking instruments (OMI and TES) stare at the Earth. Since MLS looks out the front of the spacecraft, it is the first to profile the atmosphere. The OMI and TES instruments then look at the same air mass as it passes beneath the spacecraft. As the spacecraft then moves on in its orbit, HIRDLS and TES profile the atmosphere again. This unique observing geometry allows the Aura instruments to combine their measurements to get a better picture of the atmospheric chemistry.", + ], + }, + dates: { + start: "2004-07-15T10:01:51", + end: "", + landing: "", + }, + related: [], + }, + sc_biosentinel: { + title: "BioSentinel", + description: { + blurb: [ + "NASA’s BioSentinel is a shoebox-sized CubeSat that will perform the first long-duration biology experiment in deep space.", + ], + more: [ + "The satellite launched to deep space aboard Artemis I and flew past the Moon in a direction to orbit the Sun. Once the satellite is in position beyond our planet’s protective magnetic field, it will conduct a study of the effects of deep space radiation on a living organism, yeast. Because human cells and yeast cells have many similar biological mechanisms, including DNA damage and repair, BioSentinel’s experiments can help us better understand the radiation risks for long-duration deep space human exploration. BioSentinel will carry living organisms farther into space than ever before. NASA’s Artemis missions at the Moon will prepare humans to travel on increasingly farther and longer-duration missions to destinations like Mars. Results from BioSentinel’s six- to nine-month mission will fill critical gaps in knowledge about the health risks in deep space posed by space radiation.", + ], + }, + dates: { + start: "2022-11-16T11:45:33", + end: "", + landing: "", + }, + related: ["moon", "sc_artemis_1", "sc_lunar_icecube"], + }, + sc_calipso: { + title: "CALIPSO", + description: { + blurb: [ + "The CALIPSO satellite provided new insight into the role that clouds and atmospheric aerosols (airborne particles) play in regulating Earth's weather, climate, and air quality.", + ], + more: [ + "CALIPSO (Cloud-Aerosol Lidar and Infrared Pathfinder Satellite Observation) combined an active lidar instrument with passive infrared and visible imagers to probe the vertical structure and properties of thin clouds and aerosols over the globe. CALIPSO was launched on April 28, 2006. CALIPSO, along with the CloudSat mission, were highly complementary and together provided new, never-before-seen 3-D perspectives of how clouds and aerosols form, evolve, and affect weather and climate.", + ], + }, + dates: { + start: "2006-04-28T10:02:16", + end: "2023-08-01T12:00:00", + landing: "", + }, + parent: "earth", + related: ["sc_cloudsat"], + }, + sc_capstone: { + title: "CAPSTONE", + description: { + blurb: [ + "Cislunar Autonomous Positioning System Technology Operations and Navigation Experiment (CAPSTONE) is a lunar orbiter that will test and verify a unique, elliptical orbit that is planned for the Gateway space station.", + ], + more: [ + "As a precursor for Gateway, a Moon-orbiting outpost that is part of NASA’s Artemis program, CAPSTONE will help reduce risk for future spacecraft by validating innovative navigation technologies and verifying the dynamics of this halo-shaped orbit.", + ], + }, + dates: { + start: "2022-06-28T09:55:52", + end: "", + landing: "", + }, + parent: "moon", + related: ["sc_artemis_1"], + }, + sc_cassini: { + title: "Cassini", + description: { + blurb: [ + "For more than a decade, NASA’s Cassini spacecraft shared the wonders of Saturn and its family of icy moons—taking us to astounding worlds where methane rivers run to a methane sea and where jets of ice and gas are blasting material into space from a liquid water ocean that might harbor the ingredients for life. Cassini revealed in great detail the true wonders of Saturn, a giant world ruled by raging storms and delicate harmonies of gravity.", + ], + more: [ + "Cassini was one of the most ambitious efforts ever mounted in planetary exploration. A joint endeavor of NASA, ESA (the European Space Agency) and the Italian space agency (ASI), Cassini was a sophisticated robotic spacecraft sent to study Saturn and its complex system of rings and moons in unprecedented detail. Cassini carried a probe called Huygens to the Saturn system. The probe, which was built by ESA, parachuted to the surface of Saturn’s largest moon, Titan, in January 2005—the most distant landing to date in our solar system. Huygens returned spectacular images and other science results during a two-and-a-half-hour descent through Titan’s hazy atmosphere, before coming to rest amid rounded cobbles of ice on a floodplain damp with liquid methane.Cassini completed its initial four-year mission in June 2008 and earned two mission extensions that enabled the team to delve even deeper into Saturn’s mysteries. Key discoveries during its 13 years at Saturn included a global ocean with strong indications of hydrothermal activity within Enceladus, and liquid methane seas on Titan. After 20 years in space — 13 of those years exploring Saturn — Cassini exhausted its fuel supply. And so, to protect moons of Saturn that could have conditions suitable for life, Cassini was sent on a daring final mission that would seal its fate. After a series of nearly two dozen nail-biting dives between the planet and its icy rings, Cassini plunged into Saturn’s atmosphere on Sept. 15, 2017, returning science data to the very end.", + ], + }, + dates: { + start: "1997-10-15T09:26:00Z", + end: "2017-09-15T11:55:14Z", + landing: "", + highlight: "2017-04-22T09:36:00Z", + }, + parent: "saturn", + related: ["saturn", "titan", "jupiter", "enceladus"], + }, + sc_clementine: { + title: "Clementine", + description: { + blurb: [ + "Clementine was the first U.S. spacecraft launched to the Moon in over 20 years. It was designed to test spacecraft components during extended exposure to space and to study the Moon and an asteroid.", + ], + more: [ + "Clementine was launched in 1994 and The lunar observations included imaging at various wavelengths in the visible as well as in ultraviolet and infrared, laser ranging altimetry, gravimetry, and charged particle measurements. Clementine successfully entered an elliptical polar orbit (about 270 × 1,830 miles or 430 × 2,950 kilometers) around the Moon on Feb. 19, 1994, with a period of five days. In two months during 1994, it transmitted about 1.6 million digital images of the lunar surface, many of them with resolutions down to about 330-660 feet (100-200 meters). In the process, it provided scientists with their first look at the total lunar landscape including polar regions.", + ], + }, + dates: { + start: "1994-01-25T16:34:00", + end: "1995-05-10T00:00:00", + landing: "", + highlight: "1994-02-01T00:00:00", + }, + parent: "moon", + related: ["moon", "sc_lunar_reconaissance_orbiter"], + }, + sc_cloudsat: { + title: "CloudSat", + description: { + blurb: [ + "Part of NASA's fleet of weather- and climate-tracking satellites, CloudSat used advanced radar to examine the inner structure of clouds, helping researchers better understand how severe tropical cyclones as well as climate changes related to clouds occur.", + ], + more: [ + "In August 2010, CloudSat embarked on a new mission phase to study the genesis and patterns of tropical cyclones. Since its launch in 2006, CloudSat has played an instrumental role in new techniques for estimating the intensity of hurricanes from space, in addition to producing data about links between pollution and rainfall. The mission ended in late December of 2023.", + ], + }, + dates: { + start: "2006-04-28T10:02:16", + end: "2023-12-20T00:00:00", + landing: "", + }, + parent: "earth", + related: ["sc_calipso"], + }, + sc_cluster_ii_fm5: { + title: "Rumba", + description: { + blurb: [ + "Rumba is one of four spacecraft of the Cluster II mission of the European Space Agency, which studies the Earth's magnetosphere.", + ], + more: [ + "The mission is composed of four identical spacecraft flying in a tetrahedral formation. Four spacecraft allow scientists make the 3D, time-resolved measurements needed to create a realistic picture of the complex plasma interactions occurring between regions of the magnetosphere and between the magnetosphere and the solar wind.", + ], + }, + dates: { + start: "2000-08-09T11:13:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_cluster_ii_fm6", "sc_cluster_ii_fm7", "sc_cluster_ii_fm8"], + }, + sc_cluster_ii_fm6: { + title: "Salsa", + description: { + blurb: [ + "Salsa is one of four spacecraft of the Cluster II mission of the European Space Agency, which studies the Earth's magnetosphere.", + ], + more: [ + "The mission is composed of four identical spacecraft flying in a tetrahedral formation. Four spacecraft allow scientists make the 3D, time-resolved measurements needed to create a realistic picture of the complex plasma interactions occurring between regions of the magnetosphere and between the magnetosphere and the solar wind.", + ], + }, + dates: { + start: "2000-07-16T12:39:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_cluster_ii_fm5", "sc_cluster_ii_fm7", "sc_cluster_ii_fm8"], + }, + sc_cluster_ii_fm7: { + title: "Samba", + description: { + blurb: [ + "Samba is one of four spacecraft of the Cluster II mission of the European Space Agency, which studies the Earth's magnetosphere.", + ], + more: [ + "The mission is composed of four identical spacecraft flying in a tetrahedral formation. Four spacecraft allow scientists make the 3D, time-resolved measurements needed to create a realistic picture of the complex plasma interactions occurring between regions of the magnetosphere and between the magnetosphere and the solar wind.", + ], + }, + dates: { + start: "2000-07-16T12:39:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_cluster_ii_fm5", "sc_cluster_ii_fm6", "sc_cluster_ii_fm8"], + }, + sc_cluster_ii_fm8: { + title: "Tango", + description: { + blurb: [ + "Tango is one of four spacecraft of the Cluster II mission of the European Space Agency, which studies the Earth's magnetosphere.", + ], + more: [ + "The mission is composed of four identical spacecraft flying in a tetrahedral formation. Four spacecraft allow scientists make the 3D, time-resolved measurements needed to create a realistic picture of the complex plasma interactions occurring between regions of the magnetosphere and between the magnetosphere and the solar wind.", + ], + }, + dates: { + start: "2000-08-09T11:13:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_cluster_ii_fm5", "sc_cluster_ii_fm6", "sc_cluster_ii_fm7"], + }, + sc_dart: { + title: "DART", + description: { + blurb: [ + "DART, or Double Asteroid Redirection Test, was the first attempt to change the course of an asteroid with a kinetic impact.", + ], + link: "https://dart.jhuapl.edu/", + more: [ + "An on-orbit demonstration of asteroid deflection was a key test that NASA and other agencies wished to perform before any actual need is present. The DART mission was NASA's demonstration of kinetic impactor technology, impacting an asteroid to adjust its speed and path. The targeted system is composed of two asteroids: the larger asteroid Didymos (diameter: 780 meters, 0.48 miles), and the smaller moonlet asteroid, Dimorphos (diameter: 160 meters, 525 feet), which orbits Didymos. On September 26th, 2022, the DART spacecraft impacted Dimorphos nearly head-on, shortening the time it takes the small asteroid moonlet to orbit Didymos by several minutes.", + ], + }, + dates: { + start: "2021-11-24T06:20:00", + end: "2022-09-26T23:14:20", + landing: "", + }, + related: ["65803_didymos", "dimorphos"], + }, + sc_dawn: { + title: "Dawn", + description: { + blurb: [ + "Dawn was the first spacecraft to orbit two extraterrestrial bodies, as well as the first spacecraft to visit either Vesta or Ceres, and the first to orbit a dwarf planet.", + ], + link: "https://solarsystem.nasa.gov/missions/dawn/overview/", + more: [ + 'Dawn launched in 2007 on a journey that put about 4.3 billion miles (6.9 billion kilometers) on its odometer. Propelled by ion engines, the spacecraft achieved many firsts until its extended mission concluded on Oct. 31, 2018. The Dawn mission was designed to study two large bodies in the asteroid belt in order to answer questions about the formation of the Solar System, as well as to test the performance of its ion thrusters in deep space. Ceres and Vesta were chosen as two contrasting protoplanets, the first one apparently "wet" (i.e. icy and cold) and the other "dry" (i.e. rocky). The Dawn mission ran out of fuel in 2018 and still orbits the dwarf planet Ceres.', + ], + }, + dates: { + start: "2007-09-27T13:15:00", + end: "2018-10-30T00:00:00", + landing: "", + }, + related: ["4_vesta", "1_ceres"], + }, + sc_deep_impact: { + title: "Deep Impact", + description: { + blurb: [ + "The primary mission of NASA's Deep Impact was to probe beneath the surface of a comet. The spacecraft delivered a special impactor into the path of Tempel 1 to reveal never before seen materials and provide clues about the internal composition and structure of a comet. The spacecraft released its impactor which collided with the comet, and then the spacecraft observed the result.", + ], + link: "https://www.jpl.nasa.gov/missions/deep-impact", + more: [ + "On July 3, 2005, at 06:00 UT (or 06:07 UT Earth-receive time), Deep Impact released the impactor probe, which, using small thrusters, moved into the path of the comet, where it hit the following day, July 4, at 05:44:58 UT. The mission was then renamed as EPOXI, with a dual purpose to study extrasolar planets and the comet 103/P Hartley 2. The spacecraft arrived at Hartley 2 in 2010, and then planned to study an asteroid when contact was lost in August of 2013.", + ], + }, + dates: { + start: "2005-01-12T20:20:08", + end: "2013-08-08T00:00:00", + landing: "", + }, + related: [ + "sc_deep_impact_impactor", + "9p_tempel_1", + "103p_hartley_2", + "c_2012_s1", + ], + }, + sc_deep_impact_impactor: { + title: "Deep Impact Impactor", + description: { + blurb: [ + "The Impactor was a part of the Deep Impact spacecraft that would detatch and intentionally collide with the Comet Tempel 1.", + ], + more: [ + "On July 3, 2005, at 06:00 UT (or 06:07 UT Earth-receive time), Deep Impact released the impactor probe, which, using small thrusters, moved into the path of the comet, where it hit the following day, July 4, at 05:44:58 UT. The probe was traveling at a relative velocity of about 23,000 miles per hour (37,000 kilometers per hour) at the time of impact. The impact generated an explosion the equivalent of 4.7 tons of TNT and a crater estimated to be about 490 feet (150 meters) in diameter. The impact generated an explosion the equivalent of 4.7 tons of TNT and a crater estimated to be about 490 feet (150 meters) in diameter.", + ], + }, + dates: { + start: "2005-01-12T18:47:08", + end: "2005-07-04T06:05:00", + landing: "", + highlight: "2005-07-04T00:00:00", + }, + related: ["sc_deep_impact", "9p_tempel_1"], + }, + sc_deep_space_1: { + title: "Deep Space 1", + description: { + blurb: [ + "NASA's Deep Space 1 was an engineering test flight for a dozen new technologies, including highly-efficient ion engines and autonomous navigation software. It also flew by a comet and an asteroid.", + ], + link: "https://www.jpl.nasa.gov/missions/deep-space-1-ds1", + more: [ + "DS1 passed the near-Earth asteroid 9660 Braille on July 29th, 1999, at a range of about 16 miles (26 kilometers) and at a velocity of about 10 miles per second (15.5 kilometers per second). On Sept. 22, 2001, DS1 entered the coma of Comet Borrelly, making its closest approach of about 1,350 miles (2,171 kilometers) to the nucleus. Traveling at about 10 miles per second (16.58 kilometers per second) relative to the nucleus at the time, it returned some of the best images of a comet to date, as well as other significant data. It was the first NASA mission to use an ion propulsion engine.", + ], + }, + dates: { + start: "1998-10-24T12:08:00", + end: "2001-12-18T20:00:00", + landing: "", + }, + related: ["19p_borrelly"], + }, + sc_eo_1: { + title: "EO-1", + description: { + blurb: [ + "Earth Observing-1 (EO-1) was a NASA Earth observation satellite created to develop and validate a number of instrument and spacecraft bus breakthrough technologies.", + ], + more: [ + "It was the first satellite to map active lava flows from space; the first to measure a facility's methane leak from space; and the first to track re-growth in a partially logged Amazon forest from space. EO-1 captured scenes such as the ash after the World Trade Center attacks, the flooding in New Orleans after Hurricane Katrina, volcanic eruptions and a large methane leak in southern California.", + ], + }, + dates: { + start: "2000-11-21T18:24:25", + end: "2017-03-30T00:00:00", + landing: "", + highlight: "2017-01-01T00:00:00", + }, + parent: "earth", + related: ["earth"], + }, + sc_euclid: { + title: "Euclid", + description: { + blurb: [ + "Euclid is a European Space Agency mission to map the geometry of the Universe and better understand dark matter and dark energy, which make up most of the energy budget of the cosmos.", + ], + more: [ + "Euclid will probe the history of the expansion of the Universe and the formation of cosmic structures by measuring the redshift of galaxies out to a value of 2, which is equivalent to seeing back 10 billion years into the past. In this way, Euclid will cover the entire period over which dark energy played a significant role in accelerating the expansion of the Universe.", + ], + }, + dates: { + start: "2023-07-01T15:12:00", + end: "", + landing: "", + }, + related: ["sc_jwst"], + }, + sc_europa_clipper: { + title: "Europa Clipper", + description: { + blurb: [ + "Europa Clipper will search for signs of potential habitability on Jupiter's icy ocean moon Europa.", + ], + more: [ + "To determine if this distant moon has conditions favorable for life, NASA’s Europa Clipper mission is preparing to conduct the first dedicated and detailed study of an ocean world beyond Earth.", + "The expedition’s objective is to explore Europa to investigate its habitability. The spacecraft is not being sent to find life itself, but will instead try to answer specific questions about Europa’s ocean, ice shell, composition and geology.", + ], + }, + dates: { + start: "2024-10-10T01:44:00", + end: "", + landing: "", + }, + parent: "europa", + related: ["sc_galileo"], + }, + sc_explorer_1: { + title: "Explorer 1", + description: { + blurb: [ + "On January 31st, 1958, Explorer 1 became the first satellite launched by the United States of America. It followed the launch the previous year of the Russian satellites Sputnik 1 and 2.", + ], + more: [ + "It was the first spacecraft to detect the Van Allen radiation belt, returning data until its batteries were exhausted after nearly four months. It remained in orbit until 1970.", + ], + }, + dates: { + start: "1958-02-01T03:48:00", + end: "1958-05-23T00:00:00", + landing: "", + }, + parent: "earth", + related: [], + }, + sc_galileo: { + title: "Galileo", + description: { + blurb: [ + "The Galileo mission was the first spacecraft to enter orbit around the planet Jupiter, arriving in December of 1995 and staying for eight years, and made close passes by all its major moons. Galileo even carried a small probe that it deployed and sent deep into the atmosphere of Jupiter, taking readings for almost an hour before the probe was crushed by overwhelming pressure.", + ], + link: "https://solarsystem.nasa.gov/missions/galileo/overview/", + more: [ + "The Galileo spacecraft logged quite a few other firsts during its 14-year mission to Jupiter. Among its discoveries: an intense radiation belt above Jupiter's cloud tops, helium in about the same concentration as the Sun, extensive and rapid resurfacing of the moon Io because of volcanism and a magnetic field at Ganymede.", + ], + }, + dates: { + start: "1989-10-18T16:53:40", + end: "2003-09-21T18:57:18", + landing: "", + }, + related: ["jupiter", "europa", "ganymede", "io", "callisto", "amalthea"], + }, + sc_galileo_probe: { + title: "Galileo Probe", + description: { + blurb: [ + "The Galileo orbiter carried a small probe that became the first to sample the atmosphere of a gas planet.", + ], + more: [ + "The probe measured temperature, pressure, chemical composition, cloud characteristics, sunlight and energy internal to the planet, and lightning. During its 58-minute life, the probe penetrated 124 miles (200 kilometers) into Jupiter's violent atmosphere before it was crushed, melted and/or vaporized by the intense pressure and temperature.", + ], + }, + dates: { + start: "1995-07-13T05:30:00", + end: "1995-07-13T05:30:01", + landing: "", + highlight: "1995-07-13T05:30:00", + }, + parent: "jupiter", + related: ["sc_galileo", "jupiter"], + }, + sc_geotail: { + title: "Geotail", + description: { + blurb: [ + "Geotail provides information about the way the magnetic envelope surrounding Earth, called the magnetosphere, responds to incoming material and energy from the Sun.", + ], + more: [ + "The Geotail mission was a joint project of Japan’s Institute of Space and Astronautical Science (ISAS) and later, from 2003, the Japan Aerospace Exploration Agency (JAXA) and NASA. The mission was part of the International Solar Terrestrial Physics (ISTP) project, which also included the Wind, Polar, SOHO, and Cluster missions. Geotail’s goal was to study the structure and dynamics of the long tail region of Earth’s magnetosphere, which is created on the nightside of Earth by the solar wind. During active periods, the tail couples with the near-Earth magnetosphere, and often releases energy that is stored in the tail, activating auroras in the polar ionosphere.", + ], + }, + dates: { + start: "1992-07-24T14:26:00", + end: "2022-11-28T00:00:00", + landing: "", + }, + related: ["earth"], + }, + sc_gpm: { + title: "GPM", + description: { + blurb: [ + "Global Precipitation Measurement (GPM) is an international satellite mission to provide next-generation observations of rain and snow worldwide every three hours.", + ], + more: [ + "NASA and the Japanese Aerospace Exploration Agency (JAXA) launched the GPM Core Observatory satellite on February 27th, 2014, carrying advanced instruments that set a new standard for precipitation measurements from space. The data they provide is used to unify precipitation measurements made by an international network of partner satellites to quantify when, where, and how much it rains or snows around the world.", + "The GPM mission contributes to advancing our understanding of Earth's water and energy cycles, improves the forecasting of extreme events that cause natural disasters, and extends current capabilities of using satellite precipitation information to directly benefit society.", + ], + }, + dates: { + start: "2014-02-27T18:37:00", + end: "", + landing: "", + }, + related: ["earth"], + }, + sc_grace_1: { + title: "GRACE-1", + description: { + blurb: [ + "The Gravity Recovery and Climate Experiment (GRACE) was a joint mission of NASA and the German Aerospace Center (DLR). Twin satellites took detailed measurements of Earth's gravity field anomalies from its launch in March 2002 to the end of its science mission in October 2017.", + ], + more: [ + "The twin GRACE spacecraft tracked Earth's water movement to monitor changes in underground water storage, the amount of water in large lakes and rivers, soil moisture, ice sheets and glaciers, and sea level caused by the addition of water to the ocean. These discoveries provide a unique view of Earth's climate and have far-reaching benefits to society and the world's population. GRACE is able to make accurate measurements thanks in part to two advanced technologies: a microwave ranging system based on Global Positioning System (GPS) technology, and a very sensitive accelerometer—an instrument that measures the forces on the satellites besides gravity (such as atmospheric drag). Using the microwave ranging system, GRACE can measure the distance between satellites to within one micron -- about the diameter of a blood cell. Together, these very precise measurements of location, force and orbital change translate into an observation of gravity with unprecedented accuracy. Flight engineers maneuver the satellites only if they separate by more than 155 miles (250 km), otherwise they are left alone and gravity ‘tugs and pulls’ on them.", + ], + }, + dates: { + start: "2002-03-17T09:21:00", + end: "2017-10-27T00:00:00", + landing: "", + }, + parent: "earth", + related: ["sc_grace_2", "sc_grace_fo1", "sc_grace_fo2"], + }, + sc_grace_2: { + title: "GRACE-2", + description: { + blurb: [ + "The Gravity Recovery and Climate Experiment (GRACE) was a joint mission of NASA and the German Aerospace Center (DLR). Twin satellites took detailed measurements of Earth's gravity field anomalies from its launch in March 2002 to the end of its science mission in October 2017.", + ], + more: [ + "The twin GRACE spacecraft tracked Earth's water movement to monitor changes in underground water storage, the amount of water in large lakes and rivers, soil moisture, ice sheets and glaciers, and sea level caused by the addition of water to the ocean. These discoveries provide a unique view of Earth's climate and have far-reaching benefits to society and the world's population. GRACE is able to make accurate measurements thanks in part to two advanced technologies: a microwave ranging system based on Global Positioning System (GPS) technology, and a very sensitive accelerometer—an instrument that measures the forces on the satellites besides gravity (such as atmospheric drag). Using the microwave ranging system, GRACE can measure the distance between satellites to within one micron -- about the diameter of a blood cell. Together, these very precise measurements of location, force and orbital change translate into an observation of gravity with unprecedented accuracy. Flight engineers maneuver the satellites only if they separate by more than 155 miles (250 km), otherwise they are left alone and gravity ‘tugs and pulls’ on them.", + ], + }, + dates: { + start: "2002-03-17T09:21:00", + end: "2017-10-27T00:00:00", + landing: "", + }, + parent: "earth", + related: ["sc_grace_1", "sc_grace_fo1", "sc_grace_fo2"], + }, + sc_grace_fo1: { + title: "GRACE-FO1", + description: { + blurb: [ + "The Gravity Recovery and Climate Experiment Follow-on (GRACE-FO) mission measures changes in Earth's gravity field. It consists of two spacecraft that follow each other in orbit.", + ], + more: [ + "Launched on May 22, 2018, GRACE-FO continues the work of tracking Earth's water movement to monitor changes in underground water storage, the amount of water in large lakes and rivers, soil moisture, ice sheets and glaciers, and sea level caused by the addition of water to the ocean. These discoveries provide a unique view of Earth's climate and have far-reaching benefits to society and the world's population. GRACE-FO is able to make accurate measurements thanks in part to two advanced technologies: a microwave ranging system based on Global Positioning System (GPS) technology, and a very sensitive accelerometer—an instrument that measures the forces on the satellites besides gravity (such as atmospheric drag).", + "Using the microwave ranging system, GRACE can measure the distance between satellites to within one micron -- about the diameter of a blood cell. Together, these very precise measurements of location, force and orbital change translate into an observation of gravity with unprecedented accuracy. Flight engineers maneuver the satellites only if they separate by more than 155 miles (250 km), otherwise they are left alone and gravity ‘tugs and pulls’ on them.", + ], + }, + dates: { + start: "2018-05-22T19:47:58", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_grace_1", "sc_grace_2", "sc_grace_fo2"], + }, + sc_grace_fo2: { + title: "GRACE-FO2", + description: { + blurb: [ + "The Gravity Recovery and Climate Experiment Follow-on (GRACE-FO) mission measures changes in Earth's gravity field. It consists of two spacecraft that follow each other in orbit.", + ], + more: [ + "Launched on May 22, 2018, GRACE-FO continues the work of tracking Earth's water movement to monitor changes in underground water storage, the amount of water in large lakes and rivers, soil moisture, ice sheets and glaciers, and sea level caused by the addition of water to the ocean. These discoveries provide a unique view of Earth's climate and have far-reaching benefits to society and the world's population. GRACE-FO is able to make accurate measurements thanks in part to two advanced technologies: a microwave ranging system based on Global Positioning System (GPS) technology, and a very sensitive accelerometer—an instrument that measures the forces on the satellites besides gravity (such as atmospheric drag).", + "Using the microwave ranging system, GRACE can measure the distance between satellites to within one micron -- about the diameter of a blood cell. Together, these very precise measurements of location, force and orbital change translate into an observation of gravity with unprecedented accuracy. Flight engineers maneuver the satellites only if they separate by more than 155 miles (250 km), otherwise they are left alone and gravity ‘tugs and pulls’ on them.", + ], + }, + dates: { + start: "2018-05-22T19:47:58", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_grace_1", "sc_grace_2", "sc_grace_fo1"], + }, + sc_grail_a: { + title: "GRAIL A", + description: { + blurb: [ + "NASA's GRAIL mission flew twin spacecraft—Ebb and Flow—in tandem around the Moon to map variations in the lunar gravitational field", + ], + more: [ + "As the two spacecraft flew over areas of increasing gravity, the probes moved slightly toward and away from each other, while an instrument measured changes in their relative velocity, providing key information on the Moon’s gravitational field. At the end of the mission, the probes were purposely crashed on the Moon.", + ], + }, + dates: { + start: "2011-09-10T13:08:52", + end: "2012-12-17T22:28:51", + landing: "", + }, + parent: "moon", + related: ["moon", "sc_grail_b"], + }, + sc_grail_b: { + title: "GRAIL B", + description: { + blurb: [ + "NASA's GRAIL mission flew twin spacecraft—Ebb and Flow—in tandem around the Moon to map variations in the lunar gravitational field", + ], + more: [ + "As the two spacecraft flew over areas of increasing gravity, the probes moved slightly toward and away from each other, while an instrument measured changes in their relative velocity, providing key information on the Moon’s gravitational field. At the end of the mission, the probeswere purposely crashed on the Moon.", + ], + }, + dates: { + start: "2011-09-10T13:08:52", + end: "2012-12-17T22:29:21", + landing: "", + }, + parent: "moon", + related: ["moon", "sc_grail_a"], + }, + sc_grifex: { + title: "GRIFEX", + description: { + blurb: [ + "GRIFEX, the Geo-cape Roic In-Flight performance Experiment, was a CubeSat technology validation test for the proposed GEO-CAPE mission.", + ], + more: [ + "GRIFEX advanced the technology required for future space-borne measurements of atmospheric composition from geostationary orbit that are relevant to climate change. The size of GRIFEX was three CubeSat units, or 30 x 10 x 10 cm.", + ], + }, + dates: { + start: "2015-01-31", + end: "2024-02-22", + landing: "", + }, + related: [], + }, + sc_hubble_space_telescope: { + title: "Hubble Space Telescope", + description: { + blurb: [ + "NASA’s Hubble Space Telescope is the first astronomical observatory placed into orbit around Earth with the ability to record images in wavelengths of light spanning from ultraviolet to near-infrared.", + ], + more: [ + "The Hubble Space Telescope's launch and deployment in April 1990 marked the most significant advancement in astronomy since Galileo's telescope. The first major optical telescope to be placed in space, Hubble operates from the ultimate mountaintop. Far above the distortion of Earth's atmosphere, clouds and light pollution, Hubble has an unobstructed view of the universe.", + "Hubble can see far more than what we can with our eyes. Its domain extends from the ultraviolet, through the visible, and to the near-infrared.", + "The telescope has had a major impact on every area of astronomy, from the solar system to objects at the edge of the universe. Scientists have used Hubble to observe the most distant stars and galaxies as well as the planets in our solar system.", + "Data and from the orbiting telescope are the backbone of more than 15,000 technical papers. It also, of course, continues to dazzle us with stunning pictures of stars, galaxies and planets.", + ], + }, + dates: { + start: "1990-04-24T12:33:51", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_spitzer", "sc_chandra"], + }, + sc_huygens: { + title: "Huygens", + description: { + blurb: [ + "The European Space Agency's Huygens Probe was a unique, advanced spacecraft and a crucial part of the overall Cassini mission to explore Saturn.", + ], + more: [ + "The probe was about 9 feet wide (2.7 meters) and weighed roughly 700 pounds (318 kilograms). It was built like a shellfish: a hard shell protected its delicate interior from high temperatures during the a two hour and 27 minute descent through the atmosphere of Saturn's giant moon Titan. Huygens landed on Titan on January 14, 2005.", + ], + }, + dates: { + start: "1997-10-15T08:43:00", + end: "2005-01-14T13:37:00", + landing: "2005-01-14T12:43:00", + highlight: "2004-12-25T02:00:15", + }, + parent: "saturn", + related: ["sc_cassini", "titan"], + }, + sc_ibex: { + title: "IBEX", + description: { + blurb: [ + "Interstellar Boundary Explorer (IBEX) is a NASA spacecraft mapping the boundary of our solar system.", + ], + more: [ + 'IBEX is a small satellite the size of a bus tire. It has "telescopes" that look out toward the edge of the solar system. However, these telescopes are different than most telescopes. They collect particles instead of light. These particles are called energetic neutral atoms (ENAs)—high-energy particles produced at the very edge of our solar system.', + ], + }, + dates: { + start: "2008-10-08T17:47:23", + end: "", + landing: "", + }, + related: [], + }, + sc_icesat_2: { + title: "ICESat-2", + description: { + blurb: [ + "The Ice, Cloud, and land Elevation Satellite-2, or ICESat-2, will measure the height of a changing Earth – one laser pulse at a time, 10,000 laser pulses a second.", + ], + more: [ + "ICESat-2 (short for Ice, Cloud, and land Elevation Satellite), launched Sept. 15, 2018, uses lasers and a very precise detection instrument to measure the elevation of Earth’s surface. By timing how long it takes laser beams to travel from the satellite to Earth and back, scientists can calculate the height of glaciers, sea ice, forests, lakes and more – including the changing ice sheets of Greenland and Antarctica. Our planet's frozen and icy areas, called the cryosphere, are a key focus of NASA's Earth science research. ICESat-2 will help scientists investigate why, and how much, our cryosphere is changing in a warming climate. The satellite will also measure heights across Earth's temperate and tropical regions, and take stock of the vegetation in forests worldwide.", + ], + }, + dates: { + start: "2018-09-15T13:02:00", + end: "", + landing: "", + }, + related: ["earth"], + }, + sc_image: { + title: "IMAGE", + description: { + blurb: [ + "IMAGE (Imager for Magnetopause-to-Aurora Global Exploration) is a NASA mission that studied the global response of the Earth's magnetosphere to changes in the solar wind.", + ], + more: [ + "IMAGE was the first spacecraft dedicated to imaging the Earth's magnetosphere, producing comprehensive global images of plasma in the inner magnetosphere.", + ], + }, + dates: { + start: "2000-03-25T20:34:43", + end: "2005-12-18T07:39:00", + landing: "", + }, + related: ["sc_wind"], + }, + sc_ipex: { + title: "IPEX", + description: { + blurb: [ + 'IPEX was a CubeSat mission that was an "Intelligent Payload EXperiment."', + ], + more: [ + "The purpose of the mission was to validate onboard instrument processing and autonomous payload operations that could be used in the future on the proposed NASA HYperSPectral Infra-Red Instrument (HyspIRI) mission.", + ], + }, + dates: { + start: "2013-12-06T07:13:40", + end: "", + landing: "", + }, + related: [], + }, + sc_isas: { + title: "ISAS", + description: { + blurb: ["Operational for two months in February and March of 1994."], + more: [ + "The Clementine Interstage Adapter Satellite (ISAS) was the lunar transfer booster used to propel the Clementine spacecraft to the Moon from Earth orbit.", + ], + }, + dates: { + start: "", + end: "", + landing: "", + }, + related: [], + }, + sc_iss: { + title: "International Space Station (ISS)", + description: { + blurb: [ + "The International Space Station (ISS) is a permanently crewed on-orbit laboratory that enables scientific research supporting innovation on Earth and future deep space exploration.", + ], + more: [ + "From design to launch, 15 countries collaborated to assemble the world's only permanently crewed orbital facility, which can house a crew of six and 150 ongoing experiments annually across an array of disciplines. The ISS represents a global effort to expand our knowledge and improve life on Earth while testing technology that will extend our reach to the moon, Mars and beyond.", + ], + }, + dates: { + start: "1998-11-20", + end: "", + landing: "", + }, + parent: "earth", + }, + sc_ixpe: { + title: "IXPE", + description: { + blurb: [ + "The Imaging X-Ray Polarimetry Explorer (IXPE) will allow astronomers to explore, for the first time, the hidden details of some of the most extreme and exotic astronomical objects, such as stellar and supermassive black holes, neutron stars and pulsars.", + ], + }, + dates: { + start: "2021-12-13T06:00:00", + end: "", + landing: "", + }, + related: ["earth"], + }, + sc_jason_1: { + title: "Jason-1", + description: { + blurb: [ + "Jason-1 was a satellite altimeter oceanography mission. It sought to monitor global ocean circulation, study the ties between the ocean and the atmosphere, improve global climate forecasts and predictions, and monitor events such as El Niño and ocean eddies.", + ], + more: [ + "Jason-1 is the successor to the TOPEX/Poseidon mission, which measured ocean surface topography from 1992 through 2005. Like its predecessor, Jason-1 is a joint project between the NASA (United States) and CNES (France) space agencies. Jason-1 has led to Jason-2 and Jason-3, and then the Sentinel-6 Michael Freilich mission.", + ], + }, + dates: { + start: "2001-12-07T15:07:00", + end: "2013-07-01T00:00:00", + landing: "", + }, + parent: "earth", + related: ["sc_jason_2", "sc_jason_3", "sc_sentinel_6"], + }, + sc_jason_2: { + title: "Jason-2/OSTM", + description: { + blurb: [ + "Jason-2/OSTM used high-precision ocean altimetry to measure the distance between the satellite and the ocean surface to within a few centimeters.", + ], + more: [ + "The third in a series of sea level missions, Jason-2/Ocean Surface Topography Mission follows the TOPEX/Poseiden and Jason-1 missions. These very accurate observations of variations in sea surface height — also known as ocean topography — provide information about global sea level, the speed and direction of ocean currents, and heat stored in the ocean.", + ], + }, + dates: { + start: "2008-06-20T07:46:25", + end: "2019-10-09T00:00:00", + landing: "", + }, + parent: "earth", + related: ["sc_jason_3", "sc_sentinel_6"], + }, + sc_jason_3: { + title: "Jason-3", + description: { + blurb: [ + "Jason-3 is the fourth mission in U.S.-European series of satellite missions that measure the height of the ocean surface.", + ], + more: [ + "Launched on January 17, 2016, the mission will extend the time series of ocean surface topography measurements (the hills and valleys of the ocean surface) begun by the TOPEX/Poseidon satellite mission in 1992 and continuing through the Jason-1 (launched in 2001) and the currently operating OSTM/Jason-2 (launched in 2008) missions. These measurements provide scientists with critical information about circulation patterns in the ocean and about both global and regional changes in sea level and the climate implications of a warming world.", + "The primary instrument on Jason-3 is a radar altimeter. The altimeter will measure sea-level variations over the global ocean with very high accuracy (as 1.3 inches or 3.3 centimeters, with a goal of achieving 1 inch or 2.5 centimeters). Continual, long-term, reliable data of changes in ocean surface topography will be generated and will be used by scientists and operational agencies (NOAA, European weather agencies, marine operators, etc.) for scientific research and operational oceanography for the benefit of society.", + ], + }, + dates: { + start: "2016-01-17T18:42:18", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_jason_2", "sc_sentinel_6"], + }, + sc_juice: { + title: "Juice", + description: { + blurb: [ + "The ESA’s Jupiter Icy Moons Explorer, Juice, will make detailed observations of the giant gas planet and its three large ocean-bearing moons – Ganymede, Callisto and Europa – with a suite of remote sensing, geophysical and in situ instruments.", + ], + more: [ + "The mission will characterize these moons as both planetary objects and possible habitats, explore Jupiter’s complex environment in depth, and study the wider Jupiter system as an archetype for gas giants across the Universe. Juice will reach the Jovian system in July 2031 after four gravity assists and eight years of travel. In December of 2034, the spacecraft will enter orbit around Ganymede for its close-up science mission.", + ], + }, + dates: { + start: "2023-04-14T12:14:36", + end: "", + }, + related: ["jupiter", "sc_juno", "ganymede", "europa", "callisto"], + }, + sc_juno: { + title: "Juno", + description: { + blurb: [ + "Juno is studying the interior and origins of giant planet Jupiter for the first time. It has been orbiting Jupiter since it arrived in 2016.", + ], + more: [ + "Juno’s marching orders — to pick the lock on Jupiter’s secrets — have been spectacularly fulfilled. High above Jupiter’s roiling clouds, three giant blades stretch out from a cylindrical, six-sided body. Some 66 feet (20 meters) wide, the Juno spacecraft is a dynamic engineering marvel, spinning to keep itself stable as it makes sweeping elliptical (oval-shaped) orbits around Jupiter. At their widest point, these carry Juno far from the giant planet and its moons, keeping it mostly clear of heavy radiation regions. But on closer passes, every 38 days, Juno cuts within 3,100 miles (5,000 kilometers) of Jupiter’s cloud tops. Juno achieved rough, global coverage of the giant planet by the end of 2018, but at a coarse resolution; it then began a new set of orbits to fill in the details. The spacecraft’s long, looping orbits are meant to keep it mostly clear of the doughnut-shaped belts of harmful radiation close to Jupiter and its moons. Every 38 days, however, Juno makes a close pass to observe Jupiter’s gigantic clouds and titanic storms, crackling with lightning. Powerful pulses of energy — super-charged particles streaming through Jupiter’s magnetic field — create auroras. They’re similar to the northern and southern lights on Earth, that is, if you can imagine scaling them up to the size of a planet that could hold 1,300 Earths.", + ], + }, + dates: { + start: "2011-08-05T16:25:00", + end: "", + landing: "", + }, + related: ["jupiter", "sc_galileo"], + parent: "jupiter", + }, + sc_jwst: { + title: "James Webb Space Telescope", + description: { + blurb: [ + "The James Webb Space Telescope (JWST) is a large infrared telescope with an approximately 6.5 meter primary mirror.", + ], + more: [ + "Webb will be the premier observatory of the next decade, serving thousands of astronomers worldwide. It will study every phase in the history of our Universe, ranging from the first luminous glows after the Big Bang, to the formation of solar systems capable of supporting life on planets like Earth, to the evolution of our own Solar System.", + ], + }, + dates: { + start: "2021-12-25T12:20:00", + end: "", + landing: "", + }, + parent: "earth", + related: [], + }, + sc_kepler_space_telescope: { + title: "Kepler", + description: { + blurb: [ + 'NASA\'s Kepler spacecraft was launched to search for Earth-like planets orbiting other stars. It discovered more than 2,600 of these "exoplanets"—including many that are promising places for life to exist.', + ], + more: [ + "Kepler was equipped to look for planets with size spans from one-half to twice the size of Earth (terrestrial planets) in the habitable zone of their stars where liquid water might exist in the natural state on the surface of the planet. It operated from 2009 to 2018.", + ], + }, + dates: { + start: "2009-03-07T03:49:57", + end: "2018-11-15T00:00:00", + landing: "", + }, + parent: "earth", + related: [ + "sc_hubble_space_telescope", + "sc_chandra", + "sc_spitzer", + "sc_tess", + ], + }, + sc_ladee: { + title: "LADEE", + description: { + blurb: [ + "NASA's LADEE was a robotic mission that orbited the Moon to gather detailed information about the lunar atmosphere, conditions near the surface and the environmental influences on lunar dust.", + ], + more: [ + "By studying the exosphere—an atmosphere that is so thin that its molecules do not collide with each other—the Lunar Atmosphere and Dust Environment Explorer (LADEE) helped further the study of other planetary bodies with exospheres such as Mercury and some of Jupiter’s moons.", + ], + }, + dates: { + start: "2013-09-07T03:27:00", + end: "2014-04-08T04:30:00", + landing: "", + }, + parent: "moon", + related: ["moon", "sc_lunar_reconaissance_orbiter"], + }, + sc_landsat_7: { + title: "Landsat 7", + description: { + blurb: [ + "The Landsat program offers the longest continuous global record of the Earth’s surface, supplying more than 40 years of imagery of the entire surface of Earth.", + ], + more: [ + "Landsat 7 is the seventh satellite of the Landsat program. Launched on 15 April 1999, Landsat 7's primary goal is to refresh the global archive of satellite photos, providing up-to-date and cloud-free images. The Landsat program is managed and operated by the United States Geological Survey, and data from Landsat 7 is collected and distributed by the USGS.", + ], + }, + dates: { + start: "1999-04-15T18:32:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_landsat_8"], + }, + sc_landsat_8: { + title: "Landsat 8", + description: { + blurb: [ + "The Landsat program offers the longest continuous global record of the Earth’s surface, supplying more than 40 years of imagery of the entire surface of Earth.", + ], + more: [ + "It is the eighth satellite in the Landsat program; the seventh to reach orbit successfully. Originally called the Landsat Data Continuity Mission (LDCM), it is a collaboration between NASA and the United States Geological Survey (USGS). NASA Goddard Space Flight Center in Greenbelt, Maryland, provided development, mission systems engineering, and acquisition of the launch vehicle while the USGS provided for development of the ground systems and will conduct on-going mission operations. It comprises the camera of the Operational Land Imager (OLI) and the Thermal Infrared Sensor (TIRS) which can be used to study earth surface temperature and is used to study global warming.", + ], + }, + dates: { + start: "2013-02-11T18:02:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_landsat_7", "sc_landsat_9"], + }, + sc_landsat_9: { + title: "Landsat 9", + description: { + blurb: [ + "The Landsat program offers the longest continuous global record of the Earth’s surface, supplying more than 40 years of imagery of the entire surface of Earth.", + ], + more: [ + "It is the ninth satellite in the Landsat program; the eigth to reach orbit successfully. Originally called the Landsat Data Continuity Mission (LDCM), it is a collaboration between NASA and the United States Geological Survey (USGS). NASA Goddard Space Flight Center in Greenbelt, Maryland, provided development, mission systems engineering, and acquisition of the launch vehicle while the USGS provided for development of the ground systems and will conduct on-going mission operations. It comprises the camera of the Operational Land Imager (OLI) and the Thermal Infrared Sensor (TIRS) which can be used to study earth surface temperature and is used to study global warming.", + ], + }, + dates: { + start: "2021-09-27T18:11:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["sc_landsat_7", "sc_landsat_8"], + }, + sc_lcross: { + title: "LCROSS", + description: { + blurb: [ + "NASA's Lunar Crater Observation and Sensing Satellite (LCROSS) was launched with the Lunar Reconnaissance Orbiter to determine if water-ice exists in a permanently shadowed crater at the Moon's south pole.", + ], + more: [ + "The identification of water is very important to the future of human activities on the Moon. LCROSS remained paired to its upper stage centaur until reaching the south pole of the moon. The centaur was then separated from LCROSS and intentionally crashed into the south pole of the Moon. The impact ejected material from the crater's floor to create a plume that specialized instruments have been able to analyze for the presence of water (ice and vapor), hydrocarbons and hydrated materials. About fifteeen minutes after the upper stage centaur impacted, LCROSS also intentionally crashed into the perpetually dark floor of the Moon's polar crater Cabeus.", + ], + }, + dates: { + start: "2009-06-18T21:32:00", + end: "2009-10-09T11:37:00", + landing: "", + }, + parent: "moon", + related: ["sc_lunar_reconnaissance_orbiter", "moon"], + }, + sc_lucy: { + title: "Lucy", + description: { + blurb: [ + "The Lucy spacecraft will explore a record-breaking number of asteroids, flying by two asteroids in the solar system’s main asteroid belt, and by eight Trojan asteroids that share an orbit around the Sun with Jupiter.", + ], + link: "https://science.nasa.gov/mission/lucy/", + more: [ + "Trojan asteroids associated with Jupiter are thought to be remnants of the primordial material that formed the outer planets. These primitive bodies may hold clues to the history of solar system formation. Lucy is the first mission to visit the Trojans.", + ], + }, + dates: { + start: "2021-10-16T09:34:00", + end: "", + landing: "", + }, + related: [ + "jupiter", + "152830_dinkinesh", + "52246_donaldjohanson", + "3548_eurybates", + "15094_polymele", + "11351_leucus", + "21900_orus", + "617_patroclus", + ], + }, + sc_lunar_flashlight: { + title: "Lunar Flashlight", + description: { + blurb: [ + "Roughly the size of a briefcase, Lunar Flashlight is a very small satellite that uses near-infrared lasers and an onboard spectrometer to map ice in permanently shadowed regions near the Moon's south pole.", + ], + more: [ + 'The observations made by the low-cost mission provide unambiguous information about the presence of water ice deposits inside craters that would be an valuable in-situ resource for future Artemis missions to the lunar surface. As a technology demonstration mission, Lunar Flashlight showcases several technological firsts, including being the first mission to look for water ice using a laser reflectometer and the first planetary CubeSat mission to use "green" propulsion - a propellant that is less toxic and safer than hydrazine, a common propellant used by spacecraft.', + ], + }, + dates: { + start: "2022-11-30T09:45:00", + end: "", + landing: "", + }, + related: ["moon", "sc_artemis_1"], + }, + sc_lunar_prospector: { + title: "Lunar Prospector", + description: { + blurb: [ + "NASA's Lunar Prospector orbited the Moon for almost 19 months to map its surface composition and to look for polar ice.", + ], + more: [ + "The probe found evidence suggesting water ice at both poles. The mission ended in July of 1999 with the spacecraft impacting the lunar surface, creating a dust cloud that was studied from Earth.", + ], + }, + dates: { + start: "1998-01-07T02:28:44", + end: "1999-07-31T09:52:02", + landing: "", + }, + parent: "moon", + related: ["moon"], + }, + sc_lunar_reconnaissance_orbiter: { + title: "Lunar Reconnaissance Orbiter", + description: { + blurb: [ + "The Lunar Reconnaissance Orbiter (LRO) was launched in 2009 on the first U.S. mission to the Moon in over 10 years.", + ], + more: [ + "LRO’s primary goal was to make a 3D map of the Moon’s surface from lunar polar orbit as part of a high-resolution mapping program to identify landing sites and potential resources, to investigate the radiation environment, and to prove new technologies in anticipation of future automated and human missions to the surface of the Moon.The LRO instruments return global data, such as day-night temperature maps, a global geodetic grid, high resolution color imaging and the moon's UV albedo. However there is particular emphasis on the polar regions of the moon where continuous access to solar illumination may be possible and the prospect of water in the permanently shadowed regions at the poles may exist.", + ], + }, + dates: { + start: "2009-06-18T21:32:00", + end: "", + landing: "", + }, + parent: "moon", + related: ["sc_lcross", "moon", "sc_lunar_prospector", "sc_ladee"], + }, + sc_magellan: { + title: "Magellan", + description: { + blurb: [ + "NASA's Magellan mission was the first spacecraft to image the entire surface of Venus and made several discoveries about the planet.", + ], + more: [ + "The Magellan probe was the first interplanetary mission to be launched from the Space Shuttle, the first mission to map the entire surface of Venus, and the first spacecraft to test aerobraking as a method for circularizing its orbit. Magellan was the fifth successful NASA mission to Venus, and it ended an eleven-year gap in U.S. interplanetary probe launches. It self-destructed in the Venusian atmosphere in 1994.", + ], + }, + dates: { + start: "1989-05-04T18:47:00", + end: "1994-10-13T10:05:00", + landing: "", + }, + parent: "venus", + related: ["venus"], + }, + sc_marco_a: { + title: "MarCO A", + description: { + blurb: ["MarCO was the first mission to test CubeSats in deep space"], + more: [ + "Launching with the InSight mission to Mars, the twin spacecraft provided an experimental communications relay to let scientists on Earth know quickly about InSight's landing.", + ], + }, + dates: { + start: "2018-05-05T11:05:00", + end: "2019-01-04T00:00:00", + landing: "", + }, + related: [], + }, + sc_marco_b: { + title: "MarCO B", + description: { + blurb: ["MarCO was the first mission to test CubeSats in deep space"], + more: [ + "Launching with the InSight mission to Mars, the twin spacecraft provided an experimental communications relay to let scientists on Earth know quickly about InSight's landing.", + ], + }, + dates: { + start: "2018-05-05T11:05:00", + end: "2018-12-29T00:00:00", + landing: "", + }, + related: [], + }, + sc_mars_express: { + title: "Mars Express", + description: { + blurb: [ + "The Mars Express mission is exploring the planet Mars, and is the first planetary mission attempted by the European Space Agency (ESA).", + ], + more: [ + "NASA is participating in a mission of the European Space Agency and the Italian Space Agency called Mars Express, which has been exploring the atmosphere and surface of Mars from polar orbit since arriving at the red planet on December 26, 2003. The mission's main objective is to search for sub-surface water from orbit. Seven scientific instruments on the orbiting spacecraft have conducted rigorous investigations to help answer fundamental questions about the geology, atmosphere, surface environment, history of water, and potential for life on Mars. Examples of discoveries - still debated by scientists -- by Mars Express are evidence of recent glacial activity, explosive volcanism, and methane gas.", + "Mars Express is so called because it will be built more quickly than any other comparable planetary mission.", + ], + }, + dates: { + start: "2003-06-02T17:45:00", + end: "", + landing: "", + }, + related: ["mars"], + parent: "mars", + }, + sc_mars_global_surveyor: { + title: "Mars Global Surveyor", + description: { + blurb: [ + "Mars Global Surveyor was a global mapping mission that examined the entire planet, from the ionosphere down through the atmosphere to the surface.", + ], + more: [ + "During its mission, Mars Global Surveyor also produced the first three-dimensional profiles of Mars’ North Pole using laser altimeter readings. In addition, the laser altimeter essentially mapped almost all of the planet, by firing approximately 500 billion pulses at the surface, providing topographical data that was more detailed than many places on Earth. The spacecraft’s primary mission concluded on Feb. 1, 2001, by which time it had returned 83,000 images of Mars, more than all previous missions to Mars combined. It continued to operate until late 2006.", + ], + }, + dates: { + start: "1996-11-07T17:00:00", + end: "2006-11-02T00:00:00", + landing: "", + }, + parent: "mars", + related: ["mars"], + }, + sc_mars_odyssey: { + title: "Mars Odyssey", + description: { + blurb: [ + "Still in orbit around Mars, 2001 Mars Odyssey holds the record for the longest continually active spacecraft in orbit around a planet other than Earth.", + ], + more: [ + "Mars Odyssey was designed to investigate the Martian environment, providing key information on its surface and the radiation hazards future explorers might face. The goal was to map the chemical and mineralogical makeup of Mars as a step to detecting evidence of past or present water and volcanic activity on Mars. One of Mars Odyssey’s most exciting findings came early in the mission. In May 2002, NASA announced that the probe had identified large amounts of hydrogen in the soil, implying the presence of ice below the planet’s surface. During its many years in Martian orbit, Mars Odyssey globally mapped the amount and distribution of the numerous chemical elements and minerals in the Martian surface and also tracked the radiation environment in low Mars orbit, both necessary before humans can effectively explore the Martian surface.", + "By mid-2016, the THEMIS instrument had returned more than 208,000 images in visible-light wavelengths and more than 188,000 in thermal-infrared wavelengths.", + ], + }, + dates: { + start: "2001-04-07T15:02:22", + end: "", + landing: "", + }, + related: ["mars"], + parent: "mars", + }, + sc_mars_reconnaissance_orbiter: { + title: "Mars Reconnaissance Orbiter", + description: { + blurb: [ + "Mars Reconnaissance Orbiter (MRO) is a large orbiter, modeled in part on NASA’s highly successful Mars Global Surveyor spacecraft, designed to photograph Mars from orbit.", + ], + more: [ + "Mars Reconnaissance Orbiter is designed to track changes in the water and dust in Mars' atmosphere, look for more evidence of ancient seas and hot springs and peer into past Martian climate changes by studying surface minerals and layering. The orbiter carries a powerful camera capable of taking sharp images of surface features the size of a beach ball. The orbiter also serves as a data relay station for other Mars missions.", + ], + }, + dates: { + start: "2005-08-12T11:43:00", + end: "", + landing: "", + }, + related: ["mars", "sc_mars_global_surveyor"], + parent: "mars", + }, + sc_maven: { + title: "MAVEN", + description: { + blurb: [ + "NASA's MAVEN is currently orbiting Mars studying the structure and composition of the upper atmosphere of the Red Planet.", + ], + more: [ + "The Mars Atmosphere and Volatile Evolution Mission (MAVEN) is the first mission dedicated to studying Mars’ upper atmosphere. The goal is to use this data to determine how the loss of volatiles from the Martian atmosphere has affected the Martian climate over time, and thus contribute to a better understanding of terrestrial climatology.", + ], + }, + dates: { + start: "2013-11-18T18:28:00", + end: "", + landing: "", + }, + related: ["mars"], + parent: "mars", + }, + sc_messenger: { + title: "MESSENGER", + description: { + blurb: [ + "MESSENGER was a NASA robotic space probe that orbited the planet Mercury between 2011 and 2015, studying Mercury's chemical composition, geology, and magnetic field.", + ], + more: [ + "MESSENGER (Mercury Surface, Space Environment, Geochemistry and Ranging) was the first spacecraft to orbit Mercury. Among its accomplishments, the mission determined Mercury’s surface composition, revealed its geological history, discovered details about its internal magnetic field, and verified its polar deposits are dominantly water-ice. The mission ended when MESSENGER slammed into Mercury’s surface.", + ], + }, + dates: { + start: "2004-08-03T06:15:56", + end: "2015-04-30T19:26:00", + landing: "", + highlight: "2015-04-30T18:26:00", + }, + parent: "mercury", + related: ["mercury"], + }, + sc_mcubed_2: { + title: "MCubed-2", + description: { + blurb: [ + "MCubed-2 is a CubeSat (a miniaturized satellite) built by students at the University of Michigan in collaboration with NASA.", + ], + more: [ + "MCubed-2, short for Michigan Multipurpose Minisat 2, was designed as a technology demonstrator for a new FPGA-based image processing system intended for a future NASA mission.", + ], + }, + dates: { + start: "2013-12-06", + end: "", + landing: "", + }, + related: ["earth"], + }, + sc_mms_1: { + title: "MMS 1", + description: { + blurb: [ + "MMS consists of four identical spacecraft that orbit around Earth through the dynamic magnetic system surrounding our planet to study a little-understood phenomenon called magnetic reconnection.", + ], + more: [ + "The Magnetospheric Multiscale (MMS) mission is a Solar Terrestrial Probes mission comprising four identically instrumented spacecraft that will use Earth's magnetosphere as a laboratory to study the microphysics of three fundamental plasma processes: magnetic reconnection, energetic particle acceleration, and turbulence. These processes occur in all astrophysical plasma systems but can be studied in situ only in our solar system and most efficiently only in Earth's magnetosphere, where they control the dynamics of the geospace environment and play an important role in the processes known as \"space weather.\"", + ], + }, + dates: { + start: "2015-03-13T02:44:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["earth", "sc_mms_2", "sc_mms_3", "sc_mms_4"], + }, + sc_mms_2: { + title: "MMS 2", + description: { + blurb: [ + "MMS consists of four identical spacecraft that orbit around Earth through the dynamic magnetic system surrounding our planet to study a little-understood phenomenon called magnetic reconnection.", + ], + more: [ + "The Magnetospheric Multiscale (MMS) mission is a Solar Terrestrial Probes mission comprising four identically instrumented spacecraft that will use Earth's magnetosphere as a laboratory to study the microphysics of three fundamental plasma processes: magnetic reconnection, energetic particle acceleration, and turbulence. These processes occur in all astrophysical plasma systems but can be studied in situ only in our solar system and most efficiently only in Earth's magnetosphere, where they control the dynamics of the geospace environment and play an important role in the processes known as \"space weather.\"", + ], + }, + dates: { + start: "2015-03-13T02:44:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["earth", "sc_mms_1", "sc_mms_3", "sc_mms_4"], + }, + sc_mms_3: { + title: "MMS 3", + description: { + blurb: [ + "MMS consists of four identical spacecraft that orbit around Earth through the dynamic magnetic system surrounding our planet to study a little-understood phenomenon called magnetic reconnection.", + ], + more: [ + "The Magnetospheric Multiscale (MMS) mission is a Solar Terrestrial Probes mission comprising four identically instrumented spacecraft that will use Earth's magnetosphere as a laboratory to study the microphysics of three fundamental plasma processes: magnetic reconnection, energetic particle acceleration, and turbulence. These processes occur in all astrophysical plasma systems but can be studied in situ only in our solar system and most efficiently only in Earth's magnetosphere, where they control the dynamics of the geospace environment and play an important role in the processes known as \"space weather.\"", + ], + }, + dates: { + start: "2015-03-13T02:44:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["earth", "sc_mms_1", "sc_mms_2", "sc_mms_4"], + }, + sc_mms_4: { + title: "MMS 4", + description: { + blurb: [ + "MMS consists of four identical spacecraft that orbit around Earth through the dynamic magnetic system surrounding our planet to study a little-understood phenomenon called magnetic reconnection.", + ], + more: [ + "The Magnetospheric Multiscale (MMS) mission is a Solar Terrestrial Probes mission comprising four identically instrumented spacecraft that will use Earth's magnetosphere as a laboratory to study the microphysics of three fundamental plasma processes: magnetic reconnection, energetic particle acceleration, and turbulence. These processes occur in all astrophysical plasma systems but can be studied in situ only in our solar system and most efficiently only in Earth's magnetosphere, where they control the dynamics of the geospace environment and play an important role in the processes known as \"space weather.\"", + ], + }, + dates: { + start: "2015-03-13T02:44:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["earth", "sc_mms_1", "sc_mms_2", "sc_mms_3"], + }, + sc_near_shoemaker: { + title: "NEAR Shoemaker", + description: { + blurb: [ + "NASA's NEAR Shoemaker spacecraft was the first human-made object to orbit and the first to land an asteroid.", + ], + link: "https://solarsystem.nasa.gov/missions/near-shoemaker/in-depth/", + more: [ + "The NEAR mission studied the near-Earth asteroid Eros from close orbit over a period of a year, and also flew by the asteroid Mathilde. The mission succeeded in closing in with the asteroid and orbited it several times, finally ending by touching down on the asteroid on February 12, 2001.", + ], + }, + dates: { + start: "1996-02-17T20:43:27", + end: "2001-02-28T00:00:00", + landing: "2001-02-12T12:56:00", + }, + related: ["433_eros", "253_mathilde"], + }, + sc_new_horizons: { + title: "New Horizons", + description: { + blurb: [ + "New Horizons is a NASA mission to study the dwarf planet Pluto, its moons, and other objects in the Kuiper Belt, a region of the solar system that extends from about 30 AU, near the orbit of Neptune, to about 50 AU from the Sun.", + ], + more: [ + "New Horizons was the first spacecraft to encounter Pluto, a relic from the formation of the solar system. By the time it reached the Pluto system, the spacecraft had traveled farther away and for a longer time period (more than nine years) than any previous deep space spacecraft ever launched. On July 14, 2015, New Horizons flew about 4,800 miles (7,800 kilometers) above the surface of Pluto. Besides collecting data on Pluto and Charon (the Charon flyby was at about 17,900 miles or 28,800 kilometers), New Horizons also observed Pluto’s other satellites, Nix, Hydra, Kerberos and Styx.", + "The download of the entire set of data collected during the encounter with Pluto and Charon—about 6.25 gigabytes—took over 15 months and was officially completed at 21:48 UT Oct. 25, 2016. Such a lengthy period was necessary because the spacecraft was roughly 4.5 light-hours from Earth and it could only transmit 1-2 kilobits per second. On Jan. 1, 2019, New Horizons flew past Arrokoth (previously named 2014 MU69 and also called Ultima Thule), the most distant target in history. The New Horizons mission is currently exploring additional Kuiper Belt objects.", + ], + }, + dates: { + start: "2006-01-19T19:52:00", + end: "", + landing: "", + }, + parent: "outer_solar_system", + related: [ + "134340_pluto", + "charon", + "hydra", + "nix", + "styx", + "486958_arrokoth", + ], + }, + sc_nustar: { + title: "NuSTAR", + description: { + blurb: [ + "The Nuclear Spectroscopic Telescope Array (NuSTAR) mission has deployed the first orbiting telescopes to focus light in the high energy X-ray region of the electromagnetic spectrum. Our view of the universe in this spectral window has been limited because previous orbiting telescopes have not employed true focusing optics, but rather have used coded apertures that have intrinsically high backgrounds and limited sensitivity.", + "In addition to its core science program, NuSTAR will offer opportunities for a broad range of science investigations, ranging from probing cosmic ray origins to studying the extreme physics around collapsed stars to mapping microflares on the surface of the Sun. NuSTAR will also respond to targets of opportunity including supernovae and gamma-ray bursts.", + ], + readmore: [""], + }, + dates: { + start: "2012-06-13T16:00:37", + end: "", + landing: "", + }, + related: ["earth", "sc_chandra"], + }, + sc_oco_2: { + title: "OCO-2", + description: { + blurb: [ + "The Orbiting Carbon Observatory 2, or OCO-2, is an Earth satellite mission designed to study the sources and sinks of carbon dioxide globally and provide scientists with a better idea of how carbon is contributing to climate change.", + ], + more: [ + "The OCO-2 Project primary science objective is to collect the first space-based measurements of atmospheric carbon dioxide with the precision, resolution and coverage needed to characterize its sources and sinks and quantify their variability over the seasonal cycle.OCO-2 flies in a sun-synchronous, near-polar orbit with a group of Earth-orbiting satellites with synergistic science objectives. Near-global coverage of the sunlit portion of Earth is provided in this orbit over a 16-day (233-revolution) repeat cycle. OCO-2’s single instrument incorporates three high-resolution grating spectrometers, designed to measure the near-infrared absorption of reflected sunlight by carbon dioxide and molecular oxygen.", + ], + }, + dates: { + start: "2014-07-02T09:56:23", + end: "", + landing: "", + }, + parent: "earth", + related: ["earth", "sc_iss_oco3"], + }, + sc_osiris_rex: { + title: "OSIRIS-APEX (OSIRIS-REx)", + description: { + blurb: [ + "NASA’s OSIRIS-REx was the first U.S. mission to deliver an asteroid sample to Earth on September 24th, 2023. The spacecraft, renamed OSIRIS-APEX after the delivery, is now headed to asteroid Apophis for a 2029 rendezvous.", + ], + link: "https://www.nasa.gov/osiris-rex", + more: [ + 'OSIRIS-APEX is an acronym for "Origins, Spectral Interpretation, Resource Identification, Security-Apophis Explorer." Originally named OSIRIS-REx ("Regolith Explorer"), the goal of the mission was to collect a sample weighing 2.1 ounces (59.5 grams) from near-Earth asteroid 101955 Bennu and then to bring the sample to Earth.', + "The mission, developed by scientists at the University of Arizona, will give scientists more information about how the early solar system formed and about how life began. It will also help us better understand asteroids that could impact Earth in the future. On October 20th, 2020, approximately 121.6 grams of material from the surface of Bennu was successfully collected. On May 10th, 2021, the spacecraft left Bennu after nearly two years in orbit to begin the two-year voyage back to Earth.", + "On Sept. 24, 2023, the OSIRIS-REx spacecraft flew by Earth to release the capsule carrying the asteroid sample for a parachute landing. The sample capsule deployed its parachute at an altitude of about 1.9 miles (3 kilometers), bringing it in for a soft landing at the Utah Test and Training Range about 80 miles (130 kilometers) west of Salt Lake City, Utah.", + "The capsule was sent to Johnson Space Center in Houston, Texas, where scientists at the Astromaterials Acquisition and Curation Office will catalog it and set aside portions of the sample for partners in the Japanese and Canadian space agencies. The spacecraft collected 121.6 grams of material from Bennu. ", + "The main spacecraft (now renamed OSIRIS-APEX) will continue on to investigate the asteroid 99942 Apophis.", + "", + ], + }, + dates: { + start: "2016-09-08T23:05:00", + end: "", + landing: "", + }, + related: ["101955_bennu", "99942_apophis", "sc_osiris_rex_src"], + }, + sc_osiris_rex_src: { + title: "OSIRIS-REx Sample Return Capsule", + description: { + blurb: [ + "On September 24th, 2023, the OSIRIS-REx sample return capsule re-entered Earth's atmosphere and landed using a parachute in the state of Utah in the United States.", + ], + more: [ + "The OSIRIS-REx Sample Return Capsule (SRC) is an aeroshell design container with a heat shield and parachutes. The capsule contains 121.6 grams of material from the surface of the asteroid Bennu. The capsule containing the material from Bennu was the only part of the spacecraft to return to Earth. The spacecraft itself then changed to a new mission called OSIRIS-APEX and will proceed to study the asteroid Apophis. Lockheed Martin developed the SRC from a heritage design; the Stardust mission utilized a similar design to return tail material from Comet Wild 2 to Earth in 2006.", + ], + }, + dates: { + start: "2023-09-24T01:00:00", // coercing again + end: "2023-09-24T01:00:01", // ignore + landing: "", + highlight: "2023-09-24T10:44:00", + }, + parent: "earth", + related: ["101955_bennu", "sc_osiris_rex"], + }, + sc_pace: { + title: "PACE", + description: { + blurb: [ + "Plankton, Aerosol, Cloud, ocean Ecosystem (PACE) is a NASA Earth-observing satellite mission that will continue and advance observations of global ocean color, biogeochemistry, and ecology, as well as the carbon cycle, aerosols and clouds.", + ], + more: [ + "PACE will advance the assessment of ocean health by measuring the distribution of phytoplankton, tiny plants and algae that sustain the marine food web. It will also continue systematic records of key atmospheric variables associated with air quality and Earth's climate. PACE's data will help us better understand how the ocean and atmosphere exchange carbon dioxide. Novel uses of PACE data will benefit our economy and society; for example, it will help identify the extent and duration of harmful algal blooms. PACE will extend and expand NASA's long-term observations of our living planet. By doing so, it will take Earth's pulse in new ways for decades to come.", + ], + }, + dates: { + start: "2024-02-08T06:33:00", + end: "", + landing: "", + }, + related: ["earth"], + }, + sc_parker_solar_probe: { + title: "Parker Solar Probe", + description: { + blurb: [ + 'NASA\'s Parker Solar Probe is on a mission to "touch the Sun." The spacecraft is flying closer to the Sun’s surface than any spacecraft before it. The mission will revolutionize our understanding of the Sun.', + ], + more: [ + "NASA's Parker Solar Probe is diving into the Sun’s atmosphere, facing brutal heat and radiation, on a mission to give humanity its first-ever sampling of a star’s atmosphere.", + "During its journey, the mission will provide answers to long-standing questions that have puzzled scientists for more than 60 years: Why is the corona much hotter than the Sun's surface (the photosphere)? How does the solar wind accelerate? What are the sources of high-energy solar particles?", + "We live in the Sun's atmosphere and this mission will help scientists better understand the Sun's impact on Earth.", + "Data from Parker will be key to understanding and, perhaps, forecasting space weather. Space weather can change the orbits of satellites, shorten their lifetimes, or interfere with onboard electronics.", + "On its final three orbits, Parker Solar Probe will fly to within 3.9 million miles (6.2 million kilometers) of the Sun’s surface—more than seven times closer than the current record holder for a close solar pass: the Helios 2 spacecraft. Helios came within 27 million miles (43 million kilometers) in 1976.", + "Parker can survive these conditions because cutting-edge thermal engineering advances protect the spacecraft during its dangerous journey.", + "The probe has four instrument suites designed to study magnetic fields, plasma and energetic particles, and image the solar wind.", + "The mission is named for Dr. Eugene N. Parker, who pioneered our modern understanding of the Sun.", + ], + }, + dates: { + start: "2018-08-12T07:31", + end: "", + landing: "", + }, + related: ["sun", "sc_ulysses"], + }, + sc_philae: { + title: "Philae", + description: { + blurb: [ + "The European Space Agency's Rosetta was the first mission designed to orbit and land on a comet. It consisted of an orbiter and a lander -- called Philae.", + ], + more: [ + "On November 12th, 2014, the Philae probe successfully detached from Rosetta and landed on the surface of the comet 67P/Churyumov-Gerasimenko. Philae actually bounced off the surface of the comet twice, and its location was not known precisely for some time. Philae completed 80 percent of its planned first science sequence, returning spectacular images of its surroundings, showing a surface covered by dust and debris ranging in size from inches to a yard (millimeters to a meter).", + ], + }, + dates: { + start: "2004-03-02T07:17:51", + end: "2016-09-30T10:39:28", + landing: "2014-11-12T17:32:00", + highlight: "2014-11-12T14:31:00", + }, + parent: "67p_churyumov_gerasimenko", + related: ["67p_churyumov_gerasimenko", "sc_rosetta"], + }, + sc_pioneer_10: { + title: "Pioneer 10", + description: { + blurb: [ + "Launched in 1972, Pioneer 10 was the first spacecraft to visit Jupiter. Its mission ended in 2003, but it is one of four spacecraft (including the two Voyagers and Pioneer 11) carrying a message from Earth beyond our solar system.", + ], + more: [ + "Pioneer 10, the first NASA mission to the outer planets, garnered a series of firsts perhaps unmatched by any other robotic spacecraft in the space era: the first vehicle placed on a trajectory to escape the solar system into interstellar space; the first spacecraft to fly beyond Mars; the first to fly through the asteroid belt; the first to fly past Jupiter; and the first to use all-nuclear electrical power.", + ], + }, + dates: { + start: "1972-03-02", + end: "2003-01-23", + landing: "", + }, + parent: "outer_solar_system", + related: ["sc_pioneer_11", "sc_voyager_1", "sc_voyager_2", "jupiter"], + }, + sc_pioneer_11: { + title: "Pioneer 11", + description: { + blurb: [ + "Launched in 1973, Pioneer 11 was the first spacecraft to fly past Saturn. Its mission ended in 1995, but it is one of four spacecraft (including the two Voyagers and Pioneer 10) carrying a message from Earth beyond our solar system.", + ], + more: [ + "Pioneer 11, the sister spacecraft to Pioneer 10, was the first human-made object to fly past Saturn and also returned the first pictures of the polar regions of Jupiter. Among Pioneer 11’s many discoveries at Saturn were a narrow ring outside the A ring named the F ring and a new satellite 124 miles (200 kilometers) in diameter.", + ], + }, + dates: { + start: "1973-04-06", + end: "1995-09-30", + landing: "", + }, + parent: "outer_solar_system", + related: [ + "sc_pioneer_10", + "sc_voyager_1", + "sc_voyager_2", + "saturn", + "jupiter", + ], + }, + sc_polar: { + title: "Polar", + description: { + blurb: [ + "The Polar satellite was a NASA science spacecraft designed to study the polar magnetosphere and aurorae.", + ], + more: [ + "Launched in 1996, the Polar mission gathered multi-wavelength imaging of the aurora, measured the entry of plasma into the polar magnetosphere and the geomagnetic tail, the flow of plasma to and from the ionosphere, and the deposition of particle energy in the ionosphere and upper atmosphere.", + ], + }, + dates: { + start: "1996-02-24T11:24:00", + end: "2008-04-28T00:00:00", + landing: "", + }, + related: ["earth"], + }, + sc_psyche: { + title: "Psyche", + description: { + blurb: [ + "The Psyche mission launched on October 13th, 2023, and will explore the origin of planetary cores by studying the metallic asteroid of the same name.", + ], + link: "https://www.jpl.nasa.gov/missions/psyche", + more: [ + "Deep within the terrestrial planets, including Earth, scientists infer the presence of metallic cores, but these lie unreachably far below the planets’ rocky mantles and crusts. The asteroid Psyche offers a unique window into these building blocks of planet formation and the opportunity to investigate a previously unexplored type of world.", + ], + }, + dates: { + start: "2023-10-12T15:26:00", + end: "", + landing: "", + }, + related: [], + }, + sc_quikscat: { + title: "QuikSCAT", + description: { + blurb: [ + "The NASA QuikSCAT (Quick Scatterometer) was an Earth observation satellite designed to measure wind speeds over the ocean.", + ], + more: [ + "Its primary mission was to measure the surface wind speed and direction over the ice-free global oceans. Observations from QuikSCAT had a wide array of applications, and contributed to climatological studies, weather forecasting, meteorology, oceanographic research, marine safety, commercial fishing, tracking large icebergs, and studies of land and sea ice, among others.", + ], + }, + dates: { + start: "1999-06-19T02:15:00", + end: "2018-10-02T00:00:00", + landing: "", + }, + parent: "earth", + related: ["earth", "sc_iss_rapidscat"], + }, + sc_raincube: { + title: "RainCube", + description: { + blurb: [ + "RainCube is a CubeSat (a type of miniature satellite) that is designed to test technology and monitor precipitation.", + ], + more: [ + "RainCube has three main objectives: Develop, launch, and operate the first radar instrument on a CubeSat (6U), demonstrate new technologies and provide space validation for a Ka-band (35.75 GHz) precipitation profiling radar, and enable future precipitation profiling Earth science missions on a low-cost, quick-turnaround platform. RainCube was launched directly from the International Space Station.", + ], + }, + dates: { + start: "2018-05-21T00:00:00", + end: "2020-12-24T00:00:00", + landing: "", + }, + related: ["earth"], + }, + sc_rbsp_a: { + title: "Van Allen Probe A", + description: { + blurb: [ + "The Van Allen Probes were two robotic spacecraft that were used to study the Van Allen radiation belts that surround Earth.", + ], + more: [ + 'A Van Allen radiation belt is a zone of energetic charged particles, most of which originate from the solar wind, that are captured by and held around a planet by that planet\'s magnetic field. The Van Allen Probes were built to study these areas of "space weather" in more detail.', + ], + }, + dates: { + start: "2012-08-30T08:05:00", + end: "2019-10-18T00:00:00", + landing: "", + }, + parent: "earth", + related: ["earth", "sc_rbsp_b"], + }, + sc_rbsp_b: { + title: "Van Allen Probe B", + description: { + blurb: [ + "The Van Allen Probes were two robotic spacecraft that were used to study the Van Allen radiation belts that surround Earth.", + ], + more: [ + 'A Van Allen radiation belt is a zone of energetic charged particles, most of which originate from the solar wind, that are captured by and held around a planet by that planet\'s magnetic field. The Van Allen Probes were built to study these areas of "space weather" in more detail.', + ], + }, + dates: { + start: "2012-08-30T08:05:00", + end: "2019-07-19T00:00:00", + landing: "", + }, + parent: "earth", + related: ["earth", "sc_rbsp_a"], + }, + sc_sac_d: { + title: "Aquarius", + description: { + blurb: [ + "The Aquarius mission, also known as SAC-D, has an instrument also called Aquarius that measured sea surface salinity.", + ], + more: [ + "The Aquarius instrument's surface salinity measurements contributed to a better understanding of ocean dynamics and advancing climate and ocean models, both from season to season and year to year.", + ], + }, + dates: { + start: "2011-06-10T14:20:00", + end: "2015-06-07T00:00:00", + landing: "", + }, + related: [], + }, + sc_rosetta: { + title: "Rosetta", + description: { + blurb: [ + "Rosetta was a European Space Agency mission that was the first spacecraft to orbit a comet, 67P/Churyumov-Gerasimenko.", + ], + link: "https://www.esa.int/Enabling_Support/Operations/Rosetta", + more: [ + "The mission was launched on 2 March 2004, on a 10-year journey towards comet 67P/Churyumov-Gerasimenko. En route, it passed by two asteroids, 2867 Steins (in 2008) and 21 Lutetia (in 2010), before entering deep-space hibernation mode in June 2011. On 20 January 2014, it 'woke up' and prepared for arrival at the comet in August that year. On 12 November, the mission deployed its Philae probe to the comet, the first time in history that such a feat was achieved.", + ], + }, + dates: { + start: "2004-03-02T09:40:51", + end: "2016-09-30T10:39:28", + landing: "2014-11-12T17:32:00", + }, + related: ["67p_churyumov_gerasimenko", "21_lutetia", "2867_steins"], + }, + sc_sdo: { + title: "Solar Dynamics Observatory", + description: { + blurb: [ + "The Solar Dynamics Observatory (SDO) is the first mission to be launched for NASA's Living With a Star (LWS) Program, a program designed to understand the causes of solar variability and its impacts on Earth.", + ], + more: [ + "SDO is designed to help us understand the Sun's influence on Earth and Near-Earth space by studying the solar atmosphere on small scales of space and time and in many wavelengths simultaneously.", + ], + }, + dates: { + start: "2010-02-11T15:23:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["sun"], + }, + sc_sentinel_6: { + title: "Sentinel-6 Michael Freilich", + description: { + blurb: [ + "Sentinel-6 Michael Freilich measures sea level height worldwide, continuing the work of the Jason-3 satellite.", + ], + more: [ + "The first of two identical satellites to be launched five years apart, Sentinel-6 Michael Freilich will make high precision ocean altimetry measurements to continue the work previously done by Jason-1, Jason-2/OSTM, and the Jason-3 missions.", + "A secondary objective is to collect high resolution vertical profiles of temperature and water vapor through the Radio Occultation instrument. This is used to help numerical weather predictions.", + ], + }, + dates: { + start: "2020-11-21T17:17:08", + end: "", + landing: "", + }, + parent: "earth", + related: ["earth", "sc_jason_3", "sc_jason_2"], + }, + sc_smap: { + title: "SMAP", + description: { + blurb: [ + "The Soil Moisture Active Passive (SMAP) mission is an orbiting observatory that measures the amount of water in the surface soil everywhere on Earth.", + ], + more: [ + "The Soil Moisture Active Passive (SMAP) satellite maps global soil moisture and detects whether soils are frozen or thawed. This mission helps scientists understand the links between Earth's water, energy and carbon cycles; reduce uncertainties in predicting weather and climate; and enhance our ability to monitor and predict natural hazards such as floods and droughts. SMAP is designed to measure soil moisture, every 2-3 days. This permits changes, around the world, to be observed over time scales ranging from major storms to repeated measurements of changes over the seasons.", + "Everywhere on Earth not covered with water or not frozen, SMAP measures how much water is in the top layer of soil. It also distinguishes between ground that is frozen or thawed. Where the ground is not frozen, SMAP measures the amount of water found between the minerals, rocky material, and organic particles found in soil everywhere in the world (SMAP measures liquid water in the top layer of ground but is not able to measure the ice.)", + ], + }, + dates: { + start: "2015-01-31T14:22:00", + end: "", + landing: "", + }, + related: ["earth"], + }, + sc_soho: { + title: "SOHO", + description: { + blurb: [ + "SOHO is the longest-lived Sun-watching satellite to date. Numerous mission extensions have enabled the spacecraft to observe two 11-year solar cycles and to discover thousands of comets.", + ], + more: [ + "The ESA-sponsored Solar and Heliospheric Observatory (SOHO) carries 12 scientific instruments to study the solar atmosphere, helioseismology and the solar wind. Information from the mission has allowed scientists to learn more about the Sun’s internal structure and dynamics, the chromosphere, the corona and solar particles.", + ], + }, + dates: { + start: "1995-12-02", + end: "", + landing: "", + }, + parent: "earth", + related: ["sun", "sc_sdo", "sc_stereo_ahead", "sc_stereo_behind"], + }, + sc_sorce: { + title: "SORCE", + description: { + blurb: [ + "The Solar Radiation and Climate Experiment (SORCE) was a NASA-sponsored satellite mission that measured incoming X-ray, ultraviolet, visible, near-infrared, and total solar radiation.", + ], + more: [ + "The measurements provided by SORCE specifically address long-term climate change, natural variability and enhanced climate prediction, and atmospheric ozone and UV-B radiation. These measurements are critical to studies of the Sun; its effect on our Earth system; and its influenceon humankind. SORCE ended its mission in 2020.", + ], + }, + dates: { + start: "2003-01-25T20:13:35", + end: "2020-02-25T00:00:00", + landing: "", + }, + related: ["earth", "sun"], + }, + sc_spitzer: { + title: "Spitzer Space Telescope", + description: { + blurb: [ + "NASA's Spitzer was the first telescope to detect light from an exoplanet, or a planet outside our solar system.", + ], + more: [ + "The Spitzer Space Telescope (formerly the Space Infrared Telescope Facility or SIRTF) was the fourth and last of NASA’s “Great Observatories,” and carried a 34-inch (85-centimeter) infrared telescope to study asteroids, comets, planets and distant galaxies. It was retired in January of 2020.", + ], + }, + dates: { + start: "2003-08-25T05:35:39", + end: "2020-01-30T00:00:00", + landing: "", + }, + related: ["sc_hubble_space_telescope", "sc_chandra"], + }, + sc_stardust: { + title: "Stardust", + description: { + blurb: [ + "NASA's Stardust was the first spacecraft to bring samples from a comet to Earth.", + ], + link: "https://solarsystem.nasa.gov/missions/stardust/in-depth/", + more: [ + "Its primary goal was to fly by the Comet Wild 2, collect samples of dust from the coma of the comet as well as additional interstellar particles, and then bring the samples to Earth. In 2006, the sample return capsule re-entered Earth's atmosphere and landed in Utah, and the sampes have been studied ever since. After dropping off the samples at Earth, the spacecraft visited Comet Tempel 1 in 2011, and then the mission ended shortly thereafter.", + ], + }, + dates: { + start: "1999-02-07T22:10:00", + end: "2011-03-24T23:33:00", + landing: "2006-01-15T10:12:00", + }, + related: ["81p_wild_2", "earth", "9p_tempel_1"], + }, + sc_stereo_ahead: { + title: "STEREO Ahead", + description: { + blurb: [ + 'The twin STEREO spacecraft studied the structure and evolution of solar storms as they emerge from the Sun. STEREO A("Ahead") remains active.', + ], + more: [ + "STEREO (Solar Terrestrial Relations Observatory), the third mission in NASA’s Solar Terrestrial Probes (STP) program, consisted of two space-based observatories to study the structure and evolution of solar storms as they emerge from the Sun and move out through space.", + "The two spacecraft, one ahead of Earth in its orbit and the other trailing behind, provided the first stereoscopic images of the Sun, and collected data on the nature of its coronal mass ejections (CMEs), represented by large bursts of solar wind, solar plasma, and magnetic fields that are ejected into space. CMEs can disrupt communications, power grids, satellite operations, and air travel here on Earth. The orbital periods of STEREO A and STEREO B were 347 days and 387 days, respectively. The two spacecraft separate from each other at a (combined) annual rate of 44 degrees. At various points, the spacecraft were separated from each other by 90 degrees and 180 degrees. The latter occurred Feb. 6, 2011, allowing the entire Sun to be seen at once for the first time by any set of spacecraft.", + ], + }, + dates: { + start: "2006-10-26T00:52:00", + end: "", + landing: "", + }, + related: ["sun", "earth", "sc_stereo_behind", "sc_sdo", "sc_soho"], + }, + sc_stereo_behind: { + title: "STEREO Behind", + description: { + blurb: [ + 'The twin STEREO spacecraft studied the structure and evolution of solar storms as they emerge from the Sun. STEREO B ("Behind") is no longer active.', + ], + more: [ + "STEREO (Solar Terrestrial Relations Observatory), the third mission in NASA’s Solar Terrestrial Probes (STP) program, consisted of two space-based observatories to study the structure and evolution of solar storms as they emerge from the Sun and move out through space.", + "The two spacecraft, one ahead of Earth in its orbit and the other trailing behind, provided the first stereoscopic images of the Sun, and collected data on the nature of its coronal mass ejections (CMEs), represented by large bursts of solar wind, solar plasma, and magnetic fields that are ejected into space. CMEs can disrupt communications, power grids, satellite operations, and air travel here on Earth. The orbital periods of STEREO A and STEREO B were 347 days and 387 days, respectively. The two spacecraft separate from each other at a (combined) annual rate of 44 degrees. At various points, the spacecraft were separated from each other by 90 degrees and 180 degrees. The latter occurred Feb. 6, 2011, allowing the entire Sun to be seen at once for the first time by any set of spacecraft.", + ], + }, + dates: { + start: "2006-10-26T00:52:00", + end: "2016-09-23T00:00:00", + landing: "", + }, + related: ["sun", "earth", "sc_stereo_behind", "sc_sdo", "sc_soho"], + }, + sc_tdrs_3: { + title: "TDRS-3", + description: { + blurb: [ + "A tracking and data relay satellite (TDRS) is a type of communications satellite that forms part of the Tracking and Data Relay Satellite System (TDRSS) used by NASA and other United States government agencies for communications to and from satellites and remote ground stations.", + ], + more: [ + "Platforms such as satellites, balloons, aircraft, the International Space Station, and remote bases like the Amundsen-Scott South Pole Station are served by the TRDR system, which places satellites in geosynchronous orbit. It was designed to replace an existing worldwide network of ground stations that had supported all of NASA's crewed flight missions and uncrewed satellites in low-Earth orbits. The primary system design goal was to increase the amount of time that these spacecraft were in communication with the ground and improve the amount of data that could be transferred.", + ], + }, + dates: { + start: "1988-09-29T15:37:00", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_tdrs_5", + "sc_tdrs_6", + "sc_tdrs_7", + "sc_tdrs_8", + "sc_tdrs_9", + "sc_tdrs_10", + "sc_tdrs_11", + ], + }, + sc_tdrs_5: { + title: "TDRS-5", + description: { + blurb: [ + "A tracking and data relay satellite (TDRS) is a type of communications satellite that forms part of the Tracking and Data Relay Satellite System (TDRSS) used by NASA and other United States government agencies for communications to and from satellites and remote ground stations.", + ], + more: [ + "Platforms such as satellites, balloons, aircraft, the International Space Station, and remote bases like the Amundsen-Scott South Pole Station are served by the TRDR system, which places satellites in geosynchronous orbit. It was designed to replace an existing worldwide network of ground stations that had supported all of NASA's crewed flight missions and uncrewed satellites in low-Earth orbits. The primary system design goal was to increase the amount of time that these spacecraft were in communication with the ground and improve the amount of data that could be transferred.", + ], + }, + dates: { + start: "1991-08-02T15:02:00", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_tdrs_3", + "sc_tdrs_6", + "sc_tdrs_7", + "sc_tdrs_8", + "sc_tdrs_9", + "sc_tdrs_10", + "sc_tdrs_11", + ], + }, + sc_tdrs_6: { + title: "TDRS-6", + description: { + blurb: [ + "A tracking and data relay satellite (TDRS) is a type of communications satellite that forms part of the Tracking and Data Relay Satellite System (TDRSS) used by NASA and other United States government agencies for communications to and from satellites and remote ground stations.", + ], + more: [ + "Platforms such as satellites, balloons, aircraft, the International Space Station, and remote bases like the Amundsen-Scott South Pole Station are served by the TRDR system, which places satellites in geosynchronous orbit. It was designed to replace an existing worldwide network of ground stations that had supported all of NASA's crewed flight missions and uncrewed satellites in low-Earth orbits. The primary system design goal was to increase the amount of time that these spacecraft were in communication with the ground and improve the amount of data that could be transferred.", + ], + }, + dates: { + start: "1993-01-13T13:59:30", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_tdrs_3", + "sc_tdrs_5", + "sc_tdrs_7", + "sc_tdrs_8", + "sc_tdrs_9", + "sc_tdrs_10", + "sc_tdrs_11", + ], + }, + sc_tdrs_7: { + title: "TDRS-7", + description: { + blurb: [ + "A tracking and data relay satellite (TDRS) is a type of communications satellite that forms part of the Tracking and Data Relay Satellite System (TDRSS) used by NASA and other United States government agencies for communications to and from satellites and remote ground stations.", + ], + more: [ + "Platforms such as satellites, balloons, aircraft, the International Space Station, and remote bases like the Amundsen-Scott South Pole Station are served by the TRDR system, which places satellites in geosynchronous orbit. It was designed to replace an existing worldwide network of ground stations that had supported all of NASA's crewed flight missions and uncrewed satellites in low-Earth orbits. The primary system design goal was to increase the amount of time that these spacecraft were in communication with the ground and improve the amount of data that could be transferred.", + ], + }, + dates: { + start: "1995-07-13T13:59:30", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_tdrs_3", + "sc_tdrs_5", + "sc_tdrs_6", + "sc_tdrs_8", + "sc_tdrs_9", + "sc_tdrs_10", + "sc_tdrs_11", + ], + }, + sc_tdrs_8: { + title: "TDRS-8", + description: { + blurb: [ + "A tracking and data relay satellite (TDRS) is a type of communications satellite that forms part of the Tracking and Data Relay Satellite System (TDRSS) used by NASA and other United States government agencies for communications to and from satellites and remote ground stations.", + ], + more: [ + "Platforms such as satellites, balloons, aircraft, the International Space Station, and remote bases like the Amundsen-Scott South Pole Station are served by the TRDR system, which places satellites in geosynchronous orbit. It was designed to replace an existing worldwide network of ground stations that had supported all of NASA's crewed flight missions and uncrewed satellites in low-Earth orbits. The primary system design goal was to increase the amount of time that these spacecraft were in communication with the ground and improve the amount of data that could be transferred.", + ], + }, + dates: { + start: "2000-06-30T12:56:00", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_tdrs_3", + "sc_tdrs_5", + "sc_tdrs_6", + "sc_tdrs_7", + "sc_tdrs_9", + "sc_tdrs_10", + "sc_tdrs_11", + ], + }, + sc_tdrs_9: { + title: "TDRS-9", + description: { + blurb: [ + "A tracking and data relay satellite (TDRS) is a type of communications satellite that forms part of the Tracking and Data Relay Satellite System (TDRSS) used by NASA and other United States government agencies for communications to and from satellites and remote ground stations.", + ], + more: [ + "Platforms such as satellites, balloons, aircraft, the International Space Station, and remote bases like the Amundsen-Scott South Pole Station are served by the TRDR system, which places satellites in geosynchronous orbit. It was designed to replace an existing worldwide network of ground stations that had supported all of NASA's crewed flight missions and uncrewed satellites in low-Earth orbits. The primary system design goal was to increase the amount of time that these spacecraft were in communication with the ground and improve the amount of data that could be transferred.", + ], + }, + dates: { + start: "2002-03-08T22:59:00", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_tdrs_3", + "sc_tdrs_5", + "sc_tdrs_6", + "sc_tdrs_7", + "sc_tdrs_8", + "sc_tdrs_10", + "sc_tdrs_11", + ], + }, + sc_tdrs_10: { + title: "TDRS-10", + description: { + blurb: [ + "A tracking and data relay satellite (TDRS) is a type of communications satellite that forms part of the Tracking and Data Relay Satellite System (TDRSS) used by NASA and other United States government agencies for communications to and from satellites and remote ground stations.", + ], + more: [ + "Platforms such as satellites, balloons, aircraft, the International Space Station, and remote bases like the Amundsen-Scott South Pole Station are served by the TRDR system, which places satellites in geosynchronous orbit. It was designed to replace an existing worldwide network of ground stations that had supported all of NASA's crewed flight missions and uncrewed satellites in low-Earth orbits. The primary system design goal was to increase the amount of time that these spacecraft were in communication with the ground and improve the amount of data that could be transferred.", + ], + }, + dates: { + start: "2002-12-05T02:42:00", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_tdrs_3", + "sc_tdrs_5", + "sc_tdrs_6", + "sc_tdrs_7", + "sc_tdrs_8", + "sc_tdrs_9", + "sc_tdrs_11", + ], + }, + sc_tdrs_11: { + title: "TDRS-11", + description: { + blurb: [ + "A tracking and data relay satellite (TDRS) is a type of communications satellite that forms part of the Tracking and Data Relay Satellite System (TDRSS) used by NASA and other United States government agencies for communications to and from satellites and remote ground stations.", + ], + more: [ + "Platforms such as satellites, balloons, aircraft, the International Space Station, and remote bases like the Amundsen-Scott South Pole Station are served by the TRDR system, which places satellites in geosynchronous orbit. It was designed to replace an existing worldwide network of ground stations that had supported all of NASA's crewed flight missions and uncrewed satellites in low-Earth orbits. The primary system design goal was to increase the amount of time that these spacecraft were in communication with the ground and improve the amount of data that could be transferred.", + ], + }, + dates: { + start: "2013-01-31T01:48:00", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_tdrs_3", + "sc_tdrs_5", + "sc_tdrs_6", + "sc_tdrs_7", + "sc_tdrs_8", + "sc_tdrs_9", + "sc_tdrs_10", + ], + }, + sc_tdrs_12: { + title: "TDRS-12", + description: { + blurb: [ + "A tracking and data relay satellite (TDRS) is a type of communications satellite that forms part of the Tracking and Data Relay Satellite System (TDRSS) used by NASA and other United States government agencies for communications to and from satellites and remote ground stations.", + ], + more: [ + "Platforms such as satellites, balloons, aircraft, the International Space Station, and remote bases like the Amundsen-Scott South Pole Station are served by the TRDR system, which places satellites in geosynchronous orbit. It was designed to replace an existing worldwide network of ground stations that had supported all of NASA's crewed flight missions and uncrewed satellites in low-Earth orbits. The primary system design goal was to increase the amount of time that these spacecraft were in communication with the ground and improve the amount of data that could be transferred.", + ], + }, + dates: { + start: "2014-01-24T02:33:00", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_tdrs_3", + "sc_tdrs_5", + "sc_tdrs_6", + "sc_tdrs_7", + "sc_tdrs_8", + "sc_tdrs_9", + "sc_tdrs_10", + "sc_tdrs_11", + ], + }, + sc_tdrs_13: { + title: "TDRS-13", + description: { + blurb: [ + "A tracking and data relay satellite (TDRS) is a type of communications satellite that forms part of the Tracking and Data Relay Satellite System (TDRSS) used by NASA and other United States government agencies for communications to and from satellites and remote ground stations.", + ], + more: [ + "Platforms such as satellites, balloons, aircraft, the International Space Station, and remote bases like the Amundsen-Scott South Pole Station are served by the TRDR system, which places satellites in geosynchronous orbit. It was designed to replace an existing worldwide network of ground stations that had supported all of NASA's crewed flight missions and uncrewed satellites in low-Earth orbits. The primary system design goal was to increase the amount of time that these spacecraft were in communication with the ground and improve the amount of data that could be transferred.", + ], + }, + dates: { + start: "2017-08-18T12:29:00", + end: "", + landing: "", + }, + related: [ + "earth", + "sc_tdrs_3", + "sc_tdrs_5", + "sc_tdrs_6", + "sc_tdrs_7", + "sc_tdrs_8", + "sc_tdrs_9", + "sc_tdrs_10", + "sc_tdrs_11", + "sc_tdrs_12", + ], + }, + sc_suomi_npp: { + title: "Suomi NPP", + description: { + blurb: [ + "The Suomi National Polar-orbiting Partnership, or Suomi NPP, is a weather satellite operated by the United States National Oceanic and Atmospheric Administration.", + ], + more: [ + "NPP represents a critical first step in building the next-generation Earth-observing satellite system that will collect data on long-term climate change and short-term weather conditions. NPP is the result of a partnership between NASA, the National Oceanic and Atmospheric Administration, and the Department of Defense.", + "NPP will extend and improve upon the Earth system data records established by NASA's Earth Observing System fleet of satellites that have provided critical insights into the dynamics of the entire Earth system: clouds, oceans, vegetation, ice, solid Earth and atmosphere.", + ], + }, + dates: { + start: "2011-10-28T09:48:01.828", + end: "", + landing: "", + }, + related: ["earth"], + }, + sc_swot: { + title: "SWOT", + description: { + blurb: [ + "SWOT (Surface Water & Ocean Topography) will make the first global survey of Earth's surface water, observe the fine details of the ocean's surface topography, and measure how water bodies change over time.", + ], + }, + dates: { + start: "2022-12-16T13:00:00", + end: "", + landing: "", + }, + related: ["earth"], + }, + sc_tempo: { + title: "TEMPO", + description: { + blurb: [ + "The Tropospheric Emissions: Monitoring of Pollution (TEMPO) mission measures atmospheric pollution covering most of North America on an hourly basis and at high spatial resolution.", + ], + more: [ + "Hosted on the Intelsat 40E, the TEMPO instrument is a UV-visible spectrometer, and is the first ever space-based instrument to monitor air pollutants hourly across the North American continent during daytime. It collects high-resolution measurements of ozone, nitrogen dioxide and other pollutants, data which will revolutionize air quality forecasts.", + ], + }, + dates: { + start: "2023-04-07T04:30:00", + end: "", + landing: "", + }, + related: ["earth"], + }, + sc_terra: { + title: "Terra", + description: { + blurb: [ + "Terra explores the connections between Earth's atmosphere, land, snow and ice, ocean, and energy balance to understand Earth's climate and climate change and to map the impact of human activity and natural disasters on communities and ecosystems.", + ], + more: [ + "Terra carries five instruments that observe Earth’s atmosphere, ocean, land, snow and ice, and energy budget. Taken together, these observations provide unique insight into how the Earth system works and how it is changing. Terra observations reveal humanity’s impact on the planet and provide crucial data about natural hazards like fire and volcanoes. Terra is an international mission carrying instruments from the United States, Japan, and Canada.", + ], + }, + dates: { + start: "1999-12-18T18:57:39", + end: "", + landing: "", + }, + related: ["earth"], + }, + sc_tess: { + title: "TESS", + description: { + blurb: [ + "NASA’s Transiting Exoplanet Survey Satellite is an all-sky survey mission that will discover thousands of exoplanets around nearby bright stars.", + ], + more: [ + "The Transiting Exoplanet Survey Satellite (TESS) is the next step in the search for planets outside of our solar system, including those that could support life. The mission will find exoplanets that periodically block part of the light from their host stars, events called transits. TESS will survey 200,000 of the brightest stars near the sun to search for transiting exoplanets. TESS launched on April 18, 2018, aboard a SpaceX Falcon 9 rocket.", + "TESS scientists expect the mission will catalog thousands of planet candidates and vastly increase the current number of known exoplanets. Of these, approximately 300 are expected to be Earth-sized and super-Earth-sized exoplanets, which are worlds no larger than twice the size of Earth. TESS will find the most promising exoplanets orbiting our nearest and brightest stars, giving future researchers a rich set of new targets for more comprehensive follow-up studies.", + ], + }, + dates: { + start: "2018-04-18T22:51:31", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "sc_kepler_space_telescope", + "sc_spitzer", + "sc_hubble_space_telescope", + ], + }, + sc_themis_a: { + title: "THEMIS A", + description: { + blurb: [ + "The Time History of Events and Macroscale Interactions during Substorms (THEMIS) mission began in February 2007 as a constellation of five NASA satellites (THEMIS A through THEMIS E) to study energy releases from Earth's magnetosphere known as substorms.", + ], + more: [ + "The THEMIS mission was originally five satellites designed to study the Earth's magnetosphere and the storms it creates. Three of the satellites orbit the Earth within the magnetosphere, while two have been moved into orbit around the Moon. Those two were renamed ARTEMIS for Acceleration, Reconnection, Turbulence and Electrodynamics of the Moon's Interaction with the Sun. THEMIS B became ARTEMIS P1 and THEMIS C became ARTEMIS P2. ARTEMIS P1 and P2 together comprise the THEMIS-ARTEMIS mission. The three THEMIS spacecraft continue to collect data about the sun's interaction with Earth's magnetosphere.", + ], + }, + dates: { + start: "2007-02-17T23:01:00", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_themis_b", + "sc_themis_c", + "sc_themis_d", + "sc_themis_e", + ], + }, + sc_themis_b: { + title: "ARTEMIS P1", + description: { + blurb: [ + "The separate spacecraft ARTEMIS P1 and P2 together comprise the THEMIS-ARTEMIS mission, which studies the moon's interaction with the Sun. It is an offshoot of the THEMIS mission.", + ], + more: [ + "Launched in 2007, the THEMIS mission was originally five satellites designed to study the Earth's magnetosphere and the storms it creates. Three of the satellites orbit the Earth within the magnetosphere, while two have been moved into orbit around the Moon. Those two were renamed ARTEMIS for Acceleration, Reconnection, Turbulence and Electrodynamics of the Moon's Interaction with the Sun. THEMIS B became ARTEMIS P1 and THEMIS C became ARTEMIS P2. ARTEMIS P1 and P2 together comprise the THEMIS-ARTEMIS mission. They currently are in stable long-term orbits of the moon.", + ], + }, + dates: { + start: "2007-02-17T23:01:00", + end: "", + landing: "", + }, + parent: "moon", + related: [ + "earth", + "sc_themis_a", + "sc_themis_c", + "sc_themis_d", + "sc_themis_e", + ], + }, + sc_themis_c: { + title: "ARTEMIS P2", + description: { + blurb: [ + "The separate spacecraft ARTEMIS P1 and P2 together comprise the THEMIS-ARTEMIS mission, which studies the moon's interaction with the Sun. It is an offshoot of the THEMIS mission.", + ], + more: [ + "Launched in 2007, the THEMIS mission was originally five satellites designed to study the Earth's magnetosphere and the storms it creates. Three of the satellites orbit the Earth within the magnetosphere, while two have been moved into orbit around the Moon. Those two were renamed ARTEMIS for Acceleration, Reconnection, Turbulence and Electrodynamics of the Moon's Interaction with the Sun. THEMIS B became ARTEMIS P1 and THEMIS C became ARTEMIS P2. ARTEMIS P1 and P2 together comprise the THEMIS-ARTEMIS mission. They currently are in stable long-term orbits of the moon.", + ], + }, + dates: { + start: "2007-02-17T23:01:00", + end: "", + landing: "", + }, + parent: "moon", + related: [ + "earth", + "sc_themis_a", + "sc_themis_b", + "sc_themis_d", + "sc_themis_e", + ], + }, + sc_themis_d: { + title: "THEMIS D", + description: { + blurb: [ + "The Time History of Events and Macroscale Interactions during Substorms (THEMIS) mission began in February 2007 as a constellation of five NASA satellites (THEMIS A through THEMIS E) to study energy releases from Earth's magnetosphere known as substorms.", + ], + more: [ + "The THEMIS mission was originally five satellites designed to study the Earth's magnetosphere and the storms it creates. Three of the satellites orbit the Earth within the magnetosphere, while two have been moved into orbit around the Moon. Those two were renamed ARTEMIS for Acceleration, Reconnection, Turbulence and Electrodynamics of the Moon's Interaction with the Sun. THEMIS B became ARTEMIS P1 and THEMIS C became ARTEMIS P2. ARTEMIS P1 and P2 together comprise the THEMIS-ARTEMIS mission. The three THEMIS spacecraft continue to collect data about the sun's interaction with Earth's magnetosphere.", + ], + }, + dates: { + start: "2007-02-17T23:01:00", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_themis_a", + "sc_themis_b", + "sc_themis_c", + "sc_themis_e", + ], + }, + sc_themis_e: { + title: "THEMIS E", + description: { + blurb: [ + "The Time History of Events and Macroscale Interactions during Substorms (THEMIS) mission began in February 2007 as a constellation of five NASA satellites (THEMIS A through THEMIS E) to study energy releases from Earth's magnetosphere known as substorms.", + ], + more: [ + "The THEMIS mission was originally five satellites designed to study the Earth's magnetosphere and the storms it creates. Three of the satellites orbit the Earth within the magnetosphere, while two have been moved into orbit around the Moon. Those two were renamed ARTEMIS for Acceleration, Reconnection, Turbulence and Electrodynamics of the Moon's Interaction with the Sun. THEMIS B became ARTEMIS P1 and THEMIS C became ARTEMIS P2. ARTEMIS P1 and P2 together comprise the THEMIS-ARTEMIS mission. The three THEMIS spacecraft continue to collect data about the sun's interaction with Earth's magnetosphere.", + ], + }, + dates: { + start: "2007-02-17T23:01:00", + end: "", + landing: "", + }, + parent: "earth", + related: [ + "earth", + "sc_themis_a", + "sc_themis_b", + "sc_themis_c", + "sc_themis_d", + ], + }, + sc_trace_gas_orbiter: { + title: "Trace Gas Orbiter", + description: { + blurb: [ + "The ExoMars Trace Gas Orbiter (ExoMars TGO) is searching for methane and other trace gases in the Martian atmosphere that could be evidence of possible biological or geological activity. The orbiter is the first in a series of joint missions between the European Space Agency (ESA) and Roscosmos, the Russian space agency.", + ], + more: [ + "The ExoMars Trace Gas Orbiter (TGO) was designed to search for trace gases in the Martian atmosphere such as methane, water vapor, nitrogen oxides and acetylene. These gases could provide evidence for possible biological or geological activity on Mars. Organisms on Earth release methane during digestion, although geological processes such as the oxidation of minerals can also release methane.", + "ExoMars also will monitor seasonal changes in the Martian atmosphere and will look for water-ice beneath the surface. Information gathered during the mission will help decide landing sites for future ESA missions.", + ], + }, + dates: { + start: "2016-03-14T09:31:00", + end: "", + landing: "", + }, + related: ["mars"], + parent: "mars", + }, + sc_trmm: { + title: "TRMM", + description: { + blurb: [ + "The Tropical Rainfall Measuring Mission (TRMM) was a joint mission between NASA and the Japan Aerospace Exploration (JAXA) Agency to study rainfall for weather and climate research.", + ], + more: [ + "TRMM delivered a unique 17-year dataset of global tropical rainfall and lightning. The TRMM dataset became the space standard for measuring precipitation, and led to research that improved our understanding of tropical cyclone structure and evolution, convective system properties, lightning-storm relationships, climate and weather modeling, and human impacts on rainfall.", + ], + }, + dates: { + start: "1997-11-27T21:27:00", + end: "2015-04-15T00:00:00", + landing: "", + }, + related: ["earth"], + }, + sc_ulysses: { + title: "Ulysses", + description: { + blurb: [ + "The Ulysses mission made nearly three complete orbits of the Sun during more than 18 years in service.", + ], + more: [ + 'Ulysses was launched in 1990 and made three "fast latitude scans" of the Sun in 1994/1995, 2000/2001, and 2007/2008. In addition, the probe studied several comets. The vehicle was designed to fly a unique trajectory that would use a gravity assist from Jupiter to take it out of the plane of the solar system. Ulysses found that the solar wind has become progressively weaker over the last 50 years.', + ], + }, + dates: { + start: "1990-10-06T11:47:16", + end: "2009-06-30T00:00:00", + landing: "", + }, + related: ["sun", "jupiter", "sc_parker_solar_probe"], + }, + sc_voyager_1: { + title: "Voyager 1", + description: { + blurb: [ + "No spacecraft has gone farther than NASA's Voyager 1. Launched in 1977 to fly by Jupiter and Saturn, Voyager 1 crossed into interstellar space in August 2012 and continues to collect data.", + ], + more: [ + "NASA's Voyager 1 was launched after Voyager 2, but because of a faster route, it exited the asteroid belt earlier than its twin, having overtaken Voyager 2 on Dec. 15, 1977. The twin Voyager 1 and 2 spacecraft are exploring where no spacecraft from Earth has flown before. Continuing on their more-than-40-year journey since their 1977 launches, they each are much farther away from Earth and the sun than Pluto. In August 2012, Voyager 1 made the historic entry into interstellar space, the region between stars, filled with material ejected by the death of nearby stars millions of years ago. Voyager 2 entered interstellar space on November 5, 2018 and scientists hope to learn more about this region. Both spacecraft are still sending scientific information about their surroundings through the Deep Space Network, or DSN. The primary mission was the exploration of Jupiter and Saturn. After making a string of discoveries there — such as active volcanoes on Jupiter's moon Io and intricacies of Saturn's rings — the mission was extended. Voyager 2 went on to explore Uranus and Neptune, and is still the only spacecraft to have visited those outer planets. The adventurers' current mission, the Voyager Interstellar Mission (VIM), will explore the outermost edge of the Sun's domain. And beyond.", + ], + }, + dates: { + start: "1977-09-05T12:56:00", + end: "", + landing: "", + }, + parent: "outer_solar_system", + related: ["sc_voyager_2", "jupiter", "saturn", "titan"], + }, + sc_voyager_2: { + title: "Voyager 2", + description: { + blurb: [ + "NASA's Voyager 2 is the second spacecraft to enter interstellar space. On Dec. 10, 2018, the spacecraft joined its twin—Voyager 1—as the only human-made objects to enter the space between the stars.", + ], + more: [ + "The twin Voyager 1 and 2 spacecraft are exploring where no spacecraft from Earth has flown before. Continuing on their more-than-40-year journey since their 1977 launches, they each are much farther away from Earth and the sun than Pluto. Voyager 2 entered interstellar space on November 5, 2018 and scientists hope to learn more about this region. Both spacecraft are still sending scientific information about their surroundings through the Deep Space Network, or DSN.", + "The primary mission was the exploration of Jupiter and Saturn. After making a string of discoveries there — such as active volcanoes on Jupiter's moon Io and intricacies of Saturn's rings — the mission was extended. Voyager 2 went on to explore Uranus and Neptune, and is still the only spacecraft to have visited those outer planets. The adventurers' current mission, the Voyager Interstellar Mission (VIM), will explore the outermost edge of the Sun's domain. And beyond.", + ], + }, + dates: { + start: "1977-08-20T14:29:00", + end: "", + landing: "", + }, + parent: "outer_solar_system", + related: ["sc_voyager_1", "jupiter", "saturn", "uranus", "neptune"], + }, + sc_wind: { + title: "WIND", + description: { + blurb: [ + "The Wind spacecraft observes the solar wind that is about to impact the magnetosphere of Earth.", + ], + }, + dates: { + start: "1994-11-01T09:31:00", + end: "", + landing: "", + }, + parent: "earth", + related: ["sun"], + }, + valetudo: { + title: "Valetudo", + description: { + blurb: [ + "This tiny moon of Jupiter was first spotted in 2017. The discovery announcement was made in July 2018.", + ], + more: [ + "Valetudo is named after the Roman god Jupiter’s great-granddaughter, the goddess of health and hygiene.", + ], + }, + related: [], + }, +}; diff --git a/experiences/asteroids/web/app.css b/experiences/asteroids/web/app.css new file mode 100644 index 0000000..f9f9e93 --- /dev/null +++ b/experiences/asteroids/web/app.css @@ -0,0 +1,9452 @@ +/*!************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/settings/settings.css ***! + \************************************************************************************************************************************************************************************************/ +.settings { + display: none; + justify-content: flex-end; + transition: transform 1s ease-in-out; + margin-left: auto; +} + +.settings.active { + display: flex; + align-items: flex-end; + align-self: end; + + /* Animation */ + -webkit-animation-name: fade-in-bottom; + animation-name: fade-in-bottom; + -webkit-animation-duration: 0.95s; + animation-duration: 0.95s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +.settings.vertical { + flex-direction: column; +} + +.settings.horizontal { + flex-direction: row; +} + +.settings.hidden { + display: flex; + + /* Animation */ + -webkit-animation-name: fade-out-bottom; + animation-name: fade-out-bottom; + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +/* Buttons */ +.settings button { + padding: 0; + outline: 0; +} + +.settings button.zoom-in { + margin-bottom: 0; +} + +.settings button span { + opacity: 0.4; +} + +.settings button.hidden { + display: none; +} + +/* Container */ +.settings .container { + display: block; + position: relative; + flex-basis: auto; + transition: all 1s; + overflow: hidden; +} + +.settings .container.active { + flex-grow: 1; + flex-shrink: 1; +} + +.settings .container.hidden { + flex-grow: 0; +} + +.settings.vertical .container { + width: 100%; +} + +.settings.horizontal .container { + height: 100%; +} + +/* Overlay */ +.settings .overlay-bg { + opacity: 0.6; + width: 100vw; + height: var(--vh); + margin-right: -20px; + z-index: 100; + position: fixed; + background-color: var(--black); +} + +/* Content */ +.settings .container .content { + position: absolute; + overflow: hidden; + height: 100%; + display: grid; +} + +.settings.vertical .container .content { + grid-auto-flow: row; + row-gap: 2px; + align-items: end; +} + +.settings.horizontal .container .content { + grid-auto-flow: column; + -moz-column-gap: 2px; + column-gap: 2px; + align-items: start; +} + +/* Toggle */ +.settings.vertical .toggle { + margin-top: 2px; +} + +/* Zoom button */ +.settings .zoom { + margin: 0; +} + +.settings .horizontal-line { + background: var(--grayDark); + box-sizing: border-box; + margin: auto; +} + +.settings.vertical .zoom { + display: grid; + grid-template-rows: 30px 2px 30px; + grid-template-columns: 30px; +} + +.settings.vertical .horizontal-line { + height: 2px; + width: 22px; +} + +.settings.horizontal .zoom { + display: flex; +} + +.settings.horizontal .horizontal-line { + height: 22px; + width: 2px; + display: inline-block; +} + +/* Lighting options */ +.settings .lighting-option-container { + right: 34px; + bottom: 34px; + padding: 8px 10px; + position: fixed; + background: var(--bgGradient); + border-radius: 3px; + z-index: 101; +} + +.settings .lighting-option { + display: grid; + grid-template-columns: auto auto; + gap: 8px; + align-items: center; + padding: 4px 0; +} + +.settings .lighting-option .title { + opacity: 0.4; + white-space: nowrap; + pointer-events: none; +} + +.settings .lighting-option-container .lighting-option.selected-lighting span { + opacity: 1; +} + +.settings .lighting-option .lighting-icon { + min-width: 16px; + pointer-events: none; +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + .settings { + margin-left: auto; + } + + .settings.active { + -webkit-animation-name: fade-in-bottom; + animation-name: fade-in-bottom; + -webkit-animation-duration: 0.95s; + animation-duration: 0.95s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + } + + .settings.hidden { + display: flex; + -webkit-animation-name: fade-out-bottom; + animation-name: fade-out-bottom; + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + } + + .settings .container .content { + row-gap: 2px; + } + + .settings .overlay-bg { + bottom: -105px; + } +} + +/* Landscape. 480x320 phones and above */ +@media only screen and (min-width: 320px) and (orientation: landscape) { + .settings .overlay-bg { + bottom: -10px; + right: -56px; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .settings .overlay-bg { + bottom: -25px; + right: unset; + } +} + +/*!**************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/load_icon/load_icon.css ***! + \**************************************************************************************************************************************************************************************************/ +.load-icon { + position: fixed; + width: 80px; + height: 80px; + top: 50%; + left: 50%; + z-index: 1000; + display: flex; + flex-wrap: wrap; + transform: translate(-50%, -50%); + transition: transform 0.5s var(--ease-out-bezier); +} + +.load-icon.hidden { + display: none; +} + +/* Offsets */ +.load-icon.offset-right { + transform: translate(calc(var(--offset-right-sm, 0) - 50%), -50%); + transition-duration: 0.8s; +} + +.load-icon.offset-up { + transform: translate(-50%, calc(-50% - var(--offset-up, 0))); + transition-duration: 0.8s; +} + +.load-icon .text { + position: absolute; + bottom: -1em; + left: 50%; + transform: translateX(-50%); + color: var(--grayLight); + font-size: 1em; + text-transform: uppercase; +} + +.load-icon .top, +.load-icon .right, +.load-icon .bottom, +.load-icon .left, +.load-icon .front, +.load-icon .bg { + position: absolute; + top: 0; + left: 0; + background: transparent url(./assets/default/svg/cubemap.svg) no-repeat 0 -400px; + width: 80px; + height: 80px; + display: block; +} + +.load-icon .bg { + opacity: 0.15; +} + +.load-icon .top, +.load-icon .right, +.load-icon .bottom, +.load-icon .left, +.load-icon .front { + -webkit-animation: pulse 2s infinite; + animation: pulse 2s infinite; +} + +.load-icon .front { + background-position-y: -320px; + transform-origin: 47px 48px; +} + +.load-icon .left { + background-position-y: 0; + transform-origin: 17px 44px; + -webkit-animation-delay: 0.25s; + animation-delay: 0.25s; +} + +.load-icon .top { + background-position-y: -80px; + transform-origin: 41px 18px; + -webkit-animation-delay: 0.5s; + animation-delay: 0.5s; +} + +.load-icon .right { + background-position-y: -160px; + transform-origin: 67px 39.5px; + -webkit-animation-delay: 0.75s; + animation-delay: 0.75s; +} + +.load-icon .bottom { + background-position-y: -240px; + transform-origin: 40px 67px; + -webkit-animation-delay: 1s; + animation-delay: 1s; +} + +/* Over 961 wide */ +@media only screen and (min-width: 961px) { + + /* Offsets */ + .load-icon.offset-right { + transform: translate(calc(var(--offset-right-lg, 0) - 50%), -50%); + } +} + +/*!**********************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/overlay/overlay.css ***! + \**********************************************************************************************************************************************************************************************/ +:root { + --overlay-z-index: 9999; +} + +/* Scrollbar CSS override */ +.os-theme-dark>.os-scrollbar, +.os-scrollbar-vertical, +.os-host-resize-disabled.os-host-scrollbar-horizontal-hidden>.os-scrollbar-vertical { + right: 6px; + top: 40px; + bottom: 40px; +} + +.os-theme-dark>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle { + background: var(--grayDark); + width: 4px; +} + +.os-theme-dark>.os-scrollbar:active>.os-scrollbar-track>.os-scrollbar-handle { + background: var(--gray); + width: 6px; +} + +.os-theme-dark>.os-scrollbar-vertical>.os-scrollbar-track>.os-scrollbar-handle { + min-height: 20px; +} + +/* Overlay */ +.overlay-container .overlay { + position: absolute; + top: 0; + left: 0; + width: 100vw; + z-index: var(--overlay-z-index); + height: var(--vh); + background: black; + opacity: 0.9; +} + +.overlay-container .overlay.active { + -webkit-animation-duration: 0.5s; + animation-duration: 0.5s; + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + -webkit-animation-name: fade-in; + animation-name: fade-in; + display: flex; + pointer-events: all; +} + +.overlay-container .overlay.hidden { + pointer-events: none; +} + +.overlay-container.initialized .overlay.hidden { + -webkit-animation-duration: 0.5s; + animation-duration: 0.5s; + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + -webkit-animation-name: fade-out; + animation-name: fade-out; + display: flex; +} + +.overlay-container.initialized .overlay.hidden .clickable { + display: none; +} + +.overlay-container .overlay .close-button { + position: absolute; + top: 0; + right: 0; + z-index: 10; + transform: scale(1.5); + transform-origin: top right; + opacity: 0.4; + margin: 20px 20px 0 0; + padding: 0; +} + +/* Landscape. 480x320 phones and above */ +@media only screen and (min-width: 320px) and (orientation: landscape) { + .overlay-container .overlay { + left: -20px; + width: calc(100vw + 20px); + } +} + +/*!********************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/search/search.css ***! + \********************************************************************************************************************************************************************************************/ +.search-open .featured { + position: absolute; + top: 100%; + width: 100%; + height: 300px; + max-height: calc(var(--vh) - 86px); + left: 0; + border-radius: 0 0 12px 12px; + border-top: 1px solid var(--grayDivider); + transform-origin: top; + opacity: 1; + transform: scaleY(1); + transition: transform 0.3s 0.2s var(--ease-out-bezier), + opacity 0.3s 0.2s var(--ease-out-bezier); +} + +.search-close .featured.hidden { + display: unset; + transform: scaleY(0); + opacity: 0; + height: 0; + transition: transform 0.2s var(--ease-out-bezier), + opacity 0.2s var(--ease-out-bezier); +} + +.search .featured ul { + font-size: 14px; + list-style: none; + margin: 0; + padding: 24px 0 68px; + opacity: 1; + transition: opacity 0.5s 0.2s ease-out; +} + +.search .featured.hidden ul { + opacity: 0; +} + +.search .featured li { + margin: 9px 40px 9px 16px; + padding: 8px 16px; + border-radius: 6px; + background-image: radial-gradient(at 10%, #303030 0%, transparent 110%); + background-repeat: no-repeat; + background-position: center; + background-size: 0% 0%; + color: var(--grayMed); +} + +/* Search menu */ +.top-right-nav .search { + order: 1; +} + +.top-right-nav .mega-menu { + order: 3; +} + +/* Search */ +.search { + display: block; + pointer-events: none; + justify-self: end; + opacity: 1; + transition: opacity 0.6s ease-out, visibility 0.6s ease-out; +} + +.search .bar { + position: relative; + display: grid; + background: var(--grayDarkAlpha80); + padding: 7.5px; + border-radius: 0.2em; +} + +.search .cover { + pointer-events: all; + height: var(--vh); + width: 100vw; + background: var(--black); + position: fixed; + left: 0; + top: 0; + opacity: 0; + visibility: hidden; + transition: opacity 0.4s ease-out, visibility 0.4s ease-out; +} + +/* Search input */ +.search .input-focused .cover { + opacity: 0.6; + visibility: visible; + transition: opacity 0.6s ease-in, visibility 0.6s ease-in; +} + +.search input[type="text"] { + grid-area: input; + background: transparent; + padding: 0 10px; + width: inherit; + border: none; + outline: none; + color: var(--white); +} + +.search .mag-open { + grid-area: mag; + display: block; + margin: 7.5px; + filter: brightness(0.8); + transition: filter 0.1s, transform 0.1s; +} + +.search .search-open { + display: grid; + pointer-events: all; +} + +.search span.search-info { + position: absolute; + left: 50%; + bottom: -24px; + transform: translateX(-50%); + color: var(--grayAlpha); + font-weight: 600; + text-transform: uppercase; + z-index: 1; + opacity: 1; + transition: opacity 0.3s 0.3s ease-out; +} + +.search-close span.search-info { + opacity: 0; + transition: opacity 0.2s ease-out; +} + +/* Results */ +.search .bar .results { + position: absolute; + top: 100%; + width: 100%; + left: 0; + border-radius: 0 0 0.2em 0.2em; + -webkit-backdrop-filter: blur(0.5rem); + backdrop-filter: blur(0.5rem); +} + +/* Only when results have children */ +.search .bar .results:not(:empty) { + border-top: 0.1em solid var(--grayDark); +} + +.search .bar:has(.results:not(:empty)) { + border-radius: 0.2em 0.2em 0 0; +} + +.search .bar .results .result-div:first-child { + margin-top: 0.6em; +} + +.search .bar .results .result-div:last-child { + margin-bottom: 0.4em; +} + +.search .bar .results .block-container { + margin-bottom: 20px; +} + +.search .suggestion { + padding: 20px 0; +} + +.search .suggestion .title { + display: block; + padding: 2px 20px; +} + +.search .gradient { + background: linear-gradient(180deg, + var(--grayDarkAlpha80) 0%, + rgb(37 37 39 / 64%) 60.64%, + rgb(37 37 39 / 0%) 116.42%); +} + +.search .result-div { + transition: all 0.3s; + padding: 0.4em 1.3em; +} + +.search .result-div button { + padding: 0; + text-align: left; +} + +/* Search selection */ +.search .result-div.active { + background-color: var(--whiteAlpha15); + cursor: pointer; +} + +.search .result-div.active .clickable { + text-decoration: underline; +} + +.search .results .entries { + display: block; + outline: none; + text-align: left; + width: 100%; + padding: 0; +} + +/* Result card */ +.search .card-title { + padding: 15px 20px; + border-bottom: 1px solid var(--grayDark); + display: grid; + grid-template-columns: 1fr auto; + align-items: baseline; + margin-bottom: 10px; +} + +.search .bar .results .card-title.result-div:first-child { + margin-top: 0; +} + +.search .card-title img { + width: 50px; +} + +.search .results .unmatch { + opacity: 0.6; +} + +.search .detail .entry { + opacity: 1; + padding: 0; +} + +.search .title { + padding: 0 20px; +} + +.search-close-icon { + grid-area: close; +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + .search .bar { + margin: auto; + width: 90%; + grid-template-columns: 1fr auto; + grid-template-areas: "input search"; + } + + .search .search-close-icon { + display: none; + } +} + +@media (pointer: coarse) { + .search .result-div.active { + background-color: transparent; + cursor: normal; + } +} + +/*!******************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/clock/clock.css ***! + \******************************************************************************************************************************************************************************************/ +.clock .date, +.clock .time, +.clock .meridiem { + display: inline-block; + margin-right: 1em; +} + +.clock .date.hidden, +.clock .time.hidden, +.clock .meridiem.hidden { + display: none; +} + +.clock .hour-input { + background: none; + color: white; + border: 0; + padding: 0; + width: 90%; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +/* Date time container */ +.clock .datetime-container .display-container { + opacity: 0.6; + display: grid; + grid-template-columns: auto auto auto; + gap: 5px; + white-space: nowrap; +} + +.clock .datetime-container .display-container.hidden { + display: none; +} + +.clock .date, +.clock .time, +.clock .meridiem { + margin-right: 0; + font-variant: tabular-nums; +} + +.clock .time { + margin-left: 10px; +} + +/* Input */ +.clock .hour-input { + opacity: 0.6; +} + +.clock .datetime-container input, +.clock .datetime-container form { + margin: 0; + padding: 0; +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + .clock .datetime-container { + grid-column: 2; + grid-row: 1; + } + + .clock .datetime-container .display-container { + justify-content: end; + margin: 0; + gap: 2px; + } + + .clock .datetime-container form, + .clock .datetime-container input { + text-align: right; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .clock .datetime-container { + grid-row: 2; + grid-column: 1; + margin-left: 8px; + } + + .clock .datetime-container form, + .clock .datetime-container input { + text-align: left; + } + + .clock .hour-input { + margin-left: 8px; + } + + .alert { + outline-offset: 0; + } +} + +/*!************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/clock_shortcut/clock_shortcut.css ***! + \************************************************************************************************************************************************************************************************************/ +.clock-shortcut .text { + text-transform: uppercase; + display: inline-block; +} + +.clock-shortcut .active .live { + color: red; +} + +.clock-shortcut .container { + background-color: var(--grayDarkAlpha); + border-radius: 2px; + padding: 1px 7px; + margin-left: 0; +} + +.clock-shortcut .container.hidden { + display: none; +} + +.clock-shortcut .replay-container, +.clock-shortcut .live-container { + display: grid; + grid-template-columns: auto auto; + grid-template-rows: auto; + gap: 0 7px; + align-items: center; + justify-content: start; +} + +.clock-shortcut .live-container.active { + background-color: transparent; + margin-left: 8px; + padding-left: 0; +} + +/* Text */ +.clock-shortcut .text { + color: var(--gray); +} + +.clock-shortcut .active .live { + color: var(--live); +} + +/*!************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/carousel/carousel.css ***! + \************************************************************************************************************************************************************************************************/ +.carousel-container { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; +} + +.carousel-container.small h1 { + font-size: 28px; +} + +.carousel-container.small h2 { + font-size: 24px; +} + +.carousel-container.small h4 { + font-size: 16px; +} + +.carousel-container .progress { + position: absolute; + left: 0; + width: 10%; + margin: auto; + background: transparent url(./assets/default/svg/timeline_bg.svg) repeat-y 0 0; + pointer-events: all; +} + +.carousel-container .close-button { + position: absolute; + top: 0; + right: 0; + z-index: 2000; + display: flex; + align-items: center; + margin: 20px 20px 0 0; + padding: 0; +} + +.carousel-container .close-button.hidden { + display: none; +} + +.carousel-container .close-button .icon { + transform: scale(1.5); +} + +.carousel-container .carousel { + background: transparent; + height: 100%; + width: 100%; + overflow: hidden; + position: relative; + pointer-events: none; +} + +.carousel-container .carousel.initialized { + transition: all 700ms ease; +} + +.carousel-container .carousel.active { + -webkit-animation-name: fade-in-left; + animation-name: fade-in-left; + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +.carousel-container .carousel.hidden { + display: block; + -webkit-animation-name: fade-out-left; + animation-name: fade-out-left; + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +.carousel-container .carousel .track { + opacity: 1; + transition: transform 1s ease; + pointer-events: none; +} + +.carousel-container .carousel .slide { + height: var(--vh); + width: 100%; + color: var(--white); + overflow: hidden; + display: block; + pointer-events: none; +} + +.carousel-container .carousel .slide.active { + -webkit-animation-duration: 0.5s; + animation-duration: 0.5s; + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + -webkit-animation-name: fade-in; + animation-name: fade-in; +} + +.carousel-container .carousel .slide.hidden { + -webkit-animation-duration: 0.5s; + animation-duration: 0.5s; + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + -webkit-animation-name: fade-out; + animation-name: fade-out; + pointer-events: none; +} + +.carousel-container .carousel .slide.opaque { + opacity: 1; +} + +.carousel-container .carousel .slide.black { + background-color: var(--black); +} + +.carousel-container .carousel .slide.white { + background-color: var(--white); +} + +.carousel-container .carousel .slide .wrapper { + grid-column: main-start / side-end; + grid-row: head-start/ foot-end; +} + +.carousel-container .carousel .slide .container { + background: transparent; + width: 100%; + padding: 0; + display: flex; + flex-direction: column; + pointer-events: all; +} + +.carousel-container .carousel .slide.overlay .container { + text-align: center; +} + +.carousel-container .carousel .slide .container .container-wrapper { + height: 100%; + display: flex; + flex-direction: column; +} + +.carousel-container .carousel .slide.overlay .controls { + display: none; +} + +.carousel-container .carousel .slide .content-container { + width: 100%; + pointer-events: none; + overflow: inherit; + flex: 1; + display: flex; + flex-direction: column; +} + +.carousel-container .carousel .slide .content-container * { + pointer-events: none; +} + +.carousel-container .carousel .slide .content-container .clickable { + pointer-events: all; +} + +.carousel-container .carousel .slide .content-wrapper { + width: 100%; + padding: 10px 0; + overflow: auto; + pointer-events: all; + flex: 1; + display: flex; + flex-direction: column; +} + +.carousel-container .carousel .slide .content-wrapper .content { + display: flex; + flex-direction: column; +} + +.carousel-container .progress .icon-triangle { + position: absolute; + top: 0; + left: 0; + transition: top 2s ease 0s; + transform: rotate(90deg); +} + +@-webkit-keyframes animated-cursor { + 0% { + cursor: url(./assets/default/cursor/1.png), auto; + } + + 7% { + cursor: url(./assets/default/cursor/2.png), auto; + } + + 21% { + cursor: url(./assets/default/cursor/3.png), auto; + } + + 28% { + cursor: url(./assets/default/cursor/4.png), auto; + } + + 35% { + cursor: url(./assets/default/cursor/5.png), auto; + } + + 42% { + cursor: url(./assets/default/cursor/6.png), auto; + } + + 49% { + cursor: url(./assets/default/cursor/7.png), auto; + } + + 56% { + cursor: url(./assets/default/cursor/8.png), auto; + } + + 63% { + cursor: url(./assets/default/cursor/9.png), auto; + } + + 70% { + cursor: url(./assets/default/cursor/10.png), auto; + } + + 77% { + cursor: url(./assets/default/cursor/11.png), auto; + } + + 84% { + cursor: url(./assets/default/cursor/12.png), auto; + } + + 100% { + cursor: url(./assets/default/cursor/12.png), auto; + } +} + +@keyframes animated-cursor { + 0% { + cursor: url(./assets/default/cursor/1.png), auto; + } + + 7% { + cursor: url(./assets/default/cursor/2.png), auto; + } + + 21% { + cursor: url(./assets/default/cursor/3.png), auto; + } + + 28% { + cursor: url(./assets/default/cursor/4.png), auto; + } + + 35% { + cursor: url(./assets/default/cursor/5.png), auto; + } + + 42% { + cursor: url(./assets/default/cursor/6.png), auto; + } + + 49% { + cursor: url(./assets/default/cursor/7.png), auto; + } + + 56% { + cursor: url(./assets/default/cursor/8.png), auto; + } + + 63% { + cursor: url(./assets/default/cursor/9.png), auto; + } + + 70% { + cursor: url(./assets/default/cursor/10.png), auto; + } + + 77% { + cursor: url(./assets/default/cursor/11.png), auto; + } + + 84% { + cursor: url(./assets/default/cursor/12.png), auto; + } + + 100% { + cursor: url(./assets/default/cursor/12.png), auto; + } +} + +.carousel-container .carousel .icon-greater.up { + transform: rotate(-90deg); +} + +.carousel-container .carousel .icon-greater.down { + transform: rotate(90deg); +} + +.carousel-container .carousel .navigation-button { + z-index: 2; + color: var(--white); + padding: 10px; + background: transparent; + cursor: pointer; + transition: all 300ms ease; + pointer-events: all; +} + +.carousel-container .carousel .navigation-button:active { + background: var(--whiteAlpha15); +} + +.carousel-container .carousel .navigation-button:focus { + outline: 0; +} + +.carousel-container .carousel .navigation-button .icon { + display: block; + margin: auto; +} + +.carousel-container .carousel .navigation-button .icon.hidden { + display: none; +} + +.carousel-container .carousel.vertical .navigation-button { + align-self: start; +} + +/* Hide the first prev and last next buttons */ +.carousel-container .carousel .track>.slide:first-child .navigation-button.prev, +.carousel-container .carousel .track>.slide:last-child .navigation-button.next { + display: none; +} + +/* Hide replay button except last slide */ +.carousel-container .carousel .track>.slide .navigation-button.replay { + display: none; +} + +.carousel-container .carousel.vertical .navigation-button.next, +.carousel-container .carousel.vertical .navigation-button.replay { + align-self: center; + justify-self: end; + margin: auto; +} + +.carousel-container .carousel .mobile-hint { + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; +} + +.carousel-container .carousel .mobile-hint span { + display: inline-block; + vertical-align: middle; +} + +.carousel-container .carousel .slide.overlay .mobile-hint { + order: 2; +} + +/* If there's only one slide, hide mobile hint */ +.carousel-container .carousel .slide:only-child .mobile-hint { + display: none; +} + +/* If there's only one slide, hide replay button */ +.carousel-container .carousel .track>.slide:first-child:last-child .navigation-button.replay { + display: none; +} + +/* Hide the arrows for mobile-hint in first and last slides */ +.carousel-container .carousel .track>.slide:first-child .mobile-hint .icon-greater.up, +.carousel-container .carousel .track>.slide:last-child .mobile-hint .icon-greater.down { + visibility: hidden; +} + +.carousel-container .collapse-container { + grid-column: side; + grid-row: head-start / foot-end; + justify-self: end; + position: relative; + width: 100%; +} + +.carousel-container .mobile-collapse { + position: absolute; + bottom: calc(2 / 5 * 100% * 0.75); + right: 10px; +} + +.carousel-container .carousel .slide.overlay .collapse-container { + display: none; +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + .carousel-container .carousel .slide .content-container { + /* NOTE: autoprefixer doesn't prefix mask-image */ + -webkit-mask-image: linear-gradient(to top, black 95%, transparent 100%); + mask-image: linear-gradient(to top, black 95%, transparent 100%); + } + + .carousel-container .carousel .slide.overlay .content-container { + -webkit-mask-image: none; + mask-image: none; + } + + .carousel-container .carousel .slide .content-wrapper { + padding: 5% 20px 20px 20px; + justify-content: flex-start; + } + + .carousel-container .carousel .slide.overlay .content-wrapper { + padding: 0; + } + + .carousel-container .carousel .slide .content-wrapper .content { + flex-flow: column; + flex-wrap: nowrap; + } + + .carousel-container .carousel .controls { + margin-left: auto; + } + + .carousel-container .carousel .controls .icon-clock { + margin-right: 10px; + } + + .carousel-container .progress { + bottom: 0; + transform: none; + height: 40%; + } + + .carousel-container .carousel .navigation-button { + display: none; + } + + .carousel-container .carousel .track>.slide:last-child .navigation-button.replay { + display: none; + } + + .carousel-container .carousel .track>.slide:last-child .navigation-button.replay.mobile { + display: block; + } + + /* If there's only one slide, hide replay button on mobile */ + .carousel-container .carousel .track>.slide:first-child:last-child .navigation-button.replay.mobile { + display: none; + } +} + +/* Landscape. 480x320 phones and above */ +@media only screen and (min-width: 320px) and (orientation: landscape) { + .carousel-container .carousel .slide .content-wrapper { + padding: 10px 20px 20px 20px; + } + + .carousel-container .carousel .slide .content-wrapper .content { + flex-flow: row; + flex-wrap: wrap; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .carousel-container .carousel .slide .container { + align-content: center; + } + + .carousel-container .carousel .slide .content-container { + -webkit-mask-image: none; + mask-image: none; + } + + .carousel-container .carousel .slide .collapse-container { + display: none; + } + + .carousel-container .carousel .slide .content-wrapper { + padding: 0 20px 20px 40px; + justify-content: center; + } + + .carousel-container .carousel .slide .content-wrapper .content { + flex-flow: column; + flex-wrap: nowrap; + } + + .carousel-container .carousel .controls { + display: none; + } + + .carousel-container .progress { + top: 0; + height: 80%; + } + + .carousel-container .carousel .navigation-button { + display: block; + } + + .carousel-container .carousel .track>.slide:last-child .navigation-button.replay { + display: block; + } + + .carousel-container .carousel .track>.slide:last-child .navigation-button.replay.mobile { + display: none; + } + + .carousel-container .carousel .mobile-hint { + display: none; + } + + .carousel-container .close-button { + margin: 20px 20px 0 0; + } +} + +/*!****************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/tutorial_overlay/tutorial_overlay.css ***! + \****************************************************************************************************************************************************************************************************************/ +/* Main overlay */ +#tutorial-overlay { + position: absolute; + inset: 0; + display: flex; + flex-direction: column; + justify-content: space-between; + background-color: rgba(11, 17, 19, 0.8); + z-index: 1000; + -webkit-backdrop-filter: blur(5px); + backdrop-filter: blur(5px); + opacity: 1; + visibility: visible; + pointer-events: all; + transition-property: opacity, visibility; + transition-timing-function: var(--ease-out-bezier); + transition-duration: 0.8s, 0.8s; + padding: 4vh 6vh 2vh 6vh; + + /* mask-image gradient */ + mask-image: var(--tutorial-mask-grad); + mask-repeat: no-repeat; + mask-size: var(--tutorial-mask-size, 200% 200%); + mask-position: var(--tutorial-mask-pos, 50% 50%); + -webkit-mask-image: var(--tutorial-mask-grad); + -webkit-mask-repeat: no-repeat; + -webkit-mask-size: var(--tutorial-mask-size, 200% 200%); + -webkit-mask-position: var(--tutorial-mask-pos, 50% 50%); +} + +@supports not ((-webkit-backdrop-filter: blur()) or (backdrop-filter: blur())) { + #tutorial-overlay { + background-color: rgba(11, 17, 19, 0.95); + } +} + +#tutorial-overlay.hidden { + display: flex; + opacity: 0; + visibility: hidden; + transition-duration: 0.4s; + pointer-events: none; +} + +/* Carousel content vars */ +#tutorial-overlay .swiper { + --swiper-pagination-bullet-horizontal-gap: 0; + --swiper-pagination-color: var(--grayblueMed); + --swiper-pagination-bullet-inactive-color: var(--grayblueMed); + + width: 100%; + max-width: 600px; + overflow: visible; + flex-grow: 0.3; +} + +#tutorial-overlay .swiper-wrapper { + align-items: center; +} + +/* Swiper slide opacity overrides */ +/* This is because we are overriding the default overflow hidden behavior in order to move the prev and next buttons outside the main swiper area */ +#tutorial-overlay .swiper-slide { + opacity: 0; + transition: opacity 0.5s var(--ease-out-bezier); +} + +#tutorial-overlay .swiper-slide-active { + opacity: 1; + transition-property: opacity, transform; + transition-timing-function: var(--ease-out-bezier); + transition-duration: 0.5s; +} + +/* Swiper slide text */ +#tutorial-overlay .swiper-slide>h2 { + color: var(--grayblueWhite); + font-size: clamp(26px, min(5vw, 5vh), 56px); + font-weight: 100; + text-transform: uppercase; +} + +#tutorial-overlay .swiper-slide>p { + margin-top: clamp(0em, 2vh, 3em); + margin-bottom: clamp(1em, 4vh, 4em); + color: var(--grayblueMed); + font-size: clamp(14px, min(1.8vw, 1.8vh), 18px); + font-weight: 100; + line-height: 1.6; +} + +#tutorial-overlay .swiper-slide>p>br.big-br { + content: ""; + margin-top: clamp(0em, 2vh, 2em); + display: block; +} + +.swiper-slide>div.tutorial-extra { + display: flex; + flex-direction: column; + align-items: baseline; + opacity: 1; + visibility: visible; + height: 15vh; + transition-property: opacity, visibility, height; + transition-duration: 0.5s; + transition-timing-function: var(--ease-out-bezier); +} + +.swiper-slide>div.tutorial-extra>h5 { + color: var(--grayblueMed); + font-size: clamp(14px, min(1.8vw, 1.8vh), 18px); + font-weight: 600; + padding: 0.2em 0.6em 0.1em 0.6em; + margin-left: 0.5em; + line-height: 1.3; + border: 1px solid var(--grayblueText); + border-radius: 4px; + transform: rotate(-5deg); +} + +.swiper-slide>div.tutorial-extra>p { + margin: 0.5em 0 0 2em; + font-size: clamp(12px, min(1.5vw, 1.5vh), 16px); + color: var(--grayblueMed); +} + +/* Bullets */ +#tutorial-overlay .bullet-container { + position: absolute; + + /* bottom: -5vh; */ + left: 10%; + display: flex; + justify-content: space-around; + width: 80%; + min-height: 15px; + opacity: 1; + transition: opacity 0.6s ease-out, width 0.6s var(--ease-out-bezier), + transform 0.5s var(--ease-out-bezier); +} + +#tutorial-overlay .bullet-container.hidden { + width: 0%; + opacity: 0; + transition: opacity 0.2s ease-in, width 0.3s var(--ease-out-bezier); +} + +#tutorial-overlay .bullet-container::before { + content: ""; + position: absolute; + top: clamp(-36px, -3vh, -15px); + width: calc(100% + 8vw); + height: 1px; + background-color: var(--grayblueDivider); +} + +#tutorial-overlay span.swiper-pagination-bullet { + position: relative; + cursor: pointer; +} + +#tutorial-overlay span.swiper-pagination-bullet::before { + content: ""; + position: absolute; + inset: max(-2vw, -14px); +} + +#tutorial-overlay .swiper-pagination-bullet-active { + transform: scale(1.2); + transition: all 0.3s ease-out; +} + +/* Prev and Next Buttons */ +.tutorial-carousel .swiper-button-prev, +.tutorial-carousel .swiper-button-next { + top: unset; + opacity: 1; + transition-property: filter, opacity, transform; + transition-duration: 0.5s; + transition-timing-function: var(--ease-out-bezier); + bottom: max(-4em, -12vh); +} + +.tutorial-carousel .swiper-button-prev { + left: 5%; +} + +.tutorial-carousel .swiper-button-next { + right: 5%; +} + +/* Override swiper disabled */ +.tutorial-carousel .swiper-button-prev.swiper-button-disabled, +.tutorial-carousel .swiper-button-next.swiper-button-disabled { + opacity: 0; +} + +.tutorial-carousel .swiper-button-prev::after, +.tutorial-carousel .swiper-button-next::after { + font-family: "Metropolis", sans-serif; + font-size: clamp(14px, 2vh, 16px); + line-height: 1.2; + color: var(--grayblueMed); +} + +.tutorial-carousel .swiper-button-prev::after { + content: "Previous"; + position: absolute; + left: calc(100% + 12px); +} + +.tutorial-carousel .swiper-button-next::after { + content: "Next"; + position: absolute; + right: calc(100% + 12px); +} + +.tutorial-carousel .swiper-button-prev::before, +.tutorial-carousel .swiper-button-next::before { + content: ""; + position: absolute; + inset: -10px; + z-index: -1; +} + +.tutorial-carousel .swiper-button-prev::before { + right: -90px; +} + +.tutorial-carousel .swiper-button-next::before { + left: -60px; +} + +/* Dismiss button */ +#tutorial-overlay .dismiss-container { + display: flex; + flex-direction: column; + flex-grow: 0.3; + justify-content: flex-end; + align-items: center; + transition-property: transform, flex-grow; + transition-duration: 0.5s; + transition-timing-function: var(--ease-out-bezier); +} + +#tutorial-overlay .dismiss-button { + padding: 0.5em 1.5em 0.5em 1.5em; + color: var(--grayblueText); + font-size: clamp(12px, 2vh, 16px); + font-weight: 600; + border: 1px solid var(--grayblueMed); + border-radius: 24px; + transition: filter 0.2s ease-in; +} + +#tutorial-overlay .dismiss-button:active { + filter: brightness(1.5); + transition: filter 0.4s ease-out; +} + +/* Footer smallprint */ +#tutorial-overlay footer { + height: 10vh; + opacity: 1; + visibility: visible; + transition-property: opacity, visibility, height; + transition-duration: 2s; + transition-timing-function: var(--ease-out-bezier); +} + +footer p.tutorial-smallprint { + text-align: center; + font-size: clamp(11px, 1.2vh, 14px); + line-height: clamp(1.2em, 2vh, 2.5em); + color: var(--grayblueText); + max-width: 500px; + margin: auto; +} + +footer p.tutorial-smallprint>a { + text-decoration: underline; + color: var(--grayblueLight); + transition: color 0.2s ease-in; +} + +/* ------------------- Slide specific overrides ------------------- */ + +#tutorial-overlay.tutorial-slide-nav3d .bullet-container, +#tutorial-overlay.tutorial-slide-labels .bullet-container { + transform: translateY(max(2vh, 2vw)); +} + +#tutorial-overlay.tutorial-slide-nav3d .swiper-button-prev, +#tutorial-overlay.tutorial-slide-nav3d .swiper-button-next, +#tutorial-overlay.tutorial-slide-labels .swiper-button-prev, +#tutorial-overlay.tutorial-slide-labels .swiper-button-next { + transform: translateY(max(2vh, 2vw)); +} + +#tutorial-overlay .swiper-slide.tutorial-slide-nav3d, +#tutorial-overlay .swiper-slide.tutorial-slide-labels { + transform: translateY(-12vh); +} + +#tutorial-overlay.tutorial-slide-time footer { + opacity: 0; + visibility: hidden; + transition-duration: 1.2s; +} + +#tutorial-overlay.tutorial-slide-time .dismiss-container { + flex-grow: 0.1; +} + +/* ------------------- Breakpoint adjustments --------------------- */ + +/* When nav menu at bottom (mobile portrait) */ +@media only screen and (max-width: 641px) and (orientation: portrait) { + + /* Hide footer for some menu slides */ + #tutorial-overlay.tutorial-slide-learn footer, + #tutorial-overlay.tutorial-slide-watch footer, + #tutorial-overlay.tutorial-slide-filters footer, + #tutorial-overlay.tutorial-slide-search footer, + #tutorial-overlay.tutorial-slide-settings footer, + #tutorial-overlay.tutorial-slide-complete footer { + opacity: 0; + visibility: hidden; + transition-duration: 1.2s; + } +} + +/* With low vertical height, we need to hide some things */ +@media only screen and (max-height: 641px) { + + /* Hide extra */ + .swiper-slide>div.tutorial-extra { + height: 0; + opacity: 0; + visibility: hidden; + } + + /* Hide smallprint footer */ + #tutorial-overlay footer { + height: 0; + opacity: 0; + visibility: hidden; + transition-duration: 1.2s; + } +} + +@media only screen and (max-height: 481px) { + + /* Time slider needs dismiss, bullet and arrow shifting */ + #tutorial-overlay.tutorial-slide-time .dismiss-container { + transform: translateY(-15vh); + } + + #tutorial-overlay.tutorial-slide-time .swiper-slide-active, + #tutorial-overlay.tutorial-slide-time .bullet-container, + #tutorial-overlay.tutorial-slide-time .swiper-button-prev, + #tutorial-overlay.tutorial-slide-time .swiper-button-next { + transform: translateY(-12vh); + } +} + +/* Mobile time slider slide adjustments */ +@media only screen and (min-width: 320px) and (max-width: 767px) { + + /* Time slider needs dismiss, bullet and arrow shifting */ + #tutorial-overlay.tutorial-slide-time .dismiss-button { + transform: translateY(-10vh); + z-index: 10; + } + + #tutorial-overlay.tutorial-slide-time .swiper-slide-active, + #tutorial-overlay.tutorial-slide-time .bullet-container, + #tutorial-overlay.tutorial-slide-time .swiper-button-prev, + #tutorial-overlay.tutorial-slide-time .swiper-button-next { + transform: translateY(-10vh); + } +} + +/* With low horizontal width, we need to hide some things */ +@media only screen and (max-width: 481px) { + + /* Hide swiper arrow text */ + .tutorial-carousel .swiper-button-prev::after, + .tutorial-carousel .swiper-button-next::after { + content: ""; + } +} + +/*!************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/carousel_panel/carousel_panel.css ***! + \************************************************************************************************************************************************************************************************************/ +/* ------ Panel container ------ */ +#panel-container { + /* Variables */ + --sandMed: #cbb296; + + /* Properties */ + position: relative; + top: 3em; + padding: 0; + grid-column-start: 1; + grid-row-start: 3; + align-self: center; + height: -webkit-fit-content; + height: -moz-fit-content; + height: fit-content; + min-width: 300px; + max-height: calc(100vh - 72px); + opacity: 1; + visibility: visible; + transition-timing-function: var(--ease-out-bezier); + transition-property: opacity, visibility; + transition-duration: 0.6s; + z-index: 1; +} + +#panel-container.hidden { + display: unset; + opacity: 0; + visibility: hidden; + transition-duration: 0.3s; +} + +/* ------ Simple panel ------ */ +#panel-container .panel-simple { + position: absolute; + top: 50px; + left: 8px; + pointer-events: all; +} + +.panel-simple>.expand-button .icon { + transform: rotate(-90deg); +} + +.panel-simple>h5.simple-pretitle { + color: var(--grayblueText); + margin: -4px 0 0 11px; + font-size: 18px; + line-height: 1.5; +} + +.panel-simple>h4.simple-title { + margin: 8px 0 0 10px; + font-size: 22px; + text-transform: capitalize; +} + +/* The simple panel is visible when the panel container is collapsed */ +#panel-container.collapsed .panel-simple { + visibility: visible; + opacity: 1; + transition-timing-function: var(--ease-out-bezier); + transition-duration: 0.6s; + transition-delay: 0.2s; + transition-property: opacity, visibility; +} + +#panel-container.collapsed .panel-simple>* { + transition: transform 0.6s 0.1s var(--ease-out-bezier); +} + +/* The simple panel is hidden when the panel container is expanded */ +#panel-container.expanded .panel-simple { + pointer-events: none; + visibility: hidden; + opacity: 0; + transition-duration: 0.3s; +} + +#panel-container.expanded .panel-simple>.expand-button>.icon { + transform: translateX(100%) rotate(90deg); + transition-duration: 0.2s; +} + +#panel-container.expanded .panel-simple>h5.simple-pretitle { + transition-duration: 0.3s; +} + +#panel-container.expanded .panel-simple>h4.simple-title { + transform: translateY(-200%); + transition-duration: 0.4s; +} + +/* ------ Main Panel ------ */ +#panel-container .panel-main { + height: 100%; + padding: 10px 20px; + border-radius: 12px; + z-index: 101; + background: var(--bgGradient); + pointer-events: all; + display: flex; + flex-direction: column; + visibility: visible; + opacity: 1; + transition-timing-function: var(--ease-out-bezier); + transition-duration: 0.6s; + transition-property: opacity, visibility, transform; +} + +#panel-container.collapsed .panel-main { + pointer-events: none; + visibility: hidden; + opacity: 0; + transform: translateX(-75%); + transition-duration: 0.3s; +} + +/* Panel header */ +.panel-header .header-title { + display: flex; + align-items: center; + justify-content: space-between; +} + +.header-title .title-icon { + flex-shrink: 0; + transform: scale(1.2); +} + +.header-title>h4.title-text { + padding: 0 0.5em; +} + +.header-title .collapse-button { + opacity: 0.8; +} + +.header-title .collapse-button>.icon { + transform: rotate(90deg); + margin-right: -10px; +} + +.panel-header .header-caption { + text-align: center; + white-space: nowrap; + font-size: 14px; + margin-top: 4px; + color: var(--grayblueText); +} + +.panel-main .panel-content { + height: inherit; +} + +/* Tabs */ +#panel-container .tabs-container { + display: flex; + font-size: 12px; + justify-content: space-between; + position: relative; + margin-top: 0; +} + +#panel-container .tabs-container.tabs-2 { + justify-content: space-around; +} + +#panel-container .tabs-container.tabs-1 { + opacity: 0; +} + +#panel-container .tabs-container>button { + color: var(--grayblueMed); + position: relative; + padding: 0.2em; + transition: color 0.2s 0.1s var(--ease-out-bezier); +} + +#panel-container .tabs-container>button.active { + color: var(--grayblueWhite); + transition: color 0.3s var(--ease-out-bezier); +} + +#panel-container .tabs-container>button::after { + content: ""; + position: absolute; + width: 100%; + height: 2.5px; + bottom: 0; + left: 0; + background-color: var(--sandMed); + transform: scaleX(0); + transition: transform 0.2s 0.1s var(--ease-out-bezier); +} + +#panel-container .tabs-container>button.active::after { + transform: scaleX(1); + transition: transform 0.5s var(--ease-out-bezier); +} + +/* Carousel content */ +.panel-content .swiper { + --swiper-pagination-bullet-horizontal-gap: 0; + --swiper-pagination-color: var(--grayblueMed); + --swiper-pagination-bullet-inactive-color: var(--grayblueMed); + + width: 100%; + padding: 3em 0 1em 0; +} + +.swiper .swiper-wrapper { + transition-timing-function: var(--ease-out-bezier); + align-items: center; +} + +.swiper-wrapper .swiper-slide { + display: flex; + flex-direction: column; + justify-content: center; +} + +/* Bullets */ +.panel-content .bullet-container { + display: flex; + justify-content: space-around; + width: 62%; + min-height: 8px; + margin: 1em auto 3.5em auto; + opacity: 1; + z-index: 1; + transition: opacity 0.6s ease-out, width 0.6s var(--ease-out-bezier); +} + +.panel-content .bullet-container.hidden { + width: 0%; + opacity: 0; + transition: opacity 0.2s ease-in, width 0.3s var(--ease-out-bezier); +} + +.panel-content span.swiper-pagination-bullet { + position: relative; + cursor: pointer; +} + +.panel-content span.swiper-pagination-bullet::before { + content: ""; + position: absolute; + inset: -8px; +} + +.panel-content .swiper-pagination-bullet-active { + transform: scale(1.2); + transition: all 0.3s ease-out; +} + +/* Prev and Next Buttons */ +.panel-content .swiper-button-prev, +.panel-content .swiper-button-next { + top: unset; + bottom: 20px; + opacity: 1; + transition: filter 0.25s ease-out, opacity 0.3s ease-out; +} + +.panel-content .swiper-button-prev::after, +.panel-content .swiper-button-next::after { + font-family: "Metropolis", sans-serif; + font-size: 14px; + line-height: 1.2; + color: var(--grayblueText); +} + +.panel-content .swiper-button-prev::after { + content: "Previous"; + position: absolute; + left: calc(100% + 12px); +} + +.panel-content .swiper-button-next::after { + content: "Next"; + position: absolute; + right: calc(100% + 12px); +} + +.panel-content .swiper-button-prev::before, +.panel-content .swiper-button-next::before { + content: ""; + position: absolute; + inset: -10px; + z-index: -1; +} + +.panel-content .swiper-button-prev::before { + right: -90px; +} + +.panel-content .swiper-button-next::before { + left: -60px; +} + +/* Override swiper disabled */ +.panel-content .swiper-button-prev.swiper-button-disabled, +.panel-content .swiper-button-next.swiper-button-disabled { + opacity: 0; + transition: opacity 0.25s ease-out; +} + +/* Less than 641px is positioned at the bottom */ +@media only screen and (max-width: 641px) and (orientation: portrait) { + + /* ------ Panel container ------ */ + /* Position at bottom */ + #panel-container { + grid-column: foot-start / foot-end; + grid-row-start: unset; + grid-row-end: -1; + padding: 0 20px; + min-width: 0; + align-self: flex-end; + top: unset; + } + + /* ------ Simple panel ------ */ + #panel-container .panel-simple { + top: unset; + left: 2.5vw; + bottom: 100px; + margin: 0; + min-width: 150px; + } + + #panel-container.collapsed .panel-simple>* { + transition: transform 0.3s var(--ease-out-bezier); + } + + .panel-simple>.expand-button { + position: absolute; + left: 5em; + top: -23%; + } + + /* Turn expand and collapse icons */ + .panel-simple>.expand-button>.icon { + transform: rotate(-180deg); + } + + #panel-container.expanded .panel-simple>.expand-button>.icon { + transform: rotate(0deg); + } + + /* ------ Main Panel ------ */ + + /* Offseting from bottom to allow space for time slider */ + #panel-container .panel-main { + padding: 2.7vw 4.8vw; + position: relative; + bottom: 90px; + border-radius: 12px; + } + + /* Animate down when collapsing */ + #panel-container.collapsed .panel-main { + transform: translateY(75%); + } + + .panel-header .header-caption { + text-align: center; + margin-top: -4px; + } + + /* Turn expand and collapse icons */ + .header-title .collapse-button>.icon { + transform: rotate(0); + } + + /* Tabs */ + #panel-container .tabs-container { + margin-top: 0.5em; + } +} + +/* Fix layout padding issue */ +@media only screen and (max-width: 641px) and (orientation: landscape) { + #panel-container { + padding: 0; + } +} + +/* Anything over 961, we can incresed some font and icon sizes slightly */ +@media only screen and (min-width: 961px) { + + /* ------ Panel container ------ */ + #panel-container { + min-width: 385px; + } + + /* ------ Simple panel ------ */ + .panel-simple>h4.simple-title { + font-size: 29px; + } + + /* ------ Main Panel ------ */ + #panel-container .panel-main { + padding: 20px 30px; + } + + .panel-header .header-caption { + font-size: 18px; + } + + .header-title .title-icon { + flex-shrink: 0; + transform: scale(1.4); + } + + .header-title>h4.title-text { + font-size: 29px; + } + + /* Tabs */ + #panel-container .tabs-container { + font-size: 14px; + } + + /* Prev and Next Buttons */ + .panel-content .swiper-button-prev::after, + .panel-content .swiper-button-next::after { + font-size: 16px; + } + + /* Icon scales */ + .panel-simple>.expand-button, + .header-title>.collapse-button { + transform: scale(1.2); + transform-origin: left; + } +} + +/* When the height is less than 900px, we need to save a little on vertical space */ +@media only screen and (max-height: 900px) { + + /* Vertical padding */ + .panel-content .swiper { + padding: 3em 0 0 0; + } + + /* Simplify and move nav arrows up */ + .panel-content .swiper-button-prev, + .panel-content .swiper-button-next { + bottom: 1.5em; + } + + .panel-content .swiper-button-prev::before, + .panel-content .swiper-button-next::before { + inset: -6px; + } + + .panel-content .swiper-button-prev::after, + .panel-content .swiper-button-next::after { + content: ""; + } + + /* Adjust bullet margins */ + .panel-content .bullet-container { + /* width: 62%; */ + margin: 1em auto 1.7em auto; + } +} + +@media only screen and (max-height: 641px) { + + /* reduce simple panel height */ + #panel-container.collapsed .panel-simple>.expand-button { + margin-bottom: -14px; + } + + .panel-simple>h5.simple-pretitle { + margin-bottom: -2px; + } + + /* Vertical padding */ + .panel-content .swiper { + padding: 2em 0 1.5em 0; + } + + /* Tabs */ + #panel-container .tabs-container { + margin-top: 0.5em; + } + + /* move nav arrows up */ + .panel-content .swiper-button-prev, + .panel-content .swiper-button-next { + bottom: 1.2em; + } + + /* Adjust bullet margins */ + .panel-content .bullet-container { + margin: 2em auto 0 auto; + } +} + +@media only screen and (max-height: 641px) and (min-width: 641px) { + #panel-container { + grid-row-end: -2; + } +} + +/* Attach panel to bottom when height is getting really small */ +@media only screen and (max-height: 500px) { + #panel-container { + grid-row-end: -1; + top: unset; + align-self: flex-end; + } + + /* Remove round corners from bottom */ + #panel-container .panel-main { + border-radius: 12px 12px 0 0; + } + + .panel-header .header-title { + height: 2.5em; + } + + .panel-header .header-caption { + display: none; + } +} + +@media only screen and (max-height: 370px) { + + /* Adjust bullet margins */ + .panel-content .bullet-container { + margin: 1.5em auto 0 auto; + } +} + +/*!******************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/share_modal/share_modal.css ***! + \******************************************************************************************************************************************************************************************************/ +/* Share button */ +.share-button { + display: flex; + justify-content: center; + align-items: center; + width: calc(100% - 0.75rem); + height: calc(1em + 24px); + gap: 0.4em; + font-family: Inter, Metropolis, sans-serif; + font-size: 1rem; + font-weight: 500; + color: var(--white); + border-radius: 0.375em; + padding: 0 1em; + margin-top: 2rem; + order: 2; + background-color: var(--cta-blue); + transition: all 0.3s ease; +} + +/* Modal */ +#share-modal { + position: fixed; + inset: 0; + display: flex; + justify-content: center; + align-items: center; + -webkit-backdrop-filter: blur(0.5rem); + backdrop-filter: blur(0.5rem); + transition: opacity 0.3s, visibility 0.3s; + pointer-events: all; + z-index: 55; + background-color: var(--blackAlpha); + + --embed-aspect-ratio: 1.777; + --iframe-width: 100%; + --iframe-height: 100%; + --iframe-scale: 0.3; + --iframe-offset-x: 0; +} + +#share-modal.hidden { + opacity: 0; + visibility: hidden; + pointer-events: none; +} + +/* Main article */ +#share-modal>article { + position: relative; + max-width: calc(100% - min(5vw, 2.5rem)); + max-height: calc(100% - min(5vh, 2.5rem)); + width: 30rem; + padding: min(max(1vh, 1vw), 1rem); + background-image: var(--darkGrayBgGradientBtm); + border-radius: 0.5rem; +} + +/* Header */ +#share-modal .modal-header { + position: relative; + display: flex; + justify-content: space-between; + align-items: center; + height: auto; + gap: 1rem; + margin: 0 0 min(0.2vh, 0.5rem) 0; + padding-bottom: clamp(1.5rem, 4vh, 3rem); +} + +#share-modal .modal-header .icon-share { + width: 2rem; + height: 2rem; + padding: 0.4rem; +} + +#share-modal .modal-header .modal-title { + font-size: clamp(1.3rem, min(6vw, 6vh), 1.8rem); + transform: translateY(0.05rem); +} + +#share-modal .modal-header .modal-close { + transform: scale(1.5); + opacity: 0.7; + transition: opacity 0.1s, transform 0.1s; +} + +/* Tab Headers */ +#share-modal ul.tab-headers { + position: absolute; + bottom: 0; + width: calc(100% - 1rem); + display: flex; + justify-content: flex-start; + align-items: center; + padding: 0; + margin: 0 0 0 0.5rem; +} + +#share-modal ul.tab-headers::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 0.08rem; + background-color: var(--grayDivider); +} + +#share-modal ul.tab-headers>li { + position: relative; + padding: 0.5rem 1rem; + list-style: none; + opacity: 0.7; + transition: opacity 0.2s; +} + +#share-modal ul.tab-headers>li.active { + opacity: 1; +} + +#share-modal ul.tab-headers button::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 0.08rem; + background-color: var(--cta-blue); + transform: scaleX(0); + transition: transform 0.2s 0.1s var(--ease-out-bezier); + z-index: 1; +} + +#share-modal li:first-child button::after { + transform-origin: right; +} + +#share-modal li:last-child button::after { + transform-origin: left; +} + +#share-modal ul.tab-headers>li.active>button::after { + transform: scaleX(1); + transition: transform 0.3s var(--ease-out-bezier); +} + +/* Content */ +/* Tab Content */ +#share-modal .tab-content { + position: relative; + padding: min(max(1vh, 1vw), 1rem); +} + +#share-modal .tab-pane { + display: none; +} + +#share-modal .tab-pane.active { + display: flex; + flex-direction: column; + gap: min(1.5vh, 1.5rem); +} + +#share-modal .embed>section { + display: flex; + flex-direction: column; + gap: min(1vh, 1rem); +} + +#share-modal .embed>section.options-section { + height: min(min(36vw, 33vh), 20rem); +} + +#share-modal .embed .options-container { + height: 100%; + padding-right: max(6vw, 1rem); +} + +/* Link title and code */ +#share-modal .link-container { + display: flex; + flex-direction: column; +} + +#share-modal .link-container span { + display: block; + color: var(--gray); + font-size: clamp(0.5rem, min(2.5vw, 2.5vh), 0.8rem); + text-align: center; +} + +#share-modal code { + max-width: 30rem; + font-size: clamp(0.7rem, min(3vw, 3vh), 0.9rem); + padding: 0.4rem 0.8rem; + border-radius: 0.3rem; + background-image: var(--blackGradientVert); + -webkit-user-select: all; + -moz-user-select: all; + user-select: all; + overflow-x: scroll; + white-space: nowrap; +} + +/* Firefox/chrome differences: https://stackoverflow.com/questions/77894066/webkit-scrollbar-design-is-not-working-in-chrome-version-121-0-6167-86 */ +@supports not selector(::-webkit-scrollbar) { + #share-modal code { + scrollbar-width: thin; + scrollbar-color: var(--grayDivider) var(--grayDarkAlpha80); + } +} + +/* Webkit browsers (Chrome, Safari) */ +#share-modal code::-webkit-scrollbar { + height: 0.4rem; +} + +#share-modal code::-webkit-scrollbar-track { + background: var(--blackGradientVert); + border-radius: 0 0 0.3rem 0.3rem; +} + +#share-modal code::-webkit-scrollbar-thumb { + background: var(--grayDivider); + border-radius: 0.1rem 0.1rem 0.3rem 0.3rem; +} + +#share-modal .tab-content img { + width: 100%; + max-width: min(45vh, 30rem); + margin: 0 auto; + border-radius: 0.3rem; +} + +/* Copy link button */ +#share-modal .tab-content button.copy-link { + background-color: var(--cta-blue); + padding: 0.3rem; + border-radius: 0.3rem; + color: var(--grayLight); + transition: transform 0.2s, filter 0.2s; +} + +#share-modal .tab-content button.copy-link:active { + transform: scale(0.99, 0.95); + transition-duration: 0.05s; + filter: brightness(1); +} + +#share-modal .copied-overlay { + position: absolute; + inset: 0; + display: flex; + justify-content: center; + align-items: center; + background-image: var(--darkGrayBgGradientBtm); + border-radius: 0.5rem; + font-size: 1.3rem; + -webkit-backdrop-filter: blur(0.1rem); + backdrop-filter: blur(0.1rem); + opacity: 0; + pointer-events: none; +} + +#share-modal .copied-overlay.flash { + -webkit-animation: flash 2s ease-in; + animation: flash 2s ease-in; +} + +/* Embed content */ +/* Preview and iframe */ +#share-modal .preview-container { + width: 100%; + max-width: min(45vh, 30rem); + margin: 0 auto; +} + +#share-modal .preview { + position: relative; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + aspect-ratio: 1.777; +} + +#share-modal .preview-container span { + display: block; + color: var(--gray); + font-size: 0.75rem; + text-align: center; + pointer-events: none; +} + +#share-modal .preview iframe { + position: absolute; + left: 0; + top: 0; + width: var(--iframe-width); + height: var(--iframe-height); + transform: scale(var(--iframe-scale)) translateX(var(--iframe-offset-x)); + transform-origin: 0 0; + border: none; + border-radius: 1rem; +} + +/* Embed options */ +#share-modal section.options-section h5 { + color: var(--grayLight); + font-size: clamp(0.8rem, min(3.5vw, 3.5vh), 1rem); +} + +#share-modal input[type="checkbox"], +#share-modal input[type="radio"] { + transform: scale(1.2); + transform-origin: right; + filter: brightness(1.1) hue-rotate(20deg); +} + +#share-modal input[type="number"] { + width: 4rem; + padding: 0.2rem 0.4rem; + border: 0.1rem solid var(--grayDivider); + border-radius: 0.3rem; + background-image: var(--blackGradientVert); + color: var(--grayLight); + + /* Hide the spinner in Firefox */ + -webkit-appearance: textfield; + -moz-appearance: textfield; + appearance: textfield; +} + +#share-modal input[type="number"]::-webkit-inner-spin-button { + cursor: pointer; + filter: invert(0.9); +} + +#share-modal input[type="number"]:invalid { + border-color: red; +} + +#share-modal label { + color: var(--grayMed); + font-size: clamp(0.6rem, min(3vw, 3vh), 0.85rem); +} + +#share-modal input[type="radio"]:checked+label { + filter: brightness(1.15); +} + +#share-modal span.icon-help:focus { + filter: brightness(1.2); + transform: scale(1.2); + transition: filter 0.2s, transform 0.2s; +} + +/* Resolution settings */ +#share-modal .resolution-preset-buttons { + display: flex; + justify-content: center; + margin: 2rem 0 0; + gap: 0.3rem; +} + +#share-modal .custom-resolution { + display: flex; + justify-content: center; + align-items: center; + margin: 0.5rem 0; + gap: 0.5rem; +} + +#share-modal .custom-resolution input { + width: 6rem; + padding: 0.2rem 0.6rem; + border: 1px solid var(--nasa-blue); + border-radius: 0.3rem; + color: var(--grayLight); + background-color: var(--blackAlpha); +} + +#share-modal .custom-resolution>span { + color: var(--gray); + font-size: 1rem; +} + +/* Advanced options */ +#share-modal .advanced>summary { + color: var(--grayMed); +} + +#share-modal .advanced .options { + padding: 1rem 0 0; +} + +.touch #share-modal .advanced>summary, +#share-modal .advanced[open]>summary { + filter: brightness(1.2); +} + +#share-modal .options>h3 { + color: var(--gray); + font-size: 1.2rem; + text-align: center; + margin: 0.5rem 0; +} + +/* Embed group content */ +#share-modal .embed-group { + margin: 0 0 1rem; +} + +#share-modal div.input-container { + display: flex; + align-items: center; + gap: 0.5rem; +} + +/* Greyed out text */ +#share-modal div.input-container.greyed-out>label, +#share-modal div.input-container.greyed-out>span { + filter: brightness(0.5); +} + +#share-modal fieldset div.input-container:not(:last-child) { + margin-bottom: 0.6em; +} + +#share-modal fieldset div.number-container { + margin-top: 0.7em; +} + +#share-modal fieldset { + border: 1px solid var(--grayDivider); + padding: 0.4em 0.9em 0.9em; + border-radius: 0.3rem; +} + +#share-modal fieldset.radio-fieldset { + margin-top: 1em; + border: 1px solid var(--grayDarkAlpha80); + border-radius: 0.2rem; +} + +#share-modal fieldset legend { + color: var(--gray); + font-size: clamp(0.75rem, min(3vw, 3vh), 0.9rem); + padding: 0 0.5rem; +} + +/* Portrait. Portrait tablets/iPad and above */ +@media only screen and (min-width: 961px) { + + /* Main article */ + #share-modal>article { + width: unset; + } + + /* Embed preview - side by side layout */ + #share-modal .tab-pane.embed.active { + gap: 1rem; + height: 100%; + display: grid; + grid-auto-flow: column; + grid-auto-columns: minmax(30rem, 42rem) minmax(22rem, auto); + grid-auto-rows: 0fr; + } + + /* Header */ + #share-modal .modal-header { + justify-content: flex-start; + padding: 0; + } + + #share-modal .modal-header .modal-close { + margin: 0 0 0 auto; + } + + /* Tab Headers */ + #share-modal ul.tab-headers { + position: relative; + width: unset; + margin: 0 2rem; + } + + #share-modal ul.tab-headers button::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 0.16rem; + background-color: var(--cta-blue); + transform: scaleX(0); + transition: transform 0.2s 0.1s var(--ease-out-bezier); + z-index: 1; + } + + #share-modal ul.tab-headers::after { + height: 0.16rem; + } + + /* Preview and iframe */ + #share-modal .preview-container { + max-width: unset; + } + + #share-modal .embed code { + max-width: unset; + } + + /* Embed options */ + #share-modal .options { + padding: 0.5rem 0.5rem 0.5rem 0; + } + + #share-modal .embed>section { + gap: 1.5rem; + } + + #share-modal .embed .options-container { + padding-right: 1.5rem; + } + + #share-modal .embed>section.options-section { + height: unset; + gap: 0.5rem; + padding: 1rem 0 0 1.5rem; + } + + #share-modal .advanced .options { + padding: 1rem 0.5rem 0 0; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + + /* Share button */ + .share-button { + width: unset; + gap: 0.8em; + color: var(--grayMed); + margin: 0; + background-color: transparent; + } +} + +@media (max-height: 600px) { + + /* Hide stuff when not enough vertical space */ + #share-modal .tab-content img, + #share-modal .preview-container { + display: none; + } + + #share-modal .embed>section.options-section { + padding: 0 0 0 1rem; + } +} + +/* Animation */ +@-webkit-keyframes flash { + 0% { + opacity: 0; + } + + 5% { + opacity: 1; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@keyframes flash { + 0% { + opacity: 0; + } + + 5% { + opacity: 1; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +/*!**************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/time_controller/time_controller.css ***! + \**************************************************************************************************************************************************************************************************************/ +.time-controller button:focus { + outline: 0; + box-shadow: none; +} + +.time-controller label { + text-transform: uppercase; +} + +.time-controller .play-pause { + margin-right: 5%; +} + +.time-controller .prev-rate, +.time-controller .next-rate { + display: flex; + align-items: center; + justify-content: center; + width: 80px; + border: 0; + height: 30px; + padding: 0; + background: none; +} + +.time-controller .prev-rate { + margin-left: 10px; +} + +.time-controller .next-rate { + margin-right: 10px; +} + +.time-controller .prev-rate .container, +.time-controller .next-rate .container { + background-color: rgba(128, 128, 128, 0.5); + width: 100%; + margin: 0 auto; + height: 10px; +} + +.time-controller .prev-rate .container { + border-radius: 3px 0 0 3px; +} + +.time-controller .next-rate .container { + border-radius: 0 3px 3px 0; +} + +.time-controller label { + opacity: 0.6; +} + +.time-controller .play-pause { + margin-right: 30px; +} + +.time-controller .vertical-line { + opacity: 0.6; +} + +.time-controller .next-rate, +.time-controller .prev-rate { + position: relative; +} + +.time-controller .icon-forward, +.time-controller .icon-backward { + opacity: 0.2; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.time-controller .prev-rate .container, +.time-controller .next-rate .container { + background-color: var(--grayDarkAlpha); +} + +.time-controller .rate-display-label { + white-space: nowrap; +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + .time-controller .rate-container { + margin-left: 8px; + } + + .time-controller .prev-rate, + .time-controller .next-rate { + width: 75px; + } + + .time-controller .prev-rate .container, + .time-controller .next-rate .container { + height: 22px; + } + + .time-controller .vertical-line { + height: 29px; + } +} + +/* Landscape. 480x320 phones and above */ +@media only screen and (min-width: 320px) and (orientation: landscape) {} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .time-controller .rate-container { + margin-left: 0; + } + + .time-controller .prev-rate, + .time-controller .next-rate { + width: 80px; + } + + .time-controller .prev-rate .container, + .time-controller .next-rate .container { + height: 10px; + } + + .time-controller .vertical-line { + height: 20px; + } +} + +/*!************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/checkbox/checkbox.css ***! + \************************************************************************************************************************************************************************************************/ +.checkbox-option { + list-style: none; + display: grid; + grid-template-columns: auto -webkit-max-content; + grid-template-columns: auto max-content; + gap: 15px; + justify-content: start; + align-items: center; + margin: 5px 0; +} + +.checkbox-option span { + pointer-events: none; +} + +.checkbox-option .text { + grid-row: 1; + grid-column: 2; +} + +/*!******************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/layer_panel/layer_panel.css ***! + \******************************************************************************************************************************************************************************************************/ +/* Container */ +.layer-panel { + background: var(--bgGradient); + border-radius: 3px; + pointer-events: all; +} + +/* Header */ +.layer-panel .header { + padding-top: 20px; + display: grid; + grid-template-columns: auto auto; + margin: 0 10px; + cursor: pointer; +} + +/* List */ +.layer-panel .layers { + padding: 0; + margin: 10px 0; +} + +.layer-panel .layers li { + height: 100%; + list-style: none; + display: flex; + margin-bottom: 5px; + cursor: pointer; + opacity: 0.7; + transition: opacity 0.2s ease-out; + gap: 0; +} + +.layer-panel .layers li:last-child { + margin-bottom: 0; +} + +.layer-panel .layers li.active { + opacity: 1; +} + +.layer-panel .layers li>* { + pointer-events: none; +} + +.layer-panel .layers li>span.checkbox { + margin: 3px 0; +} + +.layer-panel .layers li>*:last-child { + margin-left: 10px; + line-height: 24px; +} + +.layer-panel .layers li.disabled { + opacity: 0.3; + pointer-events: none; +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + .layer-panel { + position: fixed; + bottom: 0; + right: 0; + left: 0; + width: 100%; + z-index: 10; + background: var(--mobileBgGradient); + } + + .layer-panel .container { + display: grid; + grid-template-columns: calc(50% - 5px) calc(50% - 5px); + gap: 0 10px; + padding: 20px 35px 40px; + } + + /* Header */ + .layer-panel .header { + justify-content: center; + } + + .layer-panel .header .close { + transform: rotate(90deg); + } +} + +/* Landscape. 480x320 phones and above */ +@media only screen and (min-width: 320px) and (orientation: landscape), +/* Portrait. Portrait tablets/iPad and above */ +only screen and (min-width: 641px) and (orientation: portrait) { + .layer-panel .container { + display: grid; + grid-template-columns: calc(33% - 10px) calc(33% - 10px) calc(33% - 10px); + grid-template-rows: -webkit-max-content auto; + grid-template-rows: max-content auto; + gap: 0 15px; + padding: 20px 35px 10px; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .layer-panel { + position: absolute; + right: 0; + bottom: unset; + left: unset; + background: var(--bgGradient); + border-radius: 3px; + width: auto; + } + + .layer-panel .container { + display: block; + grid-template-columns: unset; + padding: 20px 35px 40px; + } + + .layer-panel .block { + border-right: 0; + border-bottom: 1px solid #404040; + } + + .layer-panel .block:last-child { + border: 0; + } + + /* Header */ + .layer-panel .header { + justify-content: end; + } + + .layer-panel .header .close { + transform: none; + opacity: 0.6; + } +} + +/*!****************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/breadcrumb/breadcrumb.css ***! + \****************************************************************************************************************************************************************************************************/ +.breadcrumb { + /* Variables */ + --inactiveOpacity: 0.7; + --activeOpacity: 1; + + /* Properties */ + display: grid; + align-items: center; + justify-content: left; +} + +.breadcrumb nav { + display: inline-block; + vertical-align: middle; +} + +/* Use Nasa icon for home */ +.breadcrumb .container.home { + display: grid; + grid-template-columns: auto 1fr; + align-items: center; + -moz-column-gap: 0.5em; + column-gap: 0.5em; +} + +.breadcrumb .text { + font-size: inherit; + font-weight: 600; + letter-spacing: 0.64px; + color: var(--grayMed); + display: contents; +} + +.breadcrumb .link { + display: inline-block; +} + +.breadcrumb .text::first-letter { + text-transform: uppercase; +} + +.breadcrumb .home .text { + display: none; + vertical-align: middle; +} + +.breadcrumb.tiny .text, +.breadcrumb.x-small .text, +.breadcrumb.small .text, +.breadcrumb.large .text { + font-size: inherit; +} + +/* Active or not */ +.breadcrumb .container { + opacity: var(--inactiveOpacity); +} + +.breadcrumb .container.active, +.breadcrumb .container:last-child { + opacity: var(--activeOpacity); +} + +.breadcrumb .container.hidden { + display: none; +} + +/* Separator */ +.breadcrumb .container .separator { + transform: scale(0.66); + display: inline-block; + vertical-align: middle; +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .breadcrumb { + grid-auto-flow: column; + } + + .breadcrumb .container { + padding: 0; + display: grid; + grid-template-columns: -webkit-max-content -webkit-max-content; + grid-template-columns: max-content max-content; + align-items: center; + } +} + +/*!*********************************************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/story/blocks/story_base_content_block/story_base_content_block.css ***! + \*********************************************************************************************************************************************************************************************************************************************/ +.carousel .content-block { + margin: auto; + margin-bottom: 10px; +} + +.carousel .content-block:last-of-type { + margin-bottom: 20px; +} + +/* Only 1 element */ +.carousel .content-block:first-of-type:last-of-type { + margin-bottom: auto; +} + +/*!*****************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/story/blocks/hint_block/hint_block.css ***! + \*****************************************************************************************************************************************************************************************************************/ + +.hint-block .icon { + margin: auto; +} + +.hint-block.top { + margin-bottom: auto; +} + +.hint-block.bottom { + margin-top: auto; +} + +.hint-block.top .icon, +.hint-block.bottom .icon { + display: block; +} + +.hint-block .icon.hidden { + display: none; +} + +.hint-block.up .icon-greater { + transform: rotate(-90deg); +} + +.hint-block.down .icon-greater { + transform: rotate(90deg); +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .hint-block { + font-size: 18px; + } +} + +/*!*********************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/story/blocks/toggle_block/toggle_block.css ***! + \*********************************************************************************************************************************************************************************************************************/ +.toggle-block { + display: inline-block; +} + +.toggle-block button { + background: var(--whiteAlpha15); + color: var(--white); + border-radius: 5px; +} + +.toggle-block.selected button { + background: var(--white); + color: var(--black); +} + +/*!*******************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/story/blocks/image_block/image_block.css ***! + \*******************************************************************************************************************************************************************************************************************/ +.image-block { + display: inline-flex; + flex-direction: column; + align-items: center; + max-height: 70vh; +} + +.image-block.fullscreen { + display: flex; + justify-content: center; + width: 100%; + height: var(--vh); + padding: 5%; + max-width: 100%; + max-height: 100%; + margin: 0; +} + +.image-block .title { + margin: 2px 0 12px 0; + color: #aaaaaa; + text-align: center; +} + +.image-block img { + width: 100%; + height: auto; + max-width: 100%; + max-height: 100%; + -o-object-fit: contain; + object-fit: contain; + overflow: hidden; +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + .image-block { + height: 50vh; + margin-bottom: 8px; + padding-bottom: 25px; + font-size: 12px; + } +} + +@media only screen and (max-height: 600px) and (orientation: landscape) { + .carousel-container .carousel .slide.overlay .container .content-wrapper .content { + flex-direction: unset; + } + + .carousel-container .carousel .slide.overlay .image-block { + height: 100%; + width: 40%; + display: flex; + justify-content: center; + margin-bottom: auto; + } + + .image-block+.description-block { + height: 100%; + width: 60%; + display: flex; + justify-content: center; + flex-flow: column; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .image-block { + height: auto; + padding-bottom: 0; + font-size: 14px; + } +} + +/*!*******************************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/story/blocks/description_block/description_block.css ***! + \*******************************************************************************************************************************************************************************************************************************/ +.carousel .content-block { + --highlightNumber: #ffff00; +} + +/* More toggle */ +.carousel .content-block .more-toggle { + display: block; +} + +.carousel .content-block .more-toggle.hidden { + display: none; +} + +.carousel .content-block a { + text-decoration: underline; + color: var(--uranus); +} + +.carousel .content-block .number { + font-family: monospace; +} + +.carousel .content-block .number.highlight { + color: var(--highlightNumber); +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + .carousel .content-block.large .body { + font-size: 22px; + } + + .carousel .description-block .title { + margin-top: 25px; + } + + .carousel .description-block .title, + .carousel .description-block .subtitle { + margin-bottom: 5px; + } + + .carousel .description-block .subtitle { + font-size: 22px; + line-height: 1.2; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .carousel .content-block .body { + font-size: 18px; + } + + .carousel .content-block.large .body { + font-size: 26px; + } + + .carousel .description-block .title, + .carousel .description-block .subtitle { + margin-bottom: 10px; + } +} + +/*!***********************************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/story/blocks/replay_button_block/replay_button_block.css ***! + \***********************************************************************************************************************************************************************************************************************************/ +.replay-button-block { + display: inline-block; + padding-top: 20px; +} + +.replay-button-block button { + display: grid; + grid-template-columns: 30px auto; + gap: 0 2px; + align-items: center; + padding: 1px 7px 1px 2px; + background: var(--grayDarkAlpha); + color: var(--white); + border-radius: 5px; +} + +.replay-button-block .text { + text-transform: uppercase; +} + +.replay-button-block .icon, +.replay-button-block .text { + opacity: 0.4; +} + +/*!***********************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/story/blocks/buttons_block/buttons_block.css ***! + \***********************************************************************************************************************************************************************************************************************/ +.buttons-block { + display: grid; + grid-auto-rows: 1fr; + width: 90%; + height: 300px; + font-family: Metropolis, sans-serif; +} + +.block-title { + font-weight: 600; + margin-top: 20px; +} + +.custom-button { + display: flex; + gap: 20px; + align-items: center; + border: 1px solid black; + background-color: #202021; +} + +.buttons-block .focused { + background-color: #343434; + border-left: solid #0d67ff; +} + +.button-icon { + width: 56px; + height: 56px; +} + +/*!*************************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/story/blocks/checkbox_block/checkbox_block.css ***! + \*************************************************************************************************************************************************************************************************************************/ +.checkboxes-block { + width: 90%; + height: 200px; +} + +.cb-block-title { + font-weight: bold; + margin: 35px 0px 15px 0px; +} + +.cb-container { + display: block; + position: relative; + padding-left: 35px; + margin-bottom: 12px; + cursor: pointer; + font-size: 16px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.cb-container input { + position: absolute; + opacity: 0; + cursor: pointer; + height: 0; + width: 0; +} + +.checkmark { + position: absolute; + top: 2px; + left: 5px; + height: 20px; + width: 20px; + background-color: #eee; + border-radius: 3px; +} + +.cb-container input:checked~.checkmark { + background-color: #0d67ff; +} + +.checkmark:after { + content: ""; + position: absolute; + display: none; +} + +.cb-container input:checked~.checkmark:after { + display: block; +} + +.cb-container .checkmark:after { + left: 7px; + top: 3px; + width: 3px; + height: 9px; + border: solid white; + border-width: 0 3px 3px 0; + transform: rotate(45deg); +} + +/*!******************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/story/story.css ***! + \******************************************************************************************************************************************************************************************/ +.carousel-container { + /* Variables */ + --story-height: calc((var(--vh) - 4px) * 2 / 5); + + /* Properties */ + padding: 0; +} + +.carousel-container .carousel .slide.grid-layout { + display: grid; +} + +.carousel-container .carousel .slide .container { + grid-column: head-start / head-end; + grid-row: head-start / foot-end; +} + +.carousel-container .carousel .slide.overlay .container { + grid-column: head-start / head-end; + grid-row: head-start / foot-end; + z-index: 10; +} + +.carousel-container .mobile-collapse { + transition: bottom 1s; +} + +.carousel-container .slide .collapse-container.collapse .mobile-collapse { + bottom: 20px; +} + +.carousel-container .progress.overlay { + height: 100%; +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + .carousel-container .carousel .slide .container { + grid-column: main-start / side-end; + grid-row: extf-start / foot-end; + overflow: hidden; + align-content: end; + align-self: end; + height: 100%; + transition: height 1s; + } + + .carousel-container .carousel .slide .container.collapse { + height: 0; + } + + .carousel.expand .slide.active .mobile-hint { + -webkit-animation-name: text-pulse; + animation-name: text-pulse; + -webkit-animation-duration: 1.9s; + animation-duration: 1.9s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-iteration-count: 3; + animation-iteration-count: 3; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + -webkit-animation-direction: alternate; + animation-direction: alternate; + } + + .carousel.expand .slide.active .mobile-hint>.hint-text { + height: 30px; + line-height: 30px; + } + + .carousel-container .carousel .slide.overlay .container { + align-content: stretch; + align-self: unset; + height: unset; + } + + .carousel-container .carousel .slide.overlay .content-wrapper { + padding: 0 20px; + } + + .carousel-container .carousel .slide.overlay .container .content { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + } + + /* Background */ + .carousel-container .carousel.scrolling-done .slide .container .content-container { + -webkit-animation-name: mobile-gradient; + animation-name: mobile-gradient; + -webkit-animation-duration: 0.2s; + animation-duration: 0.2s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-iteration-count: 1; + animation-iteration-count: 1; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + background: linear-gradient(180deg, + rgba(37, 37, 39, 0) 0%, + rgba(37, 37, 39, 0.1) 25%, + rgba(37, 37, 39, 0.4) 100%); + } + + .carousel-container .carousel.scrolling-done .slide.overlay .container .content-container { + -webkit-animation: none; + animation: none; + background: none; + } + + .carousel.hidden .slide .container .content-container, + .carousel.scrolling .slide .container .content-container { + -webkit-animation: none; + animation: none; + } + + .carousel-container .progress { + height: calc(2 / 5 * 0.75 * 100%); + } + + .carousel-container .close-button .text { + display: none; + } +} + +/* Landscape. 480x320 phones and above */ +@media only screen and (min-width: 320px) and (orientation: landscape) { + .carousel-container .carousel .slide .container { + grid-row: extf-start / foot-end; + height: 100%; + } + + .carousel-container .progress { + height: calc(2 / 5 * 1 * 100%); + } + + .carousel-container .mobile-collapse { + bottom: calc(2 / 5 * 100% * 1); + } + + .carousel-container .close-button .text { + display: unset; + } +} + +/* Portrait. Portrait tablets/iPad and above */ +@media only screen and (min-width: 641px) and (orientation: portrait) { + .carousel-container .carousel .slide .container { + height: 75%; + } +} + +/* Landscape. Landscape iPad, big tablet, lo-res laptops/desktops, and above */ +@media only screen and (min-width: 961px) and (orientation: landscape) { + .carousel-container .carousel .slide .container { + height: 60%; + } + + .carousel-container .mobile-collapse { + bottom: calc(2 / 5 * 100% * 0.6); + } + + .carousel-container .progress { + height: calc(2 / 5 * 0.6 * 100%); + } + + .carousel-container .close-button .text { + display: unset; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .carousel-container .carousel .slide .container { + grid-column: main-start / extd-end; + grid-row: head-end / foot-start; + margin: 0 0 0 -20px; + height: 100%; + position: relative; + } + + .carousel-container .carousel .slide.overlay .container { + height: 100%; + margin: 0; + } + + .carousel-container .carousel .slide.overlay .content-wrapper { + padding: 0; + } + + .carousel-container .carousel.scrolling-done .slide .container .content-container { + -webkit-animation: none; + animation: none; + } + + .carousel-container .carousel.scrolling .slide .container .content-container, + .carousel-container .carousel.scrolling-done .slide .container .content-container { + background: none; + } + + .carousel-container .close-button { + font-size: 18px; + } + + .carousel-container .close-button .text { + display: unset; + } + + .carousel-container .progress { + height: calc(3 / 5 * 1 * 100%); + } +} + +@-webkit-keyframes gradient { + 0% { + background-position: 0% 50%; + } + + 100% { + background-position: 100% 50%; + } +} + +@keyframes gradient { + 0% { + background-position: 0% 50%; + } + + 100% { + background-position: 100% 50%; + } +} + +@-webkit-keyframes text-pulse { + 0% { + opacity: 0.5; + } + + 50% { + opacity: 0.9; + } + + 100% { + opacity: 0.5; + } +} + +@keyframes text-pulse { + 0% { + opacity: 0.5; + } + + 50% { + opacity: 0.9; + } + + 100% { + opacity: 0.5; + } +} + +/*!****************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/kiosk_base/kiosk_base.css ***! + \****************************************************************************************************************************************************************************************************/ +.kiosk-container { + position: absolute; + inset: 0; + z-index: calc(var(--overlay-z-index) * 2); + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: repeat(5, 1fr); +} + +.session-end-container { + position: absolute; + inset: 0; + z-index: calc(var(--overlay-z-index) * 2); + display: grid; + justify-items: center; + align-items: center; + background: rgba(0 0 0 / 75%); +} + +.session-end-buttons-container { + z-index: calc(var(--overlay-z-index) * 2); + pointer-events: all; + display: grid; + grid-template-columns: repeat(4, 1fr); + grid-template-rows: repeat(2, 1fr); + -moz-column-gap: 3em; + column-gap: 3em; +} + +.session-ended-msg { + align-self: center; + grid-column: 2 / span 2; + font-size: 1.75em; + font-weight: 600; + margin: 1em; + text-align: center; +} + +.kiosk-btn { + display: grid; + align-items: center; + background-color: var(--grayblueButton); + width: 14em; + height: 4.5em; + border-radius: 0.5em; + font-size: 1.75em; + font-weight: 600; + text-align: center; +} + +.session-end-btn { + grid-column: span 2; + grid-row: 2; +} + +.force-restart { + grid-column: 2 / span 2; +} + +.autoplay-container { + display: grid; + justify-self: center; + align-self: center; + grid-column-start: 2; + grid-row-start: 3; + pointer-events: all; +} + +.touch-to-start-btn { + grid-column-start: 2; + grid-row-start: 3; +} + +.session-timer-container { + display: flex; + justify-self: end; + align-self: center; + align-items: center; + grid-template-columns: 1fr 1fr; + grid-column-start: 3; + grid-row-start: 1; + margin-right: 1em; + color: rgb(255 255 188); + font-size: 1.5em; +} + +.session-countdown-timer { + opacity: 0.6; +} + +.loading-text { + display: grid; + justify-self: center; + align-self: center; + align-items: center; + grid-column-start: 2; + grid-row-start: 4; + z-index: calc(var(--overlay-z-index) * 4); + padding: 1em; + background: rgba(0 0 0 / 35%); + border-radius: 5px; + color: white; + text-align: center; + font: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 2.5em; + font-weight: 600; +} + +/*!******************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/components/toast/toast.css ***! + \******************************************************************************************************************************************************************************************/ +.toast-container { + position: inherit; + display: flex; + gap: min(2vw, 0.7em); + align-items: center; + justify-content: space-between; + grid-row: -2; + grid-column-start: 1; + background-color: var(--toast-bg-color); + padding: 0.5em 0.5em 0.5em 0.8em; + border-radius: 0.5em; + transition-property: opacity, transform; + transition-duration: 0.5s; + transition-timing-function: var(--ease-out-bezier); + opacity: 1; + z-index: 40; +} + +.toast-container.hidden { + display: flex; + transition-duration: 0.2s; + opacity: 0; + transform: translateY(2em); +} + +.toast-container button.close { + transform: scale(1.5); + filter: invert(); +} + +.toast-content>div { + display: flex; + align-items: center; + max-width: 30vw; + gap: min(2vw, 0.7em); +} + +.toast-content .content-text { + display: block; + color: var(--grayDark); + font-size: clamp(0.75rem, min(2vh, 2vw), 0.9rem); + font-weight: 600; + min-width: 0; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.toast-content button.undo { + color: rgb(0 37 158 / 80%); + font-size: clamp(0.75rem, min(2vh, 2vw), 0.9rem); + font-weight: 600; + line-height: 1; + border: 0.1em solid rgb(0 37 158 / 20%); + border-radius: 0.25em; + padding: 0.4em 0.6em; + transition: transform 0.2s var(--ease-out-bezier); + flex: 1; +} + +@media (min-width: 1025px) { + body.touch:has(nav.items-2) .toast-container { + grid-row: 2; + justify-self: center; + grid-column: 2 / -2; + margin: 0; + } +} + +/*!****************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/animation.css ***! + \****************************************************************************************************************************************************************************************/ +@-webkit-keyframes fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@-webkit-keyframes fade-out { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@keyframes fade-out { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@-webkit-keyframes fade-in-left { + 0% { + opacity: 0; + transform: translateX(-100%); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes fade-in-left { + 0% { + opacity: 0; + transform: translateX(-100%); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +@-webkit-keyframes fade-out-left { + 0% { + opacity: 1; + transform: translateX(0); + } + + 100% { + opacity: 0; + transform: translateX(-100%); + } +} + +@keyframes fade-out-left { + 0% { + opacity: 1; + transform: translateX(0); + } + + 100% { + opacity: 0; + transform: translateX(-100%); + } +} + +@-webkit-keyframes fade-out-bottom { + 0% { + transform: translateY(0); + opacity: 1; + } + + 100% { + transform: translateY(100%); + opacity: 0; + } +} + +@keyframes fade-out-bottom { + 0% { + transform: translateY(0); + opacity: 1; + } + + 100% { + transform: translateY(100%); + opacity: 0; + } +} + +@-webkit-keyframes fade-in-bottom { + 0% { + transform: translateY(100%); + opacity: 0; + } + + 100% { + transform: translateY(0); + opacity: 1; + } +} + +@keyframes fade-in-bottom { + 0% { + transform: translateY(100%); + opacity: 0; + } + + 100% { + transform: translateY(0); + opacity: 1; + } +} + +@-webkit-keyframes pulse { + 0% { + opacity: 0.75; + transform: scale(1); + } + + 30% { + opacity: 0.1; + transform: scale(0); + } + + 70% { + opacity: 0.1; + transform: scale(0); + } + + 100% { + opacity: 0.75; + transform: scale(1); + } +} + +@keyframes pulse { + 0% { + opacity: 0.75; + transform: scale(1); + } + + 30% { + opacity: 0.1; + transform: scale(0); + } + + 70% { + opacity: 0.1; + transform: scale(0); + } + + 100% { + opacity: 0.75; + transform: scale(1); + } +} + +@-webkit-keyframes spin { + 100% { + transform: rotate(360deg); + } +} + +@keyframes spin { + 100% { + transform: rotate(360deg); + } +} + +@-webkit-keyframes blink { + 0% { + outline: 1px transparent solid; + } + + 25% { + outline: 1px var(--error) solid; + } + + 50% { + outline: 4px var(--error) solid; + } + + 75% { + outline: 1px var(--error) solid; + } + + 100% { + outline: 1px transparent solid; + } +} + +@keyframes blink { + 0% { + outline: 1px transparent solid; + } + + 25% { + outline: 1px var(--error) solid; + } + + 50% { + outline: 4px var(--error) solid; + } + + 75% { + outline: 1px var(--error) solid; + } + + 100% { + outline: 1px transparent solid; + } +} + +/* Animation transitions */ + +:root { + --ease-out-bezier: cubic-bezier(0.2, 0.2, 0, 1); +} + +/*!********************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/camera_follow.css ***! + \********************************************************************************************************************************************************************************************/ +/* stylelint-disable custom-property-pattern */ +/* ---------------- Search component overrides --------------- */ + +.camera-follow>.search { + display: block; + width: 100%; + height: 2em; + margin-top: 0.5em; + transition-property: opacity, visibility, height; + transition-duration: 0.3s, 0.3s, 0.5s; + transition-delay: 0.25s, 0.25s, 0s; + /* stylelint-disable-next-line declaration-block-no-redundant-longhand-properties */ + transition-timing-function: var(--ease-out-bezier); +} + +.camera-follow .search.hidden { + transition-delay: 2s, 2s, 2.15s; + display: unset; + opacity: 0; + height: 0; +} + +.camera-follow .search .cover { + display: none; +} + +.camera-follow .search .bar { + padding: 0.4rem; + margin: 0; + grid-template-columns: auto 1fr auto; + grid-template-areas: "search input close"; + max-width: 20rem; +} + +.camera-follow .search .bar .icon-search { + grid-area: close; +} + +.camera-follow .search .search-open .bar input { + transition: opacity 0.3s var(--ease-out-bezier); + opacity: 1; +} + +.camera-follow .search .results { + background: linear-gradient(180deg, + var(--grayDarkAlpha80) 0%, + rgb(7 7 9 / 100%) 120%); + border-radius: 0 0 0.3em 0.3em; + border: none; +} + +.camera-follow .search .suggestion { + padding: 1rem 0; +} + +.camera-follow .search .results .result-div:last-child { + margin-bottom: 0.7em; +} + +.camera-follow .results-container>.results:not(:empty) { + padding-top: 1rem; +} + +.camera-follow .search .search-close-icon, +.camera-follow .search>span.icon-search { + display: none; +} + +.camera-follow .search .search-close { + display: unset; + pointer-events: auto; +} + +.camera-follow .search .search-info { + opacity: 0; +} + +.camera-follow .input-focused .search-info { + opacity: 1; + z-index: 2; +} + +.camera-follow .input-focused .search-info:has(+ .featured > ul:empty) { + opacity: 0; +} + +.camera-follow .featured { + z-index: 1; + opacity: 0; + height: unset; + border-radius: 0 0 0.3em 0.3em; + background: linear-gradient(180deg, + var(--grayDarkAlpha80) 0%, + rgb(37 37 39) 10%, + rgb(7 7 9) 100%); +} + +.camera-follow .featured.hidden { + display: unset; + transform: scaleY(0); +} + +.camera-follow .input-focused .featured { + opacity: 1; +} + +.camera-follow .featured:has(ul:empty) { + opacity: 0; +} + +.camera-follow .featured>ul { + padding: 1rem 0 0; +} + +/* On dragging, show the re-frame element - this should maybe have it's own element */ +#static-ui>div.follow-reframe { + position: absolute; + top: 12vh; + right: 8vw; + bottom: 12vh; + left: 8vw; + border: 0.1rem solid var(--toast-bg-color); + opacity: 0; + transition: opacity 0.3s 1s var(--ease-out-bezier); +} + +#static-ui>div.follow-reframe::before { + content: "▣"; + position: absolute; + inset: 8vh 8vw 8vh 8vw; + display: flex; + justify-content: center; + align-items: center; + font-size: 1rem; + font-weight: 100; + color: var(--toast-bg-color); + border: 0.1rem solid var(--toast-bg-color); + opacity: 0.4; +} + +#static-ui>div.follow-reframe::after { + content: "Re-framing follow camera"; + position: absolute; + left: 50%; + top: 0; + transform: translate(-50%, -50%); + text-align: center; + white-space: nowrap; + color: var(--toast-bg-color); + text-shadow: 0 0 0.3em rgb(30 30 80 / 80%), 0 0 0.3em rgb(30 30 80 / 80%), + 0 0 1em rgb(21 42 65 / 100%); + border-radius: 0.5em; + font-size: clamp(0.8rem, min(2vh, 2vw), 1rem); + font-weight: 600; + padding: 0.4em 0.8em; + z-index: 1; +} + +body.offset-right #static-ui>div.follow-reframe { + left: calc(8vw + var(--offset-right) * 2); +} + +body.offset-up #static-ui>div.follow-reframe { + bottom: calc(12vh + var(--offset-up) * 2); +} + +#static-ui.follow-dragging>div.follow-reframe { + transition: opacity 0.5s var(--ease-out-bezier); + opacity: 0.9; +} + +/*!************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/color.css ***! + \************************************************************************************************************************************************************************************/ +:root { + /* Primary */ + --black: #000000; + --blackAlpha: #00000380; + --white: #ffffff; + --whiteAlpha15: #ffffff26; + /* 15% transparent */ + --gray: #95959d; + --grayAlpha: #95959d33; + /* 20% transparent */ + --grayMed: #c6c6c9; + --grayLight: #eaeaeb; + --grayDark: #252527; + --grayDarkAlpha: #25252799; + /* 60% transparent */ + --grayDarkAlpha80: #252527cc; + /* 80% transparent */ + --cta-blue: #3e63dd; + --toast-bg-color: #c6d4f9; + --grayblueWhite: #f0f8fc; + --grayblueLight: #d2e1e8; + --grayblueMed: #a4bac1; + --grayblueText: #83959b; + --grayblueDivider: #25282b; + --grayblueBackground: #151a1d; + --grayblueButton: #425571; + + /* Semantic */ + --live: #47da84; + --liveAlpha: #47da84bf; + /* 75% transparent */ + --error: #d55033; + --grayDivider: rgb(55 55 58); + + /* Gradients */ + --bgGradient: linear-gradient(180deg, + #272527 0%, + rgb(37 37 39 / 80%) 52.08%, + rgb(37 37 39 / 0%) 100%); + --mobileBgGradient: linear-gradient(180deg, + #252527ee 0%, + rgb(37 37 39 / 85%) 52.08%, + rgb(0 0 0 / 80%) 100%); + + /* Secondary */ + --sun: #f7f4df; + --sunMed: #b8b7a7; + --sunDark: #626259; + --mercury: #9768ac; + --mercuryMed: #714e81; + --mercuryDark: #3c2a45; + --venus: #b07919; + --venusMed: #845b13; + --venusDark: #46300a; + --earth: #0099cc; + --earthMed: #007399; + --earthDark: #003d52; + --mars: #9a4e19; + --marsMed: #733a13; + --marsDark: #3d1f0a; + --jupiter: #da8b72; + --jupiterMed: #a36855; + --jupiterDark: #57382e; + --saturn: #d5c187; + --saturnMed: #786d4c; + --saturnDark: #554d36; + --uranus: #68ccda; + --uranusMed: #4e99a3; + --uranusDark: #2a5257; + --neptune: #708ce3; + --neptuneMed: #5469aa; + --neptuneDark: #2d385b; + --nasa-blue: #288bff; + + /* Tertiary */ + --spacecraft: #cd9745; + --moon: #b6acac; + --dwarfPlanet: #929871; + --comet: #7e86b0; + --asteroid: #806262; + --constellation: #59b2ff; + --constellationGlow: #287bc4; + --constellationGlowMed: #165d9b; + --constellationGlowDark: #070a99; +} + +/*!***********************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/font.css ***! + \***********************************************************************************************************************************************************************************/ +/* Metropolis */ +@font-face { + font-family: "Metropolis"; + font-weight: 100; + src: url("./assets/default/fonts/Metropolis-Thin.woff"); +} + +@font-face { + font-family: "Metropolis"; + font-weight: 300; + src: url("./assets/default/fonts/Metropolis-Light.woff"); +} + +@font-face { + font-family: "Metropolis"; + font-weight: 600; + src: url("./assets/default/fonts/Metropolis-SemiBold.woff"); +} + +/* Inter */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url("./assets/default/fonts/Inter-Light.woff2?v=3.15") format("woff2"), + url("./assets/default/fonts/Inter-Light.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("./assets/default/fonts/Inter-Regular.woff2?v=3.15") format("woff2"), + url("./assets/default/fonts/Inter-Regular.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url("./assets/default/fonts/Inter-SemiBold.woff2?v=3.15") format("woff2"), + url("./assets/default/fonts/Inter-SemiBold.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url("./assets/default/fonts/Inter-Bold.woff2?v=3.15") format("woff2"), + url("./assets/default/fonts/Inter-Bold.woff?v=3.15") format("woff"); +} + +/* DM Mono */ +@font-face { + font-family: "DMMono"; + font-weight: 300; + src: url("./assets/default/fonts/DMMono-Light.woff"); +} + +@font-face { + font-family: "DMMono"; + font-weight: 400; + src: url("./assets/default/fonts/DMMono-Regular.woff"); +} + +@font-face { + font-family: "DMMono"; + font-weight: 500; + src: url("./assets/default/fonts/DMMono-Medium.woff"); +} + +/*!*************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/sprite.css ***! + \*************************************************************************************************************************************************************************************/ +.icon { + display: inline-block; + background-repeat: no-repeat; + background-image: url(./assets/default/svg/sprite.svg); +} + +.icon-arrow-left-large { + width: 60px; + height: 60px; + background-position: 0 0; +} + +.icon-arrow-right-large { + width: 60px; + height: 60px; + background-position: -76px 0; +} + +.icon-back-to-live { + width: 10px; + height: 10px; + background-position: 0 -76px; +} + +.icon-live { + width: 10px; + height: 10px; + background-position: -26px -76px; +} + +.icon-external { + width: 14px; + height: 14px; + background-position: 0 -102px; +} + +.icon-backward { + width: 14px; + height: 14px; + background-position: -30px -102px; +} + +.icon-forward { + width: 14px; + height: 14px; + background-position: -60px -102px; +} + +.icon-checkmark { + width: 15px; + height: 15px; + background-position: 0 -132px; +} + +.icon-checkbox { + width: 15px; + height: 15px; + background-position: -62px -132px; +} + +.icon-checkbox-selected { + width: 15px; + height: 15px; + background-position: -93px -132px; +} + +.icon-radio-circle { + width: 15px; + height: 15px; + background-position: -124px -132px; +} + +.icon-radio-selected { + width: 15px; + height: 15px; + background-position: -186px -132px; +} + +.icon-hexagon { + width: 14px; + height: 16px; + background-position: 0 -163px; +} + +.icon-circle-white-small { + width: 16px; + height: 16px; + background-position: -32px -163px; +} + +.icon-natural-light { + width: 8px; + height: 16px; + background-position: -64px -163px; +} + +.icon-flood-light { + width: 16px; + height: 16px; + background-position: -96px -163px; +} + +.icon-shadow-light { + width: 16px; + height: 16px; + background-position: -128px -163px; +} + +.icon-triangle { + width: 20px; + height: 20px; + background-position: 0 -195px; +} + +.icon-circle-earth { + width: 20px; + height: 20px; + background-position: -36px -195px; +} + +.icon-circle-jupiter { + width: 20px; + height: 20px; + background-position: -72px -195px; +} + +.icon-circle-mars { + width: 20px; + height: 20px; + background-position: -108px -195px; +} + +.icon-circle-mercury { + width: 20px; + height: 20px; + background-position: -144px -195px; +} + +.icon-circle-neptune { + width: 20px; + height: 20px; + background-position: -180px -195px; +} + +.icon-circle-saturn { + width: 20px; + height: 20px; + background-position: -216px -195px; +} + +.icon-circle-sun { + width: 20px; + height: 20px; + background-position: -252px -195px; +} + +.icon-circle-uranus { + width: 20px; + height: 20px; + background-position: -288px -195px; +} + +.icon-circle-venus { + width: 20px; + height: 20px; + background-position: -324px -195px; +} + +.icon-circle-white { + width: 20px; + height: 20px; + background-position: -360px -195px; +} + +.icon-hd { + width: 30px; + height: 30px; + background-position: 0 -231px; + opacity: 0.4; + background-color: none; +} + +.icon-hd-on { + width: 30px; + height: 30px; + background-position: -46px -231px; + opacity: 0.4; + background-color: none; +} + +.icon-constellation { + width: 30px; + height: 30px; + background-position: -92px -231px; +} + +.icon-layers { + width: 30px; + height: 30px; + background-position: -184px -231px; +} + +.icon-arrow-down { + width: 30px; + height: 30px; + background-position: -276px -231px; +} + +.icon-arrow-left { + width: 30px; + height: 30px; + background-position: -322px -231px; +} + +.icon-arrow-right { + width: 30px; + height: 30px; + background-position: -368px -231px; +} + +.icon-arrow-up { + width: 30px; + height: 30px; + background-position: -414px -231px; +} + +.icon-clock { + width: 30px; + height: 30px; + background-position: -460px -231px; +} + +.icon-story { + width: 30px; + height: 30px; + background-position: -552px -231px; +} + +.icon-auto-cam { + width: 30px; + height: 30px; + background-position: -644px -231px; +} + +.icon-free-cam { + width: 30px; + height: 30px; + background-position: -46px -277px; +} + +.icon-box { + width: 30px; + height: 30px; + background-position: -92px -277px; +} + +.icon-info { + width: 30px; + height: 30px; + background-position: -184px -277px; +} + +.icon-hide { + width: 30px; + height: 30px; + background-position: -230px -277px; +} + +.icon-km { + width: 30px; + height: 30px; + background-position: -322px -277px; +} + + +.icon-mi { + width: 30px; + height: 30px; + background-position: -414px -277px; +} + +.icon-lighting { + width: 54px; + height: 30px; + background-position: -506px -277px; +} + +.icon-fullscreen { + width: 30px; + height: 30px; + background-position: 0 -323px; +} + +.icon-expand { + width: 30px; + height: 30px; + background-position: -92px -323px; +} + +.icon-controls { + width: 30px; + height: 30px; + background-position: -230px -323px; +} + +.icon-expand-side { + width: 30px; + height: 30px; + background-position: -276px -323px; +} + +.icon-replay { + width: 30px; + height: 30px; + background-position: -368px -323px; +} + +.icon-menu { + width: 30px; + height: 30px; + background-position: -414px -323px; +} + +.icon-search { + width: 30px; + height: 30px; + background-position: -460px -323px; +} + +.icon-close { + width: 30px; + height: 30px; + background-position: -506px -323px; +} + +.icon-minus { + width: 30px; + height: 30px; + background-position: -552px -323px; +} + +.icon-plus { + width: 30px; + height: 30px; + background-position: -598px -323px; +} + +.icon-collapse { + width: 30px; + height: 30px; + background-position: -644px -323px; +} + + +.icon-collapse-side { + width: 30px; + height: 30px; + background-position: 0 -369px; +} + + +.icon-dropdown { + width: 30px; + height: 30px; + background-position: -92px -369px; +} + +.icon-dropup { + width: 31px; + height: 30px; + background-position: -138px -369px; +} + +.icon-greater { + width: 30px; + height: 30px; + background-position: -184px -369px; +} + +.icon-lesser { + width: 30px; + height: 30px; + background-position: -230px -369px; +} + +.icon-pause { + width: 30px; + height: 30px; + background-position: -276px -369px; +} + + + +.icon-play { + width: 30px; + height: 30px; + background-position: -368px -369px; +} + + +.icon-telescope { + width: 30px; + height: 30px; + background-position: -460px -369px; +} + +/*!***********************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/icon.css ***! + \***********************************************************************************************************************************************************************************/ +:root { + --customIconLabelMargin: 50%; +} + +/* Additional icons outside of the sprite.css */ +.icon-nasa-logo { + background-image: url(./assets/default/svg/nasa_logo.svg); + width: 45px; + height: 45px; +} + +.icon-crosshair { + background-image: url(./assets/default/svg/crosshair.svg); + width: 80px; + height: 40px; +} + +.icon-finger { + background-image: url(./assets/default/svg/finger.svg); + width: 30px; + height: 30px; +} + +.icon-bg { + background: var(--grayDarkAlpha); + border-radius: 3px; +} + +.icon-share { + background-image: url(./assets/default/svg/share_arrow.svg); + background-origin: content-box; + background-position: center; + background-size: contain; + width: 1.125rem; + height: 1.125rem; +} + +.icon-help { + background-image: url(./assets/default/svg/help_icon.svg); + background-origin: content-box; + background-position: center; + width: 1.5rem; + height: 1.5rem; +} + +.icon-locked { + background-image: url(./assets/default/svg/locked.svg); + background-origin: content-box; + background-position: center; + width: 1.4rem; + height: 1.4rem; +} + +.icon.hidden { + display: none; +} + + +/*!******************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/grid_layout.css ***! + \******************************************************************************************************************************************************************************************/ +/* Default properties */ +.grid-layout { + display: grid; + gap: 2px; + background: transparent; + padding: 0; +} + +.grid-5-12 { + grid-template-columns: repeat(12, 1fr); + grid-template-rows: repeat(5, 1fr); + grid-template-areas: + "header header header header header header header header header header header header" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "footer footer footer footer footer footer footer footer footer footer footer footer"; +} + +.grid-6-12 { + grid-template-columns: repeat(12, 1fr); + grid-template-rows: repeat(6, 1fr); + grid-template-areas: + "header header header header header header header header header header header header" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "footer footer footer footer footer footer footer footer footer footer footer footer"; +} + +.grid-8-12 { + grid-template-columns: repeat(12, 1fr); + grid-template-rows: repeat(8, 1fr); + grid-template-areas: + "header header header header header header header header header header header header" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "left left left mid-left mid-left mid-left mid-right mid-right mid-right right right right" + "footer footer footer footer footer footer footer footer footer footer footer footer"; +} + +.simple-grid { + /* Variables */ + --rowGap: 4px; + --columnGap: 8px; + + /* Properties */ + grid-template-columns: repeat(12, 1fr); + grid-template-rows: repeat(5, 1fr); + grid-template-areas: + "head head head head head head head head head head head head" + "main main main extd .... .... .... .... .... .... side side" + "main main main extd extm extm extm extm extm extm side side" + "main main main extd extf extf extf extf extf extf side side" + "foot foot foot foot foot foot foot foot foot foot foot foot"; + gap: var(--rowGap) var(--columnGap); + padding: 0; +} + +/* Landscape. 480x320 phones and above */ +@media only screen and (min-width: 320px) and (orientation: landscape), +/* Portrait. Portrait tablets/iPad and above */ +only screen and (min-width: 641px) and (orientation: portrait) { + .simple-grid { + /* Variables */ + --rowGap: 4px; + --columnGap: 4px; + + /* Properties */ + padding: 0 20px; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .simple-grid { + /* Variables */ + --rowGap: 20px; + --columnGap: 24px; + + /* Properties */ + padding: 0 20px; + } +} + +/*!*************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/layout.css ***! + \*************************************************************************************************************************************************************************************/ +/* Layout */ +body { + -ms-scroll-chaining: none; + overscroll-behavior: none; + margin: 0; + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100%; + color: black; +} + +#pioneer { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +.ui { + position: absolute; + left: 0; + top: 0; + width: 100vw; + height: 100%; + min-width: 320px; + pointer-events: none; +} + +.ui .clickable { + pointer-events: all; + cursor: pointer; +} + +.ui .hidden .clickable { + pointer-events: none; + cursor: unset; +} + +/* Components */ +.time-controller .rate-container { + display: grid; + grid-template-rows: auto; + justify-content: start; + align-items: center; +} + +.clock-shortcut { + grid-row: 1; + grid-column: 1; + display: grid; +} + +.extended-controls { + display: grid; + grid-template-columns: auto auto; + align-items: center; + width: 100%; +} + +.grid-layout header .breadcrumb { + height: 45px; + grid-column: 1; + grid-row: 1; +} + +.grid-layout header .top-right-nav { + grid-column: 2; + grid-row: 1; + justify-self: end; + display: flex; + align-items: center; + justify-content: flex-end; + gap: 1rem; + font-family: Inter, Metropolis, sans-serif; +} + +body.story-view header .top-right-nav { + margin-right: 6rem; +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + .clock { + grid-row: 1; + grid-column: 2; + align-self: end; + justify-self: end; + } + + .time-controller { + justify-self: stretch; + } + + .time-controller .rate-container { + grid-template-columns: auto 85px 2px 85px auto; + grid-template-rows: 30px; + } + + .time-controller .rate-container .play-pause { + display: none; + } + + .clock-shortcut { + grid-template-rows: auto auto; + } + + .extended-controls { + border-top: 1px solid var(--grayDark); + grid-column: span 2; + padding-top: 10px; + margin-bottom: 10px; + } +} + +/* Landscape. 480x320 phones and above */ +@media only screen and (min-width: 320px) and (orientation: landscape) { + .clock-shortcut { + grid-template-rows: auto; + grid-template-columns: auto auto; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .clock { + grid-row: 2; + grid-column: 1; + align-self: auto; + justify-self: auto; + } + + .time-controller { + justify-self: auto; + } + + .time-controller .rate-container { + grid-template-columns: auto auto 90px 2px 90px auto; + grid-template-rows: 30px; + } + + .time-controller .rate-container .play-pause { + display: block; + } + + .clock-shortcut { + grid-column: span 2; + grid-template-rows: auto; + grid-template-columns: auto auto; + } + + .extended-controls { + border-top: none; + grid-row: 2; + grid-column: 2; + padding-top: 0; + margin-bottom: 0; + } +} + +/*!***********************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/grid.css ***! + \***********************************************************************************************************************************************************************************/ +/* Shared properties */ +:root { + --gridHeaderHeight: 75px; +} + +/* Timeline */ +.simple-grid .float-mid { + width: 100%; + align-self: end; + justify-self: start; +} + +/* Overlay */ +.simple-grid .overlay-container .overlay { + grid-column: auto; + grid-row: auto; +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + + /* Content panel */ + .simple-grid .content-panel { + grid-column: main-start / side-end; + grid-row: extf-start / foot-end; + } + + .simple-grid .content-panel.overlay { + grid-row: head-start / foot-end; + } + + /* Featured Stories panel */ + .simple-grid .featured-stories-panel { + grid-column: main-start / side-end; + grid-row: extf-start / foot-end; + } + + /* Header */ + .simple-grid header { + grid-area: head; + display: grid; + grid-template-columns: auto minmax(70px, -webkit-max-content); + grid-template-columns: auto minmax(70px, max-content); + justify-content: space-between; + align-items: center; + margin: 0 20px; + gap: 10px; + } + + /* Controls */ + .simple-grid .float-right-bottom { + grid-column: 11 / side-end; + grid-row: foot-start / foot-end; + align-self: end; + justify-self: start; + width: 100%; + margin-bottom: 105px; + padding-right: 20px; + position: absolute; + } + + /* Timeline */ + .simple-grid .float-mid { + grid-column: 2 / side-start; + grid-row: 3; + } + + .simple-grid .float-mid.low { + grid-row: 4; + } + + /* Time */ + .simple-grid .float-mid-bottom { + grid-area: foot; + grid-template-columns: auto -webkit-max-content; + grid-template-columns: auto max-content; + grid-template-rows: auto auto; + align-self: center; + justify-self: center; + margin: 0 20px; + width: calc(100% - 40px); + display: grid; + justify-items: start; + position: absolute; + gap: 10px 5px; + bottom: 0; + } + + /* TODO Add animations */ + .simple-grid .float-mid-bottom.hidden { + display: none; + } + + /* Compare */ + .simple-grid .compare { + display: grid; + grid-template-rows: 60px calc(var(--vh) / 2 - 60px) calc(var(--vh) / 2 - 40px) 40px; + grid-template-columns: auto; + grid-row: head-start / foot-end; + grid-column: main-start / foot-end; + } +} + +/* Landscape. 480x320 phones and above */ +@media only screen and (min-width: 320px) and (orientation: landscape) { + + /* Header */ + .simple-grid header { + margin: 0; + } + + /* Controls */ + .simple-grid .float-right-bottom { + grid-column: 9 / side-end; + grid-row: foot; + align-self: end; + justify-self: end; + display: grid; + align-items: end; + justify-content: end; + margin-bottom: 0; + padding-right: 56px; + padding-bottom: 10px; + } + + /* Timeline */ + .simple-grid .float-mid { + grid-row: main; + } + + /* Time */ + .simple-grid .float-mid-bottom { + grid-template-columns: auto -webkit-max-content; + grid-template-columns: auto max-content; + grid-template-rows: auto auto; + grid-column: main-start / side-end; + grid-row: foot-start / foot-end; + height: auto; + align-self: start; + align-items: initial; + gap: 10px 5px; + } + + /* Compare */ + .simple-grid .compare { + display: grid; + grid-template-rows: 60px auto 40px; + grid-template-columns: 50% 50%; + grid-row: head-start / foot-end; + grid-column: main-start / foot-end; + width: calc(100% + 40px); + margin-left: -20px; + } +} + +/* Portrait Tablets */ +@media only screen and (min-width: 641px) and (orientation: portrait) { + + /* Controls */ + .simple-grid .float-right-bottom { + grid-column: 9 / side-end; + grid-row: foot; + align-self: end; + justify-self: end; + display: grid; + align-items: end; + justify-content: end; + height: 51px; + margin-bottom: 0; + padding-right: 56px; + padding-bottom: 10px; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + + /* Detail panel */ + .simple-grid .detail { + grid-column: main-start / main-end; + grid-row: head-start / foot-end; + } + + /* Content panel */ + .simple-grid .content-panel { + grid-column: main-start / main-end; + grid-row: head-start / foot-end; + display: grid; + grid-template-rows: 80px -webkit-max-content auto 3%; + grid-template-rows: 80px max-content auto 3%; + grid-template-columns: 1fr; + gap: 5px; + } + + /* Featured Stories panel */ + .simple-grid .featured-stories-panel { + grid-column: main-start / main-end; + grid-row: head-start / foot-end; + display: grid; + grid-template-rows: 80px -webkit-max-content auto 3%; + grid-template-rows: 80px max-content auto 3%; + grid-template-columns: 1fr; + gap: 5px; + } + + /* Header */ + .simple-grid header { + margin: 0; + height: var(--gridHeaderHeight); + } + + /* Controls */ + .simple-grid .float-right-bottom { + grid-column: 11 / side-end; + grid-row: side-start / foot-end; + align-self: end; + justify-self: end; + margin-bottom: 25px; + align-items: end; + padding: 0; + height: 100%; + width: 100%; + } + + /* Timeline */ + .simple-grid .float-mid { + grid-column: main-end / side-start; + grid-row: extf-start; + } + + /* Time */ + .simple-grid .float-mid-bottom { + grid-template-columns: minmax(250px, 30%) 70%; + grid-template-rows: 50% 50%; + grid-column: main-end / side-start; + grid-row: foot-start / foot-end; + align-self: end; + align-items: center; + justify-items: start; + height: auto; + display: grid; + gap: 0 30px; + position: static; + margin-bottom: 25px; + } + + /* Compare */ + .simple-grid .compare { + display: grid; + grid-template-rows: 65px auto 40px; + grid-template-columns: 50% 50%; + grid-row: head-start / foot-end; + grid-column: main-start / foot-end; + } +} + +/*!************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/label.css ***! + \************************************************************************************************************************************************************************************/ +.pioneer-constellation-label { + --constellationFadeIn: 1; + --constellationFadeOut: 0.05; +} + +.pioneer-label-div { + /* Variables */ + --fontSize: 16px; + --fontSizeLarge: 18px; + --fontSizeSmall: 14px; + --fontSizeXSmall: 12px; + --fontSizeTiny: 10px; + --secondaryFadeIn: 0.35; + --secondaryFadeOut: 0.05; + --primaryFadeIn: 0.75; + --primaryFadeOut: 0.05; + + /* Properties */ + font-size: var(--fontSizeSmall); + white-space: nowrap; + color: var(--white); + padding-left: calc(16px / 2 + 6px); + padding-bottom: 10px; +} + +/* Icon */ +.pioneer-label-div .icon { + position: absolute; + top: 50%; + left: 0; + width: 16px; + height: 16px; + transform: translate(-50%, -50%); +} + +.pioneer-label-div.spacecraft .icon { + width: 14px; +} + +.pioneer-label-div .icon.no-icon { + display: none; +} + +.pioneer-label-div.sun .icon, +.pioneer-label-div.planet .icon { + width: 20px; + height: 20px; +} + +/* Padding adjustments */ +.pioneer-label-div.spacecraft { + padding-left: calc(14px / 2 + 6px); +} + +.pioneer-label-div.planet { + padding-left: calc(20px / 2 + 8px); + padding-bottom: 14px; + letter-spacing: 0.3em; +} + +.pioneer-label-div.sun { + padding-left: calc(20px / 2 + 10px); + padding-bottom: 0; + padding-top: 14px; + letter-spacing: 0.3em; + font-size: var(--fontSize); +} + +/* Text */ +.pioneer-label-div.planet .text { + text-transform: uppercase; + font-weight: 600; +} + +.pioneer-label-div.sun .text { + text-transform: uppercase; + font-weight: 600; +} + +/* Constellations */ +.pioneer-constellation-label .text { + text-transform: uppercase; + color: var(--constellation); + letter-spacing: 0.5em; + font-size: 20px; + font-family: "DMMono", monospace; + font-weight: 300; + text-shadow: 0 0 7px var(--constellationGlowMed), + 0 0 10px var(--constellationGlowDark); + filter: brightness(0.5); +} + +.pioneer-constellation-label .icon { + display: none; +} + +.pioneer-constellation-label.active { + pointer-events: all; +} + +.pioneer-constellation-label.hidden { + pointer-events: none; + display: initial; +} + +.pioneer-constellation-label.active .text { + transition: opacity 0.25s, transform 0.25s ease-in-out; + opacity: var(--constellationFadeIn); +} + +.pioneer-constellation-label.hidden .text { + transition: opacity 0.75s, transform 0.75s ease-in-out; + opacity: var(--constellationFadeOut); +} + + +/* Primary and secondary fade in/out */ +.pioneer-label-div.active { + pointer-events: all; +} + +.pioneer-label-div.unclickable { + pointer-events: none; +} + +.pioneer-label-div.hidden { + pointer-events: none; + display: initial; +} + +.pioneer-label-div.active .icon, +.pioneer-label-div.active .text { + transition: opacity 0.25s, transform 0.25s ease-in-out; + opacity: var(--secondaryFadeIn); +} + +.pioneer-label-div.hidden .icon, +.pioneer-label-div.hidden .text { + transition: opacity 0.75s, transform 0.75s ease-in-out; + opacity: var(--secondaryFadeOut); +} + +.pioneer-label-div.sun.active .icon, +.pioneer-label-div.planet.active .icon, +.pioneer-label-div.sun.active .text, +.pioneer-label-div.planet.active .text { + opacity: var(--primaryFadeIn); +} + +.pioneer-label-div.sun.hidden .icon, +.pioneer-label-div.planet.hidden .icon, +.pioneer-label-div.sun.hidden .text, +.pioneer-label-div.planet.hidden .text { + opacity: var(--primaryFadeOut); +} + +.ring-label { + background: var(--grayDark); + padding: 0 4px; + border-radius: 5px; + pointer-events: none; +} + +.ring-label .icon { + display: none; +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .pioneer-label-div { + font-size: var(--fontSize); + } + + .pioneer-label-div.sun { + font-size: var(--fontSizeLarge); + } +} + +/*!************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/style.css ***! + \************************************************************************************************************************************************************************************/ +/* Generic */ +* { + box-sizing: border-box; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: transparent; +} + +input, +textarea { + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + font: inherit; +} + +html, +body { + height: 100%; + overflow: hidden; + position: relative; + -webkit-text-size-adjust: none; + -moz-text-size-adjust: none; + text-size-adjust: none; +} + +html { + height: var(--vh); +} + +body { + font-size: 16px; + line-height: 150%; + letter-spacing: 0; + font-family: Metropolis, sans-serif; + font-weight: 300; + color: var(--white); +} + +body .semi { + letter-spacing: 0.02em; +} + +/* Visibility */ +.hidden { + display: none; +} + +.invisible { + visibility: hidden; +} + +/* Interactions */ +.editable { + pointer-events: all; + cursor: text; +} + +.clickable { + pointer-events: all; + cursor: pointer; +} + +.clickable.underline { + position: relative; + color: var(--white); + opacity: 0.75; + text-decoration: underline; + cursor: pointer; + transition: opacity 0.25s ease-in-out; +} + +/* Font properties */ +.wide-text { + letter-spacing: 0.6em; +} + +.semi { + font-weight: 600; +} + +.small { + font-size: 14px; + line-height: 150%; + letter-spacing: 0; + font-family: Metropolis, sans-serif; +} + +.x-small { + font-size: 12px; + line-height: 180%; + letter-spacing: 0.03em; + font-family: Metropolis, sans-serif; +} + +.tiny { + font-size: 11px; + line-height: 180%; + letter-spacing: 0.03em; + font-family: Metropolis, sans-serif; +} + +.uppercase { + text-transform: uppercase; +} + +.capitalize { + text-transform: capitalize; +} + +/* Lines */ +.vertical-line { + border: 1px solid #ffffff; + box-sizing: border-box; + width: 2px; + height: 20px; +} + +/* Headers */ +.display, +h1, +h2, +h3, +h4, +h5 { + color: var(--white); + font-family: Metropolis, sans-serif; + letter-spacing: -0.02em; + margin: 0; +} + +.display.semi, +h1.semi, +h2.semi, +h3.semi, +h4.semi, +h5.semi { + letter-spacing: -0.02em; +} + +.display { + font-size: 48px; + line-height: 120%; + font-weight: 100; +} + +h1 { + font-size: 41px; + line-height: 120%; + font-weight: 100; +} + +h2 { + font-size: 36px; + line-height: 120%; + font-weight: 100; +} + +h3 { + font-size: 29px; + line-height: 95%; + font-weight: 300; +} + +h3.semi { + line-height: 100%; +} + +h4 { + font-size: 22px; + line-height: 120%; + font-weight: 300; +} + +h5 { + font-size: 18px; + line-height: 180%; + font-weight: 300; +} + +h5.semi { + line-height: 150%; +} + +/* Buttons */ +button { + background-color: transparent; + border: 0; +} + +/* Support line break in text */ +.line-break-text { + white-space: pre-line; +} + +/* Alert outline */ +.alert { + outline: none; + outline-offset: 4px; + -webkit-animation-name: blink; + animation-name: blink; + -webkit-animation-duration: 0.5s; + animation-duration: 0.5s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-iteration-count: 3; + animation-iteration-count: 3; + -webkit-animation-direction: alternate; + animation-direction: alternate; +} + +/* Checkbox style using custom color */ +.checkbox { + background-color: var(--grayDark); + border-radius: 3px; + width: 15px; + height: 15px; +} + +/* Tooltip */ +.tippy-box[data-theme~="default"] { + background-color: var(--grayDark); + border-color: var(--grayDark); + color: var(--grayLight); + opacity: 0.9; +} + +.tippy-box[data-theme~="default"][data-placement^="top"]>.tippy-arrow::before { + border-top-color: var(--grayDark); +} + +.tippy-box[data-theme~="default"][data-placement^="bottom"]>.tippy-arrow::before { + border-bottom-color: var(--grayDark); +} + +.tippy-box[data-theme~="default"][data-placement^="left"]>.tippy-arrow::before { + border-left-color: var(--grayDark); +} + +.tippy-box[data-theme~="default"][data-placement^="right"]>.tippy-arrow::before { + border-right-color: var(--grayDark); +} + +/*!****************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/scrollbar.css ***! + \****************************************************************************************************************************************************************************************/ +/* Scrollbar CSS override */ +.os-theme-dark>.os-scrollbar, +.os-scrollbar-vertical, +.os-host-resize-disabled.os-host-scrollbar-horizontal-hidden>.os-scrollbar-vertical { + right: 6px; + top: 0; + bottom: 0; +} + +.os-theme-dark>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle { + background: var(--grayDark); + width: 4px; +} + +.os-theme-dark>.os-scrollbar:active>.os-scrollbar-track>.os-scrollbar-handle { + background: var(--gray); + width: 6px; +} + +.os-theme-dark>.os-scrollbar-vertical>.os-scrollbar-track>.os-scrollbar-handle { + min-height: 20px; +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .os-theme-dark>.os-scrollbar { + display: block; + } +} + +@media (pointer: coarse) { + .os-theme-dark>.os-scrollbar { + display: none; + } +} + +/*!*****************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/src/assets/css/components.css ***! + \*****************************************************************************************************************************************************************************************/ +/* TOGGLE SWITCH */ +/* +
+ + +
+*/ +.eyes-toggle { + position: relative; + height: 26px; +} + +.eyes-toggle input[type="checkbox"] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + cursor: pointer; +} + +.eyes-toggle input[type="checkbox"]:focus { + outline: 0; +} + +.eyes-toggle input { + height: 26px; + width: 40px; + border-radius: 16px; + display: inline-block; + position: relative; + margin: 0; + border: 1px solid #827a7a; + background: linear-gradient(180deg, #2d2f39 0%, #1f2027 100%); + transition: all 0.2s ease; +} + +.eyes-toggle input::after { + content: ""; + position: absolute; + top: 2px; + left: 2px; + width: 20px; + height: 20px; + border-radius: 50%; + background: #827a7a; + box-shadow: 0 1px 2px rgba(44, 44, 44, 0.2); + transition: all 0.2s cubic-bezier(0.5, 0.1, 0.75, 1.35); +} + +.eyes-toggle input:checked { + border-color: #b6acac; +} + +.eyes-toggle input:checked::after { + transform: translateX(15px); + background: #b6acac; +} + +.eyes-toggle label { + cursor: pointer; + width: 26px; + height: 26px; + position: absolute; + left: 0; + top: 0; + transition: all 0.2s ease; +} + +.eyes-toggle label::after { + border: 2px solid #252527; + border-top: none; + border-right: none; + content: ""; + width: 6px; + height: 3px; + position: absolute; + left: 10px; + top: 10px; + opacity: 0; + transform: rotate(-45deg); + transition: all 0.2s ease; +} + +.eyes-toggle input[type="checkbox"]:checked+label { + border-color: #b6acac; + left: 14px; +} + +.eyes-toggle input[type="checkbox"]:checked+label::after { + opacity: 1; +} + +/* END TOGGLE SWITCH */ + +/* CHECKBOX */ +/* +
+ + +
+*/ +.eyes-checkbox { + position: relative; + width: 22px; + height: 22px; +} + +.eyes-checkbox label { + background-color: #252527; + border: 1px solid #b6acac; + cursor: pointer; + width: 22px; + height: 22px; + position: absolute; + left: 0; + top: 0; + border-radius: 3px; + transition: all 0.2s ease; +} + + +.eyes-checkbox label::after { + border: 2px solid #252527; + border-top: none; + border-right: none; + content: ""; + width: 9px; + height: 4px; + position: absolute; + left: 5px; + top: 6px; + opacity: 0; + transform: rotate(-45deg); + transition: all 0.2s ease; +} + +.eyes-checkbox input[type="checkbox"] { + visibility: hidden; +} + +.eyes-checkbox input[type="checkbox"]:checked+label { + background-color: #b6acac; + border-color: #b6acac; +} + +.eyes-checkbox input[type="checkbox"]:checked+label::after { + opacity: 1; +} + +/* END CHECKBOX */ + +/*!*****************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/assets/css/font.css ***! + \*****************************************************************************************************************************************************************************/ +/* Mamam */ +@font-face { + font-family: "Mamam"; + font-style: normal; + src: url("./assets/fonts/Mamam.woff"); +} + +/*!*********************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/assets/css/viewport.css ***! + \*********************************************************************************************************************************************************************************/ +/* Viewport offsets */ + +/* Offset vars */ +:root { + --offset-right-sm: 150px; + --offset-right-lg: 200px; + --offset-up: 22vh; +} + +/* Pioneer pseudo element fading gradients */ +#pioneer::after { + content: ""; + position: absolute; + inset: 0; + opacity: 0; + background-image: linear-gradient(to right, + black var(--offset-right-sm), + transparent calc(var(--offset-right-sm) + 20vw)); + transition: opacity 2s var(--ease-out-bezier); + pointer-events: none; +} + +#pioneer.offset-right::after { + opacity: 1; + transition: opacity 0.8s var(--ease-out-bezier); +} + +#pioneer.offset-up::after { + opacity: 1; + transition: opacity 0.8s var(--ease-out-bezier); +} + +/* Main Viewport offsets */ +/* stylelint-disable declaration-no-important */ +#main-viewport { + transition-property: left, bottom; + transition-duration: 0.5s; + transition-timing-function: var(--ease-out-bezier); + bottom: 0; + left: 0; +} + +#main-viewport.offset-right { + left: var(--offset-right-sm); + transition-duration: 0.8s; + transition-delay: 0.3s; +} + +#main-viewport.offset-up { + bottom: var(--offset-up); + transition-duration: 0.8s; + transition-delay: 0.3s; +} + +/* Over 961 wide */ +@media only screen and (min-width: 961px) { + #pioneer.offset-right::after { + background-image: linear-gradient(to right, + black var(--offset-right-lg), + transparent calc(var(--offset-right-lg) + 20vw)); + } + + #main-viewport.offset-right { + left: var(--offset-right-lg); + } +} + +/* Portrait mobile */ +@media only screen and (max-width: 641px) and (orientation: portrait) { + #pioneer::after { + background-image: linear-gradient(to top, + black var(--offset-up), + transparent calc(var(--offset-up) + 25vh)); + } +} + +/*!******************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/assets/css/color.css ***! + \******************************************************************************************************************************************************************************/ +:root { + /* Primary */ + --grayBackground: #19191a; + + /* Grayblue variations */ + --grayblueDarkAlpha: #0b1113bb; + + /* Secondary */ + --sunAsteroids: #e7e764; + --spacecraftAsteroids: #e4e385; + + /* Gradients */ + --bgGradient: linear-gradient(to bottom, + rgba(17, 17, 19, 0.95) 10%, + rgba(17, 17, 19, 0.75) 100%); +} + +/*!*********************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/assets/css/asteroid.css ***! + \*********************************************************************************************************************************************************************************/ +h1, +h2, +h3, +h4, +h5 { + color: var(--grayblueWhite); +} + +.hidden a { + pointer-events: none; +} + +button { + font-size: inherit; + line-height: 150%; + font-family: "Metropolis", sans-serif; + font-weight: 300; + letter-spacing: 0.02em; + color: var(--grayblueWhite); +} + +.description { + color: var(--grayblueMed); + filter: brightness(1.2); +} + +.carousel .content-block a { + color: var(--grayblueLight); +} + +/* DEEPDIVE */ +/* +
Deep Dive into Asteroids 101
" +*/ +.eyes-deepdive { + display: inline-block; + min-height: 37px; + border-radius: 50px; + text-align: center; + padding: 8px 16px 8px 12px; + margin-bottom: 8px; + font-weight: 600; + line-height: 21px; + color: var(--grayDark); + background: var(--grayMed); + cursor: pointer; + transition: background 0.2s ease-out; +} + + +.eyes-deepdive::before { + content: ""; + display: inline-block; + vertical-align: middle; + width: 20px; + height: 20px; + margin-right: 6px; + margin-top: -3px; + color: var(--grayDark); + background: url(./assets/svg/circuit_brain.svg); + background-size: cover; +} + +@media only screen and (max-width: 440px) { + .eyes-deepdive { + font-size: 13px; + } +} + +/* END DEEPDIVE */ + +/*!******************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/assets/css/label.css ***! + \******************************************************************************************************************************************************************************/ +/* Asteroids-specific label CSS */ + +.pioneer-label-div { + filter: brightness(1); + transition: filter 3s 1s ease-in-out, opacity 0.1s var(--ease-out-bezier); +} + +/* ------------------------------- Asteroid Watch ------------------------------- */ + +.pioneer-label-div.asteroid-watch-label { + padding-left: 2rem; +} + +.pioneer-label-div.asteroid-watch-label.hidden { + pointer-events: auto; + display: block; + + /* Increased transparency label collisions as we always want to see all 5 */ + /* stylelint-disable-next-line declaration-no-important */ + opacity: var(--secondaryFadeIn) !important; +} + +.pioneer-label-div.asteroid-watch-label span.asteroid-watch-text { + opacity: 1; + filter: brightness(0.8); + color: var(--grayblueLight); +} + +.pioneer-label-div.asteroid-watch-label.selected span.asteroid-watch-text { + opacity: 1; + filter: brightness(1); + transform: translateX(-0.25rem); + transition: filter 0.4s var(--ease-out-bezier), + transform 0.4s var(--ease-out-bezier); +} + +.pioneer-label-div.asteroid-watch-label span.asteroid-watch-icon, +.pioneer-label-div.asteroid-watch-label.hidden span.asteroid-watch-icon { + opacity: 1; + filter: brightness(0.8); + transform: translate(-50%, -50%) scale(1.2); +} + +.pioneer-label-div.asteroid-watch-label.selected span.asteroid-watch-icon { + opacity: 1; + filter: brightness(1); + transform: translate(-50%, -50%) scale(1.5); +} + +/* Background label dimming */ +.pioneer-label-div.watch-dim { + filter: brightness(0.25); +} + +.pioneer-label-div.asteroid-watch-label .icon { + display: unset; +} + +.pioneer-label-div.asteroid-watch-label .icon.hidden { + display: none; +} + +/* ------------------------------- Overview labels ------------------------------- */ + +/* Comet label needs a little more left padding due to offset icon */ +.pioneer-label-div.comet { + padding-left: 1.7rem; +} + +.pioneer-label-div.spacecraft .icon { + width: 0.6rem; +} + +/* Spacecraft label can go slightly closer */ +.pioneer-label-div.spacecraft { + padding-left: 0.75rem; +} + +/* Planet, sun and moon text can go a bit closer */ +.pioneer-label-div.planet, +.pioneer-label-div.sun, +.pioneer-label-div.moon { + padding-left: 0.8rem; +} + +.pioneer-label-div.planet .icon, +.pioneer-label-div.moon .icon { + background-image: none; + width: 0.5rem; + height: 0.5rem; + border-radius: 0.25rem; + opacity: 1; + filter: brightness(0.85); + transition-property: transform, filter; +} + +/* Make comet and asteroid icons slightly smaller */ +.pioneer-label-div .icon.asteroid { + width: 1.1rem; + height: 1.1rem; +} + +.pioneer-label-div .icon.comet { + width: 1.4rem; + height: 1.4rem; +} + +.pioneer-label-div .text { + text-shadow: 0 0 0.25rem black, 0 0 0.3rem black; + display: block; + transition: filter 0.4s, transform 0.4s var(--ease-out-bezier); +} + +.pioneer-label-div .text.hidden { + display: none; +} + +/* Adjust text default opacity, weight and size range */ +.pioneer-label-div.comet .text, +.pioneer-label-div.asteroid .text, +.pioneer-label-div.spacecraft .text, +.pioneer-label-div.dwarf-planet .text, +.pioneer-label-div.moon .text, +.pioneer-label-div.sun .text, +.pioneer-label-div.planet .text { + opacity: 1; + filter: brightness(0.8); + font-weight: 400; + font-size: clamp(var(--fontSizeSmall), 1.4vw, var(--fontSize)); + letter-spacing: 0.02em; +} + +/* Adjust caps text spacing and size */ +.pioneer-label-div.moon .text, +.pioneer-label-div.sun .text, +.pioneer-label-div.planet .text { + letter-spacing: 0.1em; + font-weight: 600; + font-size: clamp(var(--fontSizeTiny), 1.2vw, var(--fontSizeXSmall)); +} + +/* Adjust text colors */ +.pioneer-label-div.sun .text { + color: var(--sunAsteroids); +} + +.pioneer-label-div.moon .text { + text-transform: uppercase; + color: var(--moon); +} + +.pioneer-label-div.spacecraft .text { + color: var(--spacecraftAsteroids); + filter: brightness(0.7); +} + +.pioneer-label-div.comet .text, +.pioneer-label-div.asteroid .text, +.pioneer-label-div.dwarf-planet .text { + color: var(--grayblueLight); +} + +.pioneer-label-div.sun, +.pioneer-label-div.planet { + letter-spacing: unset; +} + +/* Planets */ +.pioneer-label-div.mercury { + color: var(--mercury); +} + +.pioneer-label-div.venus { + color: var(--venus); +} + +.pioneer-label-div.earth { + color: var(--earth); +} + +.pioneer-label-div.mars { + color: var(--mars); +} + +.pioneer-label-div.jupiter { + color: var(--jupiter); +} + +.pioneer-label-div.saturn { + color: var(--saturn); +} + +.pioneer-label-div.uranus { + color: var(--uranus); +} + +.pioneer-label-div.neptune { + color: var(--neptune); +} + +/* Make sure all icons have opacity 1 but reduced brightness */ +.pioneer-label-div.active .icon { + opacity: 1; + filter: brightness(0.7); + transition: filter 0.25s, transform 0.25s ease-in-out; +} + +/*!*****************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/assets/css/grid.css ***! + \*****************************************************************************************************************************************************************************/ +/* Adding a minmax removes minWidth for grid items and prevents them from expanding the whole grid */ +.simple-grid { + grid-template-columns: repeat(12, minmax(0, 1fr)); + grid-template-rows: minmax(4.5rem, -webkit-max-content) repeat(4, + minmax(0, 1fr)); + grid-template-rows: minmax(4.5rem, max-content) repeat(4, minmax(0, 1fr)); +} + +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + + /* Header */ + .grid-layout header.header { + display: flex; + height: unset; + justify-content: space-between; + gap: 0; + } + + /* Controls */ + .grid-layout .float-right-bottom { + grid-row: side; + height: unset; + margin-bottom: 50px; + padding-bottom: 0; + } + + /* Time */ + .grid-layout .float-mid-bottom { + grid-template-columns: unset; + grid-template-rows: 50% 50%; + margin: 0; + width: 100%; + justify-items: stretch; + bottom: 0; + } +} + +/* Landscape. 480x320 phones and above */ +@media only screen and (min-width: 320px) and (orientation: landscape) { + + /* Controls */ + .grid-layout .float-right-bottom { + grid-row: side; + height: unset; + margin-bottom: 20px; + padding-bottom: 0; + padding-right: 0; + } + + /* Mid-bottom float */ + /* .asteroid-view .grid-layout .float-mid-bottom { + bottom: 32px; + } */ +} + +/* Landscape Tablets */ +@media only screen and (min-width: 1025px) and (orientation: landscape) { + .asteroid-view .grid-layout .float-mid-bottom { + bottom: 0; + } +} + +/* Portrait Tablets */ +@media only screen and (min-width: 641px) and (orientation: portrait) { + + /* Controls */ + .grid-layout .float-right-bottom { + grid-row: side; + height: unset; + margin-bottom: 0; + padding-bottom: 0; + padding-right: 0; + } +} + +@media only screen and (min-width: 641px) { + .grid-layout header.header { + justify-content: flex-start; + margin: 0; + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + + /* Time */ + .grid-layout .float-mid-bottom { + grid-area: foot; + grid-template-rows: unset; + height: 100%; + align-items: start; + } +} + +@media only screen and (max-height: 600px) { + + /* Main grid */ + .simple-grid { + grid-template-rows: minmax(12vh, -webkit-max-content) repeat(4, + minmax(0, 1fr)); + grid-template-rows: minmax(12vh, max-content) repeat(4, minmax(0, 1fr)); + } + + .grid-layout .float-mid-bottom { + gap: 0; + } + + .grid-layout header.header { + margin: 0.25rem 0 0; + } +} + +/*!*****************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/assets/css/icon.css ***! + \*****************************************************************************************************************************************************************************/ + +.os-scrollbar-handle:active { + cursor: -webkit-grabbing; + cursor: grabbing; +} + +.icon.asteroid { + width: 24px; + height: 24px; + background-image: url(./assets/svg/asteroid.svg); + background-size: cover; +} + +.icon.asteroid-watch-icon { + background-image: url(./assets/svg/asteroid.svg); + background-position: center; + background-size: cover; +} + +.icon.comet { + width: 28px; + height: 28px; + background-image: url(./assets/svg/comet.svg); + background-size: cover; + transform: translate(-25%, -75%); +} + +.icon-large.comet { + width: 32px; + height: 32px; + transform: none; +} + +.icon.spacecraft { + width: 10px; + height: 10px; + background-image: url(./assets/svg/spacecraft.svg); + background-size: cover; +} + +.icon-large.spacecraft { + width: 18px; + height: 18px; +} + +.icon.circle-arrow { + width: 44px; + height: 44px; + background-image: url(./assets/svg/mobile_arrow.svg); + background-size: cover; +} + +.icon.prev-arrow { + width: 23px; + height: 15px; + background-image: url(./assets/svg/arrow_prev.svg); + background-size: cover; +} + +.icon.next-arrow { + width: 23px; + height: 15px; + background-image: url(./assets/svg/arrow_next.svg); + background-size: cover; +} + +.icon.rock { + width: 80px; + height: 80px; + background-image: url(./assets/svg/rock.svg); + background-size: cover; +} + +.icon.ruler { + width: 83px; + height: 11px; + background-image: url(./assets/svg/ruler.svg); + background-size: cover; +} + +/* Individual planet/moon dots */ +.icon-circle-mercury { + background-color: var(--mercury); +} + +.icon-circle-venus { + background-color: var(--venus); +} + +.icon-circle-earth { + background-color: var(--earth); +} + +.icon-circle-mars { + background-color: var(--mars); +} + +.icon-circle-jupiter { + background-color: var(--jupiter); +} + +.icon-circle-saturn { + background-color: var(--saturn); +} + +.icon-circle-uranus { + background-color: var(--uranus); +} + +.icon-circle-neptune { + background-color: var(--neptune); +} + +.pioneer-label-div.moon .icon { + background-color: var(--moon); +} + +/* Story close icon */ +.carousel-container .icon-close { + margin: min(14px, 2.6vw) 0; + transform: scale(1.2); +} + +/*!*******************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/assets/css/search.css ***! + \*******************************************************************************************************************************************************************************/ +.featured .os-padding { + -webkit-mask-image: linear-gradient(to bottom, + transparent 30px, + white 32px, + white 70%, + transparent 90%); + mask-image: linear-gradient(to bottom, + transparent 30px, + white 32px, + white 70%, + transparent 90%); + -webkit-mask-image: linear-gradient(to bottom, + transparent 24px, + white 36px, + white 70%, + transparent 90%); + mask-image: linear-gradient(to bottom, + transparent 24px, + white 36px, + white 70%, + transparent 90%); +} + +.results .os-padding { + -webkit-mask-image: linear-gradient(to bottom, + transparent 0, + white 12px, + white 80%, + transparent 100%); + mask-image: linear-gradient(to bottom, + transparent 0, + white 12px, + white 80%, + transparent 100%); +} + +#search .os-scrollbar-vertical { + right: 18px; + top: 40px; + bottom: 40px; +} + +.search { + padding-left: 3vw; + z-index: 2; + order: 3; +} + +.search>div { + position: absolute; + left: 1rem; + top: 0.7rem; + right: 2rem; +} + +.search .bar { + position: relative; + display: grid; + transform-origin: right; + width: calc(100% + 16px); + padding: 0; + background-color: var(--grayblueBackground); +} + +.search input[type="text"] { + font-weight: 100; + font-size: 14px; + color: var(--grayblueWhite); +} + +.search input[type="text"]::-moz-placeholder { + color: var(--grayblueText); +} + +.search input[type="text"]:-ms-input-placeholder { + color: var(--grayblueText); +} + +.search input[type="text"]::placeholder { + color: var(--grayblueText); +} + +/* .search input[type="text"]:focus { + outline: 3px solid #555555; +} */ + +.search-close input[type="text"] { + opacity: 0; +} + +.search-open input[type="text"] { + opacity: 1; + transition: opacity 1s 0.3s var(--ease-out-bezier); +} + +.search .mag-open, +.search .mag-close { + position: relative; + margin: 0 0 0 auto; + z-index: 102; + display: block; +} + +.icon-search { + transform: scale(1.1); + opacity: 0.75; + transition: opacity 0.2s 0.1s ease-out, transform 0.2s 0.1s ease-out; +} + +.bar .icon-search { + opacity: 0; +} + +.search .search-open { + display: unset; + z-index: 1; +} + +.search .cover { + width: unset; + height: unset; + inset: 0; +} + +.search span.search-info { + color: var(--grayblueDivider); +} + +.search-close span.search-info { + transition-duration: 0s; +} + +.search .suggestion label { + color: var(--grayblueMed); +} + +.search-close .bar { + width: 0; + border-radius: 12px; + opacity: 0; + transform: scaleX(0); + transition: transform 0.5s 0.1s var(--ease-out-bezier), + opacity 0.5s 0.1s var(--ease-out-bezier); +} + +.search-open .bar { + border-radius: 12px 12px 0 0; + opacity: 1; + padding: 0.5rem; + transform: scaleX(1); + transition: transform 0.4s var(--ease-out-bezier), border-radius 0.2s ease-out; +} + +.search-open .featured { + background: linear-gradient(to bottom, + var(--grayblueBackground) 64%, + var(--grayblueDarkAlpha)); + border-top: 1px solid var(--grayblueDivider); +} + +.search .featured li { + color: var(--grayblueMed); + background-image: radial-gradient(at 10%, + var(--grayblueDivider) 0%, + transparent 110%); +} + +.search .results { + border-top: 1px solid var(--grayblueDivider); + border-radius: 0 0 12px 12px; + padding: 24px 0 48px; + height: 300px; + background: linear-gradient(to bottom, + var(--grayblueBackground) 64%, + var(--grayblueDarkAlpha)); +} + +.search .result-div { + margin: 9px 40px 9px 16px; + padding: 8px 16px; + border-radius: 6px; + background-image: radial-gradient(at 10%, + var(--grayblueDivider) 0%, + transparent 110%); + background-repeat: no-repeat; + background-position: center; + background-size: 0% 0%; + color: var(--grayblueMed); +} + +.search .result-div.active { + background-color: transparent; + background-size: 100% 100%; + transition: background-size 0.15s ease-out; + color: var(--grayblueWhite); +} + +.search .featured li.active { + color: var(--grayblueWhite); +} + +.search .results .entries { + padding: 1.5px 0; + font-size: 14px; + color: inherit; +} + +.search .suggestion { + margin-left: 20px; +} + +@media only screen and (min-width: 641px) { + .search>div { + left: unset; + } +} + +@media only screen and (min-width: 961px) { + .search { + padding-left: 5vw; + } +} + + +/*!*********************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/assets/css/settings.css ***! + \*********************************************************************************************************************************************************************************/ +/* 480x320 phones and above */ +@media only screen and (min-width: 320px) { + + .settings.active, + .settings .container.active { + transition-duration: 0.6s; + transition-timing-function: var(--ease-out-bezier); + } + + .settings.hidden, + .settings .container.hidden { + transition-duration: 0.3s; + transition-timing-function: ease-in; + } +} + +/*!******************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/assets/css/clock.css ***! + \******************************************************************************************************************************************************************************/ + +.time-container .clock .time, +.time-container .clock .meridiem { + align-self: center; + height: 100%; +} + +/*!**********************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/navigation/navigation.css ***! + \**********************************************************************************************************************************************************************************************/ +.navigation.menu-div.bottom { + grid-column-start: 1; + grid-row-start: 2; + grid-auto-flow: column; + display: grid; + -moz-column-gap: 15px; + column-gap: 15px; + align-content: center; + padding: 14px 0 24px; + border-top: 1px solid var(--grayDark); + background: linear-gradient(180deg, + var(--grayblueBackground) 0.7%, + #000000 100%); + transform: translateY(0); + opacity: 1; + transition: 0.6s var(--ease-out-bezier); + transition-property: transform, opacity; +} + +.navigation.menu-div.bottom.hidden { + transform: translateY(100%); + opacity: 0; + transition-duration: 0.3s; +} + +.navigation.menu-div.bottom button { + cursor: pointer; +} + +.navigation.menu-div.bottom button h2 { + cursor: pointer; + font-size: 12px; + line-height: 1.5; + font-weight: 600; + letter-spacing: 0.02em; + color: var(--grayblueLight); +} + +.navigation.menu-div.bottom>div { + padding: 0; + display: block; + text-align: center; + position: relative; + opacity: 1; +} + +.navigation.menu-div.bottom img { + display: block; + opacity: 1; + margin: 0 auto; + transform: translate(0, 0); + width: 22px; + height: 22px; + filter: brightness(1.2); +} + +.navigation.menu-div.top { + z-index: 1; + display: none; + position: relative; + margin-left: auto; + order: 2; +} + +.navigation.menu-div.top::before { + content: ""; + position: absolute; + inset: -100% -40%; + background-image: radial-gradient(rgb(0 0 0 / 70%) 0%, transparent 70%); +} + +.navigation.menu-div.top button { + cursor: pointer; +} + +.navigation.menu-div.top>div { + position: relative; + opacity: 0.8; + transition-duration: 0.2s; + transition-timing-function: var(--ease-out-bezier); + transition-property: opacity, transform; +} + +.navigation>div .navigation-badge { + opacity: 0; +} + +.navigation.menu-div.top>div.badged, +.navigation.menu-div.top>div.active { + transform: translateX(8px); + transition-duration: 0.5s; +} + +.navigation>div.badged .navigation-badge { + position: absolute; + top: 0; + left: calc(50% + 7px); + width: 6px; + height: 6px; + background: #f93f2e; + border-radius: 50%; + opacity: 1; + transition: opacity 0.3s 0.2s ease-out; +} + +@media only screen and (min-width: 641px) { + .navigation.menu-div.top { + display: grid; + grid-auto-flow: column; + gap: 0; + position: relative; + transform: translateY(0); + opacity: 1; + transition: 0.6s var(--ease-out-bezier); + transition-property: transform, opacity; + } + + .navigation.menu-div.top.hidden { + transform: translateY(-100%); + opacity: 0; + transition-duration: 0.3s; + } + + .navigation.menu-div.top>div { + white-space: nowrap; + padding: 0 0.7vw; + display: flex; + position: relative; + } + + .navigation.menu-div.top>div.badged img, + .navigation.menu-div.top>div.active img { + opacity: 1; + filter: brightness(1.3); + transform: translate(0, 0) scale(0.8); + } + + .navigation>div.badged .navigation-badge { + left: 24px; + top: 2px; + } + + .navigation.menu-div.top>div img, + .navigation.menu-div.top>div button { + transition: all 300ms; + } + + .navigation.menu-div.top>div button h2 { + font-size: 14px; + font-weight: 600; + letter-spacing: 0.02em; + } + + .navigation.menu-div.top>div img { + opacity: 0; + margin-right: 3px; + transform: translate(-10px, 0) scale(0.88); + } + + .navigation.menu-div.bottom { + display: none; + } +} + +@media only screen and (min-width: 961px) { + + /* .navigation.menu-div.top { + padding-right: 80px; + } */ + .navigation.menu-div.top>div { + white-space: nowrap; + padding: 0 20px; + display: flex; + } + + .navigation.menu-div.top>div.badged img, + .navigation.menu-div.top>div.active img { + opacity: 1; + transform: translate(0, 0) scale(0.9); + } + + .navigation>div.badged .navigation-badge { + left: 39px; + top: 2px; + } + + .navigation.menu-div.top>div button h2 { + font-size: 16px; + } + + .navigation.menu-div.top>div img { + margin-right: 10px; + transform: translate(-15px, 0) scale(0.9); + } +} + +/* Landscape mobile */ +@media only screen and (max-width: 641px) and (orientation: landscape) { + .navigation.menu-div.bottom { + width: calc(100% + 40px); + left: -20px; + position: relative; + } +} + + +/*!***************************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/asteroid_modals/modals/filters_modal/filters_modal.css ***! + \***************************************************************************************************************************************************************************************************************************/ +.filters-modal .filters-modal-description { + padding: 2px 36px 18px 36px; + font-weight: 200; + font-size: 16px; + letter-spacing: 1px; + color: var(--grayblueMed); + text-align: center; +} + +.filters-modal .filters-modal-body { + padding: 28px; + border-top: 1px solid var(--grayblueDivider); + border-bottom: 1px solid var(--grayblueDivider); +} + +.filters-section { + margin-bottom: 30px; +} + +.filters-section:last-child { + margin-bottom: 0; +} + +.filters-section-item { + display: flex; + justify-content: space-between; +} + +.filters-section-item>div:last-child { + margin: 12px 0 auto 0; +} + +.filters-modal .filters-section-item .eyes-checkbox { + margin: auto 48px auto 0; +} + +.filters-modal .filters-section-item .eyes-toggle { + margin: auto 38px auto 0; +} + +.filters-section-h { + font-size: 14px; + color: var(--grayblueLight); + font-weight: 600; + line-height: 21px; + padding: 0 2px; + margin-bottom: 12px; + letter-spacing: 1px; +} + +.filters-section-h2 { + font-size: 18px; + font-weight: 400; + line-height: 26px; + letter-spacing: 1px; + color: var(--grayblueLight); +} + +.filters-section-h2>div:first-child { + display: flex; + height: 28px; + line-height: 28px; +} + +.filters-section-h2>div:last-child { + font-size: 14px; + line-height: 21px; + color: #95959d; +} + +.filters-help { + padding: 4px; + margin-left: 16px; + color: var(--grayblueMed); + transition: color 0.2s ease-in; + cursor: pointer; +} + +.filters-help * { + pointer-events: none; +} + +.filters-section-content { + margin-left: 46px; +} + +.filters-modal .filters-modal-footer { + display: flex; + justify-content: space-between; + padding: 16px 18px 16px 18px; + white-space: nowrap; +} + +.filters-modal-reset { + cursor: pointer; + text-decoration: underline; + padding: 6px 12px 10px 12px; + font-size: 17px; + font-weight: 200; + letter-spacing: 0.5px; + height: 37px; + color: var(--grayblueMed); + transition: color 0.2s ease-in; +} + +.filters-modal-count { + height: 37px; + padding: 8px 12px 8px 12px; + color: var(--grayblueText); + font-size: 16px; + font-weight: 600; + letter-spacing: 0.5px; +} + +@media only screen and (max-width: 641px) { + + .filters-modal .filters-section-item .eyes-checkbox, + .filters-modal .filters-section-item .eyes-toggle { + margin: auto 0; + } + + .filters-section-content { + margin-left: 20px; + } +} + +@media only screen and (max-width: 350px) { + .filters-modal-description { + display: none; + } + + .filters-modal-reset { + font-size: 12px; + color: var(--white); + } + + .filters-modal-count { + font-size: 12px; + } + + .filters-modal .filters-modal-body { + padding: 18px; + } +} + +@media only screen and (max-height: 590px) { + .filters-modal-description { + display: none; + } +} + +/*!***********************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/asteroid_modals/modals/learn_modal/learn_modal.css ***! + \***********************************************************************************************************************************************************************************************************************/ +.learn-modal .learn-modal-description { + padding: 2px 56px 18px 56px; + color: var(--grayblueMed); + font-weight: 200; + font-size: 20px; + letter-spacing: 1px; + text-align: center; + border-bottom: 2px solid var(--grayblueDivider); +} + +.learn-modal .learn-modal-body { + padding: 0 28px 14px 28px; + overflow-y: auto; + max-height: calc(100vh - 206px); +} + +.learn-modal .learn-modal-story-card { + position: relative; + padding: 28px 28px 28px 48px; + border-bottom: 1px solid var(--grayblueDivider); + cursor: pointer; +} + +.learn-modal .learn-modal-story-card:last-child { + border-bottom: none; +} + +.learn-modal .learn-modal-story-card-title { + font-size: 27px; + line-height: 27px; + font-weight: 600; + margin-bottom: 2px; + letter-spacing: 1px; + color: var(--grayblueLight); +} + +.learn-modal .learn-modal-story-card-question { + font-size: 18px; + color: var(--grayblueText); + margin-left: 36px; + padding-top: 8px; + letter-spacing: 1px; +} + +@media only screen and (max-width: 641px) { + .learn-modal .learn-modal-description { + padding: 2px 20px 18px 20px; + font-size: 18px; + } + + .learn-modal .learn-modal-body { + padding: 0 20px; + max-height: calc(100vh - 281px); + } + + .learn-modal .learn-modal-story-card { + padding: 20px; + } + + .learn-modal .learn-modal-story-card-title { + font-size: 22px; + line-height: 22px; + margin-bottom: 8px; + } + + .learn-modal .learn-modal-story-card-question { + font-size: 16px; + margin-left: 24px; + } +} + +@media only screen and (max-width: 390px) { + .learn-modal .learn-modal-description { + padding: 2px 20px 10px 20px; + font-size: 16px; + } +} + + +/*!********************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/asteroid_modals/asteroid_modals.css ***! + \********************************************************************************************************************************************************************************************************/ +#asteroid-modals { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 1; + pointer-events: all; + z-index: 1000; + transition: opacity 0.2s ease-in, top 0.4s ease-in-out; +} + +#asteroid-modals.hidden { + display: block !important; + opacity: 0; + pointer-events: none; +} + +#asteroid-modals .asteroid-modals-backdrop { + width: 100%; + height: 100%; + background: var(--black); + opacity: 0.75; +} + +#asteroid-modals .asteroid-modal { + background: linear-gradient(to bottom, + var(--grayblueBackground) 64%, + var(--grayblueDarkAlpha)); + border-radius: 12px; + width: 500px; + position: absolute; + top: 50%; + left: 50%; + transform: translateX(-50%) translateY(-50%); + max-height: calc(100vh - 70px); + overflow: hidden; +} + +#asteroid-modals .asteroid-modal-header { + display: flex; + justify-content: space-between; + height: 30px; + line-height: 30px; + padding: 0 18px; + margin: 18px 0; +} + +#asteroid-modals .asteroid-modal-svg { + font-size: 29px; + line-height: 34px; +} + +#asteroid-modals .asteroid-modal-title { + font-size: 26px; + line-height: 34px; + letter-spacing: 1px; +} + +#asteroid-modals .asteroid-modal-close span { + transform: scale(2.1); + opacity: 0.5; + transition: opacity 0.25s ease-in-out; +} + +#asteroid-modals .asteroid-modal-collapse { + display: none; + width: 30px; + height: 30px; + padding: 4px; + color: var(--grayblueWhite); +} + +#asteroid-modals .asteroid-modal-content { + max-height: calc(100vh - 136px); + overflow-y: auto; +} + +@media only screen and (max-width: 641px) { + #asteroid-modals .asteroid-modal { + width: calc(100% - 30px); + background: linear-gradient(to bottom, + var(--grayblueBackground) 64%, + rgba(0, 0, 0, 0.8)); + top: unset; + bottom: 80px; + left: 50%; + transform: translateX(-50%); + } + + #asteroid-modals .asteroid-modal-content { + max-height: calc(100vh - 160px); + } + + #asteroid-modals.hidden { + top: 100vh; + } + + #asteroid-modals .asteroid-modal-close { + display: none; + } + + #asteroid-modals .asteroid-modal-collapse { + display: block; + } +} + + +/*!************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/home_button/home_button.css ***! + \************************************************************************************************************************************************************************************************/ +/* Home button CSS */ +.home-button { + white-space: nowrap; + grid-column-start: 1; + grid-row-start: 2; + align-self: flex-start; + justify-self: flex-start; + color: var(--grayblueText); + font-size: 1rem; + letter-spacing: 0; + opacity: 1; + visibility: visible; + transform: translateX(0); + transition: filter 0.2s, opacity 0.6s, visibility 0.6s, transform 0.6s; + transition-timing-function: var(--ease-out-bezier); + filter: drop-shadow(0 0 0.1rem rgb(0 0 0 / 30%)); +} + +.home-button.hidden { + opacity: 0; + visibility: hidden; + transform: translateX(-60%); + transition: opacity 0.3s, visibility 0.3s, transform 0.4s; + display: unset; +} + +/* Arrow */ +.home-button::before { + content: "‹"; + position: relative; + top: 0.1rem; + font-size: 1.8rem; + font-weight: 600; + line-height: 0; + margin: 0 0.75rem 0 0.2rem; +} + +/* Increase touch/click area */ +.home-button::after { + content: ""; + position: absolute; + inset: 0% -15% -15% -6%; +} + +@media only screen and (max-width: 641px) { + .home-button { + margin-left: 20px; + } +} + +@media only screen and (max-height: 600px) { + .home-button { + margin-top: 1vh; + } +} + + +/*!********************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/countdown/countdown.css ***! + \********************************************************************************************************************************************************************************************/ + +.countdown { + margin: 24px auto; + padding: 20px 12px 14px 12px; + position: relative; + z-index: 0; + max-width: 335px; + width: 100%; +} + +/* Masked border technique -> https://stackoverflow.com/questions/51496204/border-gradient-with-border-radius/51496341 */ +.countdown::before { + content: ""; + position: absolute; + z-index: -1; + inset: 0; + padding: 2px; + border-radius: 12px; + background: radial-gradient(ellipse at top, + transparent 34%, + var(--live) 34.01%); + -webkit-mask: linear-gradient(#ffffff 0 0) content-box, + linear-gradient(#ffffff 0 0); + mask: linear-gradient(#ffffff 0 0) content-box, linear-gradient(#ffffff 0 0); + -webkit-mask-composite: destination-out; + mask-composite: exclude; +} + +.countdown .countdown-title { + position: absolute; + left: 50%; + top: 0; + transform: translate(-50%, -40%); +} + +.countdown .digits-container { + display: flex; + justify-content: flex-end; +} + +.digits-container .t-text { + position: absolute; + left: 5%; + top: 28%; +} + +.digits-container .digit-block { + text-align: center; + min-width: 22%; +} + +.digits-container .digit-block>h3.digit { + margin: 0 -0.1em -2px 0; + letter-spacing: 0.1em; +} + +.countdown .countdown-title, +.digits-container .digit, +.digits-container .digit-unit { + color: var(--live); +} + +/* Less than 961px */ +@media only screen and (max-width: 961px) { + .countdown .countdown-title { + font-size: 12px; + } + + .digits-container .t-text { + font-size: 14px; + top: 32%; + } + + .digits-container .digit-block>h3.digit { + font-size: 26px; + margin: 0 -0.05em -4px 0; + } + + .digits-container span.digit-unit { + font-size: 10px; + font-weight: 300; + } +} + +/*!***********************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/watch_panel/watch_card.css ***! + \***********************************************************************************************************************************************************************************************/ +/* Watch Card CSS */ +.watch-card { + display: flex; + justify-content: space-between; + align-items: flex-end; + max-width: 335px; + width: 100%; + margin: 0 auto; +} + +/* Text Group */ +.watch-card .text-group { + width: 60%; +} + +.watch-card .text-group>h3 { + color: var(--grayblueLight); +} + +.text-group .date-block { + margin-top: 0.7em; +} + +.text-group .distance-block { + margin-top: 0.4em; +} + +.date-block>.date-text { + display: flex; + align-items: baseline; +} + +.date-text>.date-day, +.date-text>.date-time { + text-transform: uppercase; + white-space: nowrap; +} + +.date-text>.date-time { + margin-left: 1em; +} + +.diameter-text { + text-align: center; +} + +.date-text>.date-day, +.date-text>.date-time, +.distance-text>.distance-value, +.distance-text>.distance-unit, +.diameter-text>.diameter-value, +.diameter-text>.diameter-unit { + color: var(--grayblueLight); +} + +.diameter-text .diameter-estimated { + display: block; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--grayblueMed); +} + +.distance-block>.distance-text { + display: flex; + align-items: center; +} + +.date-block>span.date-label, +.distance-block>span.distance-label { + color: var(--grayblueText); +} + +/* Rock Group */ +.watch-card .rock-group { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; +} + +.distance-block h5.distance-unit, +.rock-group span.diameter-unit { + margin-left: 0.3em; + /* text-decoration: underline; */ +} + +/* Less than 961px */ +@media only screen and (max-width: 961px) { + + /* Text Group */ + .watch-card .text-group>h3 { + font-size: 22px; + } + + .watch-card .text-group>span, + .text-group span.date-time { + font-size: 12px; + } + + .date-block .date-text>h5, + .distance-block .distance-text>h5 { + font-size: 14px; + } + + /* Rock Group */ + .watch-card .rock-group { + width: 25%; + min-width: 65px; + } + + .rock-group .icon.rock, + .rock-group .icon.ruler { + transform: scale(0.7); + } + + .rock-group .diameter-text>span { + font-size: 12px; + } + + .diameter-text span.diameter-estimated { + font-size: 10px; + letter-spacing: 0.02em; + } +} + +/*!************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/watch_panel/watch_panel.css ***! + \************************************************************************************************************************************************************************************************/ +/* CSS unique to the watch panel that will override the base carousel panel CSS */ +.watch-panel .panel-header { + position: relative; +} + +.watch-panel .panel-header::before, +.watch-panel .panel-header::after { + content: ""; + position: absolute; + height: 1px; + width: 42%; + left: -12px; + bottom: -1.2em; + background-color: var(--grayblueDivider); +} + +.watch-panel .panel-header::after { + left: unset; + right: -12px; +} + +/* Adjusting divider on widths below 961 */ +@media only screen and (max-width: 961px) { + .watch-panel .panel-header::before { + width: 38%; + left: 0; + } + + .watch-panel .panel-header::after { + width: 38%; + right: 0; + } +} + +/* Saving vertical height below 641px */ +@media only screen and (max-height: 641px) { + .watch-panel .panel-header::after { + content: none; + } + + .watch-panel .panel-header::before { + width: 100%; + left: 0; + bottom: -0.7em; + } +} + +/* Pagination fraction, ie. 1 OF 5 */ +.watch-carousel>.watch-carousel-fraction { + display: inline-table; + top: 0.6em; + text-transform: uppercase; + color: var(--grayblueDivider); + font-size: 14px; + filter: brightness(1.5); +} + +@media only screen and (max-width: 961px) { + + /* Smaller fraction font */ + .watch-carousel>.watch-carousel-fraction { + font-size: 12px; + } +} + +/* When the height is less than 900px, we need to save a little on vertical space */ +@media only screen and (max-height: 900px) and (max-width: 641px) { + + /* Reduce main swiper padding */ + .watch-panel .panel-content .swiper { + padding: 1.8em 0 0 0; + } + + /* Reduce caption padding */ + .watch-panel .panel-header .header-caption { + line-height: 1.2; + } + + /* Reduce countdown vertical margins */ + .watch-carousel .countdown { + margin: 10px auto; + padding: 13px 12px 7px 12px; + } + + /* Adjust bullet margins */ + .watch-panel .panel-content .bullet-container { + margin: 1em auto 1em auto; + } + + /* Reposition nav arrows up */ + .watch-panel .panel-content .swiper-button-prev, + .watch-panel .panel-content .swiper-button-next { + bottom: 0.8em; + } + + /* Smaller fraction font */ + .watch-carousel>.watch-carousel-fraction { + font-size: 11px; + top: 0; + } +} + +@media only screen and (max-height: 750px) and (min-height: 642px) { + .watch-panel { + margin-top: 50px; + } +} + +/* When the height is less than 641px, we need to save A LOT on vertical space */ +/* Ways to save vertical space: +- hide the countdown +- hide the fractions +*/ +@media only screen and (max-height: 641px) { + + /* Reduce main swiper padding */ + .watch-panel .panel-content .swiper { + padding: 1em 0 0.5em 0; + } + + /* Adjust bullet margins */ + .watch-panel .panel-content .bullet-container { + margin: 1.2em auto 0.5em auto; + } + + /* Reposition nav arrows up */ + .watch-panel .panel-content .swiper-button-prev, + .watch-panel .panel-content .swiper-button-next { + bottom: 0.8em; + } + + /* hide clock */ + .watch-carousel .countdown { + display: none; + } + + /* hide fractions - divider lines changed in watch_panel.css */ + .watch-carousel>.watch-carousel-fraction { + display: none; + } +} + +/*!******************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/asteroid_panel/asteroid_panel.css ***! + \******************************************************************************************************************************************************************************************************/ +/* Carousel content */ +.panel-content .asteroid-carousel { + padding: 2em 0 4.2em; + height: 250px; +} + +/* Bullets */ +.asteroid-carousel .bullet-container { + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); +} + +/* Slides */ +.asteroid-carousel .swiper-slide { + padding: 5px 0 0.1em; + margin: 0 0 1.5em; + -webkit-mask-image: linear-gradient(to bottom, + transparent 5px, + white 10px, + white 90%, + transparent 100%); + mask-image: linear-gradient(to bottom, + transparent 5px, + white 10px, + white 90%, + transparent 100%); +} + +.asteroid-carousel .swiper-slide h4 { + font-size: 18px; + letter-spacing: 0; + color: var(--grayblueWhite); + padding: 0.75em 0; +} + +.asteroid-carousel .swiper-slide p { + margin: 0; + color: var(--grayblueMed); + font-size: 14px; + line-height: 1.6; +} + +.asteroid-carousel .swiper-slide p.long { + padding: 0 1.5em 1em 0; +} + +.asteroid-carousel .swiper-slide .value { + color: var(--grayblueLight); + font-size: 16px; + letter-spacing: 0; + margin-top: 0.4em; +} + +/* Anything over 961, we can incresed some font and icon sizes slightly */ +@media only screen and (min-width: 961px) { + + /* Carousel content */ + .panel-content .asteroid-carousel { + height: 275px; + } + + /* Text */ + .asteroid-carousel .swiper-slide h4 { + font-size: 20px; + } + + .asteroid-carousel .swiper-slide p { + font-size: 18px; + line-height: 1.8; + } + + .asteroid-carousel .swiper-slide .value { + font-size: 18px; + } +} + +/* Less than 641px and portrait */ +@media only screen and (max-width: 641px) and (orientation: portrait) { + + /* Main padding */ + #panel-container.asteroid-panel .panel-main { + padding: 12px 20px; + } + + /* Carousel content */ + .panel-content .asteroid-carousel { + height: 175px; + padding: 1.8em 0 3em; + } + + /* Slides */ + .asteroid-carousel .swiper-slide { + -webkit-mask-image: linear-gradient(to bottom, + transparent 2px, + white 6px, + white 80%, + transparent 100%); + mask-image: linear-gradient(to bottom, + transparent 2px, + white 6px, + white 80%, + transparent 100%); + } + + /* Bullets */ + .asteroid-carousel .bullet-container { + margin-top: 0.5em; + } + + /* Adjust text */ + .asteroid-carousel .swiper-slide h4 { + padding: 0 0 0.4em; + } + + /* .asteroid-carousel .swiper-slide p.long { + padding: 0.7em 1em 1em 0; + } */ + + .asteroid-carousel .swiper-slide .value { + margin-top: 0.2em; + } +} + +/* Height-related queries */ +@media only screen and (max-height: 641px) { + + /* Main padding */ + #panel-container.asteroid-panel .panel-main { + padding: 16px 20px; + } + + /* Carousel content */ + .panel-content .asteroid-carousel { + height: min(220px, 50vh); + padding: 1.8em 0 2.5em; + } + + /* Bullets */ + .asteroid-carousel .bullet-container { + margin: 0 auto 1.5em; + } + + /* Text */ + .asteroid-carousel .swiper-slide h4 { + font-size: 16px; + } + + .asteroid-carousel .swiper-slide p { + line-height: 1.4; + } +} + +/*!****************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/mission_panel/mission_panel.css ***! + \****************************************************************************************************************************************************************************************************/ +/* Carousel content */ +.panel-content .mission-carousel { + padding: 1em 0 4.5em; + height: 200px; +} + +#panel-container.mission-panel a { + color: var(--grayblueLight); + text-decoration: underline; + transition: color 0.2s ease-in; +} + +/* Bullets */ +.mission-carousel .bullet-container { + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); + margin: 1em auto 3.8em; +} + +/* Slides */ +.mission-carousel .swiper-slide { + padding: 0.5em 0; + -webkit-mask-image: linear-gradient(to bottom, + transparent 5px, + white 10px, + white 80%, + transparent 100%); + mask-image: linear-gradient(to bottom, + transparent 5px, + white 10px, + white 80%, + transparent 100%); +} + +.mission-carousel .swiper-slide h4 { + font-size: 18px; + letter-spacing: 0; + color: var(--grayblueWhite); + padding: 0 0 0.75em; +} + +.mission-carousel .swiper-slide p { + margin: 0; + color: var(--grayblueMed); + font-size: 14px; + line-height: 1.6; +} + +.mission-carousel .swiper-slide p.long { + padding: 0 1.5em 0.1em 0; +} + +.mission-carousel .swiper-slide .value { + position: absolute; + right: 1px; + transform: translateY(85%); + border: 1px solid var(--grayblueMed); + border-radius: 24px; + color: var(--grayblueText); + font-size: 10px; + line-height: 1; + padding: 0.6em 2em 0.6em 1.1em; + transition: filter 0.2s ease-in; +} + +.mission-carousel .swiper-slide .value::after { + content: "›"; + position: absolute; + transform: scale(1.7); + margin-left: 0.6em; + line-height: 0.8; +} + +.mission-carousel .swiper-slide .value:active { + filter: brightness(1.5); + transition: filter 0.4s ease-out; +} + +/* Anything over 961, we can incresed some font and icon sizes slightly */ +@media only screen and (min-width: 961px) { + + /* Carousel content */ + .panel-content .mission-carousel { + height: 275px; + } + + /* Bullets */ + .mission-carousel .bullet-container { + margin: 1em auto 4.2em; + } + + /* Text */ + .mission-carousel .swiper-slide h4 { + font-size: 20px; + } + + .mission-carousel .swiper-slide p { + font-size: 18px; + line-height: 1.8; + } + + .mission-carousel .swiper-slide .value { + font-size: 12px; + } +} + +/* Less than 641px and portrait */ +@media only screen and (max-width: 641px) and (orientation: portrait) { + + /* Main padding */ + #panel-container.mission-panel .panel-main { + padding: 12px 20px; + } + + /* Carousel content */ + .panel-content .mission-carousel { + height: 175px; + padding: 0.5em 0 3em; + } + + /* Slides */ + .mission-carousel .swiper-slide { + padding: 0.5em 0; + -webkit-mask-image: linear-gradient(to bottom, + transparent 2px, + white 6px, + white 90%, + transparent 100%); + mask-image: linear-gradient(to bottom, + transparent 2px, + white 6px, + white 90%, + transparent 100%); + } + + /* Bullets */ + .mission-carousel .bullet-container { + margin: 1em auto 2em; + } + + /* Adjust text */ + .mission-carousel .swiper-slide h4 { + padding: 0 0 0.4em; + } +} + +/* Height-related queries */ +@media only screen and (max-height: 641px) { + + /* Main padding */ + #panel-container.mission-panel .panel-main { + padding: 16px 20px; + } + + #panel-container.mission-panel .header-title>h4.title-text { + font-size: 22px; + } + + /* Carousel content */ + .panel-content .mission-carousel { + height: min(220px, 50vh); + padding: 1.8em 0 2.5em; + } + + /* Prev and next buttons */ + .mission-carousel .swiper-button-prev, + .mission-carousel .swiper-button-next { + bottom: 0.7em; + } + + /* Bullets */ + .mission-carousel .bullet-container { + margin: 0 auto 1em; + } + + /* Text */ + .mission-carousel .swiper-slide h4 { + font-size: 16px; + } + + .mission-carousel .swiper-slide p { + line-height: 1.4; + } +} + + +/*!********************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/following_panel/following_panel.css ***! + \********************************************************************************************************************************************************************************************************/ +/* CSS unique to the following panel that will override the base Panel CSS */ + +#panel-container.following-panel .panel-simple { + pointer-events: none; +} + +.following-panel .panel-main, +.following-panel .panel-simple .expand-button { + display: none; +} + +.following-panel .panel-simple>h4.simple-title { + margin: 0.1em 0 0 10px; + filter: drop-shadow(0 0 0.1rem rgb(0 0 0 / 70%)); +} + +/*!****************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/splash_screen/splash_screen.css ***! + \****************************************************************************************************************************************************************************************************/ +/* Splash Screen CSS */ +.splash-screen { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: black; + z-index: 9998; +} + +.splash-screen-wrapper { + -webkit-animation: fade-in 0.3s ease-in; + animation: fade-in 0.3s ease-in; +} + +.splash-screen-logo { + position: absolute; + left: 50%; + top: 15%; + transform: translateX(-50%) translateY(-50%); + width: 110px; + height: 110px; + opacity: 0.7; + background-size: contain; + background-repeat: no-repeat; + background-image: url(./assets/default/svg/nasa_logo.svg); +} + +.splash-screen-asteroid { + position: absolute; + left: 50%; + top: 44%; + transform: translateX(-50%) translateY(-50%); + width: 68vh; + height: 68vh; + background-size: contain; + background-repeat: no-repeat; + background-image: url(./assets/images/splash_bennu.png); +} + +.splash-screen-text { + position: absolute; + left: 50%; + top: 55%; + transform: translateX(-50%) translateY(-50%); + text-transform: uppercase; + letter-spacing: 8px; + font-weight: 300; + text-align: center; +} + +.splash-screen-text>div:nth-child(1) { + font-size: 34px; + line-height: 60px; + padding-left: 8px; + color: var(--grayblueLight); +} + +.splash-screen-text>div:nth-child(2) { + font-size: 24px; + line-height: 40px; + padding-left: 8px; + color: var(--grayblueMed); +} + +.splash-screen-text>div:nth-child(3) { + font-size: 48px; + line-height: 80px; + font-weight: bold; + letter-spacing: 42px; + padding-left: 42px; + color: var(--grayblueWhite); +} + +.splash-screen-enter-background { + content: ""; + position: absolute; + left: 50%; + top: calc(86% - 54px); + background: radial-gradient(circle at center, + rgba(255, 255, 255, 0), + rgba(255, 255, 255, 0.03) 67%, + rgba(255, 255, 255, 0.08) 70%, + rgba(255, 255, 255, 0.09)); + width: 100vw; + height: 100vw; + border-radius: 50%; + padding-top: 8px; + transform: translateX(-50%); +} + +.splash-screen-enter { + position: absolute; + left: 50%; + top: calc(86% - 54px); + height: calc(14% + 54px); + width: 100vw; + cursor: pointer; + transform: translateX(-50%); +} + +.splash-screen-swipe-arrow { + display: flex; + flex-flow: column; + color: var(--grayblueMed); +} + +.splash-screen-swipe-arrow::before { + content: "Scroll to enter"; + font-size: 20px; + opacity: 0.7; + margin-top: 20px; + line-height: 38px; + font-weight: 200; + text-align: center; +} + +.splash-screen-swipe-arrow>svg { + margin: auto; + opacity: 0.8; +} + +.splash-screen-stars1 { + width: 3px; + height: 3px; + background: transparent; + pointer-events: none; +} + +.splash-screen-stars2 { + width: 2px; + height: 2px; + background: transparent; + pointer-events: none; +} + +@-webkit-keyframes fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@media only screen and (max-width: 960px) { + .splash-screen-logo { + width: 90px; + height: 90px; + } + + .splash-screen-text>div:nth-child(1) { + font-size: 24px; + line-height: 50px; + } + + .splash-screen-text>div:nth-child(2) { + font-size: 20px; + line-height: 30px; + padding-left: 8px; + } + + .splash-screen-text>div:nth-child(3) { + font-size: 36px; + line-height: 70px; + letter-spacing: 32px; + padding-left: 32px; + } + + .splash-screen-swipe-arrow::before { + content: "Swipe to enter"; + font-size: 16px; + line-height: 20px; + } + + .splash-screen-swipe-arrow>svg { + transform: rotateZ(180deg) scale(0.7); + } +} + +@media only screen and (max-width: 660px) { + .splash-screen-logo { + width: 80px; + height: 80px; + } + + .splash-screen-text>div:nth-child(1) { + font-size: 20px; + line-height: 40px; + } + + .splash-screen-text>div:nth-child(2) { + font-size: 16px; + line-height: 20px; + } + + .splash-screen-text>div:nth-child(3) { + font-size: 26px; + line-height: 50px; + letter-spacing: 18px; + padding-left: 18px; + } + + .splash-screen-swipe-arrow::before { + font-size: 14px; + line-height: 20px; + } + + .splash-screen-swipe-arrow>svg { + transform: rotateZ(180deg) scale(0.6); + } +} + +@media only screen and (max-height: 550px) { + .splash-screen-logo { + width: 70px; + height: 70px; + } + + .splash-screen-text>div:nth-child(1) { + font-size: 20px; + line-height: 40px; + } + + .splash-screen-text>div:nth-child(2) { + font-size: 16px; + line-height: 20px; + } + + .splash-screen-text>div:nth-child(3) { + font-size: 26px; + line-height: 50px; + letter-spacing: 18px; + padding-left: 18px; + } + + .splash-screen-swipe-arrow::before { + font-size: 14px; + line-height: 20px; + } + + .splash-screen-swipe-arrow>svg { + transform: rotateZ(180deg) scale(0.6); + } +} + +/*!**************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/definition_overlay/definition_overlay.css ***! + \**************************************************************************************************************************************************************************************************************/ +.definition-overlay { + position: absolute; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.7); + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + visibility: visible; + z-index: 2001; + pointer-events: all; + transition: opacity 0.5s var(--ease-out-bezier), + visibility 0.5s var(--ease-out-bezier); +} + +.definition-overlay.hidden { + display: flex; + pointer-events: none; + opacity: 0; + visibility: hidden; + transition: opacity 0.2s ease-in, visibility 0.2s ease-in; +} + +.definition-container { + width: calc(100% - 32px); + max-width: 500px; + max-height: calc(100vh - 32px); + background-color: var(--grayBackground); + border-radius: 12px; + display: flex; + flex-direction: column; + transition: transform 0.5s var(--ease-out-bezier); +} + +.hidden .definition-container { + display: flex; + transform: translateY(50%); + transition: transform 0.2s ease-in; +} + +/* Header */ +.definition-container .definition-header { + height: 60px; + border-bottom: 1px solid var(--grayDark); + display: flex; +} + +.definition-header h4.definition-title { + flex: 1 0 auto; + line-height: 60px; + font-weight: 600; + letter-spacing: 0; +} + +.definition-header div.definition-info, +.definition-header div.definition-close { + flex-basis: 64px; + display: flex; + justify-content: center; + align-items: center; +} + +.definition-header div.definition-close { + pointer-events: all; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.definition-info span { + transform: scale(0.9); +} + +.definition-close span { + transform: scale(1.6); + opacity: 0.5; + transition: opacity 0.25s ease-in-out; +} + +/* Content */ +.definition-container .definition-content { + padding: 0 30px 4px 21px; + margin: 24px 18px 16px 6px; + scroll-behavior: smooth; + -webkit-mask-image: linear-gradient(to bottom, + transparent 0, + white 8px, + white calc(100% - 16px), + transparent 100%); + mask-image: linear-gradient(to bottom, + transparent 0, + white 8px, + white calc(100% - 16px), + transparent 100%); +} + +/* scrollbar */ +#definition-overlay .os-scrollbar-vertical { + right: 0; + top: 5px; + bottom: 5px; + width: 12px; +} + +.definition-content p:first-child { + margin-top: 0; +} + +.definition-content p, +.definition-content ul { + /* font-weight: 300; */ + color: var(--grayMed); +} + +.definition-content span { + position: relative; + color: var(--white); + opacity: 0.75; + text-decoration: underline; + cursor: pointer; + transition: opacity 0.25s ease-in-out; +} + +.definition-content span::after { + content: ""; + position: absolute; + inset: -4px -8px; +} + +.definition-content .oumuamua-animation::before { + content: ""; + position: absolute; + inset: 0; + opacity: 0.25; + background-color: radial-gradient(black 10%, transparent 100%); + background-repeat: no-repeat; + background-position: 66%; + background-image: url(./assets/svg/oumuamua.svg); + background-size: auto 100%; + transform-origin: 66% 51%; + -webkit-animation: spin 20s linear infinite; + animation: spin 20s linear infinite; + z-index: -1; +} + +/* Footer */ +/* .definition-container .definition-footer { + flex-basis: 70px; +} */ + +.definition-footer .definition-divider { + position: relative; + height: 1px; + width: calc(100% - 42px); + left: 21px; + background-color: var(--grayDark); +} + +.definition-divider span { + position: absolute; + left: 50%; + transform: translate(-50%, -50%); + line-height: unset; + background-color: var(--grayBackground); + padding: 0 12px; + color: var(--gray); + font-weight: 100; +} + +.definition-footer .definition-related { + display: flex; + flex-wrap: wrap; + gap: 8px; + padding: 16px 21px 21px 21px; +} + +.definition-related .definition-related-item { + color: var(--white); + opacity: 0.7; + padding: 8px 16px; + background-color: var(--grayDark); + background-repeat: no-repeat; + background-position: center; + background-image: radial-gradient(#303030 10%, transparent 100%); + background-size: 0% 0%; + border-radius: 6px; + line-height: unset; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + + +/*!************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/time_slider/time_slider.css ***! + \************************************************************************************************************************************************************************************************/ +/* This is a bit all over the place and needs better structure */ + +.time-slider .slider-line { + background: no-repeat center/100% url(./assets/default/svg/time_slider_lines.svg); + transform: scaleX(1); + visibility: visible; + opacity: 1; + transition: transform 1s 0.3s var(--ease-out-bezier); +} + +.no-slider .slider-line, +.hidden .slider-line { + transform: scaleX(0); + visibility: hidden; + opacity: 0; + transition: transform 0.4s ease-in-out, opacity 0.4s 0.2s ease-in, + visibility 0.4s 0.2s ease-in; +} + +.time-slider .slider-icon { + position: relative; + width: 32px; + height: 25px; + justify-self: center; + background: no-repeat center/100% url(./assets/svg/icon_clock.svg); + visibility: visible; + opacity: 1; + pointer-events: all; + cursor: -webkit-grab; + cursor: grab; + transition: transform 1s cubic-bezier(0.3, 1.24, 0.34, 0.98), + opacity 0.75s 0.25s var(--ease-out-bezier), + visibility 0.75s 0.25s var(--ease-out-bezier); + transform: translateX(var(--x-icon-trans)); + z-index: 1; +} + +.no-slider .slider-icon { + visibility: hidden; + opacity: 0; + transition: opacity 0.3s 0.2s ease-in, visibility 0.3s 0.2s ease-in; +} + +.no-slider .realtime { + opacity: 0; + pointer-events: none; +} + +.time-slider .slider-icon::before { + content: ""; + position: absolute; + inset: -40% -40% -60% -40%; +} + +.time-slider .slider-icon:active { + cursor: -webkit-grabbing; + cursor: grabbing; +} + +.time-slider .slider-icon::after { + content: var(--x-rate, ""); + color: var(--grayMed); + letter-spacing: 0.02em; + font-weight: 600; + font-size: 0.8em; + position: absolute; + left: var(--customIconLabelMargin); + transform: translate(-50%, -80%); + white-space: nowrap; +} + +/* This is a bit all over the place and needs better structure */ +.time-container { + position: relative; + row-gap: 1rem; + justify-self: center; + align-self: center; + width: calc(100% - 2rem); + max-width: min(calc(50% - 1rem), 500px); + padding-bottom: 1rem; + grid-template-columns: 1fr 1fr 1fr; + grid-template-rows: 1fr 1fr; + display: grid; + grid-template-areas: + "live date date" + "slider slider slider"; + visibility: visible; + opacity: 1; + transition: all 0.5s var(--ease-out-bezier); +} + +/* Black radial bg gradient */ +.time-container::after { + content: ""; + position: absolute; + inset: -100% -40%; + background-image: radial-gradient(rgb(0 0 0 / 50%) 0%, transparent 70%); + z-index: -1; +} + +.time-container.hidden { + display: grid; + margin-top: 76px; + visibility: hidden; + opacity: 0; + transition-delay: 0.3s; +} + +.time-container.offset-right { + transform: translateX(calc(50% + 16px)); +} + +.time-container.no-slider { + transition-delay: 0.3s; + row-gap: 0; +} + +.time-container .time-slider { + grid-area: slider; + display: grid; + filter: drop-shadow(0 0 0.2rem rgb(0 0 0)) drop-shadow(0 0 1rem rgb(0 0 0)) drop-shadow(0 2px 1.5rem rgb(0 0 0)); +} + +.time-container .slider-line, +.time-container .slider-icon { + grid-area: 1 / 1; +} + +.time-container .realtime { + position: relative; + grid-area: 1 / 1; + justify-self: center; + align-self: center; + width: 0.4rem; + height: 0.4rem; + border-radius: 0.2rem; + background-color: var(--grayblueLight); + padding: 0; + z-index: 1; + pointer-events: all; + transition-property: filter, opacity, transform; + transition-duration: 0.3s; + transition-timing-function: var(--ease-out-bezier); +} + +.time-container .realtime::before { + content: ""; + position: absolute; + inset: 0; + border-radius: 0.3rem; + border: 0.05rem var(--grayblueLight) solid; + opacity: 0; + transform: scale(0.5); + transition-property: opacity, transform; + transition-duration: 0.5s; + transition-timing-function: var(--ease-out-bezier); +} + +.time-container .realtime::after { + content: ""; + position: absolute; + inset: -0.5rem; +} + +.time-container .realtime.hidden { + display: unset; + opacity: 0; + pointer-events: none; +} + +.touch .time-container .realtime { + transform: scale(1.1); + filter: brightness(1.2); + cursor: pointer; +} + +.touch .time-container .realtime::before { + opacity: 1; + transform: scale(2); +} + +.time-container .clock-shortcut { + grid-area: live; + grid-template-rows: auto; + transition: transform 0.5s var(--ease-out-bezier); + align-self: center; +} + +.time-container .clock-shortcut .live-container { + font-size: 0.9rem; + line-height: 1; + border-radius: 20px; + border: 1px solid var(--grayblueMed); + justify-self: flex-start; + align-self: end; + padding: 0.3em 1.2em 0.3em 0.6em; + margin-left: 4px; + background-repeat: no-repeat; + background-position: center; + background-image: radial-gradient(var(--liveAlpha) 60%, transparent 70%); + background-size: 0% 0%; + filter: drop-shadow(0 0 0.3rem rgb(0 0 0/70%)) drop-shadow(0 0 1rem rgb(0 0 0)); +} + +.time-container .clock-shortcut .live-container.active { + border: none; + margin: 1px 1px 1px 5px; + filter: drop-shadow(0 0 1rem rgb(0 0 0)); +} + +.time-container .clock-shortcut .live-container.active .text { + line-height: 0; +} + +.time-container .clickable .icon-live { + background-position: 0 -76px; +} + +.time-container .clock { + grid-area: date; + justify-self: stretch; + align-self: center; +} + +.time-container .clock .datetime-container { + margin: 0; +} + +.time-container .clock .datetime-container .display-container { + opacity: 1; + grid-template-columns: 1fr 1fr; + align-items: center; + filter: drop-shadow(0 0 0.15rem rgb(0 0 0)) drop-shadow(0 0 1rem rgb(0 0 0)); +} + +.time-container .clock .date { + font-family: DMMono, monospace; + justify-self: center; + text-transform: uppercase; + transition: transform 0.5s var(--ease-out-bezier); + color: var(--grayblueLight); +} + +.time-container .clock .time, +.time-container .clock .meridiem { + font-family: DMMono, monospace; + font-size: 0.8rem; + grid-column-start: 2; + grid-row-start: 1; + justify-self: flex-end; + align-self: flex-end; + transition: transform 0.5s var(--ease-out-bezier); + filter: brightness(1.2); + color: var(--grayblueMed); +} + +.time-container .clock .meridiem { + margin-right: 8px; +} + +.time-container .clock .time { + margin-right: 32px; +} + +.time-container .datetime-container>form, +.time-container input.hour-input { + text-align: center; + width: unset; +} + +.time-container input.hour-input { + -webkit-backdrop-filter: blur(10px); + backdrop-filter: blur(10px); + background-color: rgb(0 0 0/50%); +} + +/* Limited vertical space and portrait */ +.time-container.portrait { + max-width: unset; +} + +/* Offset vertically when not in home view */ +.watch-view .time-container.portrait, +.mission-view .time-container.portrait, +.following-view .time-container.portrait, +.asteroid-view .time-container.portrait { + transform: translateY(calc(100% + 12px)); +} + +.time-container.v-squeezy { + row-gap: 0.7rem; +} + +.time-container.h-squeezy .clock .date, +.time-container.v-squeezy .clock .date, +.time-container.portrait .clock .date { + font-size: 14px; +} + +.time-container.h-squeezy .clock .time, +.time-container.h-squeezy .clock .meridiem, +.time-container.h-squeezy .live-container, +.time-container.v-squeezy .clock .time, +.time-container.v-squeezy .clock .meridiem, +.time-container.v-squeezy .live-container, +.time-container.portrait .clock .time, +.time-container.portrait .clock .meridiem, +.time-container.portrait .live-container { + font-size: 12px; +} + +.live-container.clickable { + display: none; +} + +@media only screen and (min-width: 1025px) { + .time-container { + margin-bottom: 5vh; + } + + .time-container.offset-right { + transform: translateX(var(--offset-right-lg)); + } +} + +/* Exclude panorama. Big landscape tablets, laptops/desktops, and above */ +@media only screen and (min-width: 1025px) and (min-height: 600px) { + .time-container { + margin-bottom: 0; + } + + .time-container .clock .date { + font-size: 18px; + } + + .time-container .clock .meridiem { + font-size: 14px; + margin-right: 8px; + } + + .time-container .clock .time { + font-size: 14px; + margin-right: 32px; + } + + .time-container .slider-icon { + width: 40px; + height: 26px; + } +} + +/*!**********************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./src/components/breadcrumb/breadcrumb.css ***! + \**********************************************************************************************************************************************************************************************/ +.header>nav.breadcrumb { + z-index: 2; + order: 1; +} + +.breadcrumb .home .text { + position: relative; + display: inline-block; + white-space: nowrap; + letter-spacing: 0.04em; + font-size: 0.9rem; + font-weight: 600; + top: 0.08em; + filter: drop-shadow(0 0 0.2rem rgb(0 0 0)); +} + +.breadcrumb .home .icon { + filter: drop-shadow(0 0 0.2rem rgb(0 0 0)); +} + +@media only screen and (min-width: 961px) { + .breadcrumb .home .text { + font-size: 1rem; + } +} + +.hidden-on-footron { + display: none; +} + +/*# sourceMappingURL=app.css.map*/ \ No newline at end of file diff --git a/experiences/asteroids/web/app.js b/experiences/asteroids/web/app.js new file mode 100644 index 0000000..76cf4ae --- /dev/null +++ b/experiences/asteroids/web/app.js @@ -0,0 +1,98915 @@ +/******/ (function() { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +//HTML Modules + +/***/ "./src/app.html": +/*!**********************!*\ + !*** ./src/app.html ***! + \**********************/ +/***/ (function(module) { + +// Module +var code = "
\ + \ + \ + \ +
\ +\ +\ +\ +\ +\ +\ +
\ +
\ +
\ + \ + \ + \ +
\ + \ +
\ +
\ + \ + \ +
\ +\ +\ +\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "./src/components/asteroid_modals/asteroid_modals.html": +/*!*************************************************************!*\ + !*** ./src/components/asteroid_modals/asteroid_modals.html ***! + \*************************************************************/ +/***/ (function(module) { + +// Module +var code = "
\ +
\ +
\ +
\ +

{{title}}

\ +
\ + \ +
\ +
\ + \ + \ + \ +
\ +
\ +
\ + \ + \ +
\ +
\ +
"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "./src/components/asteroid_modals/modals/filters_modal/filters_modal.html": +/*!********************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/filters_modal/filters_modal.html ***! + \********************************************************************************/ +/***/ (function(module) { + +// Module +var code = "
\ +

\ + Apply a variety of filters to visualize the different groups of astronomical\ + objects\ +

\ +
\ +
\ +
Composition
\ +
\ +
\ +
\ +
\ +
Asteroids
\ + \ + \ + \ + \ + \ + \ +
\ +
\ +
Made up of rock, metals and dust
\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ +\ +
\ +
\ +
\ +
Comets
\ +
\ + \ + \ + \ + \ + \ +
\ +
\ +
Made up of rock, dust and frozen ices
\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ +
\ +
\ +
Potential Threats
\ +
\ +
\ +
\ +
\ +
PHOs
\ +
\ + \ + \ + \ + \ + \ +
\ +
\ +
Potentially hazardous objects
\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ +
\ +
\ +\ +
\ +
\ + \ +
\ +\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "./src/components/asteroid_modals/modals/learn_modal/learn_modal.html": +/*!****************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/learn_modal/learn_modal.html ***! + \****************************************************************************/ +/***/ (function(module) { + +// Module +var code = "
\ +

\ + Take a deeper dive into Asteroids with our interactive scrollable stories\ +

\ +
\ +\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "./src/components/countdown/countdown.html": +/*!*************************************************!*\ + !*** ./src/components/countdown/countdown.html ***! + \*************************************************/ +/***/ (function(module) { + +// Module +var code = "
\ + COUNTDOWN\ +
\ +
{{tText}}
\ +
\ +

{{numDays}}

\ + DAYS\ +
\ +

:

\ +
\ +

{{numHours}}

\ + HOURS\ +
\ +

:

\ +
\ +

{{numMinutes}}

\ + MINUTES\ +
\ +

:

\ +
\ +

{{numSeconds}}

\ + SECONDS\ +
\ +
\ +
\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "./src/components/definition_overlay/definition_overlay.html": +/*!*******************************************************************!*\ + !*** ./src/components/definition_overlay/definition_overlay.html ***! + \*******************************************************************/ +/***/ (function(module) { + +// Module +var code = "
\ +
\ +
\ +
\ +

{{title}}

\ +
\ +
\ +
{{content}}
\ +
\ +
RELATED TERMS
\ +
\ +
\ +
\ +
\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "./src/components/navigation/navigation.html": +/*!***************************************************!*\ + !*** ./src/components/navigation/navigation.html ***! + \***************************************************/ +/***/ (function(module) { + +// Module +var code = "\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "./src/components/splash_screen/splash_screen.html": +/*!*********************************************************!*\ + !*** ./src/components/splash_screen/splash_screen.html ***! + \*********************************************************/ +/***/ (function(module) { + +// Module +var code = "
\ +
\ +
\ +
\ +
\ +
\ +
\ +
Eyes
\ +
on
\ +
Asteroids
\ +
\ +
\ +
\ +
\ +
\ +
\ + \ + \ + \ + \ +
\ +
\ +
\ +
\ +
\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "./src/components/time_slider/time_slider.html": +/*!*****************************************************!*\ + !*** ./src/components/time_slider/time_slider.html ***! + \*****************************************************/ +/***/ (function(module) { + +// Module +var code = "
\ + \ +
\ +
\ +
;\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "./src/components/watch_panel/watch_card.html": +/*!****************************************************!*\ + !*** ./src/components/watch_panel/watch_card.html ***! + \****************************************************/ +/***/ (function(module) { + +// Module +var code = "
\ +
\ +

{{title}}

\ +
\ + DATE\ +
\ +
{{date}}
\ + {{time}}\ +
\ +\ +
\ +
\ + DISTANCE\ +
\ +
{{distance}}
\ +
{{distanceUnit}}
\ +
\ +\ +
\ +
\ +
\ +
\ +
\ +
\ + {{diameter}}\ + {{diameterUnit}}\ + {{diameterEstimatedText}}\ +
\ +\ +
\ +
\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/breadcrumb/breadcrumb.html": +/*!*********************************************************!*\ + !*** ../eyes/src/components/breadcrumb/breadcrumb.html ***! + \*********************************************************/ +/***/ (function(module) { + +// Module +var code = "\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/carousel/carousel.html": +/*!*****************************************************!*\ + !*** ../eyes/src/components/carousel/carousel.html ***! + \*****************************************************/ +/***/ (function(module) { + +// Module +var code = "
\ +
\ + \ +
\ +
\ +
\ +
\ +
\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/carousel/slide_template.html": +/*!***********************************************************!*\ + !*** ../eyes/src/components/carousel/slide_template.html ***! + \***********************************************************/ +/***/ (function(module) { + +// Module +var code = "\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/carousel_panel/carousel_panel.html": +/*!*****************************************************************!*\ + !*** ../eyes/src/components/carousel_panel/carousel_panel.html ***! + \*****************************************************************/ +/***/ (function(module) { + +// Module +var code = "
\ +\ + \ +
\ +
\ +
\ +
\ +
{{preTitle}}
\ +

{{title}}

\ +
\ +\ + \ +
\ +\ +
\ +
\ +
\ +

{{title}}

\ +
\ +
{{caption}}
\ +
\ +\ + \ +
\ + \ +
\ +
\ +\ +\ +
\ +\ +
\ +
\ +\ +
\ +\ +
\ +
\ +\ +
\ +\ +\ +\ +
\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/checkbox/checkbox.html": +/*!*****************************************************!*\ + !*** ../eyes/src/components/checkbox/checkbox.html ***! + \*****************************************************/ +/***/ (function(module) { + +// Module +var code = "
  • \ + \ + {{text}}\ +
  • \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/clock/clock.html": +/*!***********************************************!*\ + !*** ../eyes/src/components/clock/clock.html ***! + \***********************************************/ +/***/ (function(module) { + +// Module +var code = "\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/clock_shortcut/clock_shortcut.html": +/*!*****************************************************************!*\ + !*** ../eyes/src/components/clock_shortcut/clock_shortcut.html ***! + \*****************************************************************/ +/***/ (function(module) { + +// Module +var code = "\ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/kiosk_base/kiosk_base.html": +/*!*********************************************************!*\ + !*** ../eyes/src/components/kiosk_base/kiosk_base.html ***! + \*********************************************************/ +/***/ (function(module) { + +// Module +var code = "
    \ +
    \ + Starting experience...\ +
    \ +
    \ +
    \ +
    \ + This session has ended\ +
    \ +
    \ + START OVER\ +
    \ +
    \ + CONTINUE\ +
    \ +
    \ +
    \ +
    \ +
    \ + TOUCH TO START\ +
    \ +
    \ +
    \ +
    Time left:
    \ + \ +
    \ +
    \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/layer_panel/layer_panel.html": +/*!***********************************************************!*\ + !*** ../eyes/src/components/layer_panel/layer_panel.html ***! + \***********************************************************/ +/***/ (function(module) { + +// Module +var code = "
    \ +
    \ +
    Layers
    \ + \ +
    \ +
    \ +
    \ +
    \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/load_icon/load_icon.html": +/*!*******************************************************!*\ + !*** ../eyes/src/components/load_icon/load_icon.html ***! + \*******************************************************/ +/***/ (function(module) { + +// Module +var code = "
    \ +
    \ +
    \ +
    \ +
    \ +
    \ +
    \ +
    Loading
    \ +
    \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/overlay/overlay.html": +/*!***************************************************!*\ + !*** ../eyes/src/components/overlay/overlay.html ***! + \***************************************************/ +/***/ (function(module) { + +// Module +var code = "
    \ + \ +
    \ +
    \ + \ +
    \ +
    \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/search/search.html": +/*!*************************************************!*\ + !*** ../eyes/src/components/search/search.html ***! + \*************************************************/ +/***/ (function(module) { + +// Module +var code = "
    \ + \ +
    \ +
    \ +
    \ + \ + \ + \ +
    \ +
    \ +
    \ + {{searchInfo}}\ +
    \ +
      \ +
      \ +
      \ +
      \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/settings/settings.html": +/*!*****************************************************!*\ + !*** ../eyes/src/components/settings/settings.html ***! + \*****************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ +
      \ +
      \ + \ + \ + \ + \ + \ + \ + \ +
      \ + \ + \ + \ +
      \ + \ +
      \ +
      \ + \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/share_modal/share_modal.html": +/*!***********************************************************!*\ + !*** ../eyes/src/components/share_modal/share_modal.html ***! + \***********************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ +
      \ +
      \ +
      \ +

      Share

      \ + \ +
        \ +
      • \ +
      • \ +
      \ + \ +
      \ +
      \ + \ +
      \ +
      \ + \ + \ + \ + \ +
      \ +
      \ + \ +
      \ +
      \ + Interactive Preview\ +
      \ +
      \ + \ +
      \ + \ + \ + \ +
      \ +\ + \ +
      \ +
      \ +
      Embed Options
      \ +
      \ +
      \ +
      \ + Advanced Options\ +
      \ +
      \ +
      \ +\ +
      \ +
      \ +
      \ +\ +
      \ +

      Copied to clipboard!

      \ +\ +
      \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/buttons_block/buttons_block.html": +/*!****************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/buttons_block/buttons_block.html ***! + \****************************************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ +
      {$blockTitle}
      \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/checkbox_block/checkbox_block.html": +/*!******************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/checkbox_block/checkbox_block.html ***! + \******************************************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ +
      {$checkboxBlockTitle}
      \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/description_block/description_block.html": +/*!************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/description_block/description_block.html ***! + \************************************************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ +
      \ +

      {$title}

      \ +

      {$subtitle}

      \ +
      \ +
      \ +
      {$description}
      \ + \ + {$more}\ + \ + \ + \ + {{moreMessage}}\ + \ + \ + \ +
      \ +
      \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/hint_block/hint_block.html": +/*!**********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/hint_block/hint_block.html ***! + \**********************************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ + \ + {{text}}\ + \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/image_block/image_block.html": +/*!************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/image_block/image_block.html ***! + \************************************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ + \"{$alt}\"\ + {$title}\ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/replay_button_block/replay_button_block.html": +/*!****************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/replay_button_block/replay_button_block.html ***! + \****************************************************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ + \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/title_block/title_block.html": +/*!************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/title_block/title_block.html ***! + \************************************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ +

      {$title}

      \ +

      {$subtitle}

      \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/toggle_block/toggle_block.html": +/*!**************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/toggle_block/toggle_block.html ***! + \**************************************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ + \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/time_controller/time_controller.html": +/*!*******************************************************************!*\ + !*** ../eyes/src/components/time_controller/time_controller.html ***! + \*******************************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ +
      \ + \ + \ + \ +
      \ + \ + \ +
      \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/toast/toast.html": +/*!***********************************************!*\ + !*** ../eyes/src/components/toast/toast.html ***! + \***********************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ + \ +
      {{toastContent}}
      \ + \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +/***/ "../eyes/src/components/tutorial_overlay/tutorial_overlay.html": +/*!*********************************************************************!*\ + !*** ../eyes/src/components/tutorial_overlay/tutorial_overlay.html ***! + \*********************************************************************/ +/***/ (function(module) { + +// Module +var code = "
      \ +\ +
      \ +
      \ +\ +
      \ +
      \ +\ +
      \ +\ +
      \ +\ +
      \ + \ +
      \ +\ +\ + \ +
      \ +"; +// Exports +module.exports = code; + +/***/ }), + +//CSS Modules (These all seem empty and identical?) + +/***/ "./src/assets/css/asteroid.css": +/*!*************************************!*\ + !*** ./src/assets/css/asteroid.css ***! + \*************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/assets/css/clock.css": +/*!**********************************!*\ + !*** ./src/assets/css/clock.css ***! + \**********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/assets/css/color.css": +/*!**********************************!*\ + !*** ./src/assets/css/color.css ***! + \**********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/assets/css/font.css": +/*!*********************************!*\ + !*** ./src/assets/css/font.css ***! + \*********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/assets/css/grid.css": +/*!*********************************!*\ + !*** ./src/assets/css/grid.css ***! + \*********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/assets/css/icon.css": +/*!*********************************!*\ + !*** ./src/assets/css/icon.css ***! + \*********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/assets/css/label.css": +/*!**********************************!*\ + !*** ./src/assets/css/label.css ***! + \**********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/assets/css/search.css": +/*!***********************************!*\ + !*** ./src/assets/css/search.css ***! + \***********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/assets/css/settings.css": +/*!*************************************!*\ + !*** ./src/assets/css/settings.css ***! + \*************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/assets/css/viewport.css": +/*!*************************************!*\ + !*** ./src/assets/css/viewport.css ***! + \*************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/asteroid_modals/asteroid_modals.css": +/*!************************************************************!*\ + !*** ./src/components/asteroid_modals/asteroid_modals.css ***! + \************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/asteroid_modals/modals/filters_modal/filters_modal.css": +/*!*******************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/filters_modal/filters_modal.css ***! + \*******************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/asteroid_modals/modals/learn_modal/learn_modal.css": +/*!***************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/learn_modal/learn_modal.css ***! + \***************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/asteroid_panel/asteroid_panel.css": +/*!**********************************************************!*\ + !*** ./src/components/asteroid_panel/asteroid_panel.css ***! + \**********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/breadcrumb/breadcrumb.css": +/*!**************************************************!*\ + !*** ./src/components/breadcrumb/breadcrumb.css ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/countdown/countdown.css": +/*!************************************************!*\ + !*** ./src/components/countdown/countdown.css ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/definition_overlay/definition_overlay.css": +/*!******************************************************************!*\ + !*** ./src/components/definition_overlay/definition_overlay.css ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/following_panel/following_panel.css": +/*!************************************************************!*\ + !*** ./src/components/following_panel/following_panel.css ***! + \************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/home_button/home_button.css": +/*!****************************************************!*\ + !*** ./src/components/home_button/home_button.css ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/mission_panel/mission_panel.css": +/*!********************************************************!*\ + !*** ./src/components/mission_panel/mission_panel.css ***! + \********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/navigation/navigation.css": +/*!**************************************************!*\ + !*** ./src/components/navigation/navigation.css ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/splash_screen/splash_screen.css": +/*!********************************************************!*\ + !*** ./src/components/splash_screen/splash_screen.css ***! + \********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/time_slider/time_slider.css": +/*!****************************************************!*\ + !*** ./src/components/time_slider/time_slider.css ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/watch_panel/watch_card.css": +/*!***************************************************!*\ + !*** ./src/components/watch_panel/watch_card.css ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "./src/components/watch_panel/watch_panel.css": +/*!****************************************************!*\ + !*** ./src/components/watch_panel/watch_panel.css ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/animation.css": +/*!********************************************!*\ + !*** ../eyes/src/assets/css/animation.css ***! + \********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/camera_follow.css": +/*!************************************************!*\ + !*** ../eyes/src/assets/css/camera_follow.css ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/color.css": +/*!****************************************!*\ + !*** ../eyes/src/assets/css/color.css ***! + \****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/components.css": +/*!*********************************************!*\ + !*** ../eyes/src/assets/css/components.css ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/font.css": +/*!***************************************!*\ + !*** ../eyes/src/assets/css/font.css ***! + \***************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/grid.css": +/*!***************************************!*\ + !*** ../eyes/src/assets/css/grid.css ***! + \***************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/grid_layout.css": +/*!**********************************************!*\ + !*** ../eyes/src/assets/css/grid_layout.css ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/icon.css": +/*!***************************************!*\ + !*** ../eyes/src/assets/css/icon.css ***! + \***************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/label.css": +/*!****************************************!*\ + !*** ../eyes/src/assets/css/label.css ***! + \****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/layout.css": +/*!*****************************************!*\ + !*** ../eyes/src/assets/css/layout.css ***! + \*****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/scrollbar.css": +/*!********************************************!*\ + !*** ../eyes/src/assets/css/scrollbar.css ***! + \********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/sprite.css": +/*!*****************************************!*\ + !*** ../eyes/src/assets/css/sprite.css ***! + \*****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/assets/css/style.css": +/*!****************************************!*\ + !*** ../eyes/src/assets/css/style.css ***! + \****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/breadcrumb/breadcrumb.css": +/*!********************************************************!*\ + !*** ../eyes/src/components/breadcrumb/breadcrumb.css ***! + \********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/carousel/carousel.css": +/*!****************************************************!*\ + !*** ../eyes/src/components/carousel/carousel.css ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/carousel_panel/carousel_panel.css": +/*!****************************************************************!*\ + !*** ../eyes/src/components/carousel_panel/carousel_panel.css ***! + \****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/checkbox/checkbox.css": +/*!****************************************************!*\ + !*** ../eyes/src/components/checkbox/checkbox.css ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/clock/clock.css": +/*!**********************************************!*\ + !*** ../eyes/src/components/clock/clock.css ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/clock_shortcut/clock_shortcut.css": +/*!****************************************************************!*\ + !*** ../eyes/src/components/clock_shortcut/clock_shortcut.css ***! + \****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/kiosk_base/kiosk_base.css": +/*!********************************************************!*\ + !*** ../eyes/src/components/kiosk_base/kiosk_base.css ***! + \********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/layer_panel/layer_panel.css": +/*!**********************************************************!*\ + !*** ../eyes/src/components/layer_panel/layer_panel.css ***! + \**********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/load_icon/load_icon.css": +/*!******************************************************!*\ + !*** ../eyes/src/components/load_icon/load_icon.css ***! + \******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/overlay/overlay.css": +/*!**************************************************!*\ + !*** ../eyes/src/components/overlay/overlay.css ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/search/search.css": +/*!************************************************!*\ + !*** ../eyes/src/components/search/search.css ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/settings/settings.css": +/*!****************************************************!*\ + !*** ../eyes/src/components/settings/settings.css ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/share_modal/share_modal.css": +/*!**********************************************************!*\ + !*** ../eyes/src/components/share_modal/share_modal.css ***! + \**********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/buttons_block/buttons_block.css": +/*!***************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/buttons_block/buttons_block.css ***! + \***************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/checkbox_block/checkbox_block.css": +/*!*****************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/checkbox_block/checkbox_block.css ***! + \*****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/description_block/description_block.css": +/*!***********************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/description_block/description_block.css ***! + \***********************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/hint_block/hint_block.css": +/*!*********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/hint_block/hint_block.css ***! + \*********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/image_block/image_block.css": +/*!***********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/image_block/image_block.css ***! + \***********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/replay_button_block/replay_button_block.css": +/*!***************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/replay_button_block/replay_button_block.css ***! + \***************************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/story_base_content_block/story_base_content_block.css": +/*!*************************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/story_base_content_block/story_base_content_block.css ***! + \*************************************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/toggle_block/toggle_block.css": +/*!*************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/toggle_block/toggle_block.css ***! + \*************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/story/story.css": +/*!**********************************************!*\ + !*** ../eyes/src/components/story/story.css ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/time_controller/time_controller.css": +/*!******************************************************************!*\ + !*** ../eyes/src/components/time_controller/time_controller.css ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/toast/toast.css": +/*!**********************************************!*\ + !*** ../eyes/src/components/toast/toast.css ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/src/components/tutorial_overlay/tutorial_overlay.css": +/*!********************************************************************!*\ + !*** ../eyes/src/components/tutorial_overlay/tutorial_overlay.css ***! + \********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +//JS Modules (One of these is an odd recursive function that isn't explicitly a .js file) + +/***/ "./src/app.js": +/*!********************!*\ + !*** ./src/app.js ***! + \********************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AsteroidsApp": function() { return /* binding */ AsteroidsApp; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./internal */ "./src/internal.js"); +/* harmony import */ var _configs_components_info__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./configs/components_info */ "./src/configs/components_info.js"); +/* harmony import */ var _data_heroes_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./data/heroes.json */ "./src/data/heroes.json"); +/* harmony import */ var _data_tutorials_json__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./data/tutorials.json */ "./src/data/tutorials.json"); +/* harmony import */ var _configs_time_info_json__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./configs/time_info.json */ "./src/configs/time_info.json"); +/* harmony import */ var _configs_scene_info_json__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./configs/scene_info.json */ "./src/configs/scene_info.json"); +/* harmony import */ var _configs_view_info_json__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./configs/view_info.json */ "./src/configs/view_info.json"); +/* harmony import */ var _configs_story_info_json__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./configs/story_info.json */ "./src/configs/story_info.json"); +/* harmony import */ var _views__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./views */ "./src/views/index.js"); +/* harmony import */ var _data_stories__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./data/stories */ "./src/data/stories/index.js"); +/* harmony import */ var _app_html__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./app.html */ "./src/app.html"); +/* harmony import */ var _app_html__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(_app_html__WEBPACK_IMPORTED_MODULE_14__); + + + + + + + + + + + + + + + + +/** + * Asteroids app class. + * ToDo: It doesn't really make sense to store the _heroes and the _neos here. + * Maybe they could be moved to an extended content manager + */ +class AsteroidsApp extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseApp { + /** + * Constructor. + */ + constructor() { + super(_internal__WEBPACK_IMPORTED_MODULE_4__.Types); + + /** @inheritdoc */ + this._timeInfo = _configs_time_info_json__WEBPACK_IMPORTED_MODULE_8__; + + /** @inheritdoc */ + this._sceneInfo = _configs_scene_info_json__WEBPACK_IMPORTED_MODULE_9__; + + /** @inheritdoc */ + this._viewClasses = { ..._views__WEBPACK_IMPORTED_MODULE_12__["default"] }; + + /** @inheritdoc */ + this._viewInfo = _configs_view_info_json__WEBPACK_IMPORTED_MODULE_10__; + + /** @inheritdoc */ + this._componentInfo = _configs_components_info__WEBPACK_IMPORTED_MODULE_5__["default"]; + + /** + * The hero asteroids + */ + this._heroes = _data_heroes_json__WEBPACK_IMPORTED_MODULE_6__; + + /** + * The NEO information objects. + * @type {Map} + * @private + */ + this._neos = new Map(); + + this._particleMatchFunctions = {}; + + /** + * Off white colors for Pioneer + */ + this._colors = { + neos: [0.823, 0.882, 0.909], + spacecraft: [0.969, 0.957, 0.875] + }; + + /** + * Stored values to reset on leaving. + * @type {object} + */ + this._resetValues = {}; + + this.tutorials = _data_tutorials_json__WEBPACK_IMPORTED_MODULE_7__; + + this.bindFunctions(['addParticleMatchFunction', 'removeParticleMatchFunction', 'createAsteroidParticles']); + } + + /** + * Getters + */ + + /** + * Returns hero asteroids + * @returns {object} + */ + get heroes() { + return this._heroes; + } + + /** + * Gets the NEOs data. + * @returns {Map} + */ + get neos() { + return this._neos; + } + + /** + * Set up routes. + * @override + */ + setUpRoutes() { + this.getManager('router').addRoutes([ + { route: this.getManager('router').homeRoute, view: 'home' }, + { route: '/story/:id', view: 'story' }, + { route: '/missions/:spacecraft', view: 'mission' }, + { route: '/planets/:planet', view: 'following' }, + { route: '/stars/:star', view: 'following' }, + { route: '/moons/:moon', view: 'following' }, + { route: '/watch', view: 'watch' }, + { route: '/watch/:neoName', view: 'watch' }, + { route: '/:spaceObject', view: 'asteroid' } + ]); + } + + /** + * Set up scene. + * @override + */ + async setUpScene() { + // Load the NEOs. + this._neos = await _internal__WEBPACK_IMPORTED_MODULE_4__.NEOUtils.loadNEOs(this.pioneer); + + // Update the label manager icon map to adjusst icon classes. + const labelManager = this.getManager('label'); + labelManager._iconMap.Asteroid = 'asteroid'; + labelManager._iconMap['Dwarf Planet'] = 'asteroid'; + labelManager._iconMap.Comet = 'comet'; + labelManager._iconMap.Spacecraft = 'spacecraft'; + labelManager._iconMap.Default = ''; + + // Load up the main entities. + await super.setUpScene(); + + // Add in the hero asteroids, if they aren't already added. + const scene = /** @type {Pioneer.Scene} */(this.scene); + + for (const name of Object.keys(this._heroes)) { + if (scene.getEntity(name) === null && this._neos.has(name)) { + const entity = _internal__WEBPACK_IMPORTED_MODULE_4__.NEOUtils.createEntity(this._neos.get(name), scene); + this.setUpLabels(entity, { category: _data_heroes_json__WEBPACK_IMPORTED_MODULE_6__[name].category }); + } + } + + /** + * Re-define label weight map and set label weights again. + * For asteroids, we want to prioritise comets, asteroids and missions, while making planet and moon clicking harder. + */ + labelManager._weightMap.Moon = '5'; + labelManager._weightMap.Planet = '10'; + labelManager._weightMap.Spacecraft = '15'; + labelManager._weightMap.Comet = '20'; + labelManager._weightMap.Asteroid = '20'; + labelManager._weightMap['Dwarf Planet'] = '20'; + labelManager._weightMap.Star = '30'; + labelManager._weightMap.Watch = '40'; + labelManager._weightMap.Focus = '50'; + + labelManager.setWeights(this.getManager('content').getEntityList()); + + // Create the asteroid orbital particles (after neos have loaded) + if (this._neos.size) { + this.createAsteroidParticles(); + } + else { + console.error('NEOs data could not be loaded.'); + } + + // Change planet trails + const trailManager = this.getManager('trail'); + const defaultOpacity = trailManager._opacity.primary; + + const width = { + default: [4, 4], + hover: [5, 5] + }; + const planets = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityNamesInGroup('planets'); + planets.forEach(id => { + this._resetValues[id] = {}; + }); + + // Add line of sight component + const sun = this.scene.get('sun'); + if (!sun.get('orbiterLineOfSight')) { + const lineOfSight = sun.addComponent('orbiterLineOfSight'); + lineOfSight.setEnabled(false); + } + + // Create rings for Sun and Earth + const sceneManager = this.getManager('scene'); + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.SceneHelpers.waitTillEntitiesInPlace(scene, ['earth']); + sceneManager.createRing('sunRing', eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm * 1.3, 'sun', { + orbitPlaneEntityName: 'earth', + color: new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(1, 1, 1), + labelText: '1.3 AU distance from Sun', + isEnable: false + }); + sceneManager.createTorus('sunTorus', 1.496e8 * 0.95 /* - 0.05 AU */, 1.496e8 * 1.05 /* + 0.05 AU */, 'sun', { + orbitPlaneEntityName: 'earth', + color: new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(1, 1, 1, 0.2), + labelText: 'PHO boundary zone', + isEnable: false + }); + + // Make these labels always show, also 'Earth' can always + labelManager.addException('sunRingLabel'); + labelManager.addException('sunTorusLabel'); + } + + /** + * Setup labels. + * @param {Pioneer.Entity} entity + * @param {object} options - the options + * @param {string} [options.category = undefined] - optional category. + */ + setUpLabels(entity, { category = undefined } = {}) { + const contentManager = this.getManager('content'); + const labelManager = this.getManager('label'); + + // If it's a planet, set color labels + const colorLabels = ['mercury', 'venus', 'earth', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']; + + const handleMouseEnter = (_, entityName) => labelManager.triggerCallbacks('hoverchange', [entityName, true, colorLabels.includes(entityName)]); + const handleMouseLeave = (e, entityName) => { + // Determine if were hovering on a selected asteroids watch asteroid. + if (e.target?.classList?.contains('selected') && e.target?.classList?.contains('asteroid-watch-label')) { + return; + } + labelManager.triggerCallbacks('hoverchange', [entityName, false, colorLabels.includes(entityName)]); + }; + + labelManager.addEntity(entity); + labelManager.setLabelProps({ + getLabelClass: entityName => `no-select ${colorLabels.includes(entityName) ? 'color' : ''} ${contentManager.getClassName(entityName, category) ?? ''}`, + handleMouseEnter, + handleMouseLeave, + ...category && { getIconClass: _ => category.toLowerCase() } + }, [entity.getName()]); + } + + /** + * Set up managers. + */ + setUpManagers() { + super.setUpManagers(); + + // Add managers + this.addManager('watch', _internal__WEBPACK_IMPORTED_MODULE_4__.WatchManager); + this.addManager('filters', _internal__WEBPACK_IMPORTED_MODULE_4__.FiltersManager, this._scene); + this.addManager('neos', _internal__WEBPACK_IMPORTED_MODULE_4__.NEOsManager, this._scene); + this.addManager('link', _internal__WEBPACK_IMPORTED_MODULE_4__.LinkManager); + + // Set up title manager and pparsing function. + + const titleManagerOptions = { + ...this._sceneInfo.title, + parseFn: ({ url, params, query } = {}) => { + const { spaceObject, spacecraft, planet, star, moon } = params; + const entityName = spaceObject || spacecraft || planet || star || moon; + + if (query?.includes('=learn')) { + return 'Learn'; + } + if (query?.includes('=filters')) { + return 'Filters'; + } + if (url?.includes('/story') && params.id) { + const story = _configs_story_info_json__WEBPACK_IMPORTED_MODULE_11__.find(({ path }) => path === params.id); + if (story?.title) { + return story.title; + } + } + if (url?.includes('/watch')) { + return 'Asteroid Watch'; + } + if (entityName) { + const entity = this.scene.get(entityName); + const { innerText: label } = entity?.getComponentByType('div')?.getDiv() || {}; + if (label) { + return label; + } + } + return 'Home'; + } + }; + + const titleManagerClass = _internal__WEBPACK_IMPORTED_MODULE_4__.Types.get('TitleManager'); + const titleManager = this.addManager('title', titleManagerClass, titleManagerOptions); + } + + /** + * Builds search database from the content managers entity list info and a list of exceptions. + * @returns {object} + */ + _buildSearchDatabase() { + const entityInfo = eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.deepCopy(this.getManager('content').getEntityList()); + const entityList = this.scene._entities._itemsByName; + + const exceptions = ['observable_universe', 'milky_way']; + const database = {}; + + // Add entities to search database + entityList.forEach(key => { + const info = entityInfo[key]; + if (!exceptions.includes(key) && info) { + // Add url to info + info.url = `/${info.id}`; + database[key] = info; + } + }); + + // Add NEO to search database + this._neos.forEach((value, key) => { + if (key in database) { + database[key].neo = value; + } + else { + database[key] = { + id: key, + iauName: value.name, + url: `/${key}`, + neo: value + }; + } + }); + + return database; + } + + /** + * Set up components. + */ + async setUpComponents() { + await super.setUpComponents(); + + const entityInfo = this.getManager('content').getEntityList(); + + // Update story list + const contentManager = this.getManager('content'); + contentManager.setStoryList(_data_stories__WEBPACK_IMPORTED_MODULE_13__.STORY_LIST); + contentManager.setStories(_data_stories__WEBPACK_IMPORTED_MODULE_13__.STORIES); + + // Build and set search database. + const searchDatabase = this._buildSearchDatabase(); + this.getManager('search').setDatabase(searchDatabase); + + // Hero asteroids populate the featured search items (most popular). + const featuredItems = Object.keys(this.heroes).map(heroName => { + const heroEntity = entityInfo[heroName]; + if (!heroEntity) { + const heroData = _data_heroes_json__WEBPACK_IMPORTED_MODULE_6__[heroName]; + + if (heroData.iauName && heroData.id) { + return { + text: heroData.iauName, + sortText: heroData.displayName || heroData.iauName, + url: `/${heroData.id}` + }; + } + else { + console.error(`No entity found for hero: ${heroName}`); + return false; + } + } + return { + text: heroEntity.iauName, + sortText: heroEntity.displayName || heroEntity.iauName, + url: `/${heroEntity.id}` + }; + }); + + // Sort alphabetically by display name and set up. + featuredItems.sort((a, b) => a.sortText > b.sortText ? 1 : -1); + this.getComponent('search').setupFeaturedSuggestion(featuredItems); + + // Create filter array of the heroes to update trail colors. + const trailManager = this.getManager('trail'); + const neoIds = ['73p_schwassmann_wachmann_3']; + const spacecraftIds = []; + + this.scene._entities._items.forEach(entity => { + const id = entity.getName(); + const { category } = entityInfo[id] || {}; + + if (category === 'Asteroid' || category === 'Dwarf Planet' || category === 'Comet') neoIds.push(id); + else if (category === 'Spacecraft') spacecraftIds.push(id); + }); + // Set trail colors. + trailManager.setColor(neoIds, new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(...this._colors.neos, 0.35)); + trailManager.setColor(spacecraftIds, new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(...this._colors.spacecraft, 0.5)); + + // Enable layers + const layerManager = this.getManager('layer'); + const layerPanel = this.getComponent('layerPanel'); + if (!layerManager.getLayer('asteroids').visible) { + layerPanel.toggleLayer('asteroids'); + } + if (!layerManager.getLayer('comets').visible) { + layerPanel.toggleLayer('comets'); + } + if (!layerManager.getLayer('dwarfPlanets').visible) { + layerPanel.toggleLayer('dwarfPlanets'); + } + layerManager.getLayer('starfield').toggleCallback[0](false); + } + + /** + * Goes through tutorials to find and replace function calls between double braces {{}} + * Works in the same way as component's setVariables, but uses a function call instead. + * @param {Array} allTutorials + * @returns {Array} + */ + setTutorialVariables(allTutorials) { + const allTutorialsStr = JSON.stringify(allTutorials); + + const replacedJsonString = allTutorialsStr.replace(/\{\{(.+?)\}\}/g, (match, functionName) => { + if (this[functionName] && typeof this[functionName] === 'function') { + return this[functionName](); + } + return match; + }); + + return JSON.parse(replacedJsonString); + } + + /** + * Adds (or replaces) a createAsteroidParticles matchFunction + * @param {(neo: NEO) => boolean} matchFunction - A match function that returns true if the NEO should be shown. + * @param {string} functionId - matchFunction identifier + * @param {boolean?} andRun - whether to run createAsteroidParticles after + * @param {(orbitalElements: Pioneer.OrbitalElements[]) => null?} callback - if andRun, callback for createAsteroidParticles + */ + addParticleMatchFunction(matchFunction, functionId, andRun, callback) { + this._particleMatchFunctions[functionId] = matchFunction; + if (andRun) this.createAsteroidParticles(callback); + } + + /** + * Removes a createAsteroidParticles matchFunction + * @param {string} functionId - matchFunction identifier + * @param {boolean?} andRun - whether to run createAsteroidParticles after + * @param {(orbitalElements: Pioneer.OrbitalElements[]) => null?} callback - if andRun, callback for createAsteroidParticles + */ + removeParticleMatchFunction(functionId, andRun, callback) { + delete this._particleMatchFunctions[functionId]; + if (andRun) this.createAsteroidParticles(callback); + } + + /** + * Creates the asteroids as a component of the sun. + * @param {(orbitalElements: Pioneer.OrbitalElements[]) => null} callback - Callback for when all orbitalElement are first captured + */ + createAsteroidParticles(callback) { + // Get the sun. + const sun = this.scene.getEntity('sun'); + + // First remove the component if it already exists. + if (sun.getComponentByType('orbitalParticles') !== null) { + sun.removeComponent(sun.getComponentByType('orbitalParticles')); + } + + // The colors of the asteroids will be random between these two shades. + const minColor = new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(0, 0.25, 0.35); + const maxColor = new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(0, 0.45, 0.65); + + // Brighten them up a bit. + const white = new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(1, 1, 1); + minColor.lerp(minColor, white, 0.10); + maxColor.lerp(maxColor, white, 0.15); + + // Add the component. + const orbitalParticles = /** @type {Pioneer.OrbitalParticlesComponent} */(sun.addComponent('orbitalParticles')); + orbitalParticles.setLoadFunction(async () => { + const colors = /** @type {Pioneer.Color[]} */([]); + const scales = /** @type {number[]} */([]); + const orbitalElements = /** @type {Pioneer.OrbitalElements[]} */([]); + // const viewportSize = this._pioneer.getViewport('main-viewport').getBounds().size; + // const maxAspectRatio = Math.max(viewportSize.x / viewportSize.y, viewportSize.y / viewportSize.x); + let shouldSkip; + + for (const neo of this._neos.values()) { + // If the neo doesn't match, skip it. + shouldSkip = false; + for (const f in this._particleMatchFunctions) { + if (!this._particleMatchFunctions[f](neo)) { + shouldSkip = true; + break; + } + } + if (shouldSkip) continue; + + if (pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityOptions(neo.pioneerName) !== undefined) { + continue; + } + + // Set the color. + const color = new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(); + if (neo.comet) { + color.set(...this._colors.neos); + } + else { + const u = Math.random(); + color.lerp(minColor, maxColor, u); + } + colors.push(color); + + // Set the scale. + const scale = (neo.comet ? 1.3 : 1) * (neo.pho ? 1.5 : 1) * 3e-3 * Math.max(1.0, Math.log10(1.0 + neo.diameter)); + scales.push(scale); + + // Set the orbital elements. + orbitalElements.push(neo.orbitalElements); + } + if (typeof callback === 'function') callback(orbitalElements); + return { + colors, + scales, + orbitalElements + }; + }); + orbitalParticles.setResourcesLoadedCallback(() => { + const material = /** @type {Pioneer.OrbitalParticlesComponent} */(this._pioneer.get('main', 'sun', 'orbitalParticles')).getThreeJsMaterials()[0]; + + // Added master opacity uniform. + material.uniforms['masterOpacity'] = new pioneer__WEBPACK_IMPORTED_MODULE_3__.THREE.Uniform(0.5); + + material.vertexShader = material.vertexShader.replace( + 'vec4 viewPosition = modelViewMatrix * vec4(offset, 1.0) + vec4(position, 0.0) * scale;', + ` + vec4 viewOffset = modelViewMatrix * vec4(offset, 1.0); + vec4 viewPosition = viewOffset + vec4(position, 0.0) * scale; + `); + material.vertexShader = material.vertexShader.replace( + 'gl_Position = projectionMatrix * viewPosition;', + ` + float aspect_ratio_h = min(1.0, projectionMatrix[0][0] / projectionMatrix[2][1]); + float aspect_ratio_v = min(1.0, projectionMatrix[2][1] / projectionMatrix[0][0]); + gl_Position = projectionMatrix * viewOffset + vec4(position.x * viewOffset.y * scale * aspect_ratio_h, position.z * viewOffset.y * scale * aspect_ratio_v, 0, 0); + `); + material.vertexShader = material.vertexShader.replace( + 'fColor = color;', + 'fColor = color * clamp((length(viewPosition) - 21937.0) / 40000.0, 0.0, 1.0);' + ); + + material.fragmentShader = material.fragmentShader.replace( + 'varying vec2 fPosition;', + `uniform float masterOpacity; + varying vec2 fPosition; + `); + // including master opacity + material.fragmentShader = material.fragmentShader.replace( + 'gl_FragColor = fColor * (1.0 - length(fPosition));', + 'gl_FragColor = fColor * (1.0 - step(1.0, length(fPosition))) * vec4(1.0, 1.0, 1.0, masterOpacity);' + ); + material.needsUpdate = true; + material.blending = pioneer__WEBPACK_IMPORTED_MODULE_3__.THREE.NormalBlending; + }); + } + + /** + * Gets the total NEO count to maximumSignificantDigits. + * @param {number} maximumSignificantDigits + * @returns {string} + */ + getNeoTotal(maximumSignificantDigits = 2) { + return this.neos?.size.toLocaleString(undefined, { maximumSignificantDigits, roundingMode: 'floor' }); + } +} + +AsteroidsApp.html = (_app_html__WEBPACK_IMPORTED_MODULE_14___default()); + +AsteroidsApp.setAppClass(); + + +/***/ }), + +/***/ "./src/assets/index.js": +/*!*****************************!*\ + !*** ./src/assets/index.js ***! + \*****************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); + + + + + + + + + + + + +/***/ }), + +/***/ "./src/components/asteroid_menu_bottom/asteroid_menu_bottom.js": +/*!*********************************************************************!*\ + !*** ./src/components/asteroid_menu_bottom/asteroid_menu_bottom.js ***! + \*********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AsteroidMenuBottom": function() { return /* binding */ AsteroidMenuBottom; } +/* harmony export */ }); +/* harmony import */ var _navigation_navigation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../navigation/navigation */ "./src/components/navigation/navigation.js"); + + +/** + * @inheritdoc + * @extends Navigation + */ +class AsteroidMenuBottom extends _navigation_navigation__WEBPACK_IMPORTED_MODULE_0__.Navigation { + /** @inheritdoc */ + init() { + super.init(); + + this.bindFunctions(['isFilteringChange']); + this._callbackRegistry.push({ + emitter: this._app.getManager('filters'), + event: 'isFilteringChange', + callback: this.isFilteringChange + }); + + const param = { + position: 'bottom', + entry: [ + { + title: 'Learn', + svg: './assets/default/svg/learn.svg', + onClick: () => { + this._app.getManager('router').navigate({ modal: 'learn' }); + } + }, + { + title: 'Asteroid Watch', + svg: './assets/svg/asteroid.svg', + onClick: () => { + this._app.getManager('watch').onWatchClick(); + } + }, + { + title: 'Filters', + svg: './assets/svg/filter_inactive.svg', + onClick: () => { + this._app.getManager('router').navigate({ modal: 'filters' }); + } + } + ] + }; + super.setup(param); + } + + /** + * Toggles the filters badge + * @param {boolean} isFiltering + */ + isFilteringChange(isFiltering) { + super.toggleBadge('Filters', isFiltering); + } +} + + +/***/ }), + +/***/ "./src/components/asteroid_menu_top/asteroid_menu_top.js": +/*!***************************************************************!*\ + !*** ./src/components/asteroid_menu_top/asteroid_menu_top.js ***! + \***************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AsteroidMenuTop": function() { return /* binding */ AsteroidMenuTop; } +/* harmony export */ }); +/* harmony import */ var _navigation_navigation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../navigation/navigation */ "./src/components/navigation/navigation.js"); + + +/** + * @inheritdoc + * @extends Navigation + */ +class AsteroidMenuTop extends _navigation_navigation__WEBPACK_IMPORTED_MODULE_0__.Navigation { + /** @inheritdoc */ + init() { + super.init(); + + this.bindFunctions(['isFilteringChange']); + this._callbackRegistry.push({ + emitter: this._app.getManager('filters'), + event: 'isFilteringChange', + callback: this.isFilteringChange + }); + + const currentRoute = this._app.getManager('router')._currentRoute; + const query = currentRoute?.query || ''; + + const param = { + position: 'top', + entry: [ + { + title: 'Learn', + svg: './assets/default/svg/learn.svg', + active: query.includes('modal=learn'), + onClick: () => { + const router = this._app.getManager('router'); + router.navigate({ modal: 'learn' }, router.currentRoute.url); + } + }, + { + title: 'Asteroid Watch', + svg: './assets/svg/asteroid.svg', + onClick: () => { + this._app.getManager('watch').onWatchClick(); + }, + active: currentRoute.url?.includes('watch') + }, + { + title: 'Filters', + svg: './assets/svg/filter_inactive.svg', + active: query.includes('modal=filters'), + onClick: () => { + this._app.getManager('router').navigate({ modal: 'filters' }); + } + } + ] + }; + super.setup(param); + } + + /** + * Called when the url get params change. + * @param {string} modal + */ + async onQueryChange({ modal } = {}) { + super.toggleActive('Learn', modal === 'learn'); + super.toggleActive('Filters', modal === 'filters'); + } + + /** + * Toggles the filters badge + * @param {boolean} isFiltering + */ + isFilteringChange(isFiltering) { + super.toggleBadge('Filters', isFiltering); + } +} + + +/***/ }), + +/***/ "./src/components/asteroid_modals/asteroid_modals.js": +/*!***********************************************************!*\ + !*** ./src/components/asteroid_modals/asteroid_modals.js ***! + \***********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AsteroidModals": function() { return /* binding */ AsteroidModals; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _modals__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modals */ "./src/components/asteroid_modals/modals/index.js"); +/* harmony import */ var _asteroid_modals_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./asteroid_modals.html */ "./src/components/asteroid_modals/asteroid_modals.html"); +/* harmony import */ var _asteroid_modals_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_asteroid_modals_html__WEBPACK_IMPORTED_MODULE_2__); + + + + + + +/** + * A generic modal component. + * @extends BaseComponent + */ +class AsteroidModals extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options) { + super(app, null, { + title: '', + isVisible: false, + ...options + }); + + this._components = ['filtersModal', 'learnModal']; + + this._eventNames.push('overlay'); + this._initCallbacks(); + + /** + * Stored values to reset on leaving. + * @type {Object} + * @private + */ + this._modals = {}; + + /** + * Stored values to reset on leaving. + * @type {FiltersModal|LearnModal} + * @private + */ + this._activeModal = null; + + this.bindFunctions(['close']); + } + + /** + * @override + */ + async init() { + super.init(); + + // Load modals + this._modals.filters = await this._app.addComponentWithPlaceholder({ type: _modals__WEBPACK_IMPORTED_MODULE_1__.FiltersModal, name: 'filtersModal' }, this._element); + this._modals.learn = await this._app.addComponentWithPlaceholder({ type: _modals__WEBPACK_IMPORTED_MODULE_1__.LearnModal, name: 'learnModal' }, this._element); + + // Create and store a reference to icon element. + this._iconEl = document.createElement('img'); + this._children.header?.prepend(this._iconEl); + } + + /** + * Execute actions on query change. + * @param {object} params + * @param {CancelToken} params.cancelToken + * @param {string} params.modal + */ + onQueryChange({ cancelToken, modal } = {}) { + // Check if route was canceled + if (cancelToken && cancelToken.isCanceled) { + return; + } + + const activeModal = this._modals[modal] ?? null; + + // If we're already at the activeModal or at no-modal (null), return early. + if (this._activeModal === activeModal) { + return; + } + + // Set active modal. + this._activeModal = activeModal; + + // Disable all modals by default. + this._disableAllModals(); + + if (this._activeModal) { + const { _title: title, _svg: svg } = this._activeModal; + + // Set title state. + this.setState({ title }); + + // Set icon image properties. + this._iconEl.src = svg ?? ''; + this._iconEl.alt = title ?? ''; + + // Enable and show this main component. + this.setEnabled(true); + this.show(); + + // Enable and show specific modal component. + this._activeModal.setEnabled(true); + this._activeModal.show(); + } + } + + /** + * Updates the URL query to remove the modal parameter. + */ + close() { + const router = this._app.getManager('router'); + router.navigate({ __remove: ['modal'] }, router.currentRoute.url, { keepTime: true }); + } + + /** + * Get the child components. + * @returns {string[]} + */ + get components() { + return this._components; + } + + /** + * Disables this, and all child components + */ + _disableAllModals() { + Object.values(this._modals).forEach(modal => { + modal.hide(); + modal.setEnabled(false); + }); + + this.hide(); + this.setEnabled(false); + } +} + +AsteroidModals.html = (_asteroid_modals_html__WEBPACK_IMPORTED_MODULE_2___default()); + + +/***/ }), + +/***/ "./src/components/asteroid_modals/modals/filters_modal/filters_modal.js": +/*!******************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/filters_modal/filters_modal.js ***! + \******************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _filters_modal_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./filters_modal.html */ "./src/components/asteroid_modals/modals/filters_modal/filters_modal.html"); +/* harmony import */ var _filters_modal_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_filters_modal_html__WEBPACK_IMPORTED_MODULE_1__); + + + + + +/** + * Filter modal component. + * @extends BaseComponent + */ +class FiltersModal extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {import('eyes').Options} options + */ + constructor(app, options) { + super(app, null, { + ...options + }); + + this.state = { + asteroids: false, + comets: false, + phos: false + }; + + this._app = app; + + this._title = 'Filters'; + this._svg = './assets/svg/filter_inactive.svg'; + + this._lastSize = null; + + this.bindFunctions([ + '_filterCallback' + ]); + } + + /** @inheritdoc */ + init() { + super.init(); + this.filtersManager = this._app.getManager('filters'); + } + + /** + * Called when the modal is opened + */ + onShow() { + // Ensure checks and toggles match filter state + const filters = this.filtersManager.getFilters(); + document.getElementById('filters-asteroids-checkbox').checked = filters.asteroids; + document.getElementById('filters-comets-checkbox').checked = filters.comets; + document.getElementById('filters-phos-toggle').checked = filters.phos; + + // Count the objects and update the indicator + this._lastSize = this._lastSize != null ? this._lastSize : this._app.neos.size; + document.getElementsByClassName('filters-modal-count')[0].innerHTML = `${this._lastSize != null ? `${this._lastSize.toLocaleString()}` : 'All'} objects`; + } + + /** + * @override + */ + show() { + this.onShow(); + super.show(); + } + + /** + * On asteroid checkbox change + * @param {Event} e - input event + */ + handleAsteroidCheck(e) { + const checked = e.target.checked; + this.filtersManager.setFilter('asteroids', checked, this._filterCallback); + } + + /** + * On comet checkbox change + * @param {Event} e - input event + */ + handleCometCheck(e) { + const checked = e.target.checked; + this.filtersManager.setFilter('comets', checked, this._filterCallback); + } + + /** + * On PHO toggle + * @param {Event} e - input event + */ + handlePHOToggle(e) { + const checked = e.target.checked; + this.filtersManager.setFilter('phos', checked, this._filterCallback); + } + + /** + * Execute after filtering + * @param {number} size + */ + _filterCallback(size) { + this._lastSize = size; + document.getElementsByClassName('filters-modal-count')[0].innerHTML = `${this._lastSize?.toLocaleString()} objects`; + } + + /** + * Clicked 'CLear all filters' + */ + handleResetFilters() { + const filters = this.filtersManager.getFilters(); + + if (filters.asteroids) document.getElementById('filters-asteroids-checkbox').click(); + if (filters.comets) document.getElementById('filters-comets-checkbox').click(); + if (filters.phos) document.getElementById('filters-phos-toggle').click(); + + // Reset obj count label when filters are reset + this._lastSize = this._app.neos.size; + } + + /** + * Help ? clicked + * @param {Event} e - HTMLElement event + */ + handleHelp(e) { + this._app.getComponent('definitionOverlay').navigateToDefinition(e.target?.dataset?.def); + } +} + +FiltersModal.html = (_filters_modal_html__WEBPACK_IMPORTED_MODULE_1___default()); + +/* harmony default export */ __webpack_exports__["default"] = (FiltersModal); + + +/***/ }), + +/***/ "./src/components/asteroid_modals/modals/filters_modal/index.js": +/*!**********************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/filters_modal/index.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _filters_modal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./filters_modal */ "./src/components/asteroid_modals/modals/filters_modal/filters_modal.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = (_filters_modal__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "./src/components/asteroid_modals/modals/index.js": +/*!********************************************************!*\ + !*** ./src/components/asteroid_modals/modals/index.js ***! + \********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FiltersModal": function() { return /* reexport safe */ _filters_modal__WEBPACK_IMPORTED_MODULE_0__["default"]; }, +/* harmony export */ "LearnModal": function() { return /* reexport safe */ _learn_modal__WEBPACK_IMPORTED_MODULE_1__["default"]; } +/* harmony export */ }); +/* harmony import */ var _filters_modal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./filters_modal */ "./src/components/asteroid_modals/modals/filters_modal/index.js"); +/* harmony import */ var _learn_modal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./learn_modal */ "./src/components/asteroid_modals/modals/learn_modal/index.js"); + + + + + + +/***/ }), + +/***/ "./src/components/asteroid_modals/modals/learn_modal/index.js": +/*!********************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/learn_modal/index.js ***! + \********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _learn_modal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./learn_modal */ "./src/components/asteroid_modals/modals/learn_modal/learn_modal.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = (_learn_modal__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "./src/components/asteroid_modals/modals/learn_modal/learn_modal.js": +/*!**************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/learn_modal/learn_modal.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _learn_modal_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./learn_modal.html */ "./src/components/asteroid_modals/modals/learn_modal/learn_modal.html"); +/* harmony import */ var _learn_modal_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_learn_modal_html__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _configs_story_info_json__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../../configs/story_info.json */ "./src/configs/story_info.json"); + + + + + + + +/** + * Learn modal component. + * @extends BaseComponent + */ +class LearnModal extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {import('eyes').Options} options + */ + constructor(app, options) { + super(app, null, { + ...options + }); + + this._title = 'Learn'; + this._svg = './assets/default/svg/learn.svg'; + } + + /** + * Navigates router to a story + * @param {object} story + */ + goToStory(story) { + const router = this._app.getManager('router'); + document.getElementsByClassName('asteroid-modal-close')[0]?.click(); + // Use a 0.2s timeout to allow the modal to fade out cleanly + // Otherwise returning from a story keeps the modal on screen for that brief second + setTimeout(() => { + router.navigate({ __remove: ['modal'] }, `/story/${story.path}`); + }, 200); + } + + /** + * Called when the modal is opened + */ + onShow() { + const stories = _configs_story_info_json__WEBPACK_IMPORTED_MODULE_3__ || []; + const modalBody = this._children.asteroidLearnModalBody; + if (modalBody) { + modalBody.textContent = ''; + stories.forEach(story => { + const markup = [ + '
      ', + `

      ${story.title}

      `, + story.questions.map((q) => { + return `
      ${q}
      `; + }).join('\n') + ].join('\n'); + + const card = document.createElement('div'); + card.className = 'learn-modal-story-card'; + card.innerHTML = markup; + card.addEventListener('click', () => { + this.goToStory(story); + }); + + modalBody.append(card); + }); + } + } + + /** + * @override + */ + show() { + this.onShow(); + super.show(); + } +} + +LearnModal.html = (_learn_modal_html__WEBPACK_IMPORTED_MODULE_1___default()); + +/* harmony default export */ __webpack_exports__["default"] = (LearnModal); + + +/***/ }), + +/***/ "./src/components/asteroid_panel/asteroid_panel.js": +/*!*********************************************************!*\ + !*** ./src/components/asteroid_panel/asteroid_panel.js ***! + \*********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AsteroidPanel": function() { return /* binding */ AsteroidPanel; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); + + + + + +/** + * AsteroidPanel extends CarouselPanel + */ +class AsteroidPanel extends eyes__WEBPACK_IMPORTED_MODULE_0__.CarouselPanel { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options) { + super(app, { + // Class names + panelTypeClass: 'asteroid-panel', + carouselClass: 'asteroid-carousel', + prevButtonClass: 'asteroid-carousel-prev', + nextButtonClass: 'asteroid-carousel-next', + + // Options + title: 'Asteroid Panel', + caption: '', + headerIconClass: 'asteroid', + + ...options + }); + + /** + * Boolean to say whether the panel is populated with data. + * @type {boolean} + * @private + */ + this._isPopulated = false; + + this._expandOnShow = true; + } + + /** + * Compose the watch carousel slides + * @param {object} neoData + * @param {object} heroData + */ + populate(neoData, heroData) { + // Set title and icon + const icon = neoData.comet ? 'comet' : 'asteroid'; + this.setState({ + title: neoData.name, + headerIconClass: icon + }); + + // Generate tab content. + const allTabsContent = []; + + const essentialStats = this.getEssentialStats(neoData, heroData); + essentialStats.length && allTabsContent.push({ + title: 'Essential stats', + content: essentialStats + }); + + const orbitalPath = this.getOrbitalPath(neoData); + orbitalPath.length && allTabsContent.push({ + title: 'Orbital path', + content: orbitalPath + }); + + const closeApproach = this.getCloseApproach(neoData, heroData); + closeApproach.length && allTabsContent.push({ + title: 'Close approach', + content: closeApproach + }); + + // Create the tabs and init the swiper. + this.createTabs(allTabsContent); + + // Set populated to true; + this._isPopulated = true; + } + + /** + * Return essential stats + * @param {object} neoData + * @param {object} heroData + * @returns {Array} + */ + getEssentialStats(neoData, heroData) { + const { pioneerName, diameter, diameterEstimated, nextClosestApproachTime } = neoData; + + const neoEntity = this._app._scene.get(pioneerName); + const earthEntity = this._app._scene.get('earth'); + const essentialStats = []; + + // Add discovery content. + if (heroData?.stats?.discovery) { + essentialStats.push({ + title: 'Discovery', + content: heroData.stats.discovery + }); + } + + // Add size content. + if (diameter) { + essentialStats.push({ + title: 'Size', + content: `

      Average ${diameterEstimated ? 'estimated' : ''} diameter

      `, + value: `${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(diameter * 1000, 2)} m` + }); + } + + // Add distance content. + const posDifference = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(); + neoEntity.getPositionRelativeToEntity(posDifference, pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, earthEntity); + const distanceKm = posDifference.magnitude(); + const distanceAU = distanceKm / eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm; + + if (!posDifference.isNaN()) { + essentialStats.push({ + title: 'Distance', + content: '

      Current distance from Earth

      ', + value: `${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(distanceAU, 2)} AU` + }); + } + + // Add velocity. + const asteroidVelocity = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(); + neoEntity.getVelocityAtTime(asteroidVelocity, nextClosestApproachTime); + + const magnitude = asteroidVelocity.magnitude(); + if (magnitude) { + essentialStats.push({ + title: 'Velocity', + content: '

      Current velocity relative to the Sun

      ', + value: `${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(magnitude, 2)} km/s` + }); + } + + // Add rotation period. + if (heroData?.stats?.rotation) { + essentialStats.push({ + title: 'Period of Rotation', + content: '

      Time to complete one full rotation

      ', + value: `${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(heroData.stats.rotation, 2)} hours` + }); + } + + return essentialStats; + } + + /** + * Return orbital path + * @param {object} neoData + * @returns {Array} + */ + getOrbitalPath(neoData) { + const { orbitalElements } = neoData; + + const orbitalPath = []; + + if (orbitalElements) { + // Add orbital period. + const period = orbitalElements.getPeriod(); + const days = Math.round(period / 86400); // seconds to days + const years = days / 365; + const time = years >= 1 + ? `${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(years, 2)} ${years === 1 ? 'year' : 'years'}` + : `${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(days, 1)} ${days === 1 ? 'day' : 'days'}`; + + orbitalPath.push({ + title: 'Orbital Period', + content: '

      Time to complete one solar orbit

      ', + value: time + }); + + // Add eccentricity. + const { eccentricity } = orbitalElements; + + if (eccentricity) { + orbitalPath.push({ + title: 'Eccentricity', + content: '

      Deviation from circular orbit

      ', + value: eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(eccentricity, 3) + }); + } + + // Perihelion, aphelion and inclination calculations. + // The transformation from J2000Ecipse to J2000 coordinates. + const eclipJ2000ToJ2000Rotation = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.9791532214288992, 0.2031230389823101, 0, 0); + + const orbitalElementsRelEcliptic = new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements(); + orbitalElementsRelEcliptic.copy(orbitalElements); + orbitalElementsRelEcliptic.orbitOrientation.multInverseL(eclipJ2000ToJ2000Rotation, orbitalElementsRelEcliptic.orbitOrientation); + + const periapsisKm = orbitalElementsRelEcliptic.getPeriapsis(); + if (periapsisKm) { + orbitalPath.push({ + title: 'Perihelion', + content: '

      Closest distance to the Sun

      ', + value: `${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(periapsisKm / eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm, 2)} AU` + }); + } + + const apoapsisKm = orbitalElementsRelEcliptic.getApoapsis(); + if (apoapsisKm) { + orbitalPath.push({ + title: 'Aphelion', + content: '

      Farthest distance from the Sun

      ', + value: `${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(apoapsisKm / eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm, 2)} AU` + }); + } + + const inclination = orbitalElementsRelEcliptic.getInclination(); + if (inclination) { + orbitalPath.push({ + title: 'Inclination', + content: '

      Angle relative to the x-y ecliptic plane

      ', + value: `${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(pioneer__WEBPACK_IMPORTED_MODULE_1__.MathUtils.radToDeg(inclination), 3)} deg` + }); + } + } + + return orbitalPath; + } + + /** + * Return close approach + * @param {object} neoData + * @param {object} heroData + * @returns {Array} + */ + getCloseApproach(neoData, heroData) { + const { nextClosestApproachDistance, nextClosestApproachTime } = neoData; + const closeApproach = []; + + if (heroData?.approach?.fact) { + closeApproach.push({ + content: heroData.approach.fact + }); + } + + if (nextClosestApproachTime) { + const unixSeconds = pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.etToUnix(nextClosestApproachTime); + const date = new Date(unixSeconds * 1000); + + if (date) { + closeApproach.push({ + title: 'Date', + content: '

      Closest approach to Earth < 0.05 AU

      ', + value: eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatDate(date) + }); + } + } + + if (nextClosestApproachDistance) { + closeApproach.push({ + title: 'Distance', + content: '

      Nearest distance to Earth

      ', + value: `${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(nextClosestApproachDistance, 0)} km` + }); + } + + return closeApproach; + } + + /** + * Only show panel when it's populated. + * @override + */ + show(initSwiper = true) { + this._isPopulated && super.show(initSwiper); + } + + /** + * @override + */ + _destroy() { + this._isPopulated = false; + + super._destroy(); + } +} + + +/***/ }), + +/***/ "./src/components/breadcrumb/breadcrumb.js": +/*!*************************************************!*\ + !*** ./src/components/breadcrumb/breadcrumb.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Breadcrumb": function() { return /* binding */ Breadcrumb; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + + +/** + * Breadcrumb for Asteroids. + * @extends BaseBreadcrumb + */ +class Breadcrumb extends eyes__WEBPACK_IMPORTED_MODULE_0__.Breadcrumb { + /** + * @inheritdoc + * @override + */ + async init() { + super.init(); + this.setState({ + moduleText: this._crumbTexts.asteroids + }); + } + + /** + * @inheritdoc + * @override + */ + _goToHome() { + this._app.getManager('router').navigate({ __remove: 'all' }, '/home'); + } +} + + +/***/ }), + +/***/ "./src/components/countdown/countdown.js": +/*!***********************************************!*\ + !*** ./src/components/countdown/countdown.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Countdown": function() { return /* binding */ Countdown; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _countdown_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./countdown.html */ "./src/components/countdown/countdown.html"); +/* harmony import */ var _countdown_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_countdown_html__WEBPACK_IMPORTED_MODULE_2__); + + + + + + +/** + * Countdown component. + */ +class Countdown extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + super(app, null, { + isVisible: true, + tText: 'T -', + numDays: '00', + numHours: '00', + numMinutes: '00', + numSeconds: '00', + ...options + }); + + this._timeTarget = null; + this._remainingSeconds = null; + + this.bindFunctions(['update']); + } + + /** @inheritdoc */ + init() { + super.init(); + + this._callbackRegistry.push({ + emitter: this._app.getManager('time'), + event: 'update', + callback: this.update + }); + } + + /** + * Parse remaining seconds + * @param {number} remaining + * @returns {object} + */ + _parseRemaining(remaining) { + const minuteSeconds = 60; + const hourSeconds = minuteSeconds * 60; + const daySeconds = hourSeconds * 24; + + let numSeconds = parseInt(Math.abs(remaining), 10); + + const numDays = Math.floor(numSeconds / daySeconds); + numSeconds -= numDays * daySeconds; + const numHours = Math.floor(numSeconds / hourSeconds); + numSeconds -= numHours * hourSeconds; + const numMinutes = Math.floor(numSeconds / minuteSeconds); + numSeconds -= numMinutes * minuteSeconds; + + return { + tText: remaining > 0 ? 'T﹣' : 'T﹢', + numDays: String(numDays).padStart(2, '0'), + numHours: String(numHours).padStart(2, '0'), + numMinutes: String(numMinutes).padStart(2, '0'), + numSeconds: String(numSeconds).padStart(2, '0') + }; + } + + /** + * Update time display. + * @param {import('moment').Moment} currentMoment + */ + update(currentMoment) { + // Don't update if not visible + // Todo: make sure to set hide countdown when it's not visible (not sure if hiding parent component affects it) + if (!this._state.isVisible) { + return; + } + + // Get the pioneer ET time in order to reduce multiple ET to UNIX conversions + const currentEtTime = this._app?._pioneer?.getTime() || pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.unixToEt(currentMoment.valueOf() * 0.001); + + // Calculate remaining seconds and only update if it's changed. + const remainingSeconds = Math.round(this._timeTarget - currentEtTime); + + if (remainingSeconds !== this._remainingSeconds) { + // parse remaining, set states, and _remainingSeconds prop + + const { + tText, + numDays, + numHours, + numMinutes, + numSeconds + } = this._parseRemaining(remainingSeconds); + + this.setState({ + tText, + numDays, + numHours, + numMinutes, + numSeconds + }); + + this._remainingSeconds = remainingSeconds; + } + } + + /** + * Sets the time target in Ephemeris Time (ET) + * @param {number} time + */ + setTimeTarget(time) { + this._timeTarget = time; + } + + /** + * Gets time target. + * @returns {number} + */ + getTimeTarget() { + return this._timeTarget; + } + + /** + * + */ + hide() { + console.log('hide'); + super.hide(); + } +} + +Countdown.html = (_countdown_html__WEBPACK_IMPORTED_MODULE_2___default()); + + +/***/ }), + +/***/ "./src/components/definition_overlay/definition_overlay.js": +/*!*****************************************************************!*\ + !*** ./src/components/definition_overlay/definition_overlay.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "DefinitionOverlay": function() { return /* binding */ DefinitionOverlay; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _definition_overlay_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./definition_overlay.html */ "./src/components/definition_overlay/definition_overlay.html"); +/* harmony import */ var _definition_overlay_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_definition_overlay_html__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _data_definitions_json__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../data/definitions.json */ "./src/data/definitions.json"); + + + + + + +/** + * Layer panel component. + */ +class DefinitionOverlay extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + // Add state options + super(app, null, { + isVisible: false + }); + + // Store imported json definitions in class variable. + this._definitions = _data_definitions_json__WEBPACK_IMPORTED_MODULE_2__; + + // Define router reference. + this._router = null; + + // Define the query unsubscribe reference. + this._queryUnsubscribe = null; + + // Define the scrollbar component. + this._scrollbar = null; + + // Override small font size. + this._class.fontSize.small = ''; + + // Keep track of definition histories + this._activeDef = null; + this._prevDef = null; + + // Add default class to state + Object.assign(this._state, { + title: null, + content: null, + fontSizeClass: '' + }); + + // Bind functions called outside this class that need use 'this'. + this.bindFunctions([ + 'navigateToDefinition', + '_updateDefinition', + '_handleOutsideClick', + '_handleContainerClick' + ]); + } + + /** + * Initialization. + */ + init() { + super.init(); + + // Assign _router and subscribe to the definition query. + this._router = this._app.getManager('router'); + } + + /** + * Called when the url get params change. Wraps _updateDefinition + * @param {object} params + * @param {CancelToken} params.cancelToken + * @param {string} params.definition + */ + async onQueryChange({ cancelToken, definition } = {}) { + // Check if route was canceled + if (cancelToken && cancelToken.isCanceled) { + return; + } + + this._prevDef = this._activeDef; + this._activeDef = definition; + this._updateDefinition(this._activeDef, this._prevDef); + } + + /** + * Determine if the definition string has a matching object config + * @param {string} currDefinition + * @param {string} prevDefinition + */ + _updateDefinition(currDefinition, prevDefinition) { + // Validate definition by checking if its in our definitions data object. + const currDefObj = this._definitions[currDefinition] ?? false; + const prevDefObj = this._definitions[prevDefinition] ?? false; + + if (currDefObj) { + const { title, html: content, related } = currDefObj; + + // Set the states to populate the content. + this.setState({ title, content }); + + // A nice extension to Mi's nullish coalescing operator skillshare: + // https://stackoverflow.com/questions/1011317/replace-a-value-if-null-or-undefined-in-javascript + this._scrollbar ??= eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addScrollbar(this._children.contentEl, { + sizeAutoCapable: true + }); + + // Make sure to scroll to the top of the content (it may have previosly scrolled down in portrait mobile) + this._scrollbar.scroll(0, 300); + + // Create the related terms elements + const relatedElements = related.map(defId => { + const title = this._definitions[defId]?.title; + const relatedItem = document.createElement('div'); + relatedItem.className = 'definition-related-item small clickable'; + relatedItem.setAttribute('data-def', defId); + relatedItem.innerText = title; + return relatedItem; + }); + + // Replace the children of the related element container + this._children.relatedEl.replaceChildren(...relatedElements); + + // Only show if we had no prev definition. + if (!prevDefObj) { + this.show(); + } + } + else if (prevDefObj) { + // We had a prev definition but now we dont have one at all so we need to hide the overlay + this.hide(); + } + } + + /** + * Update the router query. + * @param {string} definitionId + */ + navigateToDefinition(definitionId) { + if (definitionId) { + this._router.navigate({ definition: definitionId }, this._router.currentRoute.url); + } + // if false is specifically passed, remove the query + else if (definitionId === false) { + this._router.navigate({ __remove: ['definition'] }, this._router.currentRoute.url); + } + } + + /** + * Update the route to navigate to a story (slide number optional). + * @param {string} storyId + * @param {string} storySlide + */ + navigateToStory(storyId, storySlide = '1') { + const query = { slide: `slide_${storySlide}` }; + const path = `/story/${storyId}`; + const options = { __remove: ['modal', 'definition'] }; + + this.app.getManager('router').navigate(query, path, options); + } + + /** + * Handle click outside overlay + * @param {event} e + */ + _handleOutsideClick(e) { + e.stopPropagation(); + this.navigateToDefinition(false); + } + + /** + * Handle click in container, if we find a data-def attribute, navigate to the definition + * @param {event} e + */ + _handleContainerClick(e) { + e.stopPropagation(); + + const { storyid: storyId, storyslide: storySlide, def: definitionId } = e?.target?.dataset || {}; + + if (storyId) { + this.navigateToStory(storyId, storySlide); + } + else if (definitionId) { + this.navigateToDefinition(definitionId); + } + } + + /** + * Overrides destroy method. + */ + __destroy() { + // Unsubscribe from query. + if (typeof this._queryUnsubscribe === 'function') { + this._queryUnsubscribe(); + } + + // Make sure references are null. + this._queryUnsubscribe = null; + + this._router = null; + + this._definitions = null; + + // Call superclass __destroy method. + super.__destroy(); + } +} + +DefinitionOverlay.html = (_definition_overlay_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "./src/components/following_panel/following_panel.js": +/*!***********************************************************!*\ + !*** ./src/components/following_panel/following_panel.js ***! + \***********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FollowingPanel": function() { return /* binding */ FollowingPanel; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + + + +/** + * FollowingPanel extends CarouselPanel + */ +class FollowingPanel extends eyes__WEBPACK_IMPORTED_MODULE_0__.CarouselPanel { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options) { + super(app, { + // Class names + panelTypeClass: 'following-panel', + + // Options + title: '', + preTitle: 'following', + + ...options + }); + } +} + + +/***/ }), + +/***/ "./src/components/home_button/home_button.js": +/*!***************************************************!*\ + !*** ./src/components/home_button/home_button.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "HomeButton": function() { return /* binding */ HomeButton; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + + + +/** + * HomeButton component + */ +class HomeButton extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Initilizing the component + */ + init() { + this._element = document.createElement('h5'); + this._element.innerText = 'See all asteroids'; + this._element.className = 'home-button clickable {{isVisibleClass}}'; + + // Add the click event. + this._element.addEventListener('click', () => { + // Navigate home, resetting query. + const routeManager = this._app.getManager('router'); + + // const currentQuery = routeManager.buildQuery(routeManager.query); + routeManager.navigate({ __remove: 'all' }, '/home'); + }); + + super.init(); + } +} + + +/***/ }), + +/***/ "./src/components/mission_panel/mission_panel.js": +/*!*******************************************************!*\ + !*** ./src/components/mission_panel/mission_panel.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "MissionPanel": function() { return /* binding */ MissionPanel; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + + + +/** + * MissionPanel extends CarouselPanel + */ +class MissionPanel extends eyes__WEBPACK_IMPORTED_MODULE_0__.CarouselPanel { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options) { + super(app, { + // Class names + panelTypeClass: 'mission-panel', + carouselClass: 'mission-carousel', + prevButtonClass: 'mission-carousel-prev', + nextButtonClass: 'mission-carousel-next', + + // Options + title: 'Mission Panel', + caption: '', + headerIconClass: 'spacecraft', + + ...options + }); + + /** + * Boolean to say whether the panel is populated with data. + * @type {boolean} + * @private + */ + this._isPopulated = false; + + this._expandOnShow = true; + } + + /** + * Compose the watch carousel slides + * @param {string} title + * @param {string} blurb + * @param {string} cameraTarget + * @param {object} events + */ + populate(title, blurb, cameraTarget, events = {}) { + const { hideExternalLinks } = this._app.getManager('router').configs; + + const panelTitle = hideExternalLinks === true ? this._app.getManager('content').hideExternalLinksInText(title) : title; + + // Set title + this.setState({ title: panelTitle }); + + // Generate tab content. + const allTabsContent = []; + + const panelBlurb = hideExternalLinks === true ? this._app.getManager('content').hideExternalLinksInText(blurb) : blurb; + + panelBlurb && allTabsContent.push({ + title: 'Overview', + content: [{ content: `

      ${panelBlurb}

      ` }] + }); + + // Filter events with 'visual' flag + const filteredEvents = events ? Object.values(events).filter(({ visual }) => visual) : []; + + // Create content array + if (filteredEvents.length) { + const timeManager = /** @type {TimeManager} */(this.app.getManager('time')); + const routeManager = /** @type {RouteManager} */(this.app.getManager('router')); + const content = filteredEvents.map(({ title, start, rate, target, id, distance, verticleOffset, horizontalOffset }) => { + const dateInt = start?.valueOf(); + const date = dateInt && new Date(dateInt); + + return { + title, + ...date && { + content: `

      ${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatDate(date)}

      `, + value: 'Watch' + }, + onClick: async () => { + if (start && routeManager?.currentRoute) { + // Prevent clock to stop due to min time limit reached + if (id === 'launch') { + start = start.clone().add(1, 's'); + } + timeManager.setTime(start); + timeManager.setTimeRate(rate || 1); + const query = { + time: timeManager.getTimeUrl(), + rate: timeManager.getTimeRate() + }; + + // Reset filters to avoid missing entities + this.app.getComponent('filtersModal').handleResetFilters(); + + await routeManager.navigate(query, routeManager.currentRoute.url); + // Align to target + if (target) { + // Make sure targets are loaded + await this.app.getManager('scene').isListReady([cameraTarget, target]); + await this.app.scene.getEntity(cameraTarget).getLoadedPromise(); + await this.app.scene.getEntity(target).getLoadedPromise(); + await this.app.cameraScripts.alignObjects(cameraTarget, target, { + duration: 1, + distance: distance ?? 0.1, + verticleOffset: verticleOffset ?? 0, + horizontalOffset: horizontalOffset ?? 0 + }); + } + } + } + }; + }); + + allTabsContent.push({ + title: 'Events', + content + }); + } + + // Create the tabs and init the swiper. + this.createTabs(allTabsContent); + + // Set populated to true; + this._isPopulated = true; + } + + /** + * Only show panel when it's populated. + * @override + */ + show(initSwiper = true) { + this._isPopulated && super.show(initSwiper); + } + + /** + * @override + */ + _destroy() { + this._isPopulated = false; + + super._destroy(); + } +} + + +/***/ }), + +/***/ "./src/components/navigation/navigation.js": +/*!*************************************************!*\ + !*** ./src/components/navigation/navigation.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Navigation": function() { return /* binding */ Navigation; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _navigation_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./navigation.html */ "./src/components/navigation/navigation.html"); +/* harmony import */ var _navigation_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_navigation_html__WEBPACK_IMPORTED_MODULE_1__); + + + + + +/** + * Navigation component. + * @extends BaseComponent + */ +class Navigation extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor + * @param {BaseApp} app + */ + constructor(app) { + super(app, null, { + position: 'top' + }); + + this._entries = {}; + + // Binds + this.bindFunctions(['toggleBadge']); + } + + /** + * Setup menu elements + * @param {Array} param - list of menu elements + */ + setup(param) { + const { position = 'top', entry = [] } = param; + this.setState({ position }); + + this._children.list.innerHTML = ''; + for (let i = 0; i < entry.length; i += 1) { + const div = document.createElement('div'); + div.className = 'clickable'; + if (entry[i].active) { + div.classList.add('active'); + } + const button = document.createElement('button'); + + button.innerHTML = `

      ${entry[i].title}

      `; + + if (entry[i].svg) { + const img = document.createElement('img'); + img.src = entry[i].svg; + img.alt = entry[i].title; + div.appendChild(img); + } + div.appendChild(button); + + if (entry[i].onClick) { + div.addEventListener( + 'click', + e => { + e.preventDefault(); + entry[i].onClick(entry[i], e); + }, + false + ); + div.addEventListener( + 'touchend', + e => { + e.preventDefault(); + entry[i].onClick(entry[i], e); + }, + false + ); + } + + this._entries[entry[i].title] = { entry: entry[i], element: div }; + + this._children.list.append(div); + } + } + + /** + * Toggles or sets the navigation item's active state + * @param {string} entryName + * @param {boolean?} on + */ + toggleActive(entryName, on) { + if (this._entries[entryName]) { + const elm = this._entries[entryName].element; + const wasOn = elm.classList.contains('active'); + if (wasOn !== on) { + elm.classList.toggle('active'); + } + } + } + + /** + * Toggles or sets the navigation item's badged state + * @param {string} entryName + * @param {boolean?} on + */ + toggleBadge(entryName, on) { + if (this._entries[entryName]) { + const elm = this._entries[entryName].element; + const wasOn = elm.classList.contains('badged'); + if (wasOn !== on) { + elm.classList.toggle('badged'); + } + } + } +} + +Navigation.html = (_navigation_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "./src/components/search/search.js": +/*!*****************************************!*\ + !*** ./src/components/search/search.js ***! + \*****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Search": function() { return /* binding */ Search; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + +/** + * @inheritdoc + * @extends EyesSearch + */ +class Search extends eyes__WEBPACK_IMPORTED_MODULE_0__.Search { + /** + * @inheritdoc + * @override + */ + _getLink(link) { + return this._app.getManager('link')?.getParsedLink?.(link) || link; + } +} + + +/***/ }), + +/***/ "./src/components/settings/asteroids_settings.js": +/*!*******************************************************!*\ + !*** ./src/components/settings/asteroids_settings.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AsteroidsSettings": function() { return /* binding */ AsteroidsSettings; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + +/** + * AsteroidsSettings. + */ +class AsteroidsSettings extends eyes__WEBPACK_IMPORTED_MODULE_0__.Settings { + /** + * Toggle info panel override. + */ + toggleInfoPanel() { + const tutorialIndex = 0; + const goHome = true; + this._app.getComponent('tutorialOverlay')?.navigateToTutorial(tutorialIndex, goHome); + } +} + + +/***/ }), + +/***/ "./src/components/splash_screen/splash_screen.js": +/*!*******************************************************!*\ + !*** ./src/components/splash_screen/splash_screen.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SplashScreen": function() { return /* binding */ SplashScreen; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _splash_screen_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./splash_screen.html */ "./src/components/splash_screen/splash_screen.html"); +/* harmony import */ var _splash_screen_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_splash_screen_html__WEBPACK_IMPORTED_MODULE_1__); + + + + + +/** + * A Splash screen component. + */ +class SplashScreen extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options = {}) { + // call super class and pass default state object. + super(app, null, { + ...options + }); + + this._dragging = false; + this._mousedownY = null; + this._mousewheelDeltaY = 0; + this._animationPercent = 0; + this._timeout = null; + this._lockEnd = false; + } + + /** + * Display the splash screen. + */ + _displaySplash() { + this._element.style.pointerEvents = 'all'; + + this._element.addEventListener('mousedown', this._onDown.bind(this)); + this._element.addEventListener('touchstart', this._onDown.bind(this)); + this._element.addEventListener('mousemove', this._onMove.bind(this)); + this._element.addEventListener('touchmove', this._onMove.bind(this)); + this._element.addEventListener('mouseup', this._onUp.bind(this)); + this._element.addEventListener('touchend', this._onUp.bind(this)); + this._element.addEventListener('wheel', this._onWheel.bind(this)); + + // Move past the splash screen after a timeout too + this._timeout = setTimeout(() => { + this._setAnimationPercent(1, true); + }, 5500); + + // Create Random Stars + let starsBoxShadow1 = ''; + for (let i = 0; i < 8; i++) { + starsBoxShadow1 += `${parseInt(Math.random() * window.innerWidth)}px ${parseInt(Math.random() * window.innerHeight)}px hsl(0deg, 0%, ${parseInt(Math.random() * 80) + 20}%), `; + } + this._children.splashScreenStars1.style.boxShadow = starsBoxShadow1.slice(0, -2); + + let starsBoxShadow2 = ''; + for (let i = 0; i < 24; i++) { + starsBoxShadow2 += `${parseInt(Math.random() * window.innerWidth)}px ${parseInt(Math.random() * window.innerHeight)}px hsl(0deg, 0%, ${parseInt(Math.random() * 80) + 20}%), `; + } + this._children.splashScreenStars2.style.boxShadow = starsBoxShadow2.slice(0, -2); + + // Set default pioneer transition styles + const pioneerElm = document.getElementById('pioneer'); + if (pioneerElm) { + pioneerElm.style.transform = 'scale(1.2)'; + pioneerElm.style.filter = 'brightness(0) grayscale(0)'; + pioneerElm.style.opacity = '0'; + } + + // End the loading screen. + this.app.endLoadingScreen(); + } + + /** + * On Splash Screen mouse wheel + * @param {MouseEvent} e + */ + _onWheel(e) { + this._setAnimationPercent(1, true); + } + + /** + * On Splash Screen mouse or touch down + * @param {MouseEvent} e + */ + _onDown(e) { + if (e.touches?.length > 0) e = e.touches[0]; + this._mousedownY = e.clientY; + } + + /** + * On Splash Screen drag + * @param {MouseEvent} e + */ + _onMove(e) { + if (e.touches?.length > 0) e = e.touches[0]; + const dragDistance = this._mousedownY - e.clientY; + if (this._mousedownY != null && dragDistance > 6) { + this._dragging = true; + } + if (this._dragging) { + this._setAnimationPercent(1, true); + } + } + + /** + * On Splash Screen mouse or touch up + */ + _onUp() { + this._setAnimationPercent(1, true); + + this._dragging = false; + this._mousedownY = null; + } + + /** + * Sets the overall splash screen's animation completion + * When percent == 1, the splash screen ends + * @param {number} percent - actually between 0 and 1 + * @param {boolean} useTransitions + */ + _setAnimationPercent(percent, useTransitions) { + const previousPercent = this._animationPercent; + + this._animationPercent = percent; + const baseTransition = 'all 0.8s cubic-bezier(0.645, 0.045, 0.355, 1)'; + const longTransition = 'all 1.1s cubic-bezier(0.645, 0.045, 0.355, 1)'; + + this._children.splashScreen.style.transition = useTransitions ? baseTransition : 'unset'; + this._children.splashScreen.style.opacity = `${1 - (Math.pow(percent, 2))}`; + this._children.splashScreenAsteroid.style.transition = useTransitions ? baseTransition : 'unset'; + this._children.splashScreenAsteroid.style.width = `${68 - (percent * 30)}vh`; + this._children.splashScreenAsteroid.style.height = `${68 - (percent * 30)}vh`; + this._children.splashScreenEnterBackground.style.transition = useTransitions ? baseTransition : 'unset'; + this._children.splashScreenEnterBackground.style.top = `calc(${86 - (percent * 44)}% - 54px)`; + this._children.splashScreenEnterBackground.style.width = `${100 + (percent * 1200)}vw`; + this._children.splashScreenEnterBackground.style.height = `${100 + (percent * 1200)}vw`; + this._children.splashScreenText.style.transition = useTransitions ? baseTransition : 'unset'; + this._children.splashScreenText.style.top = `${55 - (percent * 40)}%`; + this._children.splashScreenTextEyes.style.transition = useTransitions ? baseTransition : 'unset'; + this._children.splashScreenTextEyes.style.lineHeight = `${60 - (percent * 50)}px`; + this._children.splashScreenTextOn.style.transition = useTransitions ? baseTransition : 'unset'; + this._children.splashScreenTextOn.style.lineHeight = `${40 - (percent * 50)}px`; + this._children.splashScreenTextAsteroids.style.transition = useTransitions ? baseTransition : 'unset'; + this._children.splashScreenTextAsteroids.style.lineHeight = `${80 - (percent * 50)}px`; + this._children.splashScreenEnter.style.transition = useTransitions ? baseTransition : 'unset'; + this._children.splashScreenEnter.style.top = `${81 - (percent * 30)}%`; + this._children.splashScreenStars1.style.transition = useTransitions ? baseTransition : 'unset'; + this._children.splashScreenStars1.style.marginTop = `${(percent * 1)}%`; + this._children.splashScreenStars2.style.transition = useTransitions ? baseTransition : 'unset'; + this._children.splashScreenStars2.style.marginTop = `${(percent * 0.5)}%`; + + // Set pioneer transition styles + const pioneerElm = document.getElementById('pioneer'); + if (pioneerElm) { + pioneerElm.style.transition = useTransitions ? longTransition : 'unset'; + pioneerElm.style.transform = `scale(${1.2 - (percent * 0.2)})`; + pioneerElm.style.opacity = `${percent}`; + pioneerElm.style.filter = `brightness(${percent}) grayscale(${1 - percent})`; + } + + // Set the pointer events early so pioneer interaction is immediate + if (this._animationPercent >= 1) { + this._element.style.pointerEvents = 'none'; + } + else { + this._element.style.pointerEvents = 'all'; + } + + if (!this._dragging && this._animationPercent >= 1 && !this._lockEnd) { + this._lockEnd = true; + // Remove the splash screen + setTimeout(() => { + clearTimeout(this._timeout); + + if (pioneerElm) { + pioneerElm.style.transform = 'unset'; + pioneerElm.style.transition = 'unset'; + pioneerElm.style.opacity = 'unset'; + pioneerElm.style.filter = 'unset'; + } + + this.destroy(); + }, 1100 * (1 - previousPercent)); + } + } + + /** + * @override + * Override splash screen enable to determine visibility from router logic. + */ + __enable() { + super.__enable(); + + const { currentRoute, previousRoute, homeRoute } = this.app.getManager('router'); + // Only trigger splash on the base or undefined route without a previous route. + if (previousRoute.url === undefined && (currentRoute.url === undefined || currentRoute.url === homeRoute)) { + this._displaySplash(); + } + else { + this.destroy(); + } + } +} + +SplashScreen.html = (_splash_screen_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "./src/components/time_slider/time_slider.js": +/*!***************************************************!*\ + !*** ./src/components/time_slider/time_slider.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TimeSlider": function() { return /* binding */ TimeSlider; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _time_slider_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./time_slider.html */ "./src/components/time_slider/time_slider.html"); +/* harmony import */ var _time_slider_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_time_slider_html__WEBPACK_IMPORTED_MODULE_2__); + + + + + +const { debounce } = eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils; + +/** + * Time slider component. + * @extends BaseComponent + */ +class TimeSlider extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + // Set default config. + options.config = { + snapPoints: [ + 1, // 1 sec + 10, // 10 secs + 60, // 1 min + 300, // 5 mins + 600, // 10 mins + 3600, // 1 hr + 86400, // 1 day + 604800, // 1 week + 5256000, // 2 months + 31540000 // 1 year + ], + + // apply a dynamic rate coefficient to the fastest rate + enableDynamicRate: false, + // default camera distance value if not measurable + defaultCamDistance: 700000000, + // variation in fastest time rates (seconds per second) + fastestRate: { + min: 86400, // 1 day / sec + max: 157700000 // 5 yrs / sec + }, + + ...options.config + }; + + super(app, null, { + startX: null, + transX: 0, + lineMeasures: { left: null, width: null, isMeasured: false }, + fastestRate: null, + rateArray: null, + realtimeVisibleClass: 'hidden', + ...options + }); + + /** + * Current time rate + * @type {number} + * @private + */ + this._currentRate = null; + + /** + * Current camera distance to it's target + * @type {number} + * @private + */ + this._camDistance = null; + + /** + * Whether we're at a time limit. + * @type {string} + * @private + */ + this._limit = null; + + /** + * Additional classes for various screen sizes. + * @type {Array} + * @private + */ + this._extraClasses = ['offset-right', 'v-squeezy', 'h-squeezy', 'portrait', 'landscape']; + + /** + * Called if set, once cam distance has been established. + * @type {function(number):void} + * @private + */ + this._camDistanceResolve = null; + + this.bindFunctions([ + '_onMouseTouchDown', + '_onMouseTouchMove', + '_onMouseTouchUp', + '_getFastestRate', + '_snapToRate', + '_getRateArray', + '_onRealtimeClick', + '_update' + ]); + + // Debounced resize + this._resizeDebounced = debounce(this._onResize, 300); + } + + /** + * @inheritdoc + * @override + */ + init() { + super.init(); + + const timeManager = this.app.getManager('time'); + + // Add update callback. + this._callbackRegistry.push({ + emitter: timeManager, + event: 'update', + callback: this._update + }, + { + emitter: timeManager, + event: 'forcedpause', + callback: (_, limit) => this._setLimit(limit) + }); + + this._addHandlers(); + } + + /** + * Called when the url get params change. + * @param {object} params + * @param {number|undefined} params.rate + */ + async onQueryChange({ rate }) { + const negative = rate < 0; + const absRate = Math.abs(rate ?? 1); + + // If rate is paused, save come calculations. + if (rate === 0) { + this.setCurrentRate(0); + this._setTransX(0); + return; + } + + // Measure line so we have a left and width values. + const { width } = this._measureLine(); + + /** + * onQueryChange runs into a problem: + * - the 3D camera is not yet positioned (or is at NaN) so we have no distance, and cant generate the fastest rate. + * + * To resolve it (literally), we have a custom promise to wait for... + */ + await this._waitForCamDistance(); + + const { rateArray } = this._state; + + // Determine the snapped rate if snapping enabled, + let snappedAbsRate = this._snapToRate(absRate); + + // Snap to first value in rate array if less than second. + if (snappedAbsRate < rateArray[1]) { + snappedAbsRate = rateArray[0]; + } + + // Determine if we're trying to go over a max limit or under a min. + const belowMin = this._limit === 'min' && negative && rate !== undefined; + const aboveMax = this._limit === 'max' && !negative && rate !== undefined; + + // Calculate snapped rate. + const snappedRate = belowMin || aboveMax + ? 0 + : negative && snappedAbsRate !== rateArray[0] ? snappedAbsRate * -1 : snappedAbsRate; + + // Determine if we need to re-update the query, ie. query rate is different to the snapped rate. + const reupdateQuery = rate !== snappedRate && rate !== undefined; + + // Set rate. + this.setCurrentRate(snappedRate); + + // Calc and set transX. + const normVal = this._calculateNormValue(snappedAbsRate); + const absTransX = normVal * width * 0.5; + const transX = negative ? absTransX * -1 : absTransX; + + this._setTransX(transX); + + // Reupdate query if needed. + reupdateQuery && this.updateQuery(); + } + + /** + * Sets a local var for a reached limit. + * @param {string} limit + */ + _setLimit(limit) { + this._limit = limit; + } + + /** + * Async check for when camera is correctly positioned. + * Resolve in _update once cam position is not NaN + * @returns {Promise} + */ + async _waitForCamDistance() { + if (this._camDistance && !isNaN(this._camDistance)) { + return Promise.resolve(this._camDistance); + } + + return new Promise((resolve) => { + this._camDistanceResolve = resolve; + }); + } + + /** + * Add the initial event handlers. + */ + _addHandlers() { + const { iconEl } = this._children; + // Add both mouse and touch down events as some devices allow both. + iconEl.addEventListener('mousedown', this._onMouseTouchDown); + iconEl.addEventListener('touchstart', this._onMouseTouchDown); + } + + /** + * The mouse and touch down event handler. + * @param {MouseEvent|Touch} e + */ + _onMouseTouchDown(e) { + // Prevent default to stop touches making weird highlights. + e?.preventDefault(); + + // Measure line so we have a left and width values. + this._measureLine(); + + const { iconEl } = this._children; + + // Determine if it was a touch. + const { isTouch, canHover } = this.app; + + // Get the first startX point depending on touch or mouse. + const xSource = e.touches?.length ? e.touches[0] : e; + const { clientX: startX } = xSource; + + // Make sure we have immediate transition, ie. none. + iconEl.style.setProperty('transition', 'none'); + + // Set cursor to grabbing (set on document so you can move mouse outside slider area). + document.body.style.setProperty('cursor', 'grabbing'); + + // Depending on hover and touch, add event listeners accordingly. + if (isTouch) { + document.addEventListener('touchmove', this._onMouseTouchMove); + document.addEventListener('touchend', this._onMouseTouchUp); + } + if (canHover) { + document.addEventListener('mousemove', this._onMouseTouchMove); + document.addEventListener('mouseup', this._onMouseTouchUp); + } + + // Set startX state. + this.setState({ startX }); + } + + /** + * TODO: + * Check if default camera distance works for other entities, do we need to delay until cam is positioned? + * + * Fix manual time input css. + */ + + /** + * The mouse and touch move event handler. + * @param {MouseEvent|Touch} e + */ + _onMouseTouchMove(e) { + // Destructure state and set new vars. + const { lineMeasures: { left, width } } = this._state; + const xSource = e.touches?.length ? e.touches[0] : e; + let { clientX: newTransX } = xSource; + + const min = left; + const max = left + width; + const halfWidth = width * 0.5; + + // Don't allow less than min or more than max. + newTransX = Math.max(newTransX, min); + newTransX = Math.min(newTransX, max); + newTransX -= (left + halfWidth); + + // Calculate normalized value + const normValue = newTransX / halfWidth; + + // Calculate rate. + let rate = this._calculateRate(normValue); + + // Return if we havev bad calculations. + if (isNaN(normValue) || isNaN(rate)) { + return; + } + + // Determine if we're going over a max limit or under a min. + const negative = normValue < 0; + const belowMin = this._limit === 'min' && negative; + const aboveMax = this._limit === 'max' && !negative; + + if (belowMin || aboveMax) { + newTransX = 0; + rate = 0; + } + + // Set translateX. + this._setTransX(newTransX); + + // Mobile - If rate is at very left or very right of screen, update margin so the screen doesn't eat the label + if (eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobilePortrait()) { + const { snapPoints } = this._config; + const rateIsExtreme = Math.abs(rate) > snapPoints[snapPoints.length - 3]; + const rateIsFarLeft = rateIsExtreme && (rate < (snapPoints[snapPoints.length - 3] * -1)); + const rateIsFarRight = rateIsExtreme && (rate > (snapPoints[snapPoints.length - 3])); + const customMargin = rateIsFarLeft ? '100%' : rateIsFarRight ? '-10%' : '50%'; + document.documentElement.style.setProperty('--customIconLabelMargin', customMargin); + } + + // Call onUpdate. + this.setCurrentRate(rate); + } + + /** + * The mouse and touch up event handler. + * @param {MouseEvent|Touch} e + */ + _onMouseTouchUp(e) { + // Prevent default. + e?.preventDefault(); + + const { isTouch, canHover } = this.app; + const { iconEl } = this._children; + // Remove eventListeners depending on isTouch and canHover. + if (isTouch) { + document.removeEventListener('touchmove', this._onMouseTouchMove); + document.removeEventListener('touchend', this._onMouseTouchUp); + } + if (canHover) { + document.removeEventListener('mousemove', this._onMouseTouchMove); + document.removeEventListener('mouseup', this._onMouseTouchUp); + } + + // Add transition back. + iconEl.style.setProperty('transition', 'transform 0.5s cubic-bezier(.3,1.24,.34,.98)'); + + // Set document cursor back to default. + document.body.style.setProperty('cursor', 'default'); + + // Call updateQuery. + this.updateQuery(); + } + + /** + * Handle clicking realtime button + * @param {Event} e + */ + _onRealtimeClick(e) { + this.updateQuery(1); + } + + /** + * Sets the translate X CSS property and local state. + * @param {number} transX + */ + _setTransX(transX) { + const { trans: currTransX } = this._state; + + // Return if already matches current transX. + if (transX === currTransX) { + return; + } + + // Set --x-icon-trans CSS var. + this._element.style.setProperty('--x-icon-trans', `${transX}px`); + + this.setState({ transX }); + } + + /** + * To make it easier for the user to be able to reach the snap points, we can lay out + * the time slider line into the snap points rather than a linear interpolation + * (which can be hard to drag to the finer values) + * @param {number} fastestRate + * @returns {Array} + */ + _getRateArray(fastestRate) { + const { snapPoints } = this._config; + + const nearestIndex = snapPoints.findIndex(point => fastestRate <= point); + const largerThanAllPoints = nearestIndex === -1; + + // If the fastest rate is really fast, it makes sense to slice out the early snap points (up to seconds, 10 seconds, minutes, 10 minutes, and hours) + let maxSliceStart = 8; + + if (!largerThanAllPoints) { + maxSliceStart -= (snapPoints.length - nearestIndex) * 2; + } + + // If greater than all snap points, simply add it to the end + if (largerThanAllPoints) { + return [1, ...snapPoints.slice(maxSliceStart), fastestRate]; + } + + const sliceRefIndex = snapPoints.length - maxSliceStart; + const sliceStart = nearestIndex - sliceRefIndex; + + return [1, ...snapPoints.slice(sliceStart, nearestIndex), fastestRate]; + } + + /** + * Calculate rate depending on whether snapping is enabled + * @param {number} normValue - between -1 and 1 + * @returns {number} + */ + _calculateRate(normValue) { + const { fastestRate, rateArray } = this._state; + + const negative = normValue < 0; + const absValue = Math.abs(normValue); + const maxIndex = rateArray.length - 1; + + // Calculate interpolated rate. + let interpolatedRate = absValue * fastestRate; + + if (rateArray) { + const interpIndex = absValue * maxIndex; + const interpFraction = interpIndex % 1; + + const rateIndex = Math.floor(interpIndex); + interpolatedRate = rateArray[rateIndex]; + + if (rateIndex < maxIndex) { + const nextRate = rateArray[rateIndex + 1]; + const additionalRate = (nextRate - interpolatedRate) * interpFraction; + interpolatedRate += Math.round(additionalRate); + } + } + + // Snap rate if config says so. + let snappedAbsRate = this._snapToRate(interpolatedRate); + + // Snap to first value in rate array if less than second. + if (snappedAbsRate < rateArray[1]) { + snappedAbsRate = rateArray[0]; + } + + // Reapply negation if needed. + return negative && snappedAbsRate !== rateArray[0] ? snappedAbsRate * -1 : snappedAbsRate; + } + + /** + * Blah + * @param {number} absRate + * @returns {number} + */ + _calculateNormValue(absRate) { + const { rateArray } = this._state; + const maxIndex = rateArray.length - 1; + + // Find the corresponding rate index in rateArray. + let rateIndex = -1; + for (let i = 0; i < rateArray.length; i++) { + if (absRate >= rateArray[i]) { + rateIndex = i; + } + else { + break; + } + } + + if (rateIndex === maxIndex || rateIndex === -1) { + // If rate is maximum, or more than the largest rate in rateArray, limit to the max value. + return 1; + } + else { + // Calculate the normalized value based on rate index and interpolated rate. + const lowerRate = rateArray[rateIndex]; + const upperRate = rateArray[rateIndex + 1]; + const rateFraction = (absRate - lowerRate) / (upperRate - lowerRate); + const normValue = (rateIndex + rateFraction) / maxIndex; + return normValue; + } + } + + /** + * Returns the nearest snapped rate or multiple of that rate + * @param {number} value - only deals with positive values + * @returns {number} + */ + _snapToRate(value) { + const { snapPoints } = this._config; + + // dont even THINK about using the reduce function, you wrectched fiend. + const nearestIndex = snapPoints.findIndex(point => value < point); + + if (nearestIndex === 0) { + return snapPoints[nearestIndex]; + } + + // If the input value is bigger than all of the snap points (nearestIndex is -1) we calculate the value divided by the last snap point and round it. + + // Get the previous point. + const prevPoint = nearestIndex > -1 ? snapPoints[nearestIndex - 1] : snapPoints[snapPoints.length - 1]; + + // Get the snapped multiple. + const snappedMultiple = Math.round(value / prevPoint); + + // Snapped rate is the prev point times the snapped multiple. + return snappedMultiple * prevPoint; + } + + /** + * Set current time rate in pioneer and css variable. + * @param {number} rate + */ + setCurrentRate(rate) { + // Remove the limit if we're not at 0. + rate !== 0 && this._setLimit(null); + + // Set pioneer rate and local var. + this.app.pioneer.setTimeRate(rate); + this._currentRate = rate; + + // Set formatted rate. + const formattedRate = this.formatRate(rate); + this._element.style.setProperty('--x-rate', `'${formattedRate}'`); + + // Set realtime button visibility depending on ratet. + const realtimeVisibleClass = (rate === 1 || rate === 0) ? 'hidden' : ''; + this.setState({ realtimeVisibleClass }); + } + + /** + * updateQuery handler. + * @param {number} rate + */ + updateQuery(rate = this.app.pioneer.getTimeRate()) { + // Set time query in route + const router = this.app.getManager('router'); + const time = this.app.getManager('time').getTimeUrl(); + router.navigate({ time, rate }, router.currentRoute.url); + } + + /** + * Calculates the dynamic fastest time rate based on dynamic camera distance. + * @returns {number} - seconds per second + */ + _getFastestRate() { + const { enableDynamicRate, fastestRate, defaultCamDistance } = this._config; + + // Calculate the rate coefficient by getting the current camera position and comparing it to the max zoom distance (_defaultMaxDistance) + const { defaultMaxDistance } = this._app.getManager('camera'); + + let camDistance = this._camDistance; + + // Fallback to deefault cam distance if necessary (shouldnt be needed) + if (!camDistance || isNaN(camDistance)) { + console.warn('Time Slider:: Missing camera distance.'); + camDistance = defaultCamDistance; + } + + // Make sure the values are valid. + const rateCoefficient = defaultMaxDistance && !isNaN(defaultMaxDistance) + ? Math.round(camDistance) / defaultMaxDistance + : 1; + + return enableDynamicRate + ? fastestRate.min + (fastestRate.max - fastestRate.min) * rateCoefficient + : fastestRate.max; + } + + /** + * Creates a clean formatted string from the rate value + * @param {number} rate + * @returns {string} + */ + formatRate(rate) { + if (rate === 1) { + return ''; + } + if (rate === 0) { + return 'Paused'; + } + + const negative = rate < 0; + const absRate = Math.abs(rate); + + const yrs = absRate / 31540000; + const months = absRate / 2628000; + const weeks = absRate / 604800; + const days = absRate / 86400; + const hrs = absRate / 3600; + const mins = absRate / 60; + + const oneDP = (val) => { + const toOneDP = Number(`${Math.round(`${val}e1`)}e-1`); + return negative ? toOneDP * -1 : toOneDP; + }; + + if (yrs >= 1) { + return `${oneDP(yrs)} yrs/s`; + } + if (months >= 2) { + return `${Math.round(negative ? months * -1 : months)} mths/s`; + } + if (weeks >= 1) { + return `${Math.round(negative ? weeks * -1 : weeks)} wks/s`; + } + if (days >= 1) { + return `${oneDP(days)} days/s`; + } + if (hrs >= 1) { + return `${oneDP(hrs)} hrs/s`; + } + if (mins >= 1) { + return `${oneDP(mins)} mins/s`; + } + return `${rate} secs/s`; + } + + /** + * Classes are determined by the device and screen we're using. + * @param {object} options + * @returns {Array} + */ + _getClasses(options) { + const classes = []; + + if (options.removeAll) { + return classes; + } + + const limitedHeightThreshold = 641; + const limitedWidthThreshold = 961; + const offsetRightThreshold = 641; + + const portrait = eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobilePortrait(); + const landscape = eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isLandscape(); + + const limitedHeight = window.innerHeight < limitedHeightThreshold; + const limitedWidth = window.innerWidth < limitedWidthThreshold; + const offsetRight = window.innerHeight < offsetRightThreshold && !portrait; + + // Expanded or not. + if (options.expanded && offsetRight) { + classes.push('offset-right'); + } + + // Limited height. + if (limitedHeight) { + classes.push('v-squeezy'); + } + + // Limited width. + if (limitedWidth) { + classes.push('h-squeezy'); + } + + // Portrait or landsape. + if (portrait) { + classes.push('portrait'); + } + else if (landscape) { + classes.push('landscape'); + } + + return classes; + } + + /** + * Sets the position using an array of positional class names + * @param {object} options + */ + toggleExtraClasses(options) { + const classes = this._getClasses(options); + + this._extraClasses.forEach(extraClass => { + const addClass = (classes.includes(extraClass) && !options.removeAll); + this._parent.classList.toggle(extraClass, addClass); + }); + } + + /** + * Gets the current extra classes. + * @returns {DOMTokenList} + */ + get extraClasses() { + return this._parent.classList; + } + + /** + * Measures the line element and stores left and width values. + * @returns {object} + */ + _measureLine() { + // We need to run a separate getBoundingClientRect in order to get the correct 'left' value. + const { left, width } = this._children?.lineEl?.getBoundingClientRect() || {}; + + if (left === undefined || width === undefined) { + return null; + } + + // Set states. + this.setState({ + lineMeasures: { left, width, isMeasured: true } + }); + + return { left, width }; + } + + /** + * Handle component resize. + */ + _onResize() { + const { width } = this._measureLine(); + + // Update transX. + const rate = this._currentRate ?? 1; + const negative = rate < 0; + const absRate = Math.abs(rate); + const normVal = this._calculateNormValue(absRate); + const absTransX = normVal * width * 0.5; + const transX = negative ? absTransX * -1 : absTransX; + + this._setTransX(transX); + } + + /** + * Handle element resize. + * @override + */ + resize() { + // Debounce resize for improved performance. + this._resizeDebounced(); + } + + /** + * Update called eevery frame. + */ + _update() { + // Set our camDistance + const { cameraEntity } = this.app.getManager('camera'); + const camDistance = cameraEntity.getPosition().magnitude(); + + // Update cam distance. + if (this._camDistance?.toFixed(4) !== camDistance?.toFixed(4)) { + this._camDistance = camDistance; + + // Set fastestRate and rateArray when cam distance is valid. + if (this._camDistance && !isNaN(this._camDistance)) { + // Calculate and store fastest rate. + const fastestRate = this._snapToRate(this._getFastestRate()); + + // Calculate and store rateArray. + const rateArray = this._getRateArray(fastestRate); + + // Set states. + this.setState({ fastestRate, rateArray }); + } + } + + // Call and reset resolve if needed + if (this._camDistanceResolve && this._camDistance && !isNaN(this._camDistance)) { + this._camDistanceResolve(this._camDistance); + this._camDistanceResolve = null; + } + } + + /** + * Custom show override to set classes on parent (this is necessary when reusing the clock and clockshortcut components as children) + * @override + */ + show() { + this._parent?.classList.toggle('hidden', false); + } + + /** + * Custom hide override to set classes on parent (this is necessary when reusing the clock and clockshortcut components as children) + * @override + */ + hide() { + this._parent?.classList.toggle('hidden', true); + } + + /** + * Set visibility of just time slider + * @param {boolean} visible + */ + setSliderVisibility(visible) { + this._parent?.classList.toggle('no-slider', !visible); + } +} + +TimeSlider.html = (_time_slider_html__WEBPACK_IMPORTED_MODULE_2___default()); + + +/***/ }), + +/***/ "./src/components/watch_panel/watch_card.js": +/*!**************************************************!*\ + !*** ./src/components/watch_panel/watch_card.js ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "WatchCard": function() { return /* binding */ WatchCard; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _watch_card_html__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./watch_card.html */ "./src/components/watch_panel/watch_card.html"); +/* harmony import */ var _watch_card_html__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_watch_card_html__WEBPACK_IMPORTED_MODULE_3__); + + + + + + + + +/** + * + */ +class WatchCard extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options = {}) { + // call super class and pass default state object. + super(app, null, { + title: 'Asteroid Name', + date: 'April 13, 2029', + time: '10:52am', + diameterUnit: 'km', + diameter: '0.5', + diameterEstimatedText: '', + diameterRaw: 0.5, + distanceUnit: 'km', + distance: '512,321', + distanceRaw: 512321, + unitType: 'metric', + ...options + }); + + this.bindFunctions(['toggleUnit']); + } + + /** @inheritdoc */ + init() { + super.init(); + + this._callbackRegistry.push({ + emitter: this._app.getManager('watch'), + event: 'toggleUnit', + callback: this.toggleUnit + }); + } + + /** + * On html handleToggleUnit click + * @param {Event} e + */ + handleToggleUnit(e) { + this._app.getManager('watch')?.toggleUnit(); + } + + /** + * Toggles the card between km and mi units + * @param {string} newUnitType - unit to swap to + */ + toggleUnit(newUnitType) { + // This is a quick, dirty band-aid change from Jack. We need a task for a central unit manager. + const metric = newUnitType === 'metric'; + const kmMiRatio = 1.609344; + const ftInMiles = 5280; + const mInKm = 1000; + + const { diameterRaw, distanceRaw } = this._state; + + const currentDiameter = diameterRaw || 0; + let newDiameter = currentDiameter; + let newDiameterUnit = metric ? 'km' : 'mi'; + + const currentDistance = distanceRaw || 0; + let newDistance = currentDistance; + let newDistanceUnit = metric ? 'km' : 'mi'; + + if (metric) { + // Working in metric. + + if (newDiameter < 1) { + newDiameterUnit = 'm'; + newDiameter *= mInKm; + } + + if (newDistance < 1) { + newDistanceUnit = 'm'; + newDistance *= mInKm; + } + } + else { + // Working in imperial. + newDiameter = currentDiameter / kmMiRatio; + newDistance = currentDistance / kmMiRatio; + + if (newDiameter < 1) { + newDiameterUnit = 'ft'; + newDiameter *= ftInMiles; + } + + if (newDistance < 1) { + newDistanceUnit = 'ft'; + newDistance *= ftInMiles; + } + } + + this.setState({ + diameterUnit: newDiameterUnit, + diameter: this._parseDiameter(newDiameter), + distanceUnit: newDistanceUnit, + distance: `${Math.round(newDistance).toLocaleString(undefined)}`, + unitType: newUnitType + }); + } + + /** + * Make diameter value prettier and rounded + * @param {number} diameter + * @returns {string} + */ + _parseDiameter(diameter) { + return parseFloat(diameter).toFixed(1).replace(/\.0+$/, ''); + } + + /** + * Parses NEO data and sets state + * @param {NEO} neoData + */ + setTarget(neoData) { + const { name, nextClosestApproachTime, nextClosestApproachDistance, diameter, diameterEstimated } = neoData; + + const unixSeconds = pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.etToUnix(nextClosestApproachTime); + const date = new Date(unixSeconds * 1000); + + this.setState({ + title: name, + date: date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' }), + time: date.toLocaleTimeString(undefined), + + diameter: this._parseDiameter(diameter), + diameterRaw: diameter, + diameterEstimatedText: diameterEstimated ? '〚estimated〛' : '', + + distance: `${Math.round(nextClosestApproachDistance).toLocaleString(undefined)}`, + distanceRaw: nextClosestApproachDistance + }); + + // Trigger a toggle on init. + this.toggleUnit(this._state.unitType); + } +} + +WatchCard.html = (_watch_card_html__WEBPACK_IMPORTED_MODULE_3___default()); + + +/***/ }), + +/***/ "./src/components/watch_panel/watch_panel.js": +/*!***************************************************!*\ + !*** ./src/components/watch_panel/watch_panel.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "WatchPanel": function() { return /* binding */ WatchPanel; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _countdown_countdown__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../countdown/countdown */ "./src/components/countdown/countdown.js"); +/* harmony import */ var _watch_card__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./watch_card */ "./src/components/watch_panel/watch_card.js"); + + + + + + + + +/** + * WatchPanel extends CarouselPanel + */ +class WatchPanel extends eyes__WEBPACK_IMPORTED_MODULE_0__.CarouselPanel { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options) { + super(app, { + + // States + // isVisible: false, + + // Class names + panelTypeClass: 'watch-panel', + carouselClass: 'watch-carousel', + paginationClass: 'watch-carousel-fraction', + prevButtonClass: 'watch-carousel-prev', + nextButtonClass: 'watch-carousel-next', + + // Options + title: 'Asteroid Watch', + caption: 'The next five closest approaches to Earth', + headerIconClass: 'asteroid', + + ...options + }); + + /** + * Store showBeExpanded state (for when showing and hiding UI) + */ + this.shouldBeExpanded = null; + + /** + * Slide change callback + * @param {object} params + * @param {number} params.realIndex + */ + this._onSlideChange = ({ realIndex }) => { + const watchManager = this._app.getManager('watch'); + + // Get the neo to navigate to the correct URL + const neoName = watchManager.getNeoNameByIndex(realIndex); + watchManager.updateURL(neoName); + }; + } + + /** + * Compose the watch carousel slides + * @param {Array} nextFive + */ + populate(nextFive) { + // Compose the watch card and countdown components + nextFive.forEach(asteroid => { + // create watch card + const watchCard = new _watch_card__WEBPACK_IMPORTED_MODULE_2__.WatchCard(this._app); + watchCard.init(); + watchCard.setTarget(asteroid); + this._components.push(watchCard); + + // create countdown and register update callback + const countdown = new _countdown_countdown__WEBPACK_IMPORTED_MODULE_1__.Countdown(this._app); + countdown.init(); + countdown.setTimeTarget(asteroid.nextClosestApproachTime); + this._components.push(countdown); + + // Add HTML slides. + this.addSlide([watchCard.element, countdown.element]); + }); + } + + /** @inheritdoc */ + setExpandState() { + super.setExpandState(this.shouldBeExpanded); + } + + /** + * Show override + */ + show() { + this.setExpandState(); + super.show(false); + } + + /** + * Replacing expand method in Panel super class + * Rather than directly expanding or collapsing by adding or removing a class, + * we instead change the URL and respond to the onRouteChange in the watch view. + * It's therefore in the watch view that we set the expand/collapse state. + * This method is a little convoluted but it reduces the chance of going out of sync with the URL. + */ + expand() { + const watchManager = this._app.getManager('watch'); + const currentSwiperSlide = this._swiper?.realIndex; + watchManager.setSlideUrlByIndex(currentSwiperSlide); + } + + /** + * Replacing collapse method in CarouselPanel super class + */ + collapse() { + const watchManager = this._app.getManager('watch'); + watchManager.updateURL(''); + } +} + + +/***/ }), + +/***/ "./src/configs/components_info.js": +/*!****************************************!*\ + !*** ./src/configs/components_info.js ***! + \****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ([ + { + type: 'Search', + name: 'search', + options: { + config: { + placeholderText: 'Search asteroids and comets...', + allowFeatured: true, + allowDetail: false, + allowInfo: true, + stopOnExactMatch: false, + maxSuggestions: 3 + } + } + }, + { type: 'TutorialOverlay', name: 'tutorialOverlay' }, + { type: 'AsteroidMenuTop', name: 'asteroid_menu_top' }, + { type: 'AsteroidMenuBottom', name: 'asteroid_menu_bottom' }, + { type: 'AsteroidModals', name: 'asteroid_modals' }, + { + type: 'Breadcrumb', + name: 'breadcrumb', + options: { + params: { + title: 'Eyes on Asteroids' + } + } + }, + { + type: 'Clock', + name: 'clock', + postCreationFunction: (_, component) => { + // add x-small class to make time font smaller + const timeNodes = component._element?.querySelectorAll('.time, .meridiem'); + timeNodes.forEach(node => node.classList.add('x-small')); + } + }, + { type: 'ClockShortcut', name: 'clockShortcut' }, + { + type: 'TimeSlider', + name: 'timeSlider', + options: { + config: { + // dynamic based off how close the camera is to an entity + enableDynamicRate: true, + // variation in fastest time rates (seconds per second) + fastestRate: { + min: 3629000, // 6 weeks / sec + max: 157700000 // 5 yrs / sec + } + } + } + }, + { type: 'AsteroidsSettings', name: 'settings' }, + { type: 'HomeButton', name: 'homeButton' }, + { type: 'AsteroidPanel', name: 'asteroidPanel' }, + { type: 'MissionPanel', name: 'missionPanel' }, + { type: 'FollowingPanel', name: 'followingPanel' }, + { type: 'WatchPanel', name: 'watchPanel' }, + { + type: 'LayerPanel', + name: 'layerPanel', + options: { + layers: [['planets'], ['spacecraft'], ['trails', 'labels', 'icons', 'starfield'], ['ui']], + checkboxType: 'eyes' + } + }, + { type: 'DefinitionOverlay', name: 'definitionOverlay' }, + { type: 'SplashScreen', name: 'splashScreen' }, + { type: 'Story', name: 'story' } +]); + + +/***/ }), + +/***/ "./src/data/stories/asteroids_101.js": +/*!*******************************************!*\ + !*** ./src/data/stories/asteroids_101.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + +// An incrementing int used to cancel outdated camera transition awaits +let globalNonce = 0; + +/* harmony default export */ __webpack_exports__["default"] = ({ + type: 'nonsequential', + entities: [ + '4_vesta', + '67p_churyumov_gerasimenko' + ], + slides: [ + { + id: 'slide_1', + type: 'overlay', + classList: ['opaque', 'black'], + content: [ + { + type: 'title', + title: 'Asteroids and Comets 101' + } + ] + }, + { + id: 'slide_2', + type: 'overlay', + classList: ['opaque', 'black'], + content: [ + { + type: 'image', + src: 'assets/images/outterAsteroidBelt.png', + title: 'Main Asteroid Belt. Credit: NASA/JPL', + alt: 'This image illustrates the millions of asteroids between the Sun and Jupiter — know as the asteroid belt.', + clickable: true + }, + { + type: 'description', + description: 'This image illustrates the millions of asteroids between the Sun and Jupiter — know as the asteroid belt.

      The current number of known asteroids in the entire solar system is:
      0

      ', + onEnter: async (app, block) => { + const element = block.element.querySelector('.tween-count'); + // const response = await fetch('https://solarsystem.nasa.gov/api/v1/static_stellar_counts/1/'); // TODO: And uncomment this + const count = 1362000 //(await response.json()).asteroids; // TODO: Remove before pushing to staging. + // If we're keeping the hardcoded value, add some hedging like "roughly" + + eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.tween({ i: 0 }, { i: count }, { + onUpdate: object => { + if (element) { + const value = Math.round(object.i); + element.innerHTML = Number(value).toLocaleString(); + } + }, + duration: 3000 + }); + } + } + ] + }, + { + id: 'slide_3', + type: 'panel', + content: [ + { + type: 'title', + classList: ['semi'], + title: "Vesta" + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + await app.getManager('scene').isReady('4_vesta'); + if (localNonce !== globalNonce) return; + await app.cameraScripts.goToSystem('inner_solar_system', { duration: 1 }); + if (localNonce !== globalNonce) return; + await app.cameraScripts.goToCelestialObject('4_vesta', { duration: 4 }); + } + ] + }, + { + id: 'slide_4', + type: 'panel', + content: [ + { + type: 'title', + title: "67P Churyumov-Gerasimenko" + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + await app.getManager('scene').isReady('67p_churyumov_gerasimenko'); + if (localNonce !== globalNonce) return; + await app.cameraScripts.goToSystem('inner_solar_system', { duration: 1 }); + if (localNonce !== globalNonce) return; + await app.cameraScripts.goToCelestialObject('67p_churyumov_gerasimenko', { duration: 4 }); + } + ] + }, + { + id: 'slide_5', + type: 'panel', + content: [ + { + type: 'title', + title: "" + } + ], + camera: [ + async app => { + ++globalNonce; + await app.cameraScripts.goToSystem('inner_solar_system', { duration: 2 }); + } + ], + rate: 604800 + } + ] +}); + + +/***/ }), + +/***/ "./src/data/stories/asteroids_close_approach.js": +/*!******************************************************!*\ + !*** ./src/data/stories/asteroids_close_approach.js ***! + \******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = ({ + type: 'nonsequential', + entities: [ + 'moon', + '99942_apophis' + ], + slides: [ + { + id: 'slide_1', + type: 'overlay', + classList: ['opaque', 'black'], + content: [ + { + type: 'title', + title: 'What is a Close Approach?' + } + ], + camera: [ + async app => { + await app.cameraScripts.goToSystem('outer_solar_system'); + } + ] + }, + { + id: 'slide_2', + type: 'panel', + content: [ + { + type: 'description', + description: '' + } + ], + camera: [ + async app => { + await app.cameraScripts.goToSystem('inner_solar_system'); + } + ], + rate: 259200 + }, + { + id: 'slide_3', + type: 'panel', + content: [ + { + type: 'description', + title: 'Apophis', + description: '' + } + ], + time: '2029-04-13T14:40:12-07:00', + camera: [ + async app => { + // Go to Apophis looking at Earth + await app.getManager('scene').isListReady(['99942_apophis', 'earth']); + app.getManager('time').pause(); + await app.cameraScripts.alignObjects('99942_apophis', 'earth', { + duration: 2, + verticalOffset: 15, + horizontalOffset: -15 + }); + app.getManager('time').play(); + } + ], + onEnter: app => { + app.scene.get('sun').getComponentByType('orbitalParticles').setEnabled(false); + }, + onLeave: app => { + app.scene.get('sun').getComponentByType('orbitalParticles').setEnabled(true); + }, + rate: 60 + }, + { + id: 'slide_4', + type: 'panel', + content: [ + { + type: 'description', + title: "Apophis's closest approach to Earth", + classList: ['large', 'semi'], + description: '
      Distance: {{distance}} km
      ', + onEnter: (app, block) => { + block.addState('distance', '0'); + + block.update = () => { + const distance = app.getManager('scene').getDistance('earth', '99942_apophis', { precision: 3 }).toLocaleString(); + block.setState({ distance }); + }; + app.pioneer.addCallback(block.update, true); + }, + onLeave: (app, block) => { + app.pioneer.removeCallback(block.update); + } + } + ], + time: '2029-04-12T12:00:00-07:00', + camera: [ + async app => { + // View of the Earth, Moon and Apophis + await app.getManager('scene').isListReady(['earth', 'moon', '99942_apophis']); + app.getManager('time').pause(); + await app.cameraScripts.goToSystem('earth', { + duration: 2, + planeId: 'moon', + otherEntityNames: ['moon'], + distance: 385000 * 2.5, + angle: 35, + includeChildren: false, + isRelativeToPreviousCamera: false + }); + app.getManager('time').play(); + } + ], + onEnter: async (app, slide) => { + await app.getManager('scene').isListReady(['sun', 'earth', 'moon', '99942_apophis']); + const sun = app.scene.get('sun'); + + sun.getComponentByType('orbitalParticles').setEnabled(false); + + const lineOfSight = sun.get('orbiterLineOfSight'); + lineOfSight.setEnabled(true); + lineOfSight.setTargets('earth', '99942_apophis'); + + // Turn off Earth's trail + app.scene.get('earth').get('orbitLine').setEnabled(false); + + // TODO 9 moons in future + + // Only when slide changes + if (slide.getState('previousIndex') !== slide.getState('currentIndex')) { + slide.reset = {}; + + const apophis = app.scene.get('99942_apophis'); + // Disable default dynamo + apophis.getControllerByType('dynamo', 0)?.setEnabled(false); + // Add dynamo controller to Apophis for higher accuracy SSD + // Apophis uses orbital elements controller and has no dynamo by default + const dynamoController = apophis.addController('dynamo', 'earth_centric'); + dynamoController.setBaseUrl('$DYNAMIC_ASSETS_URL/dynamo/ssd/99942_apophis/earth/orb/'); + + // Change Apophis's parent + apophis.removeParentingTableEntry(Number.NEGATIVE_INFINITY); + apophis.addParentingTableEntry(Number.NEGATIVE_INFINITY, 'earth'); + } + + app.getManager('time').setMax('2029-04-14T12:00:00-07:00'); + }, + onLeave: async (app, slide) => { + // Remove added Apophis dynamo controller + const apophis = app.scene.get('99942_apophis'); + apophis.removeParentingTableEntry(Number.NEGATIVE_INFINITY); + apophis.addParentingTableEntry(Number.NEGATIVE_INFINITY, 'sun'); + apophis.removeController(apophis.getController('earth_centric')); + apophis.getControllerByType('dynamo', 0)?.setEnabled(true); + + const sun = app.scene.get('sun'); + + sun.getComponentByType('orbitalParticles').setEnabled(true); + + const lineOfSight = sun.get('orbiterLineOfSight'); + lineOfSight.setEnabled(false); + + // Turn on Earth's trail + app.scene.get('earth').get('orbitLine').setEnabled(true); + + app.getManager('time').resetMax(); + + await app.scene.getLoadedPromise(); + await app.pioneer.waitUntilNextFrame(); + }, + rate: 1800 + }, + { + id: 'slide_5', + type: 'panel', + content: [ + { + type: 'description', + title: 'Near Earth Objects (NEOs)', + description: '', + onEnter: (app, block) => { + block.auLinkClick = () => { + app.getComponent('definitionOverlay').navigateToDefinition('au'); + }; + block._children.auLink?.addEventListener('click', block.auLinkClick); + block._children.auLink?.addEventListener('click', block.auLinkClick); + }, + onLeave: (app, block) => { + block._children.auLink?.removeEventListener('click', block.auLinkClick); + } + } + ], + time: '2029-03-01T10:45:12-07:00', + rate: 300000, + camera: [ + async app => { + // Top down view of the Sun, with ring shown around the Sun + await app.getManager('scene').isListReady(['sun', 'earth', '99942_apophis']); + app.getManager('time').pause(); + await app.cameraScripts.showLocation('sun', 'earth', 'earth', 'planeNormal', { + distance: eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm * 1.3 * 1.5, + duration: 2, + startFromTarget: false, + rotateByScreenRatio: false + }); + app.getManager('time').play(); + } + ], + onEnter: app => { + // Hide all planets except Earth + const planets = pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.getEntityNamesInGroup('planets'); + planets.forEach(planet => { + if (planet !== 'earth') { + app.scene.get(planet).setEnabled(false); + } + }); + + // Hide all trails, except Earth + app.getManager('layer').toggleLayer('trails'); + app.scene.get('earth').get('orbitLine').setEnabled(true); + + // Make Apophis and Earth labels always show on collision + app.getManager('label').addException('earth'); + app.getManager('label').addException('99942_apophis'); + + // Show ring + const ringEntity = app.scene.get('sunRing'); + const labelEntity = app.scene.get('sunRingLabel'); + ringEntity.setEnabled(true); + labelEntity.setEnabled(true); + }, + onLeave: app => { + // Reset planets + const planets = pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.getEntityNamesInGroup('planets'); + planets.forEach(planet => { + if (planet !== 'earth') { + app.scene.get(planet).setEnabled(true); + } + }); + + // Reset trails + app.getManager('layer').toggleLayer('trails', undefined, true); + + // Reset Apophis and Earth labels + app.getManager('label').removeException('earth'); + app.getManager('label').removeException('99942_apophis'); + + // Hide ring + const ringEntity = app.scene.get('sunRing'); + ringEntity.setEnabled(false); + const labelEntity = app.scene.get('sunRingLabel'); + labelEntity.setEnabled(false); + } + }, + { + id: 'slide_6', + type: 'panel', + content: [ + { + type: 'description', + title: 'Potentially Hazardous Objects (PHOs)', + description: '', + onEnter: (app, block) => { + // Turn on PHO filter + block.addState('phoCount', '0'); + app.getManager('filters').setFilter({ asteroids: true, comets: true, phos: true }, null, (size) => { + block.setState({ phoCount: Number(size).toLocaleString() }); + }); + }, + onLeave: (app, block) => { + // Reset PHO filter + const filtersManager = app.getManager('filters'); + filtersManager.setFilter(filtersManager.getPreviousFilters()); + } + } + ], + time: '2029-03-27T14:45:12-07:00', + rate: 10000, + camera: [ + async app => { + await app.getManager('scene').isListReady(['earth', '99942_apophis']); + app.getManager('time').pause(); + await app.cameraScripts.showLocation('sun', 'earth', 'earth', 'planeNormal', { + distance: eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm * 1.3 * 1.5, + duration: 2, + startFromTarget: false, + rotateByScreenRatio: false + }); + await app.cameraScripts.goToSystemSideway('earth', { + duration: 2, + distance: eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm * 0.05 * 20, + angleInDegree: 30, + includeChildren: false + }); + + app.getManager('time').play(); + } + ], + onEnter: async app => { + // Show torus + const torus = app.scene.get('sunTorus'); + torus.setEnabled(true); + const torusLabel = app.scene.get('sunTorusLabel'); + torusLabel.setEnabled(true); + }, + onLeave: app => { + // Hide torus + const torus = app.scene.get('sunTorus'); + torus.setEnabled(false); + const torusLabel = app.scene.get('sunTorusLabel'); + torusLabel.setEnabled(false); + } + }, + { + id: 'slide_7', + type: 'panel', + content: [ + { + type: 'description', + description: 'Explore the next 5 closest approaches here. These are continuously updated, as NASA is constantly on the lookout.' + } + ], + camera: [ + async app => { + await app.cameraScripts.goToSystem('inner_solar_system'); + } + ], + rate: 259200 + } + ], + onEnter: app => { + }, + onLeave: app => { + // Reset force load + const sceneManager = app.getManager('scene'); + app.getManager('layer').toggleLayer('trails', undefined, true); + app.scene.get('earth').get('orbitLine').setEnabled(true); + } +}); + + +/***/ }), + +/***/ "./src/data/stories/asteroids_missions.js": +/*!************************************************!*\ + !*** ./src/data/stories/asteroids_missions.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); + + +const forceLoad = [ + // ['67p_churyumov_gerasimenko', 'model'], + // ['sc_rosetta', 'model'], + + // ['433_eros', 'model'], + // ['sc_near_shoemaker', 'model'], + + // ['9p_tempel_1', 'model'], + // ['sc_deep_impact_impactor', 'model'], + + // ['4_vesta', 'model'], + // ['sc_dawn', 'model'], + + // ['1_ceres', 'spheroid'], + + // ['sc_stardust', 'model'], + + // ['101955_bennu', 'model'], + // ['sc_osiris_rex', 'model'], + + // ['16_psyche', 'model'], + // ['sc_lucy', 'model'], + + // ['dimorphos', 'model'], + // ['sc_dart', 'model'], + + // ['earth', 'spheroid'] +]; + +// An incrementing int used to cancel outdated camera transition awaits +let globalNonce = 0; + +// Indicate that a label is clicked +let isLabelClicked = false; +const resetLabelClick = () => { + isLabelClicked = false; +}; + +/** + * Add click callback to an entity's label. + * @param {App} app + * @param {string} entityName + * @param {Function} callback + */ +const addLabelClick = (app, entityName, callback) => { + const labelEl = app.scene.getEntity(entityName)?.get('div')?.getDiv(); + + if (labelEl) { + labelEl.classList.remove('unclickable'); + labelEl.addEventListener('click', async () => { + isLabelClicked = true; + await callback(entityName, app); + }); + } +}; + +/** + * Remove click callback from an entity's label. + * @param {App} app + * @param {string} entityName + * @param {Function} callback + */ +const removeLabelClick = (app, entityName, callback) => { + const labelEl = app.scene.getEntity(entityName)?.get('div')?.getDiv(); + + if (labelEl) { + labelEl.classList.add('unclickable'); + labelEl.removeEventListener('click', callback); + } +}; + +/** + * Wrapper for camera goToSpacecraft. + * @param {string} entityName + * @param {BaseApp} app + */ +const goToSpacecraft = async (entityName, app) => { + await app.cameraScripts.goToSpacecraft(entityName); +}; + +/** + * Wrapper for camera goToCelestialObject. + * @param {string} entityName + * @param {BaseApp} app + */ +const goToCelestialObject = async (entityName, app) => { + await app.cameraScripts.goToCelestialObject(entityName); +}; + +/* harmony default export */ __webpack_exports__["default"] = ({ + type: 'nonsequential', + slides: [ + { + id: 'slide_1', + type: 'overlay', + classList: ['opaque', 'black'], + content: [ + { + type: 'title', + title: 'Asteroid and Comet Missions' + } + ], + camera: [ + async app => { + ++globalNonce; + await app.cameraScripts.goToSystem('inner_solar_system'); + } + ] + }, + { + id: 'slide_2', + type: 'panel', + time: '2015-02-14T08:14:00Z', + content: [ + { + type: 'description', + title: 'The Rosetta mission', + description: 'Orbiting comet 67P Churyumov-Gerasimenko' + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + const time = app.getManager('time'); + await app.getManager('scene').isListReady(['67p_churyumov_gerasimenko', 'sc_rosetta']); + if (localNonce !== globalNonce) return; + time.pause(); + await app.cameraScripts.goToSpacecraft('sc_rosetta', { cinematic: true, duration: 3 }); + time.play(); + } + ], + onEnter: (app, slide) => { + const camera = app.getManager('camera'); + + // Make label(s) clickable + addLabelClick(app, 'sc_rosetta', goToSpacecraft); + addLabelClick(app, '67p_churyumov_gerasimenko', goToCelestialObject); + + // Make object(s) clickable + slide.selectionCallback = camera.getSelectionCallback(); + camera.setSelectionCallback(async entity => { + const entityName = entity?.getName(); + if (entityName === '67p_churyumov_gerasimenko') { + await app.cameraScripts.goToCelestialObject(entityName); + } + else if (entityName === 'sc_rosetta') { + await app.cameraScripts.goToSpacecraft(entityName); + } + }); + }, + onLeave: (app, slide) => { + // Make label(s) unclickable + removeLabelClick(app, 'sc_rosetta', goToSpacecraft); + removeLabelClick(app, '67p_churyumov_gerasimenko', goToCelestialObject); + + // Reset object callback + app.getManager('camera').setSelectionCallback(slide.selectionCallback); + } + }, + { + id: 'slide_3', + type: 'panel', + time: '2001-02-12T18:00:00Z', + rate: 0, + content: [ + { + type: 'description', + title: 'The NEAR Shoemaker mission', + description: 'orbiting the asteroid Eros' + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + const time = app.getManager('time'); + await app.getManager('scene').isListReady(['433_eros', 'sc_near_shoemaker']); + if (localNonce !== globalNonce) return; + time.pause(); + await app.cameraScripts.alignObjects('sc_near_shoemaker', '433_eros', { + duration: 3, + verticalOffset: 15, + horizontalOffset: -15, + distance: 0.05 + }); + time.play(); + } + ], + onEnter: (app, slide) => { + const camera = app.getManager('camera'); + + // Make label(s) clickable + addLabelClick(app, 'sc_near_shoemaker', goToSpacecraft); + addLabelClick(app, '433_eros', goToCelestialObject); + + // Make object(s) clickable + slide.selectionCallback = camera.getSelectionCallback(); + camera.setSelectionCallback(async entity => { + const entityName = entity?.getName(); + if (entityName === '433_eros') { + await app.cameraScripts.goToCelestialObject(entityName); + } + else if (entityName === 'sc_near_shoemaker') { + await app.cameraScripts.goToSpacecraft(entityName); + } + }); + }, + onLeave: (app, slide) => { + // Make label(s) unclickable + removeLabelClick(app, 'sc_near_shoemaker', goToSpacecraft); + removeLabelClick(app, '433_eros', goToCelestialObject); + + // Reset object callback + app.getManager('camera').setSelectionCallback(slide.selectionCallback); + } + }, + { + id: 'slide_4', + type: 'panel', + time: '2005-07-04T05:44:20Z', + content: [ + { + type: 'description', + title: 'The Deep Impact mission', + description: 'The Deep Impact Impactor on collision course with comet Tempel 1 (9P/Tempel)' + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + const time = app.getManager('time'); + await app.getManager('scene').isListReady(['9p_tempel_1', 'sc_deep_impact', 'sc_deep_impact_impactor']); + if (localNonce !== globalNonce) return; + time.pause(); + await app.cameraScripts.alignObjects('sc_deep_impact_impactor', '9p_tempel_1', { + duration: 3, + distance: 0.005, + verticalOffset: 15, + horizontalOffset: 15 + }); + time.play(); + } + ], + onEnter: (app, slide) => { + const maxTime = '2005-07-04T05:44:33Z'; + slide.update = () => { + const time = app.getManager('time'); + if (time.getTime().valueOf() >= time.parseTime(maxTime).valueOf()) { + time.pause(); + } + }; + app.pioneer.addCallback(slide.update, true); + app.getManager('time').setMax(maxTime); + + const camera = app.getManager('camera'); + + // Make label(s) clickable + addLabelClick(app, 'sc_deep_impact_impactor', goToSpacecraft); + addLabelClick(app, 'sc_deep_impact', goToSpacecraft); + addLabelClick(app, '9p_tempel_1', goToCelestialObject); + + // Make object(s) clickable + slide.selectionCallback = camera.getSelectionCallback(); + camera.setSelectionCallback(async entity => { + const entityName = entity?.getName(); + if (entityName === '9p_tempel_1') { + await app.cameraScripts.goToCelestialObject(entityName); + } + else if (entityName === 'sc_deep_impact_impactor') { + await app.cameraScripts.goToSpacecraft(entityName); + } + }); + }, + onLeave: (app, slide) => { + app.pioneer.removeCallback(slide.update); + app.getManager('time').resetMax(); + + // Make label(s) unclickable + removeLabelClick(app, 'sc_deep_impact_impactor', goToSpacecraft); + removeLabelClick(app, '9p_tempel_1', goToCelestialObject); + + // Reset object callback + app.getManager('camera').setSelectionCallback(slide.selectionCallback); + } + }, + { + id: 'slide_5', + type: 'panel', + time: '2012-07-21T12:01:00Z', + rate: 35, + content: [ + { + type: 'description', + title: 'The Dawn mission', + description: "in orbit around Vesta" + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + const time = app.getManager('time'); + await app.getManager('scene').isListReady(['4_vesta', 'sc_dawn']); + if (localNonce !== globalNonce) return; + time.pause(); + await app.cameraScripts.goToSpacecraft('sc_dawn', { cinematic: true, duration: 3 }); + time.play(); + } + ], + onEnter: (app, slide) => { + const camera = app.getManager('camera'); + + // Make label(s) clickable + addLabelClick(app, 'sc_dawn', goToSpacecraft); + addLabelClick(app, '4_vesta', goToCelestialObject); + + // Make object(s) clickable + slide.selectionCallback = camera.getSelectionCallback(); + camera.setSelectionCallback(async entity => { + const entityName = entity?.getName(); + if (entityName === '4_vesta') { + await app.cameraScripts.goToCelestialObject(entityName); + } + else if (entityName === 'sc_dawn') { + await app.cameraScripts.goToSpacecraft(entityName); + } + }); + }, + onLeave: (app, slide) => { + // Make label(s) unclickable + removeLabelClick(app, 'sc_dawn', goToSpacecraft); + removeLabelClick(app, '4_vesta', goToCelestialObject); + + // Reset object callback + app.getManager('camera').setSelectionCallback(slide.selectionCallback); + } + }, + { + id: 'slide_6', + type: 'panel', + time: '2016-03-18T13:30:00Z', + rate: 40, + content: [ + { + type: 'description', + title: 'The Dawn mission', + description: 'in orbit around Ceres' + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + const time = app.getManager('time'); + await app.getManager('scene').isListReady(['1_ceres', 'sc_dawn']); + if (localNonce !== globalNonce) return; + time.pause(); + await app.cameraScripts.goToCelestialObject('1_ceres', { cinematic: false, duration: 3, distance: 2 }); + time.play(); + } + ], + onEnter: (app, slide) => { + const camera = app.getManager('camera'); + + // Make label(s) clickable + addLabelClick(app, 'sc_dawn', goToSpacecraft); + addLabelClick(app, '1_ceres', goToCelestialObject); + + // Make object(s) clickable + slide.selectionCallback = camera.getSelectionCallback(); + camera.setSelectionCallback(async entity => { + const entityName = entity?.getName(); + if (entityName === '1_ceres') { + await app.cameraScripts.goToCelestialObject(entityName); + } + else if (entityName === 'sc_dawn') { + await app.cameraScripts.goToSpacecraft(entityName); + } + }); + }, + onLeave: (app, slide) => { + // Make label(s) unclickable + removeLabelClick(app, 'sc_dawn', goToSpacecraft); + removeLabelClick(app, '1_ceres', goToCelestialObject); + + // Reset object callback + app.getManager('camera').setSelectionCallback(slide.selectionCallback); + } + }, + { + id: 'slide_7', + type: 'panel', + time: '2003-12-24T00:00:00Z', + rate: 90, + content: [ + { + type: 'description', + title: 'The Stardust mission', + description: 'flying by the comet Wild 2' + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + const time = app.getManager('time'); + await app.getManager('scene').isReady('sc_stardust'); + if (localNonce !== globalNonce) return; + time.pause(); + await app.cameraScripts.goToSpacecraft('sc_stardust', { distance: -0.01, cinematic: false, duration: 3 }); + time.play(); + } + ], + onEnter: (app, slide) => { + // Make label(s) clickable + addLabelClick(app, 'sc_stardust', goToSpacecraft); + addLabelClick(app, '81p_wild_2', goToCelestialObject); + }, + onLeave: (app, slide) => { + // Make label(s) unclickable + removeLabelClick(app, 'sc_stardust', goToSpacecraft); + removeLabelClick(app, '81p_wild_2', goToCelestialObject); + } + }, + { + id: 'slide_8', + type: 'panel', + time: '2020-10-20T21:50:24Z', + content: [ + { + type: 'description', + title: 'The OSIRIS-REx mission', + description: 'sampling the surface of the asteroid Bennu' + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + const time = app.getManager('time'); + await app.getManager('scene').isListReady(['101955_bennu', 'sc_osiris_rex']); + if (localNonce !== globalNonce) return; + time.pause(); + await app.cameraScripts.alignObjects('sc_osiris_rex', '101955_bennu', { + duration: 4, + distance: 0.1, + verticalOffset: 30, + horizontalOffset: -80 + }); + time.play(); + } + ], + onEnter: (app, slide) => { + app.getComponent('settings').toggleLightOptions('flood'); + + const camera = app.getManager('camera'); + + // Make label(s) clickable + addLabelClick(app, 'sc_osiris_rex', goToSpacecraft); + addLabelClick(app, '101955_bennu', goToCelestialObject); + + // Make object(s) clickable + slide.selectionCallback = camera.getSelectionCallback(); + camera.setSelectionCallback(async entity => { + if (isLabelClicked) { + return; + } + const entityName = entity?.getName(); + if (entityName === '101955_bennu') { + await app.cameraScripts.goToCelestialObject(entityName); + } + else if (entityName === 'sc_osiris_rex') { + await app.cameraScripts.goToSpacecraft(entityName); + } + }); + }, + onLeave: (app, slide) => { + app.getComponent('settings').toggleLightOptions('shadow'); + + // Make label(s) unclickable + removeLabelClick(app, 'sc_osiris_rex', goToSpacecraft); + removeLabelClick(app, '101955_bennu', goToCelestialObject); + + // Reset object callback + app.getManager('camera').setSelectionCallback(slide.selectionCallback); + } + }, + { + id: 'slide_9', + type: 'panel', + time: '2029-08-17T01:02:00Z', + content: [ + { + type: 'description', + title: 'The Psyche mission', + description: 'en route to metal asteroid 16 Psyche.' + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + const time = app.getManager('time'); + await app.getManager('scene').isListReady(['16_psyche', 'sc_psyche']); + if (localNonce !== globalNonce) return; + time.pause(); + await app.cameraScripts.goToSpacecraft('sc_psyche', { cinematic: true, duration: 3, distance: 0.05 }); + time.play(); + } + ], + onEnter: (app, slide) => { + app.getComponent('settings').toggleLightOptions('flood'); + + const camera = app.getManager('camera'); + + // Make label(s) clickable + addLabelClick(app, 'sc_psyche', goToSpacecraft); + addLabelClick(app, '16_psyche', goToCelestialObject); + + // Make object(s) clickable + slide.selectionCallback = camera.getSelectionCallback(); + camera.setSelectionCallback(async entity => { + const entityName = entity?.getName(); + if (entityName === '16_psyche') { + await app.cameraScripts.goToCelestialObject(entityName); + } + else if (entityName === 'sc_psyche') { + await app.cameraScripts.goToSpacecraft(entityName); + } + }); + }, + onLeave: (app, slide) => { + app.getComponent('settings').toggleLightOptions('shadow'); + + // Make label(s) unclickable + removeLabelClick(app, 'sc_psyche', goToSpacecraft); + removeLabelClick(app, '16_psyche', goToCelestialObject); + + // Reset object callback + app.getManager('camera').setSelectionCallback(slide.selectionCallback); + } + }, + { + id: 'slide_10', + type: 'panel', + time: '2022-09-26T23:14:11Z', + content: [ + { + type: 'description', + title: 'The DART mission', + description: 'impacting the asteroid moon Dimorphos' + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + const time = app.getManager('time'); + await app.getManager('scene').isListReady(['65803_didymos', 'dimorphos', 'sc_dart']); + if (localNonce !== globalNonce) return; + time.pause(); + await app.cameraScripts.goToSpacecraft('sc_dart', { + cinematic: false, + duration: 3, + verticalOffset: 15 + }); + time.play(); + } + ], + onEnter: (app, slide) => { + app.getManager('time').setMax('2022-09-26T23:14:18.054Z'); + + const camera = app.getManager('camera'); + + // Make label(s) clickable + addLabelClick(app, 'sc_dart', goToSpacecraft); + addLabelClick(app, 'dimorphos', goToCelestialObject); + addLabelClick(app, '65803_didymos', goToCelestialObject); + + // Make object(s) clickable + slide.selectionCallback = camera.getSelectionCallback(); + camera.setSelectionCallback(async entity => { + const entityName = entity?.getName(); + if (['dimorphos', '65803_didymos'].includes(entityName)) { + await app.cameraScripts.goToCelestialObject(entityName); + } + else if (entityName === 'sc_dart') { + await app.cameraScripts.goToSpacecraft(entityName); + } + }); + }, + onLeave: (app, slide) => { + app.getManager('time').resetMax(); + + // Make label(s) unclickable + removeLabelClick(app, 'sc_dart', goToSpacecraft); + removeLabelClick(app, 'dimorphos', goToCelestialObject); + removeLabelClick(app, '65803_didymos', goToCelestialObject); + + // Reset object callback + app.getManager('camera').setSelectionCallback(slide.selectionCallback); + } + }, + { + id: 'slide_11', + type: 'panel', + content: [ + { + type: 'description', + description: '' + } + ], + camera: [ + async app => { + const localNonce = ++globalNonce; + const time = app.getManager('time'); + await app.getManager('scene').isReady('earth'); + if (localNonce !== globalNonce) return; + time.pause(); + await app.cameraScripts.goToCelestialObject('earth', { cinematic: true, duration: 3 }); + time.play(); + } + ] + } + ], + onEnter: app => { + app.scene.get('sun', 'orbitalParticles').setEnabled(false); + app.getManager('layer').toggleLayer('starfield', { category: 'Star Field' }, true); + + window.addEventListener('mousedown', resetLabelClick); + window.addEventListener('touchstart', resetLabelClick); + }, + onLeave: app => { + app.scene.get('sun', 'orbitalParticles').setEnabled(true); + app.getManager('layer').toggleLayer('starfield', { category: 'Star Field' }, false); + + window.removeEventListener('mousedown', resetLabelClick); + window.removeEventListener('touchstart', resetLabelClick); + } +}); + + +/***/ }), + +/***/ "./src/data/stories/index.js": +/*!***********************************!*\ + !*** ./src/data/stories/index.js ***! + \***********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "STORY_LIST": function() { return /* reexport default export from named module */ _story_list_json__WEBPACK_IMPORTED_MODULE_3__; }, +/* harmony export */ "STORIES": function() { return /* binding */ STORIES; } +/* harmony export */ }); +/* harmony import */ var _asteroids_101__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./asteroids_101 */ "./src/data/stories/asteroids_101.js"); +/* harmony import */ var _asteroids_close_approach__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./asteroids_close_approach */ "./src/data/stories/asteroids_close_approach.js"); +/* harmony import */ var _asteroids_missions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./asteroids_missions */ "./src/data/stories/asteroids_missions.js"); +/* harmony import */ var _story_list_json__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./story_list.json */ "./src/data/stories/story_list.json"); + + + + + +const STORIES = { + asteroids_101: _asteroids_101__WEBPACK_IMPORTED_MODULE_0__["default"], + asteroids_close_approach: _asteroids_close_approach__WEBPACK_IMPORTED_MODULE_1__["default"], + asteroids_missions: _asteroids_missions__WEBPACK_IMPORTED_MODULE_2__["default"] +}; + + + + +/***/ }), + +/***/ "./src/internal.js": +/*!*************************!*\ + !*** ./src/internal.js ***! + \*************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FiltersManager": function() { return /* reexport safe */ _managers_filters_manager__WEBPACK_IMPORTED_MODULE_0__.FiltersManager; }, +/* harmony export */ "NEOsManager": function() { return /* reexport safe */ _managers_neos_manager__WEBPACK_IMPORTED_MODULE_1__.NEOsManager; }, +/* harmony export */ "WatchManager": function() { return /* reexport safe */ _managers_watch_manager__WEBPACK_IMPORTED_MODULE_2__.WatchManager; }, +/* harmony export */ "LinkManager": function() { return /* reexport safe */ _managers_link_manager__WEBPACK_IMPORTED_MODULE_3__.LinkManager; }, +/* harmony export */ "SelectionManager": function() { return /* reexport safe */ _managers_selection_manager__WEBPACK_IMPORTED_MODULE_4__.SelectionManager; }, +/* harmony export */ "LabelManager": function() { return /* reexport safe */ _managers_label_manager__WEBPACK_IMPORTED_MODULE_5__.LabelManager; }, +/* harmony export */ "TrailManager": function() { return /* reexport safe */ _managers_trail_manager__WEBPACK_IMPORTED_MODULE_6__.TrailManager; }, +/* harmony export */ "AsteroidMenuTop": function() { return /* reexport safe */ _components_asteroid_menu_top_asteroid_menu_top__WEBPACK_IMPORTED_MODULE_7__.AsteroidMenuTop; }, +/* harmony export */ "AsteroidMenuBottom": function() { return /* reexport safe */ _components_asteroid_menu_bottom_asteroid_menu_bottom__WEBPACK_IMPORTED_MODULE_8__.AsteroidMenuBottom; }, +/* harmony export */ "AsteroidModals": function() { return /* reexport safe */ _components_asteroid_modals_asteroid_modals__WEBPACK_IMPORTED_MODULE_9__.AsteroidModals; }, +/* harmony export */ "HomeButton": function() { return /* reexport safe */ _components_home_button_home_button__WEBPACK_IMPORTED_MODULE_10__.HomeButton; }, +/* harmony export */ "WatchPanel": function() { return /* reexport safe */ _components_watch_panel_watch_panel__WEBPACK_IMPORTED_MODULE_11__.WatchPanel; }, +/* harmony export */ "AsteroidPanel": function() { return /* reexport safe */ _components_asteroid_panel_asteroid_panel__WEBPACK_IMPORTED_MODULE_12__.AsteroidPanel; }, +/* harmony export */ "MissionPanel": function() { return /* reexport safe */ _components_mission_panel_mission_panel__WEBPACK_IMPORTED_MODULE_13__.MissionPanel; }, +/* harmony export */ "FollowingPanel": function() { return /* reexport safe */ _components_following_panel_following_panel__WEBPACK_IMPORTED_MODULE_14__.FollowingPanel; }, +/* harmony export */ "Countdown": function() { return /* reexport safe */ _components_countdown_countdown__WEBPACK_IMPORTED_MODULE_15__.Countdown; }, +/* harmony export */ "SplashScreen": function() { return /* reexport safe */ _components_splash_screen_splash_screen__WEBPACK_IMPORTED_MODULE_16__.SplashScreen; }, +/* harmony export */ "AsteroidsApp": function() { return /* reexport safe */ _app__WEBPACK_IMPORTED_MODULE_17__.AsteroidsApp; }, +/* harmony export */ "NEO": function() { return /* reexport safe */ _neos__WEBPACK_IMPORTED_MODULE_18__.NEO; }, +/* harmony export */ "NEOUtils": function() { return /* reexport safe */ _neos__WEBPACK_IMPORTED_MODULE_18__.NEOUtils; }, +/* harmony export */ "DefinitionOverlay": function() { return /* reexport safe */ _components_definition_overlay_definition_overlay__WEBPACK_IMPORTED_MODULE_19__.DefinitionOverlay; }, +/* harmony export */ "TimeSlider": function() { return /* reexport safe */ _components_time_slider_time_slider__WEBPACK_IMPORTED_MODULE_20__.TimeSlider; }, +/* harmony export */ "Breadcrumb": function() { return /* reexport safe */ _components_breadcrumb_breadcrumb__WEBPACK_IMPORTED_MODULE_21__.Breadcrumb; }, +/* harmony export */ "AsteroidsSettings": function() { return /* reexport safe */ _components_settings_asteroids_settings__WEBPACK_IMPORTED_MODULE_22__.AsteroidsSettings; }, +/* harmony export */ "Search": function() { return /* reexport safe */ _components_search_search__WEBPACK_IMPORTED_MODULE_23__.Search; }, +/* harmony export */ "Types": function() { return /* reexport safe */ _types__WEBPACK_IMPORTED_MODULE_24__.Types; } +/* harmony export */ }); +/* harmony import */ var _managers_filters_manager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./managers/filters_manager */ "./src/managers/filters_manager.js"); +/* harmony import */ var _managers_neos_manager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./managers/neos_manager */ "./src/managers/neos_manager.js"); +/* harmony import */ var _managers_watch_manager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./managers/watch_manager */ "./src/managers/watch_manager.js"); +/* harmony import */ var _managers_link_manager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./managers/link_manager */ "./src/managers/link_manager.js"); +/* harmony import */ var _managers_selection_manager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./managers/selection_manager */ "./src/managers/selection_manager.js"); +/* harmony import */ var _managers_label_manager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./managers/label_manager */ "./src/managers/label_manager.js"); +/* harmony import */ var _managers_trail_manager__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./managers/trail_manager */ "./src/managers/trail_manager.js"); +/* harmony import */ var _components_asteroid_menu_top_asteroid_menu_top__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/asteroid_menu_top/asteroid_menu_top */ "./src/components/asteroid_menu_top/asteroid_menu_top.js"); +/* harmony import */ var _components_asteroid_menu_bottom_asteroid_menu_bottom__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/asteroid_menu_bottom/asteroid_menu_bottom */ "./src/components/asteroid_menu_bottom/asteroid_menu_bottom.js"); +/* harmony import */ var _components_asteroid_modals_asteroid_modals__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/asteroid_modals/asteroid_modals */ "./src/components/asteroid_modals/asteroid_modals.js"); +/* harmony import */ var _components_home_button_home_button__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/home_button/home_button */ "./src/components/home_button/home_button.js"); +/* harmony import */ var _components_watch_panel_watch_panel__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./components/watch_panel/watch_panel */ "./src/components/watch_panel/watch_panel.js"); +/* harmony import */ var _components_asteroid_panel_asteroid_panel__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/asteroid_panel/asteroid_panel */ "./src/components/asteroid_panel/asteroid_panel.js"); +/* harmony import */ var _components_mission_panel_mission_panel__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./components/mission_panel/mission_panel */ "./src/components/mission_panel/mission_panel.js"); +/* harmony import */ var _components_following_panel_following_panel__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./components/following_panel/following_panel */ "./src/components/following_panel/following_panel.js"); +/* harmony import */ var _components_countdown_countdown__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./components/countdown/countdown */ "./src/components/countdown/countdown.js"); +/* harmony import */ var _components_splash_screen_splash_screen__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./components/splash_screen/splash_screen */ "./src/components/splash_screen/splash_screen.js"); +/* harmony import */ var _app__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./app */ "./src/app.js"); +/* harmony import */ var _neos__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./neos */ "./src/neos.js"); +/* harmony import */ var _components_definition_overlay_definition_overlay__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./components/definition_overlay/definition_overlay */ "./src/components/definition_overlay/definition_overlay.js"); +/* harmony import */ var _components_time_slider_time_slider__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./components/time_slider/time_slider */ "./src/components/time_slider/time_slider.js"); +/* harmony import */ var _components_breadcrumb_breadcrumb__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./components/breadcrumb/breadcrumb */ "./src/components/breadcrumb/breadcrumb.js"); +/* harmony import */ var _components_settings_asteroids_settings__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./components/settings/asteroids_settings */ "./src/components/settings/asteroids_settings.js"); +/* harmony import */ var _components_search_search__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./components/search/search */ "./src/components/search/search.js"); +/* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./types */ "./src/types.js"); +/* eslint-disable import/first */ + + + + + + + + + + + + + + + + + + + + + + + + + + + +// Types + + + +/***/ }), + +/***/ "./src/managers/filters_manager.js": +/*!*****************************************!*\ + !*** ./src/managers/filters_manager.js ***! + \*****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FiltersManager": function() { return /* binding */ FiltersManager; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/** + * An Asteroids manager for handling the application's filter state + * This is very basic. Logic from the filters_modal could be pulled in here + */ + + + + + +/** + * Filters Manager class. + */ +class FiltersManager extends eyes__WEBPACK_IMPORTED_MODULE_1__.BaseManager { + /** + * Constructs the filters manager. + * @param {BaseApp} app + * @param {Pioneer.Scene} scene + */ + constructor(app, scene) { + super(app, scene); + + this.state = { + isFiltering: false, + // filter keys are always {originalFilter} + s (ex. news -> newss) + filters: { + asteroids: false, + comets: false, + phos: false + }, + lastSize: null + }; + + // The previous filters state + this.previousFilters = { + asteroids: false, + comets: false, + phos: false + }; + + this._app = app; + + this._eventNames.push('isFilteringChange'); + this._eventNames.push('lastSizeChange'); + this._initCallbacks(); + + this.bindFunctions([ + 'getFilters', + 'getLastSize', + '_matchFunction' + ]); + } + + /** + * Sets the application's filtering state + * @param {boolean} isFiltering + */ + _setFiltering(isFiltering) { + if (this.state.isFiltering !== isFiltering) { + this.state.isFiltering = isFiltering; + this.triggerCallbacks('isFilteringChange', [this.state.isFiltering]); + } + } + + /** + * Sets the final size of the filtered results + * @param {number} lastSize - the final size of the filtered results + */ + _setLastSize(lastSize) { + if (this.state.lastSize !== lastSize) { + this.state.lastSize = lastSize; + this.triggerCallbacks('lastSizeChange', [this.state.lastSize]); + } + } + + /** + * Whether the application is in a filtered state or not + * @returns {boolean} filter state + */ + get isFiltering() { + return this.state.isFiltering; + } + + /** + * The filters state + * @returns {object} filters state + */ + getFilters() { + return this.state.filters; + } + + /** + * The previous filters state + * @returns {object} filters state + */ + getPreviousFilters() { + return this.previousFilters; + } + + /** + * Gets the size of filtered results + * @returns {number} - number of filtered results + */ + getLastSize() { + return this.state.lastSize; + } + + /** + * Sets a filter + * @param {string | object} filter - One of 'asteroids' | 'comets' | 'phos' or filtersState object + * @param {boolean} on - on or not + * @param {Function} callback + */ + setFilter(filter, on, callback) { + this.previousFilters = this.state.filters; + // Only trigger filter on state change, to prevent unncessary executions and flash off/on + if (typeof filter === 'string') { + if (this.state.filters[filter] != null && this.state.filters[filter] !== on) { + this.state.filters[filter] = on; + this._filter(callback); + } + } + else { + for (const key in filter) { + if (this.state.filters[key] !== filter[key]) { + this.state.filters = { ...this.state.filters, ...filter }; + this._filter(callback); + break; + } + } + } + } + + /** + * Minimally changes the current filter state to reveal an object based on the object's filter state + * @param {object} reveal - Can be neo object itself or just: { asteroid: false, comet: true, pho: false } + * @param {boolean} resetAll - If true and reveal is presently hidden, resets all filters to show everything instead of just being selective about it + * @param {Function} callback - callback for after filter completes + * @returns {boolean} Whether or not the filter state had to change to accommodate the reveal + */ + setFilterToReveal(reveal, resetAll, callback) { + let refilterNeeded = false; + // Turn off showing only phos if reveal is not a pho + if (reveal.pho !== true && this.state.filters.phos === true) { + this.state.filters.phos = false; + refilterNeeded = true; + } + + // Only check these if at least one of them is true + // (because both false means everything is shown) + if (!(this.state.filters.asteroids === false && this.state.filters.comets === false)) { + // So now we can only worry about checking them on if needed + if (reveal.asteroid === true && this.state.filters.asteroids === false) { + this.state.filters.asteroids = true; + refilterNeeded = true; + }; + if (reveal.comet === true && this.state.filters.comets === false) { + this.state.filters.comets = true; + refilterNeeded = true; + }; + } + + if (refilterNeeded) { + if (resetAll === true) { + this.state.filters = { asteroids: false, comets: false, phos: false }; + }; + this._filter(callback); + }; + return refilterNeeded; + } + + /** + * Toggles a layer + * @param {string} key - layer key + * @param {boolean} on - can be unset for a true toggle, otherwise forces + */ + _toggleLayer(key, on) { + const layerManager = this._app.getManager('layer'); + const categories = { + ui: 'User Interface', + planets: 'Planet', + asteroids: 'Asteroid', + comets: 'Comet', + dwarfPlanets: 'Dwarf Planet', + spacecraft: 'Spacecraft', + trails: 'Trail', + labels: 'Label' + }; + if ( + on == null + || (on === true && layerManager._layers[key]?.visible === false) + || (on === false && layerManager._layers[key]?.visible === true)) { + layerManager.toggleLayer(key, { category: categories[key] }); + } + } + + /** + * Determines whether or not the NEO fits in the filter + * @param {NEO} neo + * @returns {boolean} + */ + _matchFunction(neo) { + if (this.app.getManager('selection')?._id === neo.pioneerName) { + return true; + } + if (this.state.filters.asteroids && !this.state.filters.comets && neo.comet === true) { + return false; + }; + if (this.state.filters.comets && !this.state.filters.asteroids && neo.comet === false) { + return false; + }; + if (this.state.filters.phos && neo.pho === false) { + return false; + }; + return true; + } + + /** + * Narrow orbital particles, layers and entities based on the user's filters + * @param {Function} callback + */ + _filter(callback) { + const filtersAreActive = (this.state.filters.asteroids || this.state.filters.comets || this.state.filters.phos); + // Filter particles + this._app.addParticleMatchFunction(this._matchFunction, 'filters_manager', true, (orbitalElements) => { + this._setLastSize((filtersAreActive ? orbitalElements.length : this.app.neos.size) || 0); + this._setFiltering(filtersAreActive); + if (typeof callback === 'function') callback(this.state.lastSize); + }); + + // Filter layers + // If both are off, both are on + if (!this.state.filters.asteroids && !this.state.filters.comets) { + this._toggleLayer('asteroids', true); + this._toggleLayer('comets', true); + } + else { + this._toggleLayer('asteroids', this.state.filters.asteroids); + this._toggleLayer('comets', this.state.filters.comets); + } + + // Filter on a per entity level for PHOs + const { neos } = this._app; + const { _itemsByName: sceneEntities } = this.app.scene?._entities || {}; + const sceneEntityNames = sceneEntities ? Array.from(sceneEntities.keys()) : []; + + const foundNeos = []; + + for (const neoName of neos.keys()) { + if (sceneEntityNames.includes(neoName)) { + foundNeos.push(neoName); + sceneEntities.get(neoName).setEnabled(this._matchFunction(neos.get(neoName))); + } + } + + // Now, for all the entities without matching neos + const allEntities = this._app.getManager('content')?.getEntityList(); + + for (const sceneEntityName of sceneEntityNames) { + // Find the entities that are asteroids, comets or dwarf planets + if (!foundNeos.includes(sceneEntityName) && allEntities[sceneEntityName] && ['Asteroid', 'Comet', 'Dwarf Planet'].includes(allEntities[sceneEntityName].category)) { + // Apply the match function to them at a asteroid/comet basis + // Note: This treats Dwarf planets as asteroids (Ceres, then, is an asteroid here) + sceneEntities.get(sceneEntityName)?.setEnabled(this._matchFunction({ + comet: allEntities[sceneEntityName].category === 'Comet', + pho: false + })); + } + } + } +} + + +/***/ }), + +/***/ "./src/managers/label_manager.js": +/*!***************************************!*\ + !*** ./src/managers/label_manager.js ***! + \***************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LabelManager": function() { return /* binding */ LabelManager; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + +/** + * @inheritdoc + * @extends EyesSelectionManager + */ +class LabelManager extends eyes__WEBPACK_IMPORTED_MODULE_0__.LabelManager { + /** + * @inheritdoc + * @override + */ + _getLink(entityName) { + const link = super._getLink(entityName); + return this._app.getManager('link')?.getParsedLink?.(link) || link; + } +} + + +/***/ }), + +/***/ "./src/managers/link_manager.js": +/*!**************************************!*\ + !*** ./src/managers/link_manager.js ***! + \**************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LinkManager": function() { return /* binding */ LinkManager; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + +/** + * Extends the main Eyes RouteManager + */ +class LinkManager extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseManager { + /** + * Asteroids-specific parsed link method + * @param {string} link + * @returns {string} + */ + getParsedLink(link) { + const entityName = link.startsWith('/') ? link.slice(1) : link; + + const info = this._app?.getManager('content')?.getEntityInfo(entityName); + if (info) { + if (info.id === 'sun') { + return `/stars/${entityName}`; + } + + if (info.id === 'moon') { + return `/moons/${entityName}`; + } + + if (info.category === 'Spacecraft') { + return `/missions/${entityName}`; + } + + if (info.category === 'Planet') { + return `/planets/${entityName}`; + } + } + + return `/${entityName}`; + } +} + + +/***/ }), + +/***/ "./src/managers/neos_manager.js": +/*!**************************************!*\ + !*** ./src/managers/neos_manager.js ***! + \**************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "NEOsManager": function() { return /* binding */ NEOsManager; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../internal */ "./src/internal.js"); +/** + * An Asteroids manager for handling the application's NEOs. + * This is very basic. Logic from the filters_modal could be pulled in here + */ + + + + + +/** + * Filters Manager class. + */ +class NEOsManager extends eyes__WEBPACK_IMPORTED_MODULE_1__.BaseManager { + /** + * Creates a temporary NEO entity. + * @param {object} data - NEO data + * @param {Pioneer.Scene} scene + * @param {boolean} addLabel + * @returns {Pioneer.Entity} + */ + createTempNEO(data, scene = this._app.scene, addLabel = true) { + const entity = _internal__WEBPACK_IMPORTED_MODULE_2__.NEOUtils.createEntity(data, scene); + this._app.getManager('label').addEntity(entity); + this._app.getManager('scene').addTempEntity(entity); + + if (addLabel) { + // Set the label properties + const contentManager = this._app.getManager('content'); + const labelManager = this._app.getManager('label'); + + const { dwarfPlanet, asteroid, comet } = data; + + const iconClass = asteroid || dwarfPlanet + ? 'asteroid' + : (comet ? 'comet' : ''); + + labelManager.setLabelProps({ + getLabelClass: entityName => `no-select asteroid ${contentManager.getClassName(entityName) ?? ''}`, + getIconClass: () => iconClass + }, [entity.getName()]); + } + + return entity; + } +} + + +/***/ }), + +/***/ "./src/managers/selection_manager.js": +/*!*******************************************!*\ + !*** ./src/managers/selection_manager.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SelectionManager": function() { return /* binding */ SelectionManager; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + +/** + * @inheritdoc + * @extends EyesSelectionManager + */ +class SelectionManager extends eyes__WEBPACK_IMPORTED_MODULE_0__.SelectionManager { + /** + * @inheritdoc + * @override + */ + _getLink(entityName) { + const link = super._getLink(entityName); + return this._app.getManager('link')?.getParsedLink?.(link) || link; + } +} + + +/***/ }), + +/***/ "./src/managers/trail_manager.js": +/*!***************************************!*\ + !*** ./src/managers/trail_manager.js ***! + \***************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TrailManager": function() { return /* binding */ TrailManager; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); + + +/** + * @inheritdoc + * @extends EyesTrailManager + */ +class TrailManager extends eyes__WEBPACK_IMPORTED_MODULE_0__.TrailManager { + /** + * @inheritdoc + * @override + * Trials and orbit lines are treated as the same in Asteroids. + */ + toggleTrails(active) { + super.toggleTrails(active, { scene: this._scene }); + this.toggleOrbits(active); + } +} + + +/***/ }), + +/***/ "./src/managers/watch_manager.js": +/*!***************************************!*\ + !*** ./src/managers/watch_manager.js ***! + \***************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "WatchManager": function() { return /* binding */ WatchManager; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** + * An Asteroids manager for handling the asteroid watch state. + * For Asteroid Watch, although the URL is the primary state source, a manager makes sense because + * we require both UI and Pioneer changes + */ + + + + + +/** + * WatchManager + */ +class WatchManager extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseManager { + /** + * Constructs the filters manager. + * @param {BaseApp} app + */ + constructor(app) { + super(app); + + /** + * have we redirected? + * @property {boolean} + */ + this._hasRedirected = null; + + /** + * Ephermeris time (ET) + * @property {number} + */ + this._currentTime = pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now(); + + /** + * Calculated next five approaches + * @property {Array} + */ + this._nextFiveData = null; + + /** + * Next five entitoes + * @property {Array} + */ + this._nextFiveEntities = null; + + /** + * Next five names only + * @property {Array} + */ + this._nextFiveNames = null; + + /** + * Object to apply Watch and focus label weighting. + * @property {Array} + */ + this._labelWeights = null; + + /** + * Focus entity names + * @property {Array} + */ + this._focusEntityNames = null; + + /** + * The background planets. + * @property {Array} + */ + this._backgroundPlanets = ['mercury', 'venus', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']; + + /** + * The default width of the unhovered planet trail. + * (as seen in asteroids.js - this should probably be in a config) + * @property {number} + */ + this._defaultPlanetTrailWidth = 4; + + /** + * _slideIndex - which of the next five is selected (null means the panel is collapsed) + * @property {number} + */ + this._slideIndex = null; + + /** + * store Earths dynamo coverage + * @property {Interval} + */ + this._dynamoCoverage = null; + + /** + * _unitType - current unit of measurement + */ + this._unitType = 'metric'; + + this._eventNames.push('toggleUnit'); + this._initCallbacks(); + + this.bindFunctions(['setData', '_calculateNextNEOs', '_createEntities', '_calculateTimeLimits', 'getNeoNameByIndex', 'updateURL', 'toggleUnit']); + } + + /** + * Use neo data to calculate _nextFiveData + */ + setData() { + if (this._nextFiveData) { + return; + }; + + // Filter the next five. + const allNEOs = this._app.neos; + + if (!allNEOs) { + throw Error('Cannot get NEO data.'); + } + + this._nextFiveData = this._calculateNextNEOs(allNEOs); + + this._setLabelWeights(); + } + + /** + * Set the label weights. + * @param {string} focusName + */ + _setLabelWeights(focusName) { + this._labelWeights = Object.fromEntries( + this._nextFiveData.map(({ pioneerName }) => [pioneerName, { + category: pioneerName === focusName ? 'Focus' : 'Watch' + }]) + ); + + this._app.getManager('label')?.setWeights(this._labelWeights, false); + } + + /** + * Determines the index of an asteroid with a given name + * @param {string} neoName + * @returns {number|null} + */ + determineSlideIndex(neoName) { + return neoName ? this._nextFiveData.findIndex(neo => neo.pioneerName === neoName) : null; + } + + /** + * Set the slide index + * @param {number|null} index + */ + setSlideIndex(index) { + this._slideIndex = index; + } + + /** + * Adds correct selection classes to the labels so they're highlighted correctly. + * Also triggers the trail hover + */ + setAsteroidSelection() { + const labelManager = this._app.getManager('label'); + const asteroidName = this._nextFiveData[this._slideIndex]?.pioneerName ?? false; + + // Set focused label weights + this._setLabelWeights(asteroidName); + + // First remove all selections. + labelManager.removeClassFromLabels('selected', this._nextFiveNames); + + // Select the selected. + const selected = this._nextFiveNames.find(name => name === asteroidName); + selected && labelManager.addClassToLabels('selected', [selected]); + + // Set all trails to unhighlight except asteroidName + for (const name of this._nextFiveNames) { + labelManager.triggerCallbacks('hoverchange', [name, name === asteroidName]); + } + } + + /** + * Calculates the next of NEOs to pass earth according to their close approach time + * @param {Array} allNEOs + * @param {number} amount + * @returns {Array} + */ + _calculateNextNEOs(allNEOs, amount = 5) { + const maxDistance = 7479893.535; // 0.05 AUs in km + const nextFive = []; + const nearestDiffs = []; + + // eslint-disable-next-line no-unused-vars + for (const [_, value] of allNEOs.entries()) { + // Make sure its in the future + const inTheFuture = value.nextClosestApproachTime > this._currentTime; + // Make sure it's closer than the maxDistance + const withinDistance = value.nextClosestApproachDistance < maxDistance; + + if (withinDistance && inTheFuture) { + const diff = value.nextClosestApproachTime - this._currentTime; + // Push to nextFive array if it's not yet filled. + if (nearestDiffs.length < amount) { + nearestDiffs.push(diff); + nextFive.push(value); + } + else { + // Check if the diff is smaller than the largest diff in the array. If so, replace it. + const largestDiff = Math.max(...nearestDiffs); + if (diff < largestDiff) { + const replaceIndex = nearestDiffs.indexOf(largestDiff); + nearestDiffs[replaceIndex] = diff; + nextFive[replaceIndex] = value; + } + } + } + } + + return nextFive.sort((a, b) => (a.nextClosestApproachTime >= b.nextClosestApproachTime) ? 1 : -1); + } + + /** + * Creates the next five entities + * @returns {Promise} + */ + _createEntities() { + if (this._nextFiveEntities) { + return Promise.resolve(); + } + + const sceneManager = this._app.getManager('scene'); + const neosManager = this._app.getManager('neos'); + const labelManager = this._app.getManager('label'); + const contentManager = this._app.getManager('content'); + const trailManager = this._app.getManager('trail'); + + // Create the next five entities. + this._nextFiveEntities = this._nextFiveData.map(neo => neosManager.createTempNEO(neo, sceneManager.main, false)); + + // Store the name vars. + this._nextFiveNames = this._nextFiveData.map(neo => neo.pioneerName); + this._focusEntityNames = ['earth', 'moon', ...this._nextFiveNames]; + + const handleMouseLeave = (e, entityName) => { + // Determine if were hovering on a selected asteroids watch asteroid. + if (e.target?.classList?.contains('selected') && e.target?.classList?.contains('asteroid-watch-label')) { + return; + } + labelManager.triggerCallbacks('hoverchange', [entityName, false]); + }; + + // Set the label properties + labelManager.setLabelProps({ + getLabelClass: entityName => `no-select asteroid-watch-label ${contentManager.getClassName(entityName) ?? ''}`, + getIconClass: () => 'asteroid-watch-icon', + getTextClass: () => 'asteroid-watch-text', + handleClick: (_, entityName) => { + this.updateURL(entityName); + }, + handleTouch: (_, entityName) => { + if (!this.app.isDragging() && !this.app.isTouchMax()) { + this.updateURL(entityName); + } + }, + handleMouseLeave + }, this._nextFiveNames); + + // Set the trail colors. + const trailColorArray = this._app._colors?.neos; + trailColorArray && trailManager.setColor(this._nextFiveNames, new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(...trailColorArray, 0.35)); + + // Expect all entity loaded promises to eventually be resolved. + return Promise.all(this._nextFiveEntities.map(neoEntity => neoEntity.getLoadedPromise())); + } + + /** + * Determines the max and min time limits depending on the close approach times of the next five + * @returns {Interval} + */ + _calculateTimeLimits() { + // Padding is 99 days (in seconds) - to stop the day countdown getting to 3 figures. + const padding = 86400 * 99; + + const timeManager = this.app.getManager('time'); + const now = timeManager.getNow(); + const todayEtTime = timeManager.momentToET(now); + const { nextClosestApproachTime: lastApproachTime } = this._nextFiveData[this._nextFiveData.length - 1]; + + // Get the largest remaining time in ET seconds. + const largestRemainingTime = lastApproachTime - todayEtTime; + const maxPadding = padding - largestRemainingTime; + + const minET = lastApproachTime - maxPadding; + const maxET = lastApproachTime + maxPadding; + + return new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(minET, maxET); + } + + /** + * Restrict the earth controller coverage to time limits. + */ + restrictEarthCoverage() { + const earthController = this._app.scene.getEntity('earth')?.getControllerByType('dynamo'); + + if (!earthController) { + console.warn('Could not find Earth dynamo.'); + return; + } + + // Store previous coverage. + this._dynamoCoverage = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(); + this._dynamoCoverage.copy(earthController.getCoverage()); + + // Set to time restriction. + earthController.setCoverage(this._calculateTimeLimits()); + } + + /** + * Reset earth coverage to defaults. + */ + restoreEarthCoverage() { + const earthController = this._app.scene.getEntity('earth')?.getControllerByType('dynamo'); + + if (!earthController) { + console.warn('Could not find Earth dynamo.'); + return; + } + + earthController.setCoverage(this._dynamoCoverage); + } + + /** + * Dim the background labels by adding class + * @param {boolean} value + */ + dimBackgroundLabels(value) { + const labelManager = this._app.getManager('label'); + const dimClass = 'watch-dim'; + + const backgroundLabels = Object.keys(labelManager._labels).filter(labelName => !this._focusEntityNames?.includes(labelName)); + + if (value) { + labelManager.addClassToLabels(dimClass, backgroundLabels); + } + else { + labelManager.removeClassFromLabels(dimClass, backgroundLabels); + } + } + + /** + * set the default trail width for background planets + * @param {number} value + */ + setBgTrailWidthDefault(value = this._defaultPlanetTrailWidth) { + for (const planetId of this._backgroundPlanets) { + const entity = this.app.scene.get(planetId); + + if (entity?.trailHover?.width?.default) { + entity.trailHover.width.default = [value, value]; + } + } + + if (value === this._defaultPlanetTrailWidth) { + // We're reseting to default. + // Todo: put in some sort of onleave smoother camera transition function? + const trailManager = this._app.getManager('trail'); + trailManager.setMultipleWidths(this._backgroundPlanets, value, value); + } + } + + /** + * Get the neo name by index number + * @param {number} index + * @returns {string} + */ + getNeoNameByIndex(index) { + return this._nextFiveData?.[index]?.pioneerName; + } + + /** + * Navigates to correct URL + * @param {string} neoName + * @param {boolean} removeQuery + */ + updateURL(neoName, removeQuery = false) { + const routeManager = this._app.getManager('router'); + const options = { ...removeQuery && { __remove: 'all', keepTime: false } }; + + routeManager.navigate({}, `/watch/${neoName}`, options); + } + + /** + * Handle the menu item click. + * Determine which URL to go to depending on whether we've already set the data + */ + onWatchClick() { + // Do not update if we are currently transitioning + const transitioning = this._app.getManager('camera')?._isTransitioning; + + if (transitioning) { + return; + } + + // If we're already in the watch view, we can go live back to the main /watch overview + const inWatchView = this._app.getManager('router').currentView === 'watch'; + + if (this._nextFiveData && !inWatchView) { + const index = this.slideIndex === null ? 0 : this.slideIndex; + const removeQuery = true; + this.setSlideUrlByIndex(index, removeQuery); + } + else { + this._app.getManager('router').navigate({}, 'watch', { __remove: 'all', keepTime: false }); + } + } + + /** + * Goes to the slide at index zero + * @param {number} index + * @param {boolean} removeQuery + * @returns {string} + */ + setSlideUrlByIndex(index, removeQuery = false) { + // Get the neoName from index zero + const neoName = this.getNeoNameByIndex(index); + // Update URL with passed replaceState bool + this.updateURL(neoName, removeQuery); + + return neoName; + } + + /** + * Set references to null (except data ones) and remove label weights. + */ + removeReferences() { + this._app.getManager('label')?.removeWeights(this._labelWeights); + this._labelWeights = null; + + this.setSlideIndex(null); + this._nextFiveEntities = null; + } + + /** + * Getters and setters + */ + + /** + * Set boolean value for hasRedirected + * @param {boolean} value + */ + setHasRedirected(value) { + this._hasRedirected = value; + } + + /** + * gets bool value for hasRedirected + * @returns {boolean} + */ + get hasRedirected() { + return this._hasRedirected; + } + + /** + * Returns the default planet trail width. + * @returns {number} + */ + get defaultPlanetTrailWidth() { + return this._defaultPlanetTrailWidth; + } + + /** + * Get background planets + * @returns {Array} + */ + get backgroundPlanets() { + return this._backgroundPlanets; + } + + /** + * Get the current slide. + * @returns {number|null} + */ + get slideIndex() { + return this._slideIndex; + } + + /** + * return the next five data property + * @returns {Array} + */ + get nextFiveData() { + return this._nextFiveData; + } + + /** + * return the next five entities property + * @returns {Array} + */ + get nextFiveEntities() { + return this._nextFiveEntities; + } + + /** + * Triggers all watchers to switch their units + * @param {string} unitType + */ + toggleUnit(unitType) { + unitType = unitType || this._unitType === 'metric' ? 'imperial' : 'metric'; + if (['metric', 'imperial'].includes(unitType)) { + if (this._unitType !== unitType) { + this._unitType = unitType; + this.triggerCallbacks('toggleUnit', [unitType]); + } + } + } + + /** + * Get the current unitType. + * @returns {number|null} + */ + get unitType() { + return this._unitType; + } +} + + +/***/ }), + +/***/ "./src/neos.js": +/*!*********************!*\ + !*** ./src/neos.js ***! + \*********************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "NEO": function() { return /* binding */ NEO; }, +/* harmony export */ "NEOUtils": function() { return /* binding */ NEOUtils; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); + + + +/** Information on an NEO. */ +class NEO { + /** The constructor. */ + constructor() { + /** + * The full name. + * @type {string} + */ + this.name = ''; + + /** + * The name within Pioneer. + * @type {string} + */ + this.pioneerName = ''; + + /** + * 3 character orbit class 'ATI', 'ATE', 'AMO', 'APO'. + * @type {string} + */ + this.orbitClass = ''; + + /** + * Whether or not it is an asteroid. + * @type {boolean} + */ + this.asteroid = false; + + /** + * Whether or not it is a comet. + * @type {boolean} + */ + this.comet = false; + + /** + * Whether or not it is a dwarf planet. + * @type {boolean} + */ + this.dwarfPlanet = false; + + /** + * Whether or not it is an NEO. + * @type {boolean} + */ + this.neo = false; + + /** + * Whether or not it is a PHO. + * @type {boolean} + */ + this.pho = false; + + /** + * Whether or not it has multiple orbital elements and has dynamo associated with it. + * @type {boolean} + */ + this.hasSPK = false; + + /** + * The absolute magnitude. + * @type {number} + */ + this.absoluteMagnitude = 0; + + /** + * The diameter. + * @type {number} + */ + this.diameter = 0; + + /** + * Whether or not the diameter has been estimated, since the data may not be available. + * @type {boolean} + */ + this.diameterEstimated = false; + + /** + * The MOID relative to earth. + * @type {number} + */ + this.moid = 0; + + /** + * The spin rate in rad/sec. + * @type {number} + */ + this.spinRate = 0; + + /** + * Whether or not the spin rate has been estimated, since the data may not be available. + * @type {boolean} + */ + this.spinRateEstimated = false; + + /** + * The spin axis in the J2000 frame. + * @type {Pioneer.Vector3} + */ + this.spinAxis = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + /** + * Whether or not the spin axis has been estimated, since the data may not be available. + * @type {boolean} + */ + this.spinAxisEstimated = false; + + /** + * The next closest approach time in ephemeris time. + * @type {number} + */ + this.nextClosestApproachTime = 0; + + /** + * The next cosest approach distance in km. + * @type {number} + */ + this.nextClosestApproachDistance = 0; + + /** + * The orbital elements. + * @type {Pioneer.OrbitalElements} + */ + this.orbitalElements = new pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements(); + } +} + +/** A class that helps with working with NEOs. */ +class NEOUtils { + /** + * Loads the NEOs. Returns a promise that resolves with a mapping from an NEO Pioneer name to information about that NEO. + * @param {Pioneer.Engine} pioneer + * @returns {Promise>} + */ + static async loadNEOs(pioneer) { + /** @type {Map} */ + const neos = new Map(); + + // There are 10 files, so load all of them in parallel. + const loadPromises = []; + const urls = []; + for (let n = 0; n < 10; n++) { + urls.push(`neos.${n}.v1.dat`); + } + urls.push('dwarf_planets.v1.dat'); + urls.push('custom.v1.dat'); + for (const url of urls) { + loadPromises.push(pioneer.getDownloader().download(`$DYNAMIC_ASSETS_URL/ssd/${url}`, true).then(async (download) => { + if (download.status === 'cancelled') { + return Promise.resolve(); + } + else if (download.status === 'failed') { + return Promise.reject(new Error('Failed to load asteroid file "' + download.url + '": ' + download.errorMessage)); + } + if (!(download.content instanceof ArrayBuffer)) { + return Promise.reject(new Error('Failed to load asteroid file "' + download.url + '": Not a binary file.')); + } + const reader = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content); + const version = reader.readUInt16(); + if (version !== 1) { + throw new Error('Invalid version.'); + } + + // For each NEO in the file, read the data, populating the neo variable. + const numNEOs = reader.readUInt32(); + for (let i = 0; i < numNEOs; i++) { + // The neo object to populate. + const neo = new NEO(); + + // Read the name and class info. + neo.name = reader.readString(); + neo.orbitClass = reader.readString(3); + const flags = reader.readUInt8(); + neo.asteroid = ((flags & 0xc0) >> 6) === 0; + neo.comet = ((flags & 0xc0) >> 6) === 1; + neo.dwarfPlanet = ((flags & 0xc0) >> 6) === 2; + neo.neo = ((flags & 0x20) >> 5) === 1; + neo.pho = ((flags & 0x10) >> 4) === 1; + neo.hasSPK = ((flags & 0x08) >> 3) === 1; + neo.diameterEstimated = ((flags & 0x01) >> 0) === 1; + + // Read the absolute magnitude and diameter. + neo.absoluteMagnitude = reader.readFloat32(); + neo.diameter = reader.readFloat32(); + if (Number.isNaN(neo.diameter)) { + neo.diameter = 0.652999997138977; // The median asteroid size. + } + + // If an NEO, read the moid and next closest approach info. + if (neo.neo) { + neo.moid = reader.readFloat32(); + neo.nextClosestApproachTime = reader.readFloat32(); + neo.nextClosestApproachDistance = reader.readFloat32(); + } + + // Read the orbital elements. + neo.orbitalElements.epoch = reader.readFloat32(); + neo.orbitalElements.eccentricity = reader.readFloat32(); + neo.orbitalElements.semiMajorAxis = reader.readFloat32(); + neo.orbitalElements.meanAngularMotion = reader.readFloat32(); + neo.orbitalElements.meanAnomalyAtEpoch = reader.readFloat32(); + neo.orbitalElements.orbitOrientation.set(reader.readFloat32(), reader.readFloat32(), reader.readFloat32(), reader.readFloat32()); + + // Read the spin info. + const hasSpinRate = (flags & 0x04) >> 2; + const hasSpinAxis = (flags & 0x02) >> 1; + if (hasSpinRate) { + neo.spinRate = reader.readFloat32(); + neo.spinRateEstimated = false; + } + else { + neo.spinRate = 0.0075092; // Average spin rate of all NEOs as of 2021-06-24 + neo.spinRateEstimated = true; + } + if (hasSpinAxis) { + neo.spinAxis.set(reader.readFloat32(), reader.readFloat32(), reader.readFloat32()); + neo.spinAxisEstimated = false; + } + else { + neo.spinAxis.set(0, 0, 1); // Just setting it to the 'north' pole. + neo.spinAxisEstimated = true; + } + + // Get the pioneer entity name from the full name. + neo.pioneerName = neo.name.replace(/[- /]/g, '_'); + neo.pioneerName = neo.pioneerName.replace(/[^a-zA-Z0-9_]/g, ''); + neo.pioneerName = neo.pioneerName.toLowerCase(); + + // Add the neo to the neos list. + neos.set(neo.pioneerName, neo); + } + })); + } + + // Wait till all of the downloads are complete. + await Promise.all(loadPromises); + + // Add Dimorphos manually. + neos.set('dimorphos', { + ...neos.get('65803_didymos'), + name: 'Dimorphos', + pioneerName: 'dimorphos', + diameter: 0.170 + }); + + // Return the populated NEOs object. + return neos; + } + + /** + * Gets the Pioneer names of the next n closest approaches within 0.05 AU. + * @param {Map} neos + * @param {number} n + * @returns {string[]} + */ + static getNextClosestApproaches(neos, n) { + // The array we'll use to keep track of the next n closest approaches. + const nextClosestApproachNEOs = /** @type {NEO[]} */([]); + + // Go through each neo. + const now = pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.now(); + for (const entry of neos) { + const neo = entry[1]; + + // If the next closest approach is less than the last in the list, insert it into the list at the right spot (sorted), + // popping off the last one if we have too many. + if (neo.nextClosestApproachDistance < 7479893.535 // 0.05 AU + && (nextClosestApproachNEOs.length === 0 || neo.nextClosestApproachTime < nextClosestApproachNEOs.at(-1).nextClosestApproachTime) + && neo.nextClosestApproachTime >= now) { + const indexToInsert = pioneer__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(neo.nextClosestApproachTime, nextClosestApproachNEOs, (neo, time) => neo.nextClosestApproachTime < time); + nextClosestApproachNEOs.splice(indexToInsert, 0, neo); + if (nextClosestApproachNEOs.length > n) { + nextClosestApproachNEOs.pop(); + } + } + } + + // Return just the Pioneer names. + return nextClosestApproachNEOs.map(neo => neo.pioneerName); + } + + /** + * Creates an NEO entity. + * @param {NEO} neo + * @param {Pioneer.Scene} scene + * @returns {Pioneer.Entity} + */ + static createEntity(neo, scene) { + let entity = /** @type {Pioneer.Entity} */(null); + + // If Pioneer already has the entity, just use it. + if (pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.getEntityOptions(neo.pioneerName) !== undefined) { + entity = pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.create(neo.pioneerName, scene); + } + else { // Pioneer doesn't have the entity, so create a custom one. + // Create the entity options. + /** @type {import('../../pioneer/scripts/types/entity').Options } */ + const options = { + radius: neo.diameter / 2, + label: neo.name, + parents: [[Number.NEGATIVE_INFINITY, 'sun']], + trail: { + length: 31536000 / 2 + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/' + asteroidUrls[Math.floor(Math.random() * 3)], + scale: [neo.diameter / 2, neo.diameter / 2, neo.diameter / 2] + }, + controllers: [{ + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity + }, { + type: 'spin', + axis: neo.spinAxis, + periodInHours: Math.PI / neo.spinRate / 3600, + relativeToTime: 0 + }, { + type: 'custom', + func: (entity) => { + // Create Orbital elements controller + const controller = /** @type {Pioneer.OrbitalElementsController} */(entity.addController('orbitalElements')); + controller.addOrbitalElements(-3155716758.816, neo.orbitalElements); + if (neo.nextClosestApproachDistance !== 0 || isNaN(neo.nextClosestApproachTime)) { + controller.addOrbitalElements(3155716758.816, neo.orbitalElements); + } + else { + controller.addOrbitalElements(neo.nextClosestApproachTime, neo.orbitalElements); + } + return controller; + } + }] + }; + + // Add the earth dynamo if it's available. + if (neo.hasSPK) { + options.controllers.push({ + type: 'dynamo', + url: `ssd/${neo.pioneerName}/earth/orb/` + }); + } + + // Create the entity. + entity = pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.createFromOptions(neo.pioneerName, options, scene); + + // If the earth dynamo was loaded, we need to wait until it is loaded, + // then use its coverage to fix the parenting entries and orbital elements coverage, in case of impact. + if (neo.hasSPK) { + const dynamoController = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.DynamoController); + dynamoController.getLoadedPromise().then(() => { + entity.addParentingTableEntry(dynamoController.getCoverage().min, 'earth'); + entity.addParentingTableEntry(dynamoController.getCoverage().max, neo.nextClosestApproachDistance !== 0 ? 'sun' : ''); + if (neo.nextClosestApproachDistance === 0) { + const oeController = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitalElementsController); + oeController.removeOrbitalElements(1); + oeController.addOrbitalElements(dynamoController.getCoverage().max, neo.orbitalElements); + } + }); + } + } + + return entity; + } +} + +const asteroidUrls = [ + 'asteroid_1/generic_asteroid_1.gltf', + 'asteroid_2/generic_asteroid_2.gltf', + 'asteroid_3/generic_asteroid_3.gltf' +]; + + +/***/ }), + +/***/ "./src/types.js": +/*!**********************!*\ + !*** ./src/types.js ***! + \**********************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Types": function() { return /* reexport safe */ eyes__WEBPACK_IMPORTED_MODULE_0__.Types; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./internal */ "./src/internal.js"); + + + +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('SelectionManager', _internal__WEBPACK_IMPORTED_MODULE_1__.SelectionManager); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('LabelManager', _internal__WEBPACK_IMPORTED_MODULE_1__.LabelManager); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('TrailManager', _internal__WEBPACK_IMPORTED_MODULE_1__.TrailManager); + +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidsSettings', _internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidsSettings); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidMenuTop', _internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidMenuTop); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidMenuBottom', _internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidMenuBottom); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidModals', _internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidModals); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidMenuTop', _internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidMenuTop); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidMenuBottom', _internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidMenuBottom); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidPanel', _internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidPanel); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('Breadcrumb', _internal__WEBPACK_IMPORTED_MODULE_1__.Breadcrumb); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('DefinitionOverlay', _internal__WEBPACK_IMPORTED_MODULE_1__.DefinitionOverlay); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('FollowingPanel', _internal__WEBPACK_IMPORTED_MODULE_1__.FollowingPanel); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('HomeButton', _internal__WEBPACK_IMPORTED_MODULE_1__.HomeButton); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('MissionPanel', _internal__WEBPACK_IMPORTED_MODULE_1__.MissionPanel); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('SplashScreen', _internal__WEBPACK_IMPORTED_MODULE_1__.SplashScreen); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('TimeSlider', _internal__WEBPACK_IMPORTED_MODULE_1__.TimeSlider); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('WatchPanel', _internal__WEBPACK_IMPORTED_MODULE_1__.WatchPanel); +eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('Search', _internal__WEBPACK_IMPORTED_MODULE_1__.Search); + + + + +/***/ }), + +/***/ "./src/views/asteroid_view.js": +/*!************************************!*\ + !*** ./src/views/asteroid_view.js ***! + \************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AsteroidView": function() { return /* binding */ AsteroidView; } +/* harmony export */ }); +/* harmony import */ var _base_view__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base_view */ "./src/views/base_view.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); + + + +/** + * + */ +class AsteroidView extends _base_view__WEBPACK_IMPORTED_MODULE_0__["default"] { + /** + * Constructor. + * @param {...*} args - Arguments for BaseView + */ + constructor(...args) { + super(...args); + + // Make sure we have neo data for this object. + this._rules.spaceObject = { + value: name => Boolean(this._app.neos.get(name)?.pioneerName) + }; + + // Hold a reference to the asteroid panel. + this._asteroidPanel = null; + + // Specific target variables. + this._target = null; + this._neoData = null; + this._heroData = null; + this._entityInfo = null; + + this.filtersManager = null; + } + + /** @inheritdoc */ + async onEnter(params) { + // Add components to be excluded on UI show/hide. + this.addUIexcludedComponents([ + 'asteroid_modals', + 'definitionOverlay', + 'clock', + 'clockShortcut', + 'asteroid_menu_bottom' + ]); + + this.filtersManager = this._app.getManager('filters'); + + // Assign asteroidPanel prop if it isnt yet + this._asteroidPanel ??= this._app.getComponent('asteroidPanel'); + + await super.onEnter(params); + + // We need to remove some direct style properties that are set in the pioneer engine. + this._mainViewportEl.style.top = ''; + this._mainViewportEl.style.left = ''; + } + + /** @inheritdoc */ + onLeave(params) { + // Restore own particle + this._app.removeParticleMatchFunction('asteroid_view', true); + + if (params && params.cancelToken && params.cancelToken.isCanceled) { + return; + } + + // Make sure panel collapses and hides. + this._asteroidPanel.hide(); + + // We need to re-add some direct style properties that are set in the pioneer engine. + this._mainViewportEl.style.top = '0px'; + this._mainViewportEl.style.left = '0px'; + + super.onLeave(params); + } + + /** @inheritdoc */ + _reset(params) { + super._reset(params); + this._target = null; + this._neoData = null; + this._heroData = null; + this._entityInfo = null; + } + + /** @inheritdoc */ + registerCallbacks() { + super.registerCallbacks(); + // Register expand toggle callback + this._asteroidPanel.registerCallback('expandtoggle', this._onExpandToggle); + } + + /** @inheritdoc */ + removeCallbacks() { + super.removeCallbacks(); + // Remove expand toggle callback + this._asteroidPanel.removeCallback('expandtoggle', this._onExpandToggle); + } + + /** @inheritdoc */ + async _updateResources({ spaceObject }) { + const contentManager = this._app.getManager('content'); + + // Update entity name and entity info + this._target = spaceObject; + this._neoData = this._allNEOs.get(this._target); + this._heroData = this._allHeroes[this._neoData.pioneerName]; + this._entityInfo = contentManager.getEntityInfo(this._target); + + let targetEntity = this._app.scene.getEntity(this._target); + + // Create NEO entity if needed + if (!targetEntity) { + targetEntity = this._app.getManager('neos').createTempNEO(this._neoData); + } + // In case we're searching for an object that has been filtered out of the scene + else if (!targetEntity._enabled) { + const entry = this._app.getManager('search').getEntry(this._target); + if (entry.neo) { + this.filtersManager.setFilterToReveal(entry.neo, true); + } + } + + // Get the time to start as the current time clamped between the entity's + // position coverage min and max - 3600. Also set the eventInfo start so that + // the BaseView starts it at that time. + const currentTime = this.app.pioneer.getTime(); + let startTime = currentTime; + if (currentTime < targetEntity.getPositionCoverage().min) { + startTime = targetEntity.getPositionCoverage().min; + } + else if (currentTime >= targetEntity.getPositionCoverage().max - 3600) { + startTime = targetEntity.getPositionCoverage().max - 3600; + } + const startDateTime = new pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.DateTime(); + startDateTime.fromET(startTime); + this.app.pioneer.setTime(currentTime); + + // Set eventInfo start only if asteroid has a close approach day in the past we want to go to + const { nextClosestApproachTime } = this._neoData; + + if (nextClosestApproachTime != 0 && nextClosestApproachTime < currentTime) { + this._eventInfo = { start: startDateTime.toString() + 'Z' }; + } else { + this._eventInfo = { start: null }; + } + + // Make sure target NEO is loaded + await targetEntity.getLoadedPromise(); + await this._app.pioneer.waitUntilNextFrame(); + + // Remove own particle + this._app.addParticleMatchFunction((neo) => neo.pioneerName !== this._target, 'asteroid_view', true); + + // Set new target for layer manager + this._app.getManager('layer').setTarget(this._target); + this._app.getManager('selection').selectEntity(this._target); + + contentManager.resetContext(); + + // Only try to load description is there is entityInfo (ie. not for potato NEOs) + this._entityInfo && await contentManager.loadDescriptions([this._target]); + } + + /** @inheritdoc */ + async _updateComponents(params) { + // Populate the panel. + this._asteroidPanel.populate(this._neoData, this._heroData); + + super._updateComponents(params); + } + + /** @inheritdoc */ + async _updateComponentsVisibility(params) { + await super._updateComponentsVisibility(params); + + // Update time slider position. + this._updateTimeSliderPosition(); + + // Show and expand the panel if the UI is visible. (expandOnShow is set to true in the asteroidPanel) + const visibleUI = this._app.getManager('layer').getLayer('ui').visible; + visibleUI && this._asteroidPanel.show(); + + // Hide the bottom menu if it's visible + this._app.getComponent('asteroid_menu_bottom')?.hide(); + } + + /** @inheritdoc */ + async _updateCamera(params) { + await this._app.cameraScripts.goToCelestialObject(this._target); + } + + /** @inheritdoc */ + resize() { + super.resize(); + const isExpanded = this._asteroidPanel?._state.isExpanded; + this._onExpandToggle(isExpanded); + } +} + + +/***/ }), + +/***/ "./src/views/base_view.js": +/*!********************************!*\ + !*** ./src/views/base_view.js ***! + \********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ ExtendedBaseView; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); + + + + +/** + * Base view for Asteroids. + * @extends BaseView + */ +class ExtendedBaseView extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseView { + /** + * Constructor. + * @param {BaseApp} app + * @param {HTMLElement} element + * @param {Array} [components=[]] - Components of a view + */ + constructor(app, element, components = []) { + super(app, element, components); + + // Determines which components are ignore when toggling UI on/off. + this._UIexcludedComponents = null; + this.resetUIexcludedComponents(); + + this._floatMid = null; + this._floatMidBottom = null; + + this._pioneerParentEl = null; + this._mainViewportEl = null; + + this._allNEOs = null; + this._allHeroes = null; + + this._lastTime = null; + + // Set redirect rule + this._rules.redirect = name => { + const router = this._app.getManager('router'); + // If not valid, try getting a parsed link + const parsedLink = this._app.getManager('link')?.getParsedLink?.(name); + const parsedLinkIsValid = parsedLink !== `/${name}`; + if (parsedLinkIsValid) { + router.navigate(parsedLink); + } + else if (name === 'asteroids') { + // Exception for asteroids. + router.navigate(router.homeRoute); + } + else { + // Go back and automatically simulate a search + console.warn(`No object with name, ${name}.`); + router.navigate(router._previousRoute?.url || ''); + this._app.getComponent('search').simulate(name); + } + }; + + this.bindFunctions(['_onExpandToggle']); + } + + /** @inheritdoc */ + async onEnter(params, unsubscribed = []) { + // Set a reference to the main-viewport and pioneer parent. + this._mainViewportEl = this._app.pioneer?.getViewport('main-viewport')?.getDiv(); + this._pioneerParentEl = document.getElementById('pioneer'); + + // Assign the allNEOs and heroes vars. + this._allNEOs ??= this._app.neos; + this._allHeroes ??= this._app.heroes; + + await super.onEnter(params, unsubscribed); + + /** + * When we enter a new view where the previous UI is hidden, we may have new components enabled. + * Once the _resetView is called (where the components are enabbled/disabled), we need to call + * toggleViewUI again to correctly set the visibility of any newly enabled components. + * For instance: + * - Hide UI in home view where 'homeButton' component is disabled + * - Navigate to asteroid where 'homeButton' is enabled + * - Make sure homeButton is re-hidden to maintain the hidden UI state. + */ + const visibleUI = this._app.getManager('layer').getLayer('ui').visible; + this.toggleViewUI(visibleUI, false); + } + + /** @inheritdoc */ + _showControls() { + // Restore clock and time controls + this._app.getComponent('clock').show(); + this._app.getComponent('clockShortcut').show(); + this._app.getComponent('settings').show(); + + // Set element vars if needed. + this._floatMidBottom = this._floatMidBottom || document.getElementById('float-mid-bottom'); + this._floatMid = this._floatMid || document.getElementById('float-mid'); + + this._floatMidBottom.classList.remove('hidden'); + this._floatMidBottom.classList.add('active'); + if (eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode()) { + // Move timeline below + this._floatMid.classList.add('low'); + } + else { + // Restore timeline + this._floatMid.classList.remove('hidden'); + this._floatMid.classList.remove('low'); + } + } + + /** @inheritdoc */ + _hideControls() { + if (eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode()) { + this._app.getComponent('clock').hide(); + this._app.getComponent('clockShortcut').hide(); + this._app.getComponent('settings').hide(); + + // Set element vars if needed. + this._floatMidBottom = this._floatMidBottom || document.getElementById('float-mid-bottom'); + this._floatMid = this._floatMid || document.getElementById('float-mid'); + + this._floatMidBottom.classList.add('hidden'); + this._floatMidBottom.classList.remove('active'); + + // Move timeline up + this._floatMid.classList.remove('low'); + } + } + + /** @inheritdoc */ + async onQueryChange(params) { + super.onQueryChange(params); + + this._callQueryChanges(params); + } + + /** + * Update components with router parameters. + * @param {object} params + */ + _updateComponents(params) { + // Update breadcrumb. + this._app.getComponent('breadcrumb')?.onRouteChange({ + ...params + }); + + // Set settings orientation. + this._app.getComponent('settings').setConfig({ + orientation: { + smallLandscape: { + ori: 'vertical' + } + } + }); + + this._callQueryChanges(params); + } + + /** + * Store the lastTime + * @override + * @param {object} params + */ + async _updateTime(params) { + this._lastTime = this.app.pioneer.getTime(); + + await super._updateTime(params); + } + + /** + * Remove loading screen after checkReady is complete. + * @override + * @param {object} params + */ + async _checkReady(params) { + // If the current entity doesn't exist at the same time as the target entity, re-parent the camera to a temporary entity to keep it around until + // the transition is complete. + + const { cameraEntity } = this.app.getManager('camera'); + const initialEntity = cameraEntity.getParent(); + const targetEntity = this.app.scene.get(this._target); + + if (initialEntity && targetEntity) { + const time = this.app.pioneer.getTime(); + const lca = initialEntity.getLowestCommonAncestorAtTime(targetEntity, time); + + // If no lowest common ancestor, create temp entity and reparent camera to it. + if (lca === null) { + const tempEntityName = `${initialEntity.getName()}_temp`; + const initialPosCopy = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(); + initialPosCopy.copy(initialEntity.getPosition()); + + const tempEntity = pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.createFromOptions( + tempEntityName, + { + radius: initialEntity.getExtentsRadius(), + parents: [[Number.NEGATIVE_INFINITY, 'sun']] + }, + this.app.scene + ); + + // Copy position and parent of initial entity. + tempEntity.setPosition(initialPosCopy); + const tempParentName = initialEntity.getParentAtTime(this._lastTime) ?? 'sun'; + const tempParent = this.app.scene.get(tempParentName); + tempEntity.setParent(tempParent); + + // Set camera parent to temp entity. + cameraEntity.setParent(tempEntity); + + // Add it to the scene manager temp entities (will be cleared in 'after') + this.app.getManager('scene').addTempEntity(tempEntity); + } + } + + await super._checkReady(params); + + this.app.endLoadingScreen(); + } + + /** + * Determine which onQueryChanges to call depending on the current and previous query params + * @param {object} params + */ + _callQueryChanges(params) { + // Determine which queries are, and were previously defined and call onQueryChange accordingly. + const router = this.app.getManager('router'); + const prevQueries = router.parseQuery(router.previousRoute.query); + + const { modal, definition, tutorial, rate } = { + ...params, + ...prevQueries + }; + + // If we have a modal value, call for menu_top and modals. + if (modal) { + this.app.getComponent('asteroid_menu_top')?.onQueryChange(params); + this.app.getComponent('asteroid_modals')?.onQueryChange(params); + } + + // If we have a definition value, call for the definitionOverlay. + definition && this.app.getComponent('definitionOverlay')?.onQueryChange(params); + + // If we have a tutorial value, call for the tutorialOverlay. + tutorial && this.app.getComponent('tutorialOverlay')?.onQueryChange(params); + + // If we have a rate change, call for the time slider. + rate !== undefined && this.app.getComponent('timeSlider')?.onQueryChange(params); + } + + /** @inheritdoc */ + onLeave(params) { + // Always Reset UI excluded components to default. + this.resetUIexcludedComponents(); + super.onLeave(params); + } + + /** @inheritdoc */ + _shouldResetStatus() { + return true; + } + + /** + * Appended component names to UIexcludedComponents array + * @param {Array} componentNames + */ + addUIexcludedComponents(componentNames) { + this._UIexcludedComponents.push(...componentNames); + } + + /** + * Sets the default component names to exclude when toggle UI + */ + resetUIexcludedComponents() { + this._UIexcludedComponents = [ + 'breadcrumb', + 'settings', + 'loadIcon', + 'layerPanel' + ]; + } + + /** + * Override toggles UI. + * @param {boolean} showUI + * @param initSwiper + */ + toggleViewUI(showUI = this._app.getManager('layer').getLayer('ui').visible, initSwiper = true) { + // Auto hide the layer panel when toggling UI + this._app.getComponent('layerPanel').hide(); + // Go through all components in the view and show/hide them if not in the _UIexcludedComponents array. + this._components.forEach(componentName => { + // Return if we need to ignore the component. + if (this._UIexcludedComponents.includes(componentName)) { + return; + } + if (this.app.getManager('router')._alwaysHiddenComponents?.includes(componentName)) { + return; + } + + const component = this._app.getComponent(componentName); + const isStory = componentName === 'story'; + + // Before, we were disabling the component (remove it from the DOM). Now we're just hiding it. + if (showUI) { + component.setEnabled(true); + component.show(initSwiper); + isStory && component.resize(); + } + else { + component.hide(); + } + }); + + // This isn't great and should better match how the other components work when showing / hiding. + const extendedControlsDiv = document.getElementById('extended-controls'); + if (extendedControlsDiv) extendedControlsDiv.style.display = showUI ? 'grid' : 'none'; + } + + /** + * Uses threshold and non-portrait to determine whether we should right offset + * (currently used to determine if time slider and main viewport offset) + * @returns {boolean} + */ + get shouldOffsetRight() { + return !eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobilePortrait(); + } + + /** + * What determines if we should offset the viewport up. + * @returns {boolean} + */ + get shouldOffsetUp() { + return eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobilePortrait(); + } + + /** + * Handle the expand toggle + * @param {boolean} expanded + * @param {boolean} updateTimeSlider + */ + _onExpandToggle(expanded, updateTimeSlider = true) { + // Conditionally update time slider position. + updateTimeSlider && this._updateTimeSliderPosition({ expanded }); + + const loadIconEl = this._app.getComponent('loadIcon')?.element; + + // Determine if we should offset the viewport to the right or up. + const offsetRight = this.shouldOffsetRight && expanded; + this._pioneerParentEl?.classList.toggle('offset-right', offsetRight); + this._mainViewportEl?.classList.toggle('offset-right', offsetRight); + loadIconEl?.classList.toggle('offset-right', offsetRight); + + const offsetUp = this.shouldOffsetUp && expanded; + this._pioneerParentEl?.classList.toggle('offset-up', offsetUp); + this._mainViewportEl?.classList.toggle('offset-up', offsetUp); + loadIconEl?.classList.toggle('offset-up', offsetUp); + + // Show the settings only if the panel is offset vertically. + const settings = this._app.getComponent('settings'); + if (offsetUp) { + settings?.hide(); + } + else { + settings?.show(); + } + } + + /** + * Updates the time slider position. + * @param {object} options + */ + _updateTimeSliderPosition(options = {}) { + this._app.getComponent('timeSlider')?.toggleExtraClasses(options); + } +} + + +/***/ }), + +/***/ "./src/views/following_view.js": +/*!*************************************!*\ + !*** ./src/views/following_view.js ***! + \*************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FollowingView": function() { return /* binding */ FollowingView; } +/* harmony export */ }); +/* harmony import */ var _base_view__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base_view */ "./src/views/base_view.js"); + + +/** + * + */ +class FollowingView extends _base_view__WEBPACK_IMPORTED_MODULE_0__["default"] { + /** + * Constructor. + * @param {...*} args - Arguments for BaseView + */ + constructor(...args) { + super(...args); + + this._rules = { + ...this._rules, + planet: { + value: name => this._app.getManager('content')?.getEntityInfo(name)?.category === 'Planet' + }, + moon: { + value: name => this._app.getManager('content')?.getEntityInfo(name)?.id === 'moon' + }, + sun: { + value: name => this._app.getManager('content')?.getEntityInfo(name)?.id === 'sun' + } + + }; + + // Hold a reference to the following panel. + this._followingPanel = null; + + this._entityInfo = null; + } + + /** @inheritdoc */ + async onEnter(params) { + // Add components to be excluded on UI show/hide. + this.addUIexcludedComponents([ + 'asteroid_modals', + 'definitionOverlay', + 'clock', + 'clockShortcut', + 'asteroid_menu_bottom' + ]); + + // Assign followingPanel prop if it isnt yet + this._followingPanel ??= this._app.getComponent('followingPanel'); + + await super.onEnter(params); + } + + /** @inheritdoc */ + onLeave(params) { + // Make sure panel hides. + this._followingPanel.hide(); + + super.onLeave(params); + } + + /** @inheritdoc */ + _reset(params) { + super._reset(params); + const { planet, star, moon } = params; + this._target = planet || star || moon; + } + + /** @inheritdoc */ + async _updateResources(params) { + // Set new target for layer manager + this._app.getManager('layer').setTarget(this._target); + this._app.getManager('selection').selectEntity(this._target); + } + + /** @inheritdoc */ + async _updateComponents(params) { + // Use content manager to get title and set panel title state. + const info = this._app.getManager('content')?.getEntityInfo(this._target); + this._followingPanel.setState({ + title: info.iauName || info.displayName + }); + + super._updateComponents(params); + } + + /** @inheritdoc */ + async _updateComponentsVisibility(params) { + await super._updateComponentsVisibility(params); + + // Update time slider position. + this._updateTimeSliderPosition(); + + // Show the panel if the UI is visible. + const visibleUI = this._app.getManager('layer').getLayer('ui').visible; + visibleUI && this._followingPanel.show(); + + // Hide the bottom menu if it's visible + this._app.getComponent('asteroid_menu_bottom')?.hide(); + } + + /** @inheritdoc */ + async _updateCamera() { + await this._app.cameraScripts.goToCelestialObject(this._target); + } + + /** @inheritdoc */ + resize() { + super.resize(); + this._onExpandToggle(false); + } +} + + +/***/ }), + +/***/ "./src/views/home_view.js": +/*!********************************!*\ + !*** ./src/views/home_view.js ***! + \********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "HomeView": function() { return /* binding */ HomeView; } +/* harmony export */ }); +/* harmony import */ var _base_view__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base_view */ "./src/views/base_view.js"); + + +/** + * @extends BaseView + */ +class HomeView extends _base_view__WEBPACK_IMPORTED_MODULE_0__["default"] { + /** @inheritdoc */ + async onEnter(params) { + // Add components to be excluded on UI show/hide. + this.addUIexcludedComponents([ + 'splashScreen', + 'asteroid_modals', + 'definitionOverlay', + 'clock', + 'clockShortcut', + 'tutorialOverlay' + ]); + + // Apply time slider classes as needed. + this._updateTimeSliderPosition(); + + // Make sure bottom menu is visible if needed. + this._app.getComponent('asteroid_menu_bottom')?.show(); + + const unsubscribed = []; + if (this._app.getComponent('splashScreen')?.element === null) { + unsubscribed.push('splashScreen'); + }; + await super.onEnter(params, unsubscribed); + } + + /** @inheritdoc */ + _updateResources(params) { + this._app.getManager('time').resetLimits(); + this._app.getManager('layer').setTarget(''); + + this._target = 'sun'; + } + + /** @inheritdoc */ + async _updateCamera(params) { + await this.app.cameraScripts.goToSystem('inner_solar_system'); + } + + /** @inheritdoc */ + resize() { + super.resize(); + this._updateTimeSliderPosition(); + } +} + + +/***/ }), + +/***/ "./src/views/index.js": +/*!****************************!*\ + !*** ./src/views/index.js ***! + \****************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _asteroid_view__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./asteroid_view */ "./src/views/asteroid_view.js"); +/* harmony import */ var _mission_view__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mission_view */ "./src/views/mission_view.js"); +/* harmony import */ var _following_view__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./following_view */ "./src/views/following_view.js"); +/* harmony import */ var _watch_view__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./watch_view */ "./src/views/watch_view.js"); +/* harmony import */ var _home_view__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./home_view */ "./src/views/home_view.js"); +/* harmony import */ var _story_view__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./story_view */ "./src/views/story_view.js"); + + + + + + + +/* harmony default export */ __webpack_exports__["default"] = ({ + AsteroidView: _asteroid_view__WEBPACK_IMPORTED_MODULE_0__.AsteroidView, + MissionView: _mission_view__WEBPACK_IMPORTED_MODULE_1__.MissionView, + FollowingView: _following_view__WEBPACK_IMPORTED_MODULE_2__.FollowingView, + WatchView: _watch_view__WEBPACK_IMPORTED_MODULE_3__.WatchView, + HomeView: _home_view__WEBPACK_IMPORTED_MODULE_4__.HomeView, + StoryView: _story_view__WEBPACK_IMPORTED_MODULE_5__.StoryView +}); + + +/***/ }), + +/***/ "./src/views/mission_view.js": +/*!***********************************!*\ + !*** ./src/views/mission_view.js ***! + \***********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "MissionView": function() { return /* binding */ MissionView; } +/* harmony export */ }); +/* harmony import */ var _base_view__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base_view */ "./src/views/base_view.js"); + + + +/** + * + */ +class MissionView extends _base_view__WEBPACK_IMPORTED_MODULE_0__["default"] { + /** + * Constructor. + * @param {...*} args - Arguments for BaseView + */ + constructor(...args) { + super(...args); + + this._rules.spacecraft = { + value: name => this._app.getManager('content')?.getEntityInfo(name)?.category === 'Spacecraft' + }; + + // Hold a reference to the mission panel. + this._missionPanel = null; + + this._entityInfo = null; + + this.filtersManager = null; + } + + /** @inheritdoc */ + async onEnter(params) { + // Add components to be excluded on UI show/hide. + this.addUIexcludedComponents([ + 'asteroid_modals', + 'definitionOverlay', + 'clock', + 'clockShortcut', + 'asteroid_menu_bottom' + ]); + + this.filtersManager = this._app.getManager('filters'); + + // Assign asteroidPanel prop if it isnt yet + this._missionPanel ??= this._app.getComponent('missionPanel'); + + await super.onEnter(params); + + // We need to remove some direct style properties that are set in the pioneer engine. + this._mainViewportEl.style.top = ''; + this._mainViewportEl.style.left = ''; + } + + /** @inheritdoc */ + onLeave(params) { + if (params && params.cancelToken && params.cancelToken.isCanceled) { + return; + } + + // Make sure panel collapses and hides. + this._missionPanel.hide(); + + // We need to re-add some direct style properties that are set in the pioneer engine. + this._mainViewportEl.style.top = '0px'; + this._mainViewportEl.style.left = '0px'; + + super.onLeave(params); + } + + /** @inheritdoc */ + registerCallbacks() { + super.registerCallbacks(); + // Register expand toggle callback + this._missionPanel.registerCallback('expandtoggle', this._onExpandToggle); + } + + /** @inheritdoc */ + removeCallbacks() { + super.removeCallbacks(); + // Remove expand toggle callback + this._missionPanel.removeCallback('expandtoggle', this._onExpandToggle); + } + + /** @inheritdoc */ + _reset(params) { + super._reset(params); + this._target = null; + this._entityInfo = null; + } + + /** @inheritdoc */ + async _updateResources({ spacecraft }) { + const contentManager = this._app.getManager('content'); + + // Update entity name and entity info + this._target = spacecraft; + this._entityInfo = contentManager.getEntityInfo(this._target); + + // Load events and descriptions. + await this._app.getManager('content').loadDescriptions([this._target]); + await this._app.getManager('content').loadEvents(this._target, { + all: 'all_events' + }); + + // Set new target for layer manager + this._app.getManager('layer').setTarget(this._target); + this._app.getManager('selection').selectEntity(this._target); + + if (this._entityInfo === null) { + this._handleError(`MissionView._updateResources: Cannot find entity named ${this._target}.`); + return; + } + + // Remove layer filters if the current mission depends on the layer + if (this._entityInfo?.related) { + // filter and reduce here take the 'related' entity object + // and turns it into a boolean-keyed object + // { asteroid: ['bennu'], comets: [] } -> { asteroids: true } + this.filtersManager.setFilterToReveal( + Object.keys(this._entityInfo.related) + .filter((r) => this._entityInfo.related[r].length > 0) + .reduce((acc, cur) => { + acc[cur] = true; return acc; + }, {}), true); + } + } + + /** @inheritdoc */ + async _updateComponents(params) { + const contentManager = this._app.getManager('content'); + + // Get blurb. + const blurb = contentManager.context[this._target]?.description?.blurb; + + // Get events. + const events = contentManager.context?.events; + + // Determine title. + const { iauName, displayName } = this._entityInfo; + const title = iauName || displayName; + + // Populate the panel. + this._missionPanel.populate(title, blurb, this._target, events); + + super._updateComponents(params); + } + + /** @inheritdoc */ + async _updateComponentsVisibility(params) { + await super._updateComponentsVisibility(params); + + // Update time slider position. + this._updateTimeSliderPosition(); + + // Show and expand the panel if the UI is visible. (expandOnShow is set to true in the missionPanel) + const visibleUI = this._app.getManager('layer').getLayer('ui').visible; + visibleUI && this._missionPanel.show(); + + // Hide the bottom menu if it's visible + this._app.getComponent('asteroid_menu_bottom')?.hide(); + } + + /** @inheritdoc */ + async _updateCamera(params) { + const hasLanded = this._app.getManager('content').hasLanded(this._entityInfo); + if (hasLanded) { + await this._app.cameraScripts.alignSpacecraftPlanet(this._target); + } + else { + await this._app.cameraScripts.goToSpacecraft(this._target); + } + } + + /** @inheritdoc */ + resize() { + super.resize(); + const isExpanded = this._missionPanel?._state.isExpanded; + this._onExpandToggle(isExpanded); + } +} + + +/***/ }), + +/***/ "./src/views/story_view.js": +/*!*********************************!*\ + !*** ./src/views/story_view.js ***! + \*********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "StoryView": function() { return /* binding */ StoryView; } +/* harmony export */ }); +/* harmony import */ var eyes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! eyes */ "../eyes/src/index.js"); +/* harmony import */ var _base_view__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./base_view */ "./src/views/base_view.js"); + + + +/** + * + */ +class StoryView extends _base_view__WEBPACK_IMPORTED_MODULE_1__["default"] { + /** + * Constructor. + * @param {...*} args - Arguments for BaseView + */ + constructor(...args) { + super(...args); + + /** + * Copy of story context. + * @type {object} + */ + this._story = null; + + this._rules.id = { + value: val => val in this._app.getManager('content').getStoryList().stories + }; + + /** + * Callbacks to call in onLeave. + * Usually to reset values to before entering this view. + * @type {Array} + */ + this._onLeaveCallbacks = []; + } + + /** @inheritdoc */ + async onQueryChange(params) { + // Update definition if exists (needs to be called first) + this._app.getComponent('definitionOverlay')?.onQueryChange(params); + + await super.onQueryChange(params); + + // Update story + await this._updateTime(params); + await this._app.getComponent('story').onQueryChange(params); + await this._updateCamera(params); + } + + /** @inheritdoc */ + async onEnter(params, unsubscribed = []) { + // Add components to be excluded on UI show/hide. + this.addUIexcludedComponents([ + 'asteroid_modals', + 'overlay', + 'definitionOverlay', + 'clock', + 'clockShortcut', + 'asteroid_menu_bottom' + ]); + + // Turn off visibility by default. + const storyComponent = this._app.getComponent('story'); + storyComponent.hide(); + + await super.onEnter(params, unsubscribed); + + // Show and expand the panel if the UI is visible. (expandOnShow is set to true in the missionPanel) + const visibleUI = this._app.getManager('layer').getLayer('ui').visible; + visibleUI && storyComponent.show(); + + // Make sure spacecraft and planet layers are on. + const layerManager = this._app.getManager('layer'); + const layerPanel = this._app.getComponent('layerPanel'); + if (!layerManager.getLayer('spacecraft').visible) { + layerPanel.toggleLayer('spacecraft'); + } + if (!layerManager.getLayer('planets').visible) { + layerPanel.toggleLayer('planets'); + } + + // Make sure spacecraft is disabled + layerPanel.setCategoryEnabled('spacecraft', false); + + // Turn off any filters. + this._app.getManager('filters')?.setFilter({ phos: false, asteroids: false, comets: false }); + + // Temporarily disable + const clock = this._app.getComponent('clock'); + clock.setState({ allowEdit: false }); + clock.toggle('time', false); + clock.toggle('meridiem', false); + this._app.getManager('label').setClickable(false); + this._app.getManager('selection').setClickable(false); + + // Hide time slider + this._app.getComponent('timeSlider')?.setSliderVisibility(false); + } + + /** @inheritdoc */ + async onLeave(params) { + super.onLeave(params); + await this._story?.onLeave?.(this._app); + await this._app.getComponent('story').onLeave(); + + // Reset + const clock = this._app.getComponent('clock'); + clock.setState({ allowEdit: true }); + clock.toggle('time', true); + clock.toggle('meridiem', true); + this._app.getManager('label').setClickable(true); + this._app.getManager('selection').setClickable(true); + + // Show time slider + this._app.getComponent('timeSlider')?.setSliderVisibility(true); + + // Make sure spacecraft is enabled + this._app.getComponent('layerPanel')?.setCategoryEnabled('spacecraft', true); + + // Call onLeave callbacks and reset them. + for (let i = 0; i < this._onLeaveCallbacks.length; i++) { + this._onLeaveCallbacks[i](params); + } + this._onLeaveCallbacks = []; + + this._story = null; + } + + /** @inheritdoc */ + async _updateResources(params) { + // Set new target for layer manager + this._app.getManager('layer').setTarget(''); + + if (this._story) { + this._story.onLeave?.(this._app); + this._app.getComponent('story')?.onLeave(); + } + + // Load story + try { + const story = await this._app.getManager('content').getStory(params.id); + // Copy the context in case it is lost during a route change + this._story = eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.deepClone(story); + this._story?.onEnter?.(this._app); + } + catch (err) { + this._handleError(`StoryView._updateResources: Cannot find story ${params.id}.`); + } + } + + /** @inheritdoc */ + async _updateTime(params) { + super._updateTime(params); + + const timeManager = this._app.getManager('time'); + const slideInfo = params.slide + ? this._story.slides.find(slide => slide.id === params.slide) + : this._story.slides[0]; + + // Set time limits if slideInfo has it + const { min, max } = slideInfo?.timeLimits || {}; + min && timeManager.setMin(min); + max && timeManager.setMin(max); + + // Update time if slideInfo has it + if (!params.time && slideInfo.time) { + timeManager.setTime(slideInfo.time); + + // Wait for next frame to get updated position + // after time has changed + await this._app.pioneer.waitUntilNextFrame(); + } + } + + /** @inheritdoc */ + _shouldHideControls() { + return eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode() && this._app.getComponent('story').getState('isVisible'); + } + + /** @inheritdoc */ + async _updateComponents(params) { + super._updateComponents(params); + // Get the config before entering view for reset + const settings = this._app.getComponent('settings'); + const { allowInfoPanel } = settings.getConfig(); + this._onLeaveCallbacks.push(() => { + settings.setConfig({ + allowInfoPanel + }); + }); + // Set the config for this view + settings.setConfig({ + allowInfoPanel: false + }); + + // Update story + const storyComponent = this._app.getComponent('story'); + await storyComponent.onRouteChange(this._story.slides, params); + storyComponent.show(); + } + + /** @inheritdoc */ + async _updateCamera(params) { + const slideInfo = params.slide + ? this._story.slides.find(slide => slide.id === params.slide) + : this._story.slides[0]; + + if (slideInfo && slideInfo.camera) { + // Only update camera if slide changes + const story = this._app.getComponent('story'); + if (story.getState('previousIndex') !== story.getState('currentIndex')) { + const preset = slideInfo.camera[0]; + await preset(this._app); + } + } + else { + await this._app.cameraScripts.goToSystem('outer_solar_system'); + } + } +} + + +/***/ }), + +/***/ "./src/views/watch_view.js": +/*!*********************************!*\ + !*** ./src/views/watch_view.js ***! + \*********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "WatchView": function() { return /* binding */ WatchView; } +/* harmony export */ }); +/* harmony import */ var _base_view__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base_view */ "./src/views/base_view.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); + + + + +/** + * + */ +class WatchView extends _base_view__WEBPACK_IMPORTED_MODULE_0__["default"] { + /** + * Constructor. + * @param {...*} args - Arguments for BaseView + */ + constructor(...args) { + super(...args); + + // Make sure we have neo data for this object. + this._rules.neoName = { + value: name => Boolean(this._app.neos.get(name)?.pioneerName) + }; + + this._watchManager = null; + this._watchPanel = null; + + this.filtersManager = null; + } + + /** @inheritdoc */ + async onRouteChange(params) { + const missingNeoName = params.neoName === undefined; + const cameFromOutside = this._app.getManager('router').previousView !== 'watch' && missingNeoName; + + let slideIndex = this._watchManager.determineSlideIndex(params.neoName); + + const alreadyPassed = slideIndex === -1; + const notInDatabase = params.neoName && !this._app.scene.get(params.neoName); + + /** + * Three scenarios where we need to open the watch panel to the first slide (ie. redirect): + * 1) If we came from outside the watch view and there's no neoName + * 2) If the given neoName has already passed the earth + * 3) If the given neoName doesnt exist (not in database) + */ + if (cameFromOutside || alreadyPassed || notInDatabase) { + // Warning message. + if (notInDatabase) { + console.warn(`Asteroid, ${params.neoName} is not in the database. Re-directing to Next Closest Approach.`); + } + else if (alreadyPassed) { + // Todo: We need a popup that says "Phew! It missed!"" with "Show me anyway" or "See next approaching asteroids" + console.warn(`Asteroid, ${params.neoName} has safely passed earth. Re-directing to Next Closest Approach.`); + } + slideIndex = 0; + + // Re-direct to first slide. + this._watchManager.setHasRedirected(true); + this._watchManager.setSlideUrlByIndex(slideIndex); + + return; + } + + const { neoName } = params; + + // Set the panels expand state. + this._watchPanel.shouldBeExpanded = Boolean(neoName); + + // Store the slide index in the watchManager + this._watchManager.setSlideIndex(slideIndex); + + // Make sure the swiper slide is correctly synced to the URL. + // Be careful not to make an infinite loop here between slideTo and the on slideChange event handler in the watch carousel component + const swiper = this._watchPanel._swiper; + + if (neoName && swiper) { + const { realIndex } = swiper; + if (slideIndex !== null && slideIndex !== realIndex) { + // This last false arg should mean that the slideChange callback is not triggered. However this doesnt seem to work... + swiper.slideTo(slideIndex, undefined, false); + } + } + + // Once entities are loaded, set the target and + await this._entitiesLoadedPromise; + + // Trigger the asteroid selection update. + this._watchManager.setAsteroidSelection(); + + await super.onRouteChange(params); + } + + /** @inheritdoc */ + async onEnter(params) { + this.filtersManager = this._app.getManager('filters'); + + // Set time to now. + // this._app.getManager('time')?.setToNow(); + + // Activate top menu item activeness. + this._app.getComponent('asteroid_menu_top')?.toggleActive('Asteroid Watch', true); + + // Set data in the WatchManager + this._watchManager = this._app.getManager('watch'); + + // Set of the data. + this._watchManager.setData(); + const { nextFiveData } = this._watchManager; + + // Create the entities but don't await it as this can block for half a second and it's not essential for other tasks. + this._entitiesLoadedPromise = this._watchManager._createEntities(); + + // assign watchPanel prop if it isnt yet + if (!this._watchPanel) { + this._watchPanel = this._app.getComponent('watchPanel'); + } + // Compose the swiper carousel if it doesnt exist + if (!this._watchPanel._swiper) { + this._watchPanel.populate(nextFiveData); + this._watchPanel.initSwiper(); + } + + // Apply time limits earth coverage. + this._watchManager.restrictEarthCoverage(); + + // Apply classes to dim all background labels. + this._watchManager.dimBackgroundLabels(true); + + // Trails needs their default width set to ensure they remain hidden when unhovering. + this._watchManager.setBgTrailWidthDefault(0); + + // Make sure earth and moon label is not clickable. + this._app.getManager('selection').setClickable(false); + + const labelManager = this._app.getManager('label'); + labelManager.setLabelClickable('earth', false); + + // Remove all filters so that we see everything again + this.filtersManager.setFilter({ asteroids: false, comets: false, phos: false }); + this.app.getComponent('filtersModal').handleResetFilters(); + + // Add components to be excluded on UI show/hide. + this.addUIexcludedComponents([ + 'asteroid_modals', + 'definitionOverlay', + 'clock', + 'clockShortcut', + 'asteroid_menu_bottom', + 'tutorialOverlay' + ]); + + await super.onEnter(params); + + // We need to remove some direct style properties that are set in the pioneer engine. + this._mainViewportEl.style.top = ''; + this._mainViewportEl.style.left = ''; + } + + /** @inheritdoc */ + async onLeave(params) { + // Hide and collapse panel (before removing callbacks) + this._watchPanel.hide(); + + // Temp entities can be deleting using the after function in extended base view. + // This prevent it making the camera more jerky. + await super.onLeave(params); + + // Restore earth dynamo coverage. + this._watchManager.restoreEarthCoverage(); + + // Restore background labels. + this._watchManager.dimBackgroundLabels(false); + + // Restore trails default width. + this._watchManager.setBgTrailWidthDefault(); + + // Restore particles to their default opacity. + const particleShader = this._getParticleShader(); + if (particleShader) { + particleShader.uniforms.masterOpacity.value = 0.5; + } + + // Deactivate top menu item activeness. + this._app.getComponent('asteroid_menu_top')?.toggleActive('Asteroid Watch', false); + + // Clear watch manager references. + this._watchManager.removeReferences(); + + // We need to re-add some direct style properties that are set in the pioneer engine. + this._mainViewportEl.style.top = '0px'; + this._mainViewportEl.style.left = '0px'; + + // Make sure earth and moon labels clickable again + this._app.getManager('selection').setClickable(true); + + const labelManager = this._app.getManager('label'); + labelManager.setLabelClickable('earth', true); + } + + /** @inheritdoc */ + _reset() { + this._target = 'earth'; + } + + /** @inheritdoc */ + registerCallbacks() { + super.registerCallbacks(); + // Register expand toggle callback + this._watchPanel.registerCallback('expandtoggle', this._onExpandToggle); + } + + /** @inheritdoc */ + removeCallbacks() { + super.removeCallbacks(); + // Remove expand toggle callback + this._watchPanel.removeCallback('expandtoggle', this._onExpandToggle); + } + + /** + * Get the furthest asteroid from the target entity and multiply by + * @param {string} targetId + * @param {object} options + * @param {Array} options.asteroidData + * @param {number} options.duration + * @param {number} options.distanceCoeff + * @param {number} options.maxCamDistance + * @param {Function} options.onTransition + * @param options.forceAnimation + */ + async goToWatchAsteroids(targetId, { asteroidData = [], duration = 2, distanceCoeff = 4, maxCamDistance = 50000000, onTransition = undefined, forceAnimation = false }) { + const scene = /** @type {SceneManager} */(this.app.getManager('scene')).main; + const cameraManager = /** @type {CameraManager} */(this.app.getManager('camera')); + const cameraEntity = cameraManager.cameraEntity; + + const targetEntity = scene.getEntity(targetId); + const cinematic = true; + const halfDuration = duration * 0.5; + + // Get current cam distance + const currCamPosition = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(); + cameraEntity?.getPositionRelativeToEntity(currCamPosition, pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, targetEntity); + const currCamDistance = currCamPosition.magnitude(); + + // Find the asteroid that's CURRENTLY furthest from the target. + const asteroidPos = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(); + const currDistances = asteroidData.map(({ pioneerName }) => { + const entity = scene.getEntity(pioneerName); + targetEntity.getPositionRelativeToEntity(asteroidPos, pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, entity); + return asteroidPos.magnitude(); + }); + // Calculate furthest distance + const furthestDistance = Math.max(...currDistances); + // Clamp to max cam distance + const distance = Math.min(furthestDistance * distanceCoeff, maxCamDistance); + + // Only trigger camera if it's too far or too near, or we came from outside the asteroid watch view + const tooFarAway = isNaN(currCamDistance) || currCamDistance > maxCamDistance; + const tooNear = currCamDistance < furthestDistance; + + const animateCamera = tooFarAway || tooNear || forceAnimation; + + if (animateCamera) { + // Get target up. + const targetUp = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(); + targetEntity.getOrientation().getAxis(targetUp, 2); + + // The target up can be the destination so we get a 'birdseye view' + targetUp.mult(targetUp, distance); + + this._onCameraTransition = onTransition; + + // Zoom to the distance + await cameraManager.goToEntity(targetId, { distance, cinematic, destinationUp: targetUp, duration: halfDuration, transitionFunction: this.app.cameraScripts._easeInOutExpoTransition }); + + // set cam transition func back to null + this._onCameraTransition = null; + } + } + + /** @inheritdoc */ + async _updateCamera({ cancelToken }) { + if (cancelToken.isCanceled) { + return; + } + + const { nextFiveData, backgroundPlanets, defaultPlanetTrailWidth, hasRedirected } = this._watchManager; + const trailManager = this._app.getManager('trail'); + + // During the camera transition, we can pass in a function that takes the progress as an argument. + // This allows us to more smoothly transition other components (master particle opacity and trail widths for planets) + const defaultParticleOpacity = 0.5; // this value must align with the master opacity uniform in asteroids.js TODO: add it to a separate constants file. + const targetParticleOpacity = 0.2; + const watchView = this; + + // onTransition function is only applied when we've vome from the outside (ie. from another view) + const onTransition = t => { + // Interpolate opacity and trail width. + const particleOpacity = targetParticleOpacity + (1 - t) * (defaultParticleOpacity - targetParticleOpacity); + const trailWidth = defaultPlanetTrailWidth * (1 - t); + + // Set opacity and trail width. + watchView._setParticleOpacity(particleOpacity); + trailManager.setMultipleWidths(backgroundPlanets, trailWidth, trailWidth); + }; + + const cameFromOutside = hasRedirected || this._app.getManager('router').previousView !== 'watch'; + + // View all the asteroids + await this.goToWatchAsteroids(this._target, { + asteroidData: nextFiveData, + ...cameFromOutside && { onTransition, forceAnimation: true } + }); + + // It's possible that we've changed route during the camera transition (cancelled token), in which case we need to reset the particle opacity and trail width. + + if (cancelToken.isCanceled) { + this._setParticleOpacity(defaultParticleOpacity); + this._watchManager.setBgTrailWidthDefault(); + } + else { + // It's possible we havent used an onTransition function, in which case we need to set the final opacity and trail width values. + this._setParticleOpacity(targetParticleOpacity); + trailManager.setMultipleWidths(backgroundPlanets, 0, 0); + } + } + + /** + * Gets the threejs particle shader + * @returns {object} + */ + _getParticleShader() { + return this._app._pioneer.get('main', 'sun', 'orbitalParticles')?.getThreeJsMaterials()?.[0]; + } + + /** + * Sets particle master opacity + * @param {number} opacity + */ + _setParticleOpacity(opacity) { + const particleShader = this._getParticleShader(); + if (particleShader) { + particleShader.uniforms.masterOpacity.value = opacity; + } + } + + /** @inheritdoc */ + after(params) { + // Reset old target for layer manager + this._app.getManager('layer').resetTarget(); + + // Reset hasRedirected + if (this._watchManager.hasRedirected) { + this._watchManager.setHasRedirected(false); + } + } + + /** @inheritdoc */ + async _updateComponentsVisibility(params) { + await super._updateComponentsVisibility(params); + + // Show the panel if the UI is visible. + const visibleUI = this._app.getManager('layer').getLayer('ui').visible; + visibleUI && this._watchPanel.show(); + + // Hide the bottom menu if it's visible + this._app.getComponent('asteroid_menu_bottom')?.hide(); + } + + /** @inheritdoc */ + resize() { + super.resize(); + const isExpanded = this._watchPanel?._state.isExpanded; + this._onExpandToggle(isExpanded); + } +} + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale sync recursive ^\\.\\/.*$": +/*!*********************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ sync ^\.\/.*$ ***! + \*********************************************************/ +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +var map = { + "./af": "../eyes/node_modules/moment/locale/af.js", + "./af.js": "../eyes/node_modules/moment/locale/af.js", + "./ar": "../eyes/node_modules/moment/locale/ar.js", + "./ar-dz": "../eyes/node_modules/moment/locale/ar-dz.js", + "./ar-dz.js": "../eyes/node_modules/moment/locale/ar-dz.js", + "./ar-kw": "../eyes/node_modules/moment/locale/ar-kw.js", + "./ar-kw.js": "../eyes/node_modules/moment/locale/ar-kw.js", + "./ar-ly": "../eyes/node_modules/moment/locale/ar-ly.js", + "./ar-ly.js": "../eyes/node_modules/moment/locale/ar-ly.js", + "./ar-ma": "../eyes/node_modules/moment/locale/ar-ma.js", + "./ar-ma.js": "../eyes/node_modules/moment/locale/ar-ma.js", + "./ar-sa": "../eyes/node_modules/moment/locale/ar-sa.js", + "./ar-sa.js": "../eyes/node_modules/moment/locale/ar-sa.js", + "./ar-tn": "../eyes/node_modules/moment/locale/ar-tn.js", + "./ar-tn.js": "../eyes/node_modules/moment/locale/ar-tn.js", + "./ar.js": "../eyes/node_modules/moment/locale/ar.js", + "./az": "../eyes/node_modules/moment/locale/az.js", + "./az.js": "../eyes/node_modules/moment/locale/az.js", + "./be": "../eyes/node_modules/moment/locale/be.js", + "./be.js": "../eyes/node_modules/moment/locale/be.js", + "./bg": "../eyes/node_modules/moment/locale/bg.js", + "./bg.js": "../eyes/node_modules/moment/locale/bg.js", + "./bm": "../eyes/node_modules/moment/locale/bm.js", + "./bm.js": "../eyes/node_modules/moment/locale/bm.js", + "./bn": "../eyes/node_modules/moment/locale/bn.js", + "./bn-bd": "../eyes/node_modules/moment/locale/bn-bd.js", + "./bn-bd.js": "../eyes/node_modules/moment/locale/bn-bd.js", + "./bn.js": "../eyes/node_modules/moment/locale/bn.js", + "./bo": "../eyes/node_modules/moment/locale/bo.js", + "./bo.js": "../eyes/node_modules/moment/locale/bo.js", + "./br": "../eyes/node_modules/moment/locale/br.js", + "./br.js": "../eyes/node_modules/moment/locale/br.js", + "./bs": "../eyes/node_modules/moment/locale/bs.js", + "./bs.js": "../eyes/node_modules/moment/locale/bs.js", + "./ca": "../eyes/node_modules/moment/locale/ca.js", + "./ca.js": "../eyes/node_modules/moment/locale/ca.js", + "./cs": "../eyes/node_modules/moment/locale/cs.js", + "./cs.js": "../eyes/node_modules/moment/locale/cs.js", + "./cv": "../eyes/node_modules/moment/locale/cv.js", + "./cv.js": "../eyes/node_modules/moment/locale/cv.js", + "./cy": "../eyes/node_modules/moment/locale/cy.js", + "./cy.js": "../eyes/node_modules/moment/locale/cy.js", + "./da": "../eyes/node_modules/moment/locale/da.js", + "./da.js": "../eyes/node_modules/moment/locale/da.js", + "./de": "../eyes/node_modules/moment/locale/de.js", + "./de-at": "../eyes/node_modules/moment/locale/de-at.js", + "./de-at.js": "../eyes/node_modules/moment/locale/de-at.js", + "./de-ch": "../eyes/node_modules/moment/locale/de-ch.js", + "./de-ch.js": "../eyes/node_modules/moment/locale/de-ch.js", + "./de.js": "../eyes/node_modules/moment/locale/de.js", + "./dv": "../eyes/node_modules/moment/locale/dv.js", + "./dv.js": "../eyes/node_modules/moment/locale/dv.js", + "./el": "../eyes/node_modules/moment/locale/el.js", + "./el.js": "../eyes/node_modules/moment/locale/el.js", + "./en-au": "../eyes/node_modules/moment/locale/en-au.js", + "./en-au.js": "../eyes/node_modules/moment/locale/en-au.js", + "./en-ca": "../eyes/node_modules/moment/locale/en-ca.js", + "./en-ca.js": "../eyes/node_modules/moment/locale/en-ca.js", + "./en-gb": "../eyes/node_modules/moment/locale/en-gb.js", + "./en-gb.js": "../eyes/node_modules/moment/locale/en-gb.js", + "./en-ie": "../eyes/node_modules/moment/locale/en-ie.js", + "./en-ie.js": "../eyes/node_modules/moment/locale/en-ie.js", + "./en-il": "../eyes/node_modules/moment/locale/en-il.js", + "./en-il.js": "../eyes/node_modules/moment/locale/en-il.js", + "./en-in": "../eyes/node_modules/moment/locale/en-in.js", + "./en-in.js": "../eyes/node_modules/moment/locale/en-in.js", + "./en-nz": "../eyes/node_modules/moment/locale/en-nz.js", + "./en-nz.js": "../eyes/node_modules/moment/locale/en-nz.js", + "./en-sg": "../eyes/node_modules/moment/locale/en-sg.js", + "./en-sg.js": "../eyes/node_modules/moment/locale/en-sg.js", + "./eo": "../eyes/node_modules/moment/locale/eo.js", + "./eo.js": "../eyes/node_modules/moment/locale/eo.js", + "./es": "../eyes/node_modules/moment/locale/es.js", + "./es-do": "../eyes/node_modules/moment/locale/es-do.js", + "./es-do.js": "../eyes/node_modules/moment/locale/es-do.js", + "./es-mx": "../eyes/node_modules/moment/locale/es-mx.js", + "./es-mx.js": "../eyes/node_modules/moment/locale/es-mx.js", + "./es-us": "../eyes/node_modules/moment/locale/es-us.js", + "./es-us.js": "../eyes/node_modules/moment/locale/es-us.js", + "./es.js": "../eyes/node_modules/moment/locale/es.js", + "./et": "../eyes/node_modules/moment/locale/et.js", + "./et.js": "../eyes/node_modules/moment/locale/et.js", + "./eu": "../eyes/node_modules/moment/locale/eu.js", + "./eu.js": "../eyes/node_modules/moment/locale/eu.js", + "./fa": "../eyes/node_modules/moment/locale/fa.js", + "./fa.js": "../eyes/node_modules/moment/locale/fa.js", + "./fi": "../eyes/node_modules/moment/locale/fi.js", + "./fi.js": "../eyes/node_modules/moment/locale/fi.js", + "./fil": "../eyes/node_modules/moment/locale/fil.js", + "./fil.js": "../eyes/node_modules/moment/locale/fil.js", + "./fo": "../eyes/node_modules/moment/locale/fo.js", + "./fo.js": "../eyes/node_modules/moment/locale/fo.js", + "./fr": "../eyes/node_modules/moment/locale/fr.js", + "./fr-ca": "../eyes/node_modules/moment/locale/fr-ca.js", + "./fr-ca.js": "../eyes/node_modules/moment/locale/fr-ca.js", + "./fr-ch": "../eyes/node_modules/moment/locale/fr-ch.js", + "./fr-ch.js": "../eyes/node_modules/moment/locale/fr-ch.js", + "./fr.js": "../eyes/node_modules/moment/locale/fr.js", + "./fy": "../eyes/node_modules/moment/locale/fy.js", + "./fy.js": "../eyes/node_modules/moment/locale/fy.js", + "./ga": "../eyes/node_modules/moment/locale/ga.js", + "./ga.js": "../eyes/node_modules/moment/locale/ga.js", + "./gd": "../eyes/node_modules/moment/locale/gd.js", + "./gd.js": "../eyes/node_modules/moment/locale/gd.js", + "./gl": "../eyes/node_modules/moment/locale/gl.js", + "./gl.js": "../eyes/node_modules/moment/locale/gl.js", + "./gom-deva": "../eyes/node_modules/moment/locale/gom-deva.js", + "./gom-deva.js": "../eyes/node_modules/moment/locale/gom-deva.js", + "./gom-latn": "../eyes/node_modules/moment/locale/gom-latn.js", + "./gom-latn.js": "../eyes/node_modules/moment/locale/gom-latn.js", + "./gu": "../eyes/node_modules/moment/locale/gu.js", + "./gu.js": "../eyes/node_modules/moment/locale/gu.js", + "./he": "../eyes/node_modules/moment/locale/he.js", + "./he.js": "../eyes/node_modules/moment/locale/he.js", + "./hi": "../eyes/node_modules/moment/locale/hi.js", + "./hi.js": "../eyes/node_modules/moment/locale/hi.js", + "./hr": "../eyes/node_modules/moment/locale/hr.js", + "./hr.js": "../eyes/node_modules/moment/locale/hr.js", + "./hu": "../eyes/node_modules/moment/locale/hu.js", + "./hu.js": "../eyes/node_modules/moment/locale/hu.js", + "./hy-am": "../eyes/node_modules/moment/locale/hy-am.js", + "./hy-am.js": "../eyes/node_modules/moment/locale/hy-am.js", + "./id": "../eyes/node_modules/moment/locale/id.js", + "./id.js": "../eyes/node_modules/moment/locale/id.js", + "./is": "../eyes/node_modules/moment/locale/is.js", + "./is.js": "../eyes/node_modules/moment/locale/is.js", + "./it": "../eyes/node_modules/moment/locale/it.js", + "./it-ch": "../eyes/node_modules/moment/locale/it-ch.js", + "./it-ch.js": "../eyes/node_modules/moment/locale/it-ch.js", + "./it.js": "../eyes/node_modules/moment/locale/it.js", + "./ja": "../eyes/node_modules/moment/locale/ja.js", + "./ja.js": "../eyes/node_modules/moment/locale/ja.js", + "./jv": "../eyes/node_modules/moment/locale/jv.js", + "./jv.js": "../eyes/node_modules/moment/locale/jv.js", + "./ka": "../eyes/node_modules/moment/locale/ka.js", + "./ka.js": "../eyes/node_modules/moment/locale/ka.js", + "./kk": "../eyes/node_modules/moment/locale/kk.js", + "./kk.js": "../eyes/node_modules/moment/locale/kk.js", + "./km": "../eyes/node_modules/moment/locale/km.js", + "./km.js": "../eyes/node_modules/moment/locale/km.js", + "./kn": "../eyes/node_modules/moment/locale/kn.js", + "./kn.js": "../eyes/node_modules/moment/locale/kn.js", + "./ko": "../eyes/node_modules/moment/locale/ko.js", + "./ko.js": "../eyes/node_modules/moment/locale/ko.js", + "./ku": "../eyes/node_modules/moment/locale/ku.js", + "./ku.js": "../eyes/node_modules/moment/locale/ku.js", + "./ky": "../eyes/node_modules/moment/locale/ky.js", + "./ky.js": "../eyes/node_modules/moment/locale/ky.js", + "./lb": "../eyes/node_modules/moment/locale/lb.js", + "./lb.js": "../eyes/node_modules/moment/locale/lb.js", + "./lo": "../eyes/node_modules/moment/locale/lo.js", + "./lo.js": "../eyes/node_modules/moment/locale/lo.js", + "./lt": "../eyes/node_modules/moment/locale/lt.js", + "./lt.js": "../eyes/node_modules/moment/locale/lt.js", + "./lv": "../eyes/node_modules/moment/locale/lv.js", + "./lv.js": "../eyes/node_modules/moment/locale/lv.js", + "./me": "../eyes/node_modules/moment/locale/me.js", + "./me.js": "../eyes/node_modules/moment/locale/me.js", + "./mi": "../eyes/node_modules/moment/locale/mi.js", + "./mi.js": "../eyes/node_modules/moment/locale/mi.js", + "./mk": "../eyes/node_modules/moment/locale/mk.js", + "./mk.js": "../eyes/node_modules/moment/locale/mk.js", + "./ml": "../eyes/node_modules/moment/locale/ml.js", + "./ml.js": "../eyes/node_modules/moment/locale/ml.js", + "./mn": "../eyes/node_modules/moment/locale/mn.js", + "./mn.js": "../eyes/node_modules/moment/locale/mn.js", + "./mr": "../eyes/node_modules/moment/locale/mr.js", + "./mr.js": "../eyes/node_modules/moment/locale/mr.js", + "./ms": "../eyes/node_modules/moment/locale/ms.js", + "./ms-my": "../eyes/node_modules/moment/locale/ms-my.js", + "./ms-my.js": "../eyes/node_modules/moment/locale/ms-my.js", + "./ms.js": "../eyes/node_modules/moment/locale/ms.js", + "./mt": "../eyes/node_modules/moment/locale/mt.js", + "./mt.js": "../eyes/node_modules/moment/locale/mt.js", + "./my": "../eyes/node_modules/moment/locale/my.js", + "./my.js": "../eyes/node_modules/moment/locale/my.js", + "./nb": "../eyes/node_modules/moment/locale/nb.js", + "./nb.js": "../eyes/node_modules/moment/locale/nb.js", + "./ne": "../eyes/node_modules/moment/locale/ne.js", + "./ne.js": "../eyes/node_modules/moment/locale/ne.js", + "./nl": "../eyes/node_modules/moment/locale/nl.js", + "./nl-be": "../eyes/node_modules/moment/locale/nl-be.js", + "./nl-be.js": "../eyes/node_modules/moment/locale/nl-be.js", + "./nl.js": "../eyes/node_modules/moment/locale/nl.js", + "./nn": "../eyes/node_modules/moment/locale/nn.js", + "./nn.js": "../eyes/node_modules/moment/locale/nn.js", + "./oc-lnc": "../eyes/node_modules/moment/locale/oc-lnc.js", + "./oc-lnc.js": "../eyes/node_modules/moment/locale/oc-lnc.js", + "./pa-in": "../eyes/node_modules/moment/locale/pa-in.js", + "./pa-in.js": "../eyes/node_modules/moment/locale/pa-in.js", + "./pl": "../eyes/node_modules/moment/locale/pl.js", + "./pl.js": "../eyes/node_modules/moment/locale/pl.js", + "./pt": "../eyes/node_modules/moment/locale/pt.js", + "./pt-br": "../eyes/node_modules/moment/locale/pt-br.js", + "./pt-br.js": "../eyes/node_modules/moment/locale/pt-br.js", + "./pt.js": "../eyes/node_modules/moment/locale/pt.js", + "./ro": "../eyes/node_modules/moment/locale/ro.js", + "./ro.js": "../eyes/node_modules/moment/locale/ro.js", + "./ru": "../eyes/node_modules/moment/locale/ru.js", + "./ru.js": "../eyes/node_modules/moment/locale/ru.js", + "./sd": "../eyes/node_modules/moment/locale/sd.js", + "./sd.js": "../eyes/node_modules/moment/locale/sd.js", + "./se": "../eyes/node_modules/moment/locale/se.js", + "./se.js": "../eyes/node_modules/moment/locale/se.js", + "./si": "../eyes/node_modules/moment/locale/si.js", + "./si.js": "../eyes/node_modules/moment/locale/si.js", + "./sk": "../eyes/node_modules/moment/locale/sk.js", + "./sk.js": "../eyes/node_modules/moment/locale/sk.js", + "./sl": "../eyes/node_modules/moment/locale/sl.js", + "./sl.js": "../eyes/node_modules/moment/locale/sl.js", + "./sq": "../eyes/node_modules/moment/locale/sq.js", + "./sq.js": "../eyes/node_modules/moment/locale/sq.js", + "./sr": "../eyes/node_modules/moment/locale/sr.js", + "./sr-cyrl": "../eyes/node_modules/moment/locale/sr-cyrl.js", + "./sr-cyrl.js": "../eyes/node_modules/moment/locale/sr-cyrl.js", + "./sr.js": "../eyes/node_modules/moment/locale/sr.js", + "./ss": "../eyes/node_modules/moment/locale/ss.js", + "./ss.js": "../eyes/node_modules/moment/locale/ss.js", + "./sv": "../eyes/node_modules/moment/locale/sv.js", + "./sv.js": "../eyes/node_modules/moment/locale/sv.js", + "./sw": "../eyes/node_modules/moment/locale/sw.js", + "./sw.js": "../eyes/node_modules/moment/locale/sw.js", + "./ta": "../eyes/node_modules/moment/locale/ta.js", + "./ta.js": "../eyes/node_modules/moment/locale/ta.js", + "./te": "../eyes/node_modules/moment/locale/te.js", + "./te.js": "../eyes/node_modules/moment/locale/te.js", + "./tet": "../eyes/node_modules/moment/locale/tet.js", + "./tet.js": "../eyes/node_modules/moment/locale/tet.js", + "./tg": "../eyes/node_modules/moment/locale/tg.js", + "./tg.js": "../eyes/node_modules/moment/locale/tg.js", + "./th": "../eyes/node_modules/moment/locale/th.js", + "./th.js": "../eyes/node_modules/moment/locale/th.js", + "./tk": "../eyes/node_modules/moment/locale/tk.js", + "./tk.js": "../eyes/node_modules/moment/locale/tk.js", + "./tl-ph": "../eyes/node_modules/moment/locale/tl-ph.js", + "./tl-ph.js": "../eyes/node_modules/moment/locale/tl-ph.js", + "./tlh": "../eyes/node_modules/moment/locale/tlh.js", + "./tlh.js": "../eyes/node_modules/moment/locale/tlh.js", + "./tr": "../eyes/node_modules/moment/locale/tr.js", + "./tr.js": "../eyes/node_modules/moment/locale/tr.js", + "./tzl": "../eyes/node_modules/moment/locale/tzl.js", + "./tzl.js": "../eyes/node_modules/moment/locale/tzl.js", + "./tzm": "../eyes/node_modules/moment/locale/tzm.js", + "./tzm-latn": "../eyes/node_modules/moment/locale/tzm-latn.js", + "./tzm-latn.js": "../eyes/node_modules/moment/locale/tzm-latn.js", + "./tzm.js": "../eyes/node_modules/moment/locale/tzm.js", + "./ug-cn": "../eyes/node_modules/moment/locale/ug-cn.js", + "./ug-cn.js": "../eyes/node_modules/moment/locale/ug-cn.js", + "./uk": "../eyes/node_modules/moment/locale/uk.js", + "./uk.js": "../eyes/node_modules/moment/locale/uk.js", + "./ur": "../eyes/node_modules/moment/locale/ur.js", + "./ur.js": "../eyes/node_modules/moment/locale/ur.js", + "./uz": "../eyes/node_modules/moment/locale/uz.js", + "./uz-latn": "../eyes/node_modules/moment/locale/uz-latn.js", + "./uz-latn.js": "../eyes/node_modules/moment/locale/uz-latn.js", + "./uz.js": "../eyes/node_modules/moment/locale/uz.js", + "./vi": "../eyes/node_modules/moment/locale/vi.js", + "./vi.js": "../eyes/node_modules/moment/locale/vi.js", + "./x-pseudo": "../eyes/node_modules/moment/locale/x-pseudo.js", + "./x-pseudo.js": "../eyes/node_modules/moment/locale/x-pseudo.js", + "./yo": "../eyes/node_modules/moment/locale/yo.js", + "./yo.js": "../eyes/node_modules/moment/locale/yo.js", + "./zh-cn": "../eyes/node_modules/moment/locale/zh-cn.js", + "./zh-cn.js": "../eyes/node_modules/moment/locale/zh-cn.js", + "./zh-hk": "../eyes/node_modules/moment/locale/zh-hk.js", + "./zh-hk.js": "../eyes/node_modules/moment/locale/zh-hk.js", + "./zh-mo": "../eyes/node_modules/moment/locale/zh-mo.js", + "./zh-mo.js": "../eyes/node_modules/moment/locale/zh-mo.js", + "./zh-tw": "../eyes/node_modules/moment/locale/zh-tw.js", + "./zh-tw.js": "../eyes/node_modules/moment/locale/zh-tw.js" +}; + + +function webpackContext(req) { + var id = webpackContextResolve(req); + return __webpack_require__(id); +} +function webpackContextResolve(req) { + if(!__webpack_require__.o(map, req)) { + var e = new Error("Cannot find module '" + req + "'"); + e.code = 'MODULE_NOT_FOUND'; + throw e; + } + return map[req]; +} +webpackContext.keys = function webpackContextKeys() { + return Object.keys(map); +}; +webpackContext.resolve = webpackContextResolve; +module.exports = webpackContext; +webpackContext.id = "../eyes/node_modules/moment/locale sync recursive ^\\.\\/.*$"; + +/***/ }), + +/***/ "../eyes/src/app.js": +/*!**************************!*\ + !*** ../eyes/src/app.js ***! + \**************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "BaseApp": function() { return /* binding */ BaseApp; } +/* harmony export */ }); +/* harmony import */ var moment_timezone__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! moment-timezone */ "../eyes/node_modules/moment-timezone/index.js"); +/* harmony import */ var moment_timezone__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(moment_timezone__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var _data_entity_info_json__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./data/entity_info.json */ "../eyes/src/data/entity_info.json"); +/* harmony import */ var _data_entity_spheroid_layers_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./data/entity_spheroid_layers.js */ "../eyes/src/data/entity_spheroid_layers.js"); +/* harmony import */ var _data_entity_spheroid_features_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./data/entity_spheroid_features.js */ "../eyes/src/data/entity_spheroid_features.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./internal */ "../eyes/src/internal.js"); +// Import moment + + +// Import Pioneer libraries + + + +// Eyes CSS + + +// Import data + + + + +// Import locals + + +/** + * The main application class. + */ +class BaseApp { + /** + * Sets the subclass of BaseApp to be instantiated. It should be called in the main script outside of any function, by the app subclass. + */ + static setAppClass() { + BaseApp._appClass = this; + } + + /** + * Constructs the Base application. + * @param {Map} componentTypes + */ + constructor(componentTypes) { + // Make this global. + // @ts-ignore // vscode ts doesn't yet support globals in its jsdoc. + window.app = this; + + /** + * Pioneer engine. + * @type {Pioneer.Engine} + * @private + */ + this._pioneer = null; + + /** + * Pioneer scene. + * @type {Pioneer.Scene} + * @private + */ + this._scene = null; + + /** + * The router. + * @type {RouteManager} + * @private + */ + this._router = null; + + /** + * Root UI element + * @type {HTMLElement} + * @private + */ + this._element = null; + + /** + * The dynamic UI element. + * @type {HTMLElement} + * @private + */ + this._dynamicElement = null; + + /** + * Time limits info for app. + * @type {object} + */ + this._timeInfo = {}; + + /** + * Information for creating scene. + * @type {import('./internal').SceneInfo} + */ + this._sceneInfo = undefined; + + /** + * Camera scripts instance. + * @type {CameraScripts} + */ + this._cameraScripts = new _internal__WEBPACK_IMPORTED_MODULE_7__.CameraScripts(this); + + /** + * Information for creating components. + * @type {Array} + */ + this._componentInfo = []; + + /** + * Component types. + * @type {Map} + * @private + */ + this._componentTypes = componentTypes; + + /** + * List of all managers in app. + * @type {Object} + * @private + */ + this._managers = {}; + + /** + * List of all components in app. + * @type {Object} + * @private + */ + this._components = {}; + + /** + * List of all views in app. + * @type {Object} + * @private + */ + this._views = {}; + + /** + * Info to add views. + * @type {Array} + * @private + */ + this._viewInfo = []; + + /** + * Map of all view classes. + * @type {object} + * @private + */ + this._viewClasses = {}; + + /** + * List of callbacks to call every frame. + * @type {Array} + * @private + */ + this._updates = []; + + /** + * Is touch functionality available. + * @type {boolean} + */ + this.isTouch = null; + + /** + * Is hover functionality available. + * @type {boolean} + */ + this.canHover = null; + + /** + * Is the app currently searching. + * @type {boolean} + * @private + */ + this._isSearching = null; + + /** + * Starting position of touch. + * @type {Object} + */ + this._touchStartPos = { x: 0, y: 0 }; + + /** + * Is in dragging mode or not. + * @type {boolean} + */ + this._dragging = false; + + /** + * Set an additional reference to the entityInfo to allow early access to it if needed. + */ + this._entityInfo = _data_entity_info_json__WEBPACK_IMPORTED_MODULE_4__; + + this.bindFunctions([ + 'resize', + 'onTouchStart', + 'onTouchMove', + 'onTouchEnd', + 'update' + ]); + + // Scroll / Drag detection + this._touchCount = 0; + this._scrollable = false; + this._touchMax = false; + window.addEventListener('touchstart', this.onTouchStart, false); + window.addEventListener('touchmove', this.onTouchMove, { passive: false }); + window.addEventListener('touchend', this.onTouchEnd); + + // Update css vh variable + const vh = window.innerHeight; + document.documentElement.style.setProperty('--vh', `${vh}px`); + window.addEventListener('resize', this.resize, false); + + this.resize(); + } + + /** + * Inits the app. + * @returns {Promise} + */ + async init() { + // Store root UI element + this._element = document.getElementById('ui'); + this._dynamicElement = document.getElementById('dynamic-ui'); + this._staticElement = document.getElementById('static-ui'); + + // Instantiate Pioneer engine. + const rootDiv = /** @type {HTMLDivElement} */(document.getElementById('pioneer')); + rootDiv.style.position = 'absolute'; + this._pioneer = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Engine(rootDiv); + + // Set Pioneer configurations. + if (typeof window.config['staticAssetsUrl'] === 'string') { + this._pioneer.getDownloader().setReplacement('STATIC_ASSETS_URL', window.config['staticAssetsUrl']); + } + if (typeof window.config['dynamicAssetsUrl'] === 'string') { + this._pioneer.getDownloader().setReplacement('DYNAMIC_ASSETS_URL', window.config['dynamicAssetsUrl']); + } + if (typeof window.config['animdataUrl'] === 'string') { + this._pioneer.getDownloader().setReplacement('ANIMDATA_URL', window.config['animdataUrl']); + } + this._pioneer.getConfig().setValue('fontFamily', 'Raleway'); + this._pioneer.getConfig().setValue('fontSize', 16); + this._pioneer.getConfig().setValue('pbr', true); + + // Register custom components. + this._pioneer.registerComponentType('distanceLine', _internal__WEBPACK_IMPORTED_MODULE_7__.DistanceLineComponent); + this._pioneer.registerComponentType('orbiterLineOfSight', _internal__WEBPACK_IMPORTED_MODULE_7__.OrbiterLineOfSightComponent); + this._pioneer.registerComponentType('wmts', pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.WMTSComponent); + this._pioneer.registerComponentType('discGrid', pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.DiscGridComponent); + this._pioneer.registerComponentType('torus', pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.TorusComponent); + this._pioneer.registerComponentType('constellations', pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.ConstellationsComponent); + + // Register custom controllers. + this._pioneer.registerControllerType('positionSum', pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.PositionSumController); + this._pioneer.registerControllerType('zoomFit', pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.ZoomFitController); + this._pioneer.registerComponentType('orbitLine', pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.OrbitLineComponent); + + // Set the time to 'now' + this._pioneer.setTime(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now()); + // Set the timerate to realtime + this._pioneer.setTimeRate(1.0); + + await this.createManagers(); + await this.createComponents(); + + // Setup the app routes. + this.setUpRoutes(); + + // Setup the app update functions. + this.setUpUpdates(); + + // Start the router. + /** @type {RouteManager} */(this.getManager('router')).start(); + + const { spout } = this.getManager('router').configs; + if (spout === true) { + const { spoutGlobe, spoutRenderWidth, spoutGlobeDistance, spoutTarget, spoutFontSize, spoutLonAngleOffset, spoutAlignToNorthPole } = this.getManager('router').configs; + const target = spoutTarget || await this.getManager('spout').getSpoutCameraTargetEntity(this.getManager('router').currentRoute.params); + this.getManager('spout').enableSpout(spoutGlobe, spoutRenderWidth, spoutGlobeDistance, target, spoutFontSize, spoutLonAngleOffset, spoutAlignToNorthPole); + } + } + + /** + * GETTERS and SETTERS ----------------------------------------------------- + */ + + /** + * Gets Pioneer engine. + * @returns {Pioneer.Engine} + */ + get pioneer() { + return this._pioneer; + } + + /** + * Gets Pioneer scene. + * @returns {Pioneer.Scene} + */ + get scene() { + return this._scene; + } + + /** + * Sets Pioneer scene. + * @param {Pioneer.Scene} scene + */ + set scene(scene) { + this._scene = scene; + } + + /** + * Gets CameraScripts instance. + * @returns {CameraScripts} + */ + get cameraScripts() { + return this._cameraScripts; + } + + /** + * Gets the dynamic UI element. + * @returns {HTMLElement} + */ + get dynamicElement() { + return this._dynamicElement; + } + + /** + * Gets the static UI element. + * @returns {HTMLElement} + */ + get staticElement() { + return this._staticElement; + } + + /** + * Gets scene info. + * @returns {object} + */ + get sceneInfo() { + return this._sceneInfo; + } + + /** + * Gets root UI element. + * @returns {HTMLElement} + */ + get element() { + return this._element; + } + + /** + * Sets root UI element. + * @param {HTMLElement} element + * @protected + */ + set element(element) { + this._element = element; + } + + /** + * Gets if we're currently searching. + * @returns {boolean} + */ + get isSearching() { + return this._isSearching; + } + + /** + * Sets if we're currently searching. + */ + set isSearching(isSearching) { + this._isSearching = isSearching; + } + + /** + * MANAGERS ---------------------------------------------------------------- + */ + + /** + * Adds a manager to the app. + * @template {BaseManager} ManagerType + * @param {string} name - Unique name for the manager + * @param {new (baseApp: BaseApp, ...args: any[]) => ManagerType} TypeConstructor + * @param {any[]} args - List of arguments + * @returns {ManagerType} + */ + addManager(name, TypeConstructor, ...args) { + // TODO Check for TypeConstructor is string to use Types.get + if (this._managers[name] === undefined) { + this._managers[name] = new TypeConstructor(this, ...args); + } + return /** @type {ManagerType} */(this._managers[name]); + } + + /** + * Removes a manager from the app. + * @param {string} name - Unique name for the manager + */ + removeManager(name) { + if (this._managers[name] !== undefined) { + this._managers[name].destroy(); + delete this._managers[name]; + } + } + + /** + * Gets a manager. + * @param {string} name - Unique name + * @returns {BaseManager} + */ + getManager(name) { + if (this._managers[name] !== undefined) { + return this._managers[name]; + } + return null; + } + + /** + * Creates app managers. + */ + async createManagers() { + // Time manager + const timeManagerClass = _internal__WEBPACK_IMPORTED_MODULE_7__.Types.get('TimeManager'); + const timeMgr = this.addManager('time', timeManagerClass); + const min = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().tz('1949-12-31', 'Etc/UTC'); // Dec 31st 1949 + const max = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().tz('2049-12-31', 'Etc/UTC'); // Dec 31st 2049 + timeMgr.setDefaultLimits({ min, max }); + timeMgr.setLimits({ min, max }); + + // Content manager + const contentMgr = this.addManager('content', _internal__WEBPACK_IMPORTED_MODULE_7__.ContentManager); + contentMgr.setEntityList(_data_entity_info_json__WEBPACK_IMPORTED_MODULE_4__); + contentMgr.setSpheroidLayers(_data_entity_spheroid_layers_js__WEBPACK_IMPORTED_MODULE_5__["default"]); + contentMgr.setSpheroidFeatures(_data_entity_spheroid_features_js__WEBPACK_IMPORTED_MODULE_6__["default"]); + + contentMgr.setFolders({ + description: 'descriptions/', + event: 'events/', + stories: 'stories/' + }); + + // Scene manager + const sceneManager = this.addManager('scene', _internal__WEBPACK_IMPORTED_MODULE_7__.SceneManager); + this._scene = sceneManager.main; + // sceneManager.loadWMTSFromJSON(entityWMTS); + + // Layer manager + const layerManager = this.addManager('layer', _internal__WEBPACK_IMPORTED_MODULE_7__.LayerManager); + const SATELLITE_GROUPS = ['CYGNSS', 'TROPICS', 'STARLING', 'PREFIRE']; + layerManager.addLayer('ui', { + name: 'User Interface' + }); + layerManager.addLayer('trails', { + name: 'Trails' + }); + layerManager.addLayer('orbits', { + name: 'Orbits' + }); + layerManager.addLayer('labels', { + name: 'Labels' + }); + layerManager.addLayer('icons', { + name: 'Icons' + }); + layerManager.addLayer('planets', { + name: 'Planets', + categories: 'Planet' + }); + layerManager.addLayer('asteroids', { + name: 'Asteroids', + categories: 'Asteroid', + defaultVisibility: false + }); + layerManager.addLayer('comets', { + name: 'Comets', + categories: 'Comet', + defaultVisibility: false + }); + layerManager.addLayer('dwarfPlanets', { + name: 'Dwarf Planets', + categories: 'Dwarf Planet', + defaultVisibility: false + }); + layerManager.addLayer('spacecraft', { + name: 'Spacecraft', + categories: 'Spacecraft', + sublayers: ['orbiters', 'landers', 'satelliteGroup'] + }); + layerManager.addLayer('majorMoons', { + name: 'Major Moons', + categories: 'Major Moon', + group: 'moons' + }); + layerManager.addLayer('minorMoons', { + name: 'Minor Moons', + categories: 'Minor Moon', + defaultVisibility: false, + group: 'moons' + }); + layerManager.addLayer('orbiters', { + name: 'Orbiters', + categories: 'Orbiter', + group: 'spacecraft' + }); + layerManager.addLayer('satelliteGroup', { + name: 'Satellite Group', + categories: SATELLITE_GROUPS, + group: 'spacecraft', + defaultVisibility: true + }); + layerManager.addLayer('landers', { + name: 'Landers', + categories: ['Lander', 'Rover', 'Landing site'], + group: 'spacecraft' + }); + layerManager.addLayer('starfield', { + name: 'Star Field', + defaultVisibility: false + }); + layerManager.addLayer('heliosphere', { + name: 'Heliosphere', + defaultVisibility: false + }); + layerManager.addLayer('constellations', { + name: 'Constellations', + categories: 'Constellations', + defaultVisibility: false + }); + + // Camera Manager + const cameraManager = this.addManager('camera', _internal__WEBPACK_IMPORTED_MODULE_7__.CameraManager, this._scene); + this._cameraScripts.setCameraManager(cameraManager); + cameraManager.createViewportAndCamera(this._scene); + + // Search manager + this.addManager('search', _internal__WEBPACK_IMPORTED_MODULE_7__.SearchManager, { + keys: [ + { + name: 'iauName', + weight: 0.99 + }, + { + name: 'displayName', + weight: 0.98 + }, + { + name: 'altName', + weight: 0.98 + }, + { + name: 'keywords', + weight: 0.3 + }, + { + name: 'category', + weight: 0.3 + } + ] + }); + + // Comparison Manager + this.addManager('comparison', _internal__WEBPACK_IMPORTED_MODULE_7__.ComparisonManager); + + // Label manager + const labelManagerClass = _internal__WEBPACK_IMPORTED_MODULE_7__.Types.get('LabelManager'); + const labelManager = this.addManager('label', labelManagerClass, this._scene); + labelManager.setWeights(contentMgr.getEntityList()); + labelManager.setAlgorithm(labelManagerClass.Quadtree); + + // Selection Manager + const selectionManagerClass = _internal__WEBPACK_IMPORTED_MODULE_7__.Types.get('SelectionManager'); + const selectionManager = this.addManager('selection', selectionManagerClass, this._scene); + selectionManager.init3Dcallback(cameraManager); + labelManager.registerCallback('labelclicked', selectionManager.setSuppress); + + // Route manager + const routeManager = this.addManager('router', _internal__WEBPACK_IMPORTED_MODULE_7__.RouteManager); + routeManager.setValidQueries(['time', 'rate']); + routeManager.init(); + routeManager.addConfigs({ + embed: undefined, + kiosk: undefined, + logo: undefined, + detailPanel: undefined, + content: undefined, + featured: undefined, + menu: undefined, + locked: undefined, + surfaceMapTiling: undefined, + hd: undefined, + lighting: undefined, + hideExternalLinks: undefined, + hideFullScreenToggle: undefined, + maxSessionTime: undefined, + maxInactivityTime: undefined, + forceRestart: undefined, + noKeyboard: undefined, + search: undefined, + collapseSettingsOptions: undefined, + shareButton: undefined, + spout: undefined, + spoutGlobe: undefined, + spoutRenderWidth: undefined, + spoutGlobeDistance: undefined, + spoutTarget: undefined, + spoutFontSize: undefined, + spoutLonAngleOffset: undefined, + spoutAlignToNorthPole: undefined, + interactPrompt: undefined + }); + + // Trail manager + const trailManagerClass = _internal__WEBPACK_IMPORTED_MODULE_7__.Types.get('TrailManager'); + const trailManager = this.addManager('trail', trailManagerClass, this._scene); + labelManager.registerCallback('hoverchange', trailManager.onHoverChange); + + // Spout manager + this.addManager('spout', _internal__WEBPACK_IMPORTED_MODULE_7__.SpoutManager); + + // Add callbacks for layer manager + layerManager.addCallback('trails', trailManager.toggleTrails); + layerManager.addCallback('orbits', trailManager.toggleOrbits); + layerManager.addCallback('labels', labelManager.toggleLabels); + layerManager.addCallback('icons', labelManager.toggleIcons); + layerManager.addCallback('starfield', sceneManager.toggleStarfield); + layerManager.addCallback('heliosphere', sceneManager.toggleHeliosphere); + layerManager.addCallback('constellations', sceneManager.toggleConstellations); + + // Add views for this app + this.addViews(); + + // Setup viewport and camera if needed + this.setUpViewportAndCamera(); + + // Define main scene + // Populate scene with entities + await this.setUpScene(); + + // Setup managers + this.setUpManagers(); + + // Setup components + await this.setUpComponents(); + + // Add keyboard shortcuts + this.addShortcuts(); + + // Run update every frame + this._pioneer.addCallback(this.update, true); + } + + /** + * Set up managers for app. + */ + setUpManagers() { + const scene = this.scene; + const trailManager = this.getManager('trail'); + const timeManager = this.getManager('time'); + + // Set the default time limits and time limits for the app + let { limits } = this._timeInfo; + if (!limits) { + limits = { + min: moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.constants.minDate), + max: moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.constants.maxDate) + }; + } + else { + limits.min = !('min' in limits) || limits.min === '-Infinity' + ? moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.constants.minDate) + : this.getManager('time').parseTime(limits.min); + limits.max = !('max' in limits) || limits.max === 'Infinity' + ? moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.constants.maxDate) + : this.getManager('time').parseTime(limits.max); + } + timeManager.setDefaultLimits(limits); + timeManager.setLimits(limits); + + // Set the scene for managers + this.getManager('label').setScene(scene); + this.getManager('selection').setScene(scene); + trailManager.setScene(scene); + + // Update trails to new entities + trailManager.ids = Array.from(this.getManager('scene').getEntitiesNames()); + trailManager.setColor(trailManager.ids); + } + + /** + * COMPONENTS -------------------------------------------------------------- + */ + + /** + * Adds a component to the app. + * @template {BaseComponent} ComponentType + * @param {string} name - Unique name for the component + * @param {new (baseApp: BaseApp, ...args: any[]) => ComponentType} TypeConstructor - Class name + * @param {any[]} args - List of arguments + * @returns {Promise} + */ + async addComponent(name, TypeConstructor, ...args) { + // TODO Check for TypeConstructor is string to use Types.get + if (this._components[name] !== undefined) { + throw new Error(`Component ${name} was already added.`); + } + const component = new TypeConstructor(this, ...args); + this._components[name] = component; + // Check for async init function + await component.init(); + return component; + } + + /** + * Create a component of a class for a placeholder in an element. + * @template {BaseComponent} ComponentType + * @param {object} componentClass + * @param {string} componentClass.name - Unique name for the component. + * @param {new (baseApp: BaseApp, ...args: any[]) => ComponentType} componentClass.type - Class name. + * @param {any[]} [componentClass.args=[]] - List of arguments except options for class constructor. + * @param {object} [componentClass.options={}] - Options for class constructor, passed as the last argument. + * @param {HTMLElement | Document} [element=document] - Element to search for all placeholders inside it. + * @param {HTMLElement} [placeholder=null] - Placeholder element to replace component with. + * @returns {Promise} + */ + async addComponentWithPlaceholder(componentClass, element = document, placeholder = null) { + if (!componentClass.args) { + componentClass.args = []; + } + if (!componentClass.options) { + componentClass.options = {}; + } + // Get placeholder element with same dataset name as component name + // Or get first placeholder element with component's class name as tag + if (!placeholder) { + const placeholders = Array.from(element.getElementsByTagName(componentClass.type.name)); + // Find a matching placeholder + placeholder = /** @type {HTMLElement} */(placeholders.find(item => item instanceof HTMLElement && item.id === componentClass.name)); + if (!placeholder && placeholders[0] instanceof HTMLElement) { + placeholder = placeholders[0]; + } + if (!placeholder) { + return Promise.reject(new Error(`addComponentWithPlaceholder: There is no placeholder element for ${componentClass.type}`)); + } + } + // Get options from placeholder's dataset + Object.assign(componentClass.options, _internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.convertObjType({ ...placeholder.dataset })); + // Create and add component to app + const component = await this.addComponent(componentClass.name, componentClass.type, ...componentClass.args, componentClass.options); + // Replace placeholder element with component element in UI + component.setParent(placeholder.parentElement, placeholder); + + return component; + } + + /** + * Removes a component from the app. + * @param {string} name - Unique name for the component + * @returns {boolean} - Succeed or fail to remove + */ + removeComponent(name) { + if (this._components[name] !== undefined) { + this._components[name].destroy(); + delete this._components[name]; + return true; + } + + return false; + } + + /** + * Remove app components. + */ + removeComponents() { + for (let i = 0; i < this._componentInfo.length; i++) { + this.removeComponent(this._componentInfo[i].name); + } + } + + /** + * Gets a component. + * @param {string} name - Unique name + * @returns {BaseComponent} + */ + getComponent(name) { + if (this._components[name] !== undefined) { + return this._components[name]; + } + return null; + } + + /** + * Gets all components. + * @returns {object} + */ + getComponents() { + return this._components; + } + + /** + * Creates static UI components. + */ + async createComponents() { + const components = [ + { name: 'loadIcon', type: 'LoadIcon' }, + { name: 'overlay', type: 'Overlay', options: { isOpenButtonVisible: false } } + ]; + + for (let i = 0; i < components.length; i++) { + const { name, type, hasPlaceholder, args, options, postCreationFunction } = components[i]; + const componentClass = _internal__WEBPACK_IMPORTED_MODULE_7__.Types.get(type); + const component = await componentClass.create(this, name, componentClass, hasPlaceholder, args, options); + if (postCreationFunction) { + postCreationFunction(this, component); + } + } + } + + /** + * Set up keyboard shortcuts. + */ + addShortcuts() { + // Add eventListener for press of 'f' key as a shortcut to enter search + const desktopSearch = this.getComponent('searchDesktop'); + const searchShortcut = 'KeyF'; // NOTE: In other apps, this is normally the slash '/' key. + + if (desktopSearch) { + document.addEventListener('keyup', event => { + // Key F: focus search + if (event.code === searchShortcut) { + if (!this.isSearching) { + desktopSearch.open(); + desktopSearch._children.input.focus(); + } + } + }); + } + } + + /** + * Set up app components. + */ + async setUpComponents() { + this.dynamicElement.innerHTML = this.constructor.html; + for (let i = 0; i < this._componentInfo.length; i++) { + const { name, type, hasPlaceholder, args, options, postCreationFunction } = this._componentInfo[i]; + const componentClass = _internal__WEBPACK_IMPORTED_MODULE_7__.Types.get(type); + const component = await componentClass.create(this, name, componentClass, hasPlaceholder, args, options); + if (postCreationFunction) { + postCreationFunction(this, component); + } + } + } + + /** + * VIEWS ------------------------------------------------------------------- + */ + + /** + * Gets all views. + * @returns {Object} + */ + getViews() { + return this._views; + } + + /** + * Add views to app. + */ + addViews() { + // Add views + for (let i = 0; i < this._viewInfo.length; i++) { + const viewInfo = this._viewInfo[i]; + this.addView(viewInfo.name, this._viewClasses[viewInfo.class], this._element, viewInfo.components); + } + } + + /** + * Remove views from app. + */ + removeViews() { + // Remove views + for (const view in this._views) { + this.removeView(view); + } + } + + /** + * Gets a view. + * @param {string} name - Unique name + * @returns {BaseView} + */ + getView(name) { + if (this._views[name] !== undefined) { + return this._views[name]; + } + return null; + } + + /** + * Adds a view component to app. + * @param {string} name - Unique name for the view component + * @param {typeof BaseComponent} TypeConstructor - Class name + * @param {...} args - List of arguments + * @returns {object} + */ + addView(name, TypeConstructor, ...args) { + if (this._views[name] === undefined) { + this._views[name] = new TypeConstructor(this, ...args); + } + return this._views[name]; + } + + /** + * Removes a view component from app. + * @param {string} name - Unique name for the view component + */ + removeView(name) { + if (this._views[name] !== undefined) { + delete this._views[name]; + } + } + + /** + * SCENE AND CAMERA -------------------------------------------------------- + */ + + /** + * Set up scene for app. + */ + async setUpScene() { + if (this._sceneInfo === undefined) { + console.error('App._sceneInfo needs to be set.'); + return; + } + + // Set maximum zoom distance in camera manager + this.getManager('camera').defaultMaxDistance = this._sceneInfo.zoomMax || 2e18; + + // Add all of the entity names to the scene manager and call the update. + const sceneManager = /** @type {SceneManager} */(this.getManager('scene')); + sceneManager.addEntitiesFromSceneInfo(this._sceneInfo); + + const labelManager = /** @type {LabelManager} */(this.getManager('label')); + const trailManager = /** @type {TrailManager} */(this.getManager('trail')); + const cameraManager = /** @type {CameraManager} */(this.getManager('camera')); + + // Setup the entity load and unload callbacks. + sceneManager.addEntityLoadedCallback(labelManager.setUpLabel); + sceneManager.addEntityLoadedCallback(trailManager.setUpTrail); + sceneManager.addEntityLoadedCallback(labelManager.setUpIcon); + sceneManager.addEntityLoadedCallback(cameraManager.addDynamicEnvMap); + + // Specific entity loaded callback. + sceneManager.addEntityLoadedCallback(entity => { + if (entity.getName() === 'sc_mars_science_laboratory') { + entity.get('div').setFadeWhenCloseToEntity('mars'); + } + else if (entity.getName() === 'sc_mars_2020') { + entity.get('div').setFadeWhenCloseToEntity('mars'); + } + }); + + sceneManager.addEntityWillBeUnloadedCallback(labelManager.removeLabel); + + // Run an update once. + sceneManager.update(); + + this.scene = this.getManager('scene').main; + + // Disable heliosphere by default + this.scene.get('sun', 'model')?.setEnabled(false); + } + + /** + * Set up viewport and camera for app. + */ + setUpViewportAndCamera() { + const scene = this.getManager('scene').main; + const camera = this.getManager('camera'); + camera.createViewportAndCamera(scene); + this.cameraScripts.scene = scene; + this.cameraScripts.cameraEntity = camera.cameraEntity; + } + + /** + * UPDATE CALLBACKS -------------------------------------------------------- + */ + + /** + * Set up callback function called every frame. + */ + setUpUpdates() { + this.addUpdate(this.getManager('scene').update); + this.addUpdate(this.getManager('label').update); + this.addUpdate(this.getManager('camera').update); + } + + /** + * Adds a callback function to the list of updates called every frame. + * @param {Function} callback + */ + addUpdate(callback) { + if (typeof callback === 'function') { + this._updates.push(callback); + } + } + + /** + * Removes a callback function to the list of updates called every frame. + * @param {Function} callback + */ + removeUpdate(callback) { + const index = this._updates.indexOf(callback); + if (index < 0) { + return; + } + this._updates.splice(index, 1); + } + + /** + * Calls all the functions to update every frame. + */ + update() { + for (let i = 0; i < this._updates.length; i++) { + const callback = this._updates[i]; + callback(); + } + } + + /** + * HELPER FUNCTIONS -------------------------------------------------------- + */ + + /** + * Bind functions to class. + * @param {string[]} [fns=[]] - Names of functions. + */ + bindFunctions(fns = []) { + const thisAsObject = /** @type {Object} */(this); + for (let i = 0; i < fns.length; i++) { + const fn = fns[i]; + thisAsObject[fn] = thisAsObject[fn].bind(this); + } + } + + /** + * Fades out a then removes the loading-screen if any + */ + endLoadingScreen() { + const loadingScreen = document.getElementById('loading-screen'); + + if (loadingScreen) { + const duration = 400; + loadingScreen.style.transition = `opacity ${duration / 1000}s ease-out`; + loadingScreen.style.opacity = '0'; + setTimeout(() => { + loadingScreen.remove(); + }, duration); + } + } + + /** + * Set up routes for app. + * @abstract + */ + setUpRoutes() { + } + + /** + * Returns true if touch drag. + * @returns {boolean} + */ + isDragging() { + return this._dragging; + } + + /** + * Return true if more than one touch is pressed. + * @returns {boolean} + */ + isTouchMax() { + return this._touchMax; + } + + /** + * EVENT HANDLERS ---------------------------------------------------------- + */ + + /** + * Resize body height to window innerHeight. + */ + resize() { + const vh = window.innerHeight; + document.documentElement.style.setProperty('--vh', `${vh}px`); + document.body.style.height = vh + 'px'; + + // Determine whether to update touch and hover properties. + const isTouch = _internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.isTouch(); + const canHover = _internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.canHover(); + + if (this.isTouch !== isTouch) { + document.body.classList.toggle('touch', isTouch); + this.isTouch = isTouch; + } + + if (this.canHover !== canHover) { + document.body.classList.toggle('hover', canHover); + this.canHover = canHover; + } + + // For late-update browsers + setTimeout(() => { + if (vh !== window.innerHeight) { + const newVH = window.innerHeight; + document.documentElement.style.setProperty('--vh', `${newVH}px`); + document.body.style.height = newVH + 'px'; + } + }, 1000); + } + + /** + * Handles touchstart event. + * @param {Event} event + */ + onTouchStart(event) { + this._touchCount++; + this._touchMax = this._touchCount > 1; + const touchEvent = event.changedTouches[0]; + this._touchStartPos.x = touchEvent.pageX; + this._touchStartPos.y = touchEvent.pageY; + this._dragging = false; + + // Check if element is scrollable or child of scrollable + this._scrollable = false; + let element = /** @type {Element} */(event.target); + while (element.parentElement !== null) { + if (element.classList.contains('scrollable')) { + this._scrollable = true; + break; + } + element = element.parentElement; + } + } + + /** + * Handles touchmove event. + * @param {Event} event + */ + onTouchMove(event) { + const touchEvent = event.changedTouches[0]; + const pressedPositionDistance = Math.max(Math.abs(touchEvent.pageX - this._touchStartPos.x), Math.abs(touchEvent.pageY - this._touchStartPos.y)); + if (pressedPositionDistance > 5) { + this._dragging = true; + } + + // Prevent pinch zoom on the page + if (!this._scrollable) { + event.preventDefault(); + } + } + + /** + * Handles touchend event. + * @param {Event} event + */ + onTouchEnd(event) { + this._touchCount--; + if (event.touches.length === 0) { + this._touchMax = false; + } + this._dragging = false; + this._scrollable = false; + } + + /** + * Gets the Pioneer version. + * @returns {string} + */ + getPioneerVersion() { + return this.pioneer.getVersion(); + } + + /** + * Gets the eyes version. + * @returns {string} + */ + getEyesVersion() { + return _internal__WEBPACK_IMPORTED_MODULE_7__.EyesVersion; + } +} + +// Initialize the app when the window loads. +window.addEventListener('load', async () => { + try { + const app = new BaseApp._appClass(); + app.init(); + } + catch (error) { + document.body.innerHTML = ''; + throw error; + } +}); + +/** + * The subclass of BaseApp to be instantiated. + * @type {typeof BaseApp} + */ +BaseApp._appClass = BaseApp; + +window.Pioneer = pioneer__WEBPACK_IMPORTED_MODULE_1__; +window.PioneerScripts = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__; + + +/***/ }), + +/***/ "../eyes/src/assets/index.js": +/*!***********************************!*\ + !*** ../eyes/src/assets/index.js ***! + \***********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); + + + + + + + + + + + + + + + +/***/ }), + +/***/ "../eyes/src/base_view.js": +/*!********************************!*\ + !*** ../eyes/src/base_view.js ***! + \********************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "BaseView": function() { return /* binding */ BaseView; } +/* harmony export */ }); +/* harmony import */ var moment_timezone__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! moment-timezone */ "../eyes/node_modules/moment-timezone/index.js"); +/* harmony import */ var moment_timezone__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(moment_timezone__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./internal */ "../eyes/src/internal.js"); + + + + +/** + * The base view. + */ +class BaseView extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {HTMLElement} element + * @param {Array} [components=[]] - Components of a view + */ + constructor(app, element, components = []) { + super(app, element); + + /** + * All child components of this view. + * @type {string[]} + * @private + */ + this._components = [...components]; + + /** + * List of valid query keys for this view. + * @type {string[]} + * @private + */ + this._validQueries = []; + + /** + * Rules for validating queries. + * @type {object} + * @private + */ + this._rules = {}; + + /** + * Camera's target. + * @type {string} + */ + this._target = null; + + // View should be disabled by default, and enabled by router + this._enabled = false; + + this.bindFunctions(['resize', 'updateVisibility', 'toggleViewUI']); + } + + /** + * Gets the app as an BaseApp. + * @returns {BaseApp} + * @override + */ + get app() { + return /** @type {BaseApp} */(super.app); + } + + /** + * Shows control panel (clock, time controls). + */ + _showControls() { + } + + /** + * Hides control panel (clock, time controls). + */ + _hideControls() { + } + + /** + * Function to check if controls should be hidden or not. + * @returns {boolean} + */ + _shouldHideControls() { + return false; + } + + /** + * Updates component visibility. + */ + updateVisibility() { + const showUI = this._app.getManager('layer').getLayer('ui').visible; + if (!showUI) { + return; + } + + if (this._shouldHideControls()) { + this._hideControls(); + } + else { + this._showControls(); + } + } + + /** + * Resize handler. Triggers on window resize event. + */ + resize() { + this.updateVisibility(); + } + + /** + * Toggles UI for this view. + */ + toggleViewUI() { + } + + /** + * Check if view should reset enable/disable status of each component. + * Todo: see naming note below. + * @returns {boolean} + */ + _shouldResetStatus() { + // If the UI is disabled dont reset the status + return this._app.getManager('layer').getLayer('ui').visible; + } + + /** + * Reset status of child components. + * ToDo: The name "resetStatus" seems a little generic. + * We're looping through all components and enabling/disabling them. Maybe "setComponentsAbility"? + * @param {Array} [unsubscribed=[]] - List of unsubscribed components that won't be enabled/disabled by the view. + */ + _resetStatus(unsubscribed = []) { + if (this._shouldResetStatus()) { + const allComponents = Object.keys(this._app.getComponents()); + for (let i = allComponents.length - 1; i >= 0; i--) { + const component = allComponents[i]; + if (unsubscribed.includes(component)) { + continue; + } + this._app.getComponent(component).setEnabled(this._components.includes(component)); + } + } + } + + /** + * Register all callbacks for view. + */ + registerCallbacks() { + this._app.getManager('layer').addCallback('ui', this.toggleViewUI); + } + + /** + * Remove all callbacks for view. + */ + removeCallbacks() { + this._app.getManager('layer').removeCallback('ui', this.toggleViewUI); + } + + /** + * Called when entering the view. + * @param {object} params + * @param {Array} [unsubscribed=[]] - List of unsubscribed components that won't be enabled/disabled by the view. + */ + async onEnter(params, unsubscribed = []) { + // Check if route was canceled + if (params.cancelToken.isCanceled) { + return; + } + this._resetStatus(unsubscribed); + + window.addEventListener('resize', this.resize); + this.registerCallbacks(); + + const className = this._app.getManager('router').currentView + '-view'; + document.body.classList.add(className); + // Lock navigational actions + if (this._app.getManager('router').configs.locked) { + document.body.classList.add('locked'); + this._app.getManager('label').setClickable(false); + this._app.getManager('selection').setClickable(false); + } + } + + /** + * Execute actions on full route change. + * @param {object} params - Parameters and queries from url + */ + async onRouteChange(params) { + await this.before(params); + + // Check if route was canceled + if (params.cancelToken.isCanceled) { + return; + } + + // Reset variables + this._reset(params); + + // Update resources + await this._updateResources(params); + + // Check if route was canceled + if (params.cancelToken.isCanceled) { + return; + } + + // Process query params like time and time rate. + // NOTE: Is there a reason processQuery is here as well as onQueryChange? + params.setTimeLimits = true; + await this.processQuery(params); + + // Update components + await this._updateComponentsVisibility(params); + // Check if route was canceled + if (params.cancelToken.isCanceled) { + return; + } + + // Check if entities are ready + await this._checkReady(params); + + // Update camera + // TODO: Check when we need to update camera + try { + await this._updateCamera(params); + this._updateLoading(params); + } + finally { + await this.after(params); + } + + const { spout } = this.app.getManager('router').configs; + if (spout === true) { + const { spoutGlobe, spoutRenderWidth, spoutGlobeDistance, spoutTarget, spoutFontSize, spoutLonAngleOffset, spoutAlignToNorthPole } = this.app.getManager('router').configs; + const spoutTargetEntity = spoutTarget || await this.app.getManager('spout').getSpoutCameraTargetEntity(params); + this.app.getManager('spout').enableSpout(spoutGlobe, spoutRenderWidth, spoutGlobeDistance, spoutTargetEntity, spoutFontSize, spoutLonAngleOffset, spoutAlignToNorthPole); + } + } + + /** + * On query change. + * Called when query has changed but not the route. + * @param {object} params + */ + async onQueryChange(params) { + // Check if route was canceled + if (params.cancelToken.isCanceled) { + return; + } + + // Process query params like time and time rate + await this.processQuery(params); + } + + /** + * Validate queries. + * @param {object} input + * @returns {boolean} `true` if valid, otherwise `false`. + */ + validateQuery(input) { + // Make a copy so it won't modify original query. + const queries = { ...input }; + const keys = Object.keys(queries); + const newQueries = {}; + const isInvalid = {}; + const routeManager = this._app.getManager('router'); + + for (let i = keys.length - 1; i >= 0; i--) { + const key = keys[i]; + // If there is no rule, remove from query and skip + if (!(key in this._rules)) { + delete queries[key]; + continue; + } + // Validate a query against rule value + const rule = this._rules[key]; + const valid = typeof rule.value === 'function' + ? rule.value(queries[key]) + : rule.value === queries[key]; + // If not valid + if (!valid) { + isInvalid[key] = queries[key]; + // If there's a redirect rule call it. + if (typeof this._rules.redirect === 'function') { + this._rules.redirect(queries[key]); + return false; + } + // If there is a route, navigate and exit + if ('route' in rule) { + routeManager.navigate(rule.route); + return false; + } + // Else if there is default value, store in new query + else if ('default' in rule) { + newQueries[key] = rule.default; + } + } + } + + // Navigate to default values if there are any + if (!_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isEmptyObject(newQueries)) { + routeManager.navigate({ ...queries, ...newQueries }); + return false; + } + + // If invalid, but no route or default value, use default handler and exit + if (!_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isEmptyObject(isInvalid)) { + this._handleError(`validateQuery: Invalid input - ${JSON.stringify(isInvalid)}`); + return false; + } + + return true; + } + + /** + * Process the query from path. + * Only consider Pioneer-related and common queries, not app-unique ones. + * @param {object} query + * @param {string} query.time - Time string that can be parsed by moment. E.g. time=2020-153T17:32:44.550 + * @param {string} query.rate - Time rate in second that can be parsed by parseInt. E.g. rate=120 (sec/sec) + */ + async processQuery(query) { + /** + * Note: Maybe we could add an _updateTimeLimits method here. + */ + + // Set time + await this._updateTime(query); + + // Set time rate + this._updateTimeRate(query); + + const router = this._app.getManager('router'); + const prevQuery = router.parseQuery(router.previousRoute?.query); + + // Go thru all query callback keys in the router and check if the params contain the query. + for (const queryKey of Object.keys(router._queryCallbacks)) { + const currQueryVal = query[queryKey]; + const prevQueryVal = prevQuery[queryKey]; + + // If we have query values for previous of current query, loop thru the callbacks, call them, and pass the prev and curr query valuez. + if (currQueryVal || prevQueryVal) { + router._queryCallbacks[queryKey].forEach(callbackFn => callbackFn(currQueryVal, prevQueryVal)); + } + } + + // Update layer panel + const layerManager = this._app.getManager('layer'); + const layerPanel = this._app.getComponent('layerPanel'); + const layerQueries = { + layerUI: 'ui', + layerTrails: 'trails', + layerOrbits: 'orbits', + layerLabels: 'labels', + layerIcons: 'icons', + layerPlanets: 'planets', + layerAsteroids: 'asteroids', + layerComets: 'comets', + layerDwarfPlanets: 'dwarfPlanets', + layerConstellations: 'constellations', + layerSpacecraft: 'spacecraft' + }; + for (const key in layerQueries) { + if (key in query) { + const layer = layerQueries[key]; + if (query[key] === 'disable') { + layerPanel?.setCategoryEnabled(layer, false); + } + else { + if (layerPanel?.isCategoryEnabled(layer)) { + if (query[key] === 'show') { + if (!layerManager.getLayer(layer).visible) { + layerPanel.toggleLayer(layer); + } + } + else if (query[key] === 'hide') { + if (layerManager.getLayer(layer).visible) { + layerPanel.toggleLayer(layer); + } + } + } + } + } + } + + // Update title if title manager is initialized. + this.app.getManager('title')?.updateTitle(router.currentRoute); + } + + /** + * Display error message and reroute to previous url. + * @param {string} [message=''] - Message for error + * @throws {string} + */ + _handleError(message = '') { + const err = new Error(message); + console.error(err); + const router = this._app.getManager('router'); + if (router !== null) { + let url = this._app.getManager('router').previousRoute.url; + if (!url) { + url = this._app.getManager('router').homeRoute; + } + this._app.getManager('router').navigate(url); + } + } + + /** + * Called when exiting the view. + * @param {object} params + */ + onLeave(params) { + window.removeEventListener('resize', this.resize); + this.removeCallbacks(); + + const className = this._app.getManager('router').previousView + '-view'; + document.body.classList.remove(className); + + this._app.getManager('selection').unselect(); + this._app.getManager('scene').clearForceLoad(); + this._validQueries.length && this._app.getManager('router').navigate({ __remove: this._validQueries }); + } + + /** + * Takes router parameters and initialize view variables. + * ToDo: "reset" is not a good method name for something that initializes view variables. Let's change this. + * @param {object} params + */ + _reset(params) { + this._app.getManager('scene').clearForceLoad(); + } + + /** + * Update resources from managers and router parameters. + * @param {object} params + */ + async _updateResources(params) { + } + + /** + * Update time rate from query. + * @param {object} query + */ + _updateTimeRate(query) { + const timeManager = this._app.getManager('time'); + + if ('rate' in query) { + timeManager.setTimeRate(parseInt(query.rate)); + } + else { + timeManager.resetTimeRate(); + } + } + + /** + * Update time with router parameters. + * @param {object} params + */ + async _updateTime(params) { + const timeManager = this._app.getManager('time'); + const routeManager = this._app.getManager('router'); + const isStory = routeManager.currentRoute.url.includes('story'); + let numSlides = 0; + if (isStory && this._storyId) { + const story = this._app.getManager('content').getStory(this._storyId); + numSlides = story.slides.length; + } + + /** + * Note: + * To improve readability, it would maybe make sense to update the time limits in a separate method, eg. _updateTimeLimits. + * See note in processQuery method. + */ + // Apply app limits: + // If there's no target and if it's not a single slide story in case of custom timing (all single slide stories have custom timing) + // OR + // If it is a story, there's no target, and no storyId (some stories in asteroids do handle id's differently) + if ((!this._target && (numSlides > 1)) || (isStory && !this._target && !this._storyId)) { + timeManager.resetMin(); + timeManager.resetMax(); + } + + if (this._target) { + await this._updateTimeForTarget(params); + } + else if (params.time) { + const time = this._app.getManager('time').parseTime(params.time); + if (time.isValid()) { + this._app.getManager('time').setTime(params.time); + } + else { + // Remove time query if invalid + this._app.getManager('router').navigate({ __remove: ['time'] }); + } + } + else { + this._app.getManager('time').setToNow(); + } + } + + /** + * Update time relative to a target. + * @param {object} params + * @param {boolean} waitForEntity + */ + async _updateTimeForTarget(params, waitForEntity = true) { + const timeManager = this._app.getManager('time'); + + let min = timeManager.timeLimits.min.clone(); + let max = timeManager.timeLimits.max.clone(); + + if (params.setTimeLimits) { + const defaultLimits = timeManager.getDefaultLimits(); + min = defaultLimits.min.clone(); + max = defaultLimits.max.clone(); + + waitForEntity && await this._app.getManager('scene').get('main').getEntity(this._target).getLoadedPromise(); + const coverage = this._app.getManager('scene').getCoverage(this._target); + + // Apply coverage limits + if (coverage.min !== null) { + min = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().max(min, coverage.min); + } + if (coverage.max !== null) { + max = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().min(max, coverage.max); + } + + // Apply description limits + if (this._entityDesc?.dates?.start) { + const startTime = timeManager.parseTime(this._entityDesc.dates.start); + min = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().max(startTime, min); + } + if (this._entityDesc?.dates?.end) { + const endTime = timeManager.parseTime(this._entityDesc.dates.end); + max = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().min(endTime, max); + } + + // Check for anormal times + if (min.isAfter(max)) { + console.error('Start date provided is after end date.'); + const router = this._app.getManager('router'); + this._app.getComponent('clock')?.setLimitMessage(1, 'time limit error'); + // This needs to be stored and cleared to prevent memory leak / delayed nav. + setTimeout(() => router.navigate('/'), 1000); + + return; + } + + // Set time limits + timeManager.setMax(max); + timeManager.setMin(min); + } + + // If we dont have time specified in query + // Set the time to start + if (!params.time && this._eventInfo?.start) { + // E.g. /sc_cassini/events/eventID + const eventStart = timeManager.parseTime(this._eventInfo.start); + timeManager.setTime(moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().max(eventStart, min)); + } + else if (!params.time) { + const now = this._app.getManager('time').getNow(); + if (now.isAfter(max) || now.isBefore(min)) { + timeManager.setTime(min); + } + else { + timeManager.setToNow(); + } + } + else { + const time = timeManager.parseTime(params.time); + if (time.isAfter(max)) { + timeManager.setTime(max); + timeManager.setTimeRate(0); + this._app.getComponent('clock')?.setLimitMessage(1); + } + else if (time.isBefore(min)) { + timeManager.setTime(min); + this._app.getComponent('clock')?.setLimitMessage(-1); + } + else { + timeManager.setTime(time); + } + } + } + + /** + * Update components and visibility with router parameters. + * @param {object} params + */ + async _updateComponentsVisibility(params) { + await this._updateComponents(params); + // Check if route was canceled + if (params.cancelToken.isCanceled) { + return; + } + this.updateVisibility(); + } + + /** + * Update components with router parameters. + * @param {object} params + */ + async _updateComponents(params) { + } + + /** + * Update camera with router parameters. + * @param {object} params + */ + async _updateCamera(params) { + } + + /** + * Update scene loading. + * @param {object} params + */ + _updateLoading(params) { + // Update loading + if (this._target !== null) { + const promises = []; + const loadComponents = ['model', 'wmts', 'spheroidLOD']; + const sceneManager = this._app.getManager('scene'); + const contentManager = this._app.getManager('content'); + + // If target is an instrument, add it's parent to the addLoading. + const entityInfoCategory = contentManager.getEntityInfo(this._target)?.category; + if (entityInfoCategory) { + if (entityInfoCategory === 'Instrument') { + sceneManager.addLoading(sceneManager._scene.getEntity(this._target).getParent().getName(), 'view'); + } + } + sceneManager.addLoading(this._target, 'view'); + for (let i = 0; i < loadComponents.length; i++) { + const component = sceneManager.get('main').get(this._target, loadComponents[i]); + if (component !== null) { + // Force loading of component + // It will be cleared when leaving the view or reseting it + sceneManager.forceLoad(component); + promises.push(sceneManager.componentIsReady(component)); + } + } + Promise.all(promises).then(() => { + if (entityInfoCategory) { + if (entityInfoCategory === 'Instrument') { + sceneManager.removeLoading(sceneManager._scene.getEntity(this._target).getParent().getName(), 'view'); + } + } + sceneManager.removeLoading(this._target, 'view'); + }); + } + } + + /** + * Checks if entities are ready. + * @param {object} params + */ + async _checkReady(params) { + // No need to check if we dont have a target + if (this._target === null) { + return; + } + + // Make sure the objects are ready + const checklist = []; + let parent = this._target; + while (parent !== 'sun') { + checklist.push(parent); + const parentEntity = this._app.getManager('scene').get('main').get(parent)?.getParent(); + if (!parentEntity) { + break; + } + parent = parentEntity.getName(); + } + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(this._app.getManager('scene').get('main'), checklist); + await this._app.pioneer.waitUntilNextFrame(); + } + + /** + * Callback before all actions in onRouteChange. + * @param {object} params + */ + async before(params) { + } + + /** + * Callback after all actions in onRouteChange. + * @param {object} params + */ + after(params) { + // Reset old target for layer manager + this._app.getManager('layer').resetTarget(); + this._app.getManager('scene').clearTempEntities(); + } +} + + +/***/ }), + +/***/ "../eyes/src/components/base_component.js": +/*!************************************************!*\ + !*** ../eyes/src/components/base_component.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "BaseComponent": function() { return /* binding */ BaseComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + +/** + * @typedef ClassType + * @property {object} isVisible - className for visible or hidden element + * @property {string} [isVisible.true='active'] + * @property {string} [isVisible.false='hidden'] + * @property {object} fontSize + * @property {string} fontSize.small + * @property {string} fontSize.default + * @property {string} fontSize.large + */ + +/** + * @typedef Options + * @property {HTMLElement} parent + * @property {Object} config + * @property {Object} params + * @property {boolean} [isVisible] + */ + +/** + * @typedef CallbackRegistryType + * @property {object} emitter - The emitter to register callback to or remove callback from. Can be app, manager, view, or component instance. + * @property {string} event - Emitter's event name to trigger the callback + * @property {Function} callback - The callback to trigger on event + */ + +/** The base class for all components. */ +class BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {HTMLElement} element - The element given to the component + * @param {Options} [options = { parent: null, config: {}, params: {} }] - Initial state and optional config + */ + constructor(app, element, options = { parent: null, config: {}, params: {}, isVisible: true }) { + /** + * The element given to the component. + * @type {Element} + */ + this._element = element; + + /** + * Application. + * @type {BaseApp} + * @private + */ + this._app = app; + + /** + * Configurations of component. + * @type {Object} + * @private + */ + this._config = options['config'] || {}; + delete options['config']; + if (!('hiddenMode' in this._config)) { + this._config.hiddenMode = 'hidden'; + } + + /** + * Static variables to insert into element HTML text on initialization. + * @type {Object} + */ + this._params = options['params'] || {}; + delete options['params']; + + // Default state of component's visibility + if (!('isVisible' in options)) { + options['isVisible'] = false; + } + + /** + * Store className for element's state. + * @type {ClassType} + * @private + */ + this._class = { + isVisible: { + true: 'active', + false: this._config.hiddenMode === 'hidden' ? 'hidden' : 'invisible' + }, + fontSize: { + small: 'small', + default: '', + large: '' + } + }; + + /** + * The current states of component. + * @type {Object} + * @private + */ + this._state = { + ...options, + isVisibleClass: this._class.isVisible[options.isVisible ? 'true' : 'false'], + fontSizeClass: this._class.fontSize.default + }; + + /** + * The old states of component. + * @type {Object} + * @private + */ + this._oldState = {}; + + /** + * The children/grandchildren of element. + * @type {Object} + */ + this._children = {}; + + /** + * The child components to be managed by this component. + * @type {Array} + */ + this._components = []; + + /** + * Text node elements that associate with state. + * @type {Object>} + */ + this._vars = {}; + + /** + * The parent element of component's element. + * @type {HTMLElement} + */ + this._parent = this._element ? this._element.parentElement : (options.parent || null); + + /** + * Flag that indicates whether the user has enabled or disabled the component. + * @type {boolean} + * @private + */ + this._enabled = false; + + /** + * Array of possible event names. + * @type {string[]} + * @default + */ + this._eventNames = ['statuschange', 'visiblechange']; + + /** + * Callbacks reference object. + * @type {Object void>>} + * @default + */ + this._callbacks = {}; + this._initCallbacks(); + + /** + * Registry of callbacks to register on enable and remove on disable. + * @type {Array} + */ + this._callbackRegistry = []; + + this.bindFunctions([ + 'resize', + 'isEnabled', + 'setEnabled', + 'show', + 'hide', + 'toggle', + 'loadHTML', + 'getState', + 'setState' + ]); + } + + /** + * Get the child components. + * @returns {Array} + */ + get components() { + return this._components; + } + + /** + * Gets the app. + * @returns {BaseApp} + */ + get app() { + return this._app; + } + + /** + * Resize handler. Triggers on window resize event. + */ + resize() { + this._updateFontSize(); + } + + /** + * Update font size of component's element. + */ + _updateFontSize() { + let fontSizeClass = this._class.fontSize.default; + + if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobile()) { + fontSizeClass = this._class.fontSize.small; + } + else if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isTablet()) { + fontSizeClass = this._class.fontSize.default; + } + else if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isPanorama()) { + fontSizeClass = this._class.fontSize.default; + } + else if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.is2K() || _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.is4K()) { + fontSizeClass = this._class.fontSize.large; + } + + this.setState({ + fontSizeClass + }); + } + + /** + * Get the root element of the component. + * @returns {Element} + */ + get element() { + return this._element; + } + + /** + * Get the parent element of component's element. + * @returns {HTMLElement|null} + */ + getParent() { + return this._parent; + } + + /** + * Set the parent element for component's element. + * @param {HTMLElement} parent + * @param {HTMLElement} [replaceElement=null] - Element to replace with component's element. + */ + setParent(parent, replaceElement = null) { + this._parent = parent; + + // Remove replaceElement + if (replaceElement) { + this._parent.removeChild(replaceElement); + } + + // Add element to parent if component is enabled + if (this._enabled) { + this._parent.appendChild(this._element); + } + } + + /** + * Initialization. + * Called automatically by addComponent. + * @param {Object} params - Parameters to replace in html + * @returns {Promise} + */ + async init(params = {}) { + Object.assign(this._params, params); + + const componentType = /** @type {typeof BaseComponent} */(this.constructor); + if (componentType.html !== undefined) { + this._element = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.htmlWithParamsToElement(componentType.html, this._params); + this._element.classList.add('{{fontSizeClass}}'); + this._setVariables(this._element); + this._setEventHandlersFromAttributes(this._element); + } + else { + this._element.classList.add('{{fontSizeClass}}'); + this._setVariables(this._element); + } + this._updateFontSize(); + } + + /** + * Get component's config. + * @returns {object} + */ + getConfig() { + return this._config; + } + + /** + * Update component's config. + * @param {object} config + */ + setConfig(config) { + Object.assign(this._config, config); + } + + /** + * Bind functions to class. + * @param {string[]} [fns=[]] - Names of functions. + */ + bindFunctions(fns = []) { + const thisAsObject = /** @type {Object} */(this); + for (let i = 0; i < fns.length; i++) { + const fn = fns[i]; + thisAsObject[fn] = thisAsObject[fn].bind(this); + } + } + + /** + * Returns true if the component is enabled by the user. + * @returns {boolean} + */ + isEnabled() { + return this._enabled; + } + + /** + * Sets whether the component is enabled by the user. + * @param {boolean} enabled + */ + setEnabled(enabled) { + const wasEnabled = this._enabled; + + if (enabled && !wasEnabled) { + this.__enable(); + } + else if (!enabled && wasEnabled) { + this.__disable(); + } + + /** + * NOTE from Jack: + * The _enabled prop is now set here as previously, calling __disable and any subsequent triggerCallbacks method, + * would result in the callback not being called. This is because triggerCallbacks returns false is _enabled is false. + * We still want to trigger a statuschange as the component is being disabled. + * Update: the isEnabled check in triggerCallbacks has been commented out. + */ + this._enabled = enabled; + + this._components.forEach(item => { + const component = (typeof item === 'string') + ? this._app.getComponent(item) + : item; + component.setEnabled(enabled); + }); + } + + /** + * Destroy component. + */ + destroy() { + this.__destroy(); + } + + /** + * Show component's element. + */ + show() { + this.setState({ + isVisible: true, + isVisibleClass: this._class.isVisible.true + }, () => this.triggerCallbacks('visiblechange', [true])); + } + + /** + * Hide component's element. + */ + hide() { + this.setState({ + isVisible: false, + isVisibleClass: this._class.isVisible.false + }, () => this.triggerCallbacks('visiblechange', [false])); + } + + /** + * Toggle visibility of component's element. + */ + toggle() { + if (this._state['isVisible']) { + this.hide(); + } + else { + this.show(); + } + } + + /** + * Load HTML from file into element. + * @param {string} filename + * @param {HTMLElement} [element=null] - The element to load html into + */ + async loadHTML(filename, element = null) { + const response = await fetch(filename); + if (!response.ok) { + console.error(response.status + ': ' + response.statusText); + } + else { + const html = await response.text(); + this._parseHTML(html, element); + } + } + + /** + * Get state value using its key. + * @param {string} key + * @returns {any} + */ + getState(key) { + if (!(key in this._state)) { + return null; + } + return this._state[key]; + } + + /** + * Add a state to component. + * @param {string} key + * @param {any} value + * @param {HTMLElement} element - Element to call _setVariables on + */ + addState(key, value, element) { + this._state[key] = value; + if (element) { + this._setVariables(element); + } + } + + /** + * Set state. Will trigger rerender if new state is not empty. + * @param {Object} state - Changed states + * @param {() => void} [callback] - Optional callback + */ + setState(state, callback) { + if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isEmptyObject(state)) { + return; + } + + // Simple check for changes + let hasChanged = false; + for (const key in state) { + if (state[key] !== this._state[key]) { + hasChanged = true; + break; + } + } + + // Don't render if no change + if (!hasChanged) { + return; + } + + this._oldState = { ...this._state }; + this._state = { ...this._state, ...state }; + this._render(state); + + if (callback !== undefined) { + callback(); + } + } + + /** + * Parse HTML and store variables. + * @param {string} html + * @param {Element} [element=null] - Element to load html into + */ + _parseHTML(html, element = null) { + if (!html) { + return; + } + + const outElement = element || this._element; + + // Create the template and add the html content as the root node. + this._roots = [..._internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.htmlToElements(html)]; + + const docFrag = document.createDocumentFragment(); + for (let i = 0; i < this._roots.length; i++) { + const item = this._roots[i]; + if (item instanceof HTMLElement) { + // Set the variables and store the elements with key. + this._setVariables(item); + + // Set the event handlers. + this._setEventHandlersFromAttributes(item); + + // Add parsed element to component's div + docFrag.appendChild(item); + } + } + outElement.appendChild(docFrag); + } + + /** + * Check if a text contain a variable (enclosed in {{ and }}). + * @param {string} text + * @returns {boolean} + */ + _containVar(text) { + return ( + text + && typeof text.includes === 'function' + && text.includes('{{') + && text.includes('}}') + ); + } + + /** + * Split a string without empty results. + * @param {string} str + * @returns {string[]} + */ + _splitNonEmpty(str) { + return str.split(/\s+/g).filter(part => part !== ''); + } + + /** + * Store all variables as state or children for update. + * Format of HTML variable: {{var}}. Format of HTML key: key="childVar". + * @example + * // Replace
      {{text}}
      with value of this._state.text. + * // Replace
      with value of this._state.aClass. + * // Store
      as this._children.aChild. + * @param {Node} element + * @param {boolean} [setForChildren=true] - Also set variables for children + * @private + */ + _setVariables(element, setForChildren = true) { + let outElement; + + // Store elements with key + if (element instanceof Element) { + for (let i = element.attributes.length - 1; i >= 0; i--) { + const attribute = element.attributes[i]; + if (attribute.name === 'key') { + this._children[attribute.value] = element; + break; + } + } + } + + // Get variables to be stored + const elementVars = []; + + // Text node + if (element.nodeType === Node.TEXT_NODE) { + if (this._containVar(element.nodeValue)) { + elementVars.push({ + field: 'nodeValue', + elementVar: element.nodeValue + }); + } + } + // Not text node + else if (element instanceof Element) { + // Class name/list + let className = element.className; + while (this._containVar(className)) { + const endIndex = className.indexOf('}}') + 2; + elementVars.push({ + field: 'classList', + elementVar: className.substring(className.indexOf('{{'), endIndex) + }); + className = className.substring(endIndex); + } + } + + // Store variables + for (let i = 0; i < elementVars.length; i++) { + let { field, elementVar } = elementVars[i]; + if (field && elementVar.startsWith('{{') && elementVar.endsWith('}}')) { + // Replace variable + const key = elementVar.replace('{{', '').replace('}}', ''); + // With classnames + if (field === 'classList' && element instanceof Element) { + element.classList.remove(elementVar); + const state = this._state[key]; + if (state !== undefined) { + const classList = this._splitNonEmpty(state); + element.classList.add(...classList); + } + } + else { + // With an element + if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isHTML(this._state[key])) { + const newElement = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.htmlToElement(this._state[key]); + element.parentNode.replaceChild(newElement, element); + outElement = newElement; + } + // With text containing HTML + else if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.hasHTML(this._state[key])) { + // Update element since text node cannot display HTML + if (element.nodeType === Node.TEXT_NODE) { + const newElement = document.createElement('span'); + newElement.innerHTML = this._state[key]; + const parent = element.parentElement || element.parentNode; + parent.replaceChild(newElement, element); + outElement = newElement; + field = 'innerHTML'; + } + else { + element.innerHTML = this._state[key]; + } + } + // With other properties + else { + const elementAsObj = /** @type {Object} */(element); + elementAsObj[field] = this._state[key]; + } + } + // Store variable + if (this._vars[key] === undefined) { + this._vars[key] = []; + } + this._vars[key].push({ + element: outElement || element, + field + }); + } + } + + // Go through the children and so on. + if (setForChildren) { + for (let i = element.childNodes.length - 1; i >= 0; i--) { + this._setVariables(element.childNodes[i]); + } + } + } + + /** + * Sets the event handlers for all children of elem. Searches for all attributes starting with 'on' and processes them. + * @param {Element} element + * @private + */ + _setEventHandlersFromAttributes(element) { + const attributeNamesToRemove = []; + for (let i = element.attributes.length - 1; i >= 0; i--) { + const attribute = element.attributes[i]; + if (attribute.name.startsWith('on')) { + // Get the event type. + const event = attribute.name.substring(2).toLowerCase(); + // Get the callback. + const handler = /** @type {BaseComponent & { [key: string]: any }} */(this)[attribute.value]; + if (handler === undefined || !(handler instanceof Function)) { + throw new Error('Could not find valid ' + event + ' handler ' + attribute.value + ' for element with id ' + element.id); + } + // Get the callback bound to this. + const boundHandler = handler.bind(this); + // Remove the attribute so there's no conflict. + attributeNamesToRemove.push(attribute.name); + // Add the event listener. + element.addEventListener(event, boundHandler); + } + } + // Remove the attributes that were handlers to remove any conflicts. + for (let i = attributeNamesToRemove.length - 1; i >= 0; i--) { + element.removeAttribute(attributeNamesToRemove[i]); + } + // Go through the children and so on. + for (let i = element.children.length - 1; i >= 0; i--) { + this._setEventHandlersFromAttributes(element.children[i]); + } + } + + /** + * Render div innerHTML with changed states. + * @param {Object} state + */ + _render(state) { + const keys = Object.keys(state); + for (let i = keys.length - 1; i >= 0; i--) { + const key = keys[i]; + if (key in this._vars && state[key] !== this._oldState[key]) { + const _var = this._vars[key]; + for (let j = 0; j < _var.length; j++) { + // Update variable + const { field, element } = _var[j]; + // With classnames + if (field === 'classList') { + let classList = this._splitNonEmpty(this._oldState[key]); + const elementAsObj = /** @type {Object} */(element); + elementAsObj[field].remove(...classList); + classList = this._splitNonEmpty(state[key]); + elementAsObj[field].add(...classList); + } + else { + // With an element + if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isHTML(state[key])) { + const newElement = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.htmlToElement(state[key]); + element.parentNode.replaceChild(newElement, element); + this._vars[key][j].element = newElement; + } + // With text containing HTML + else if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.hasHTML(state[key])) { + if (element.nodeType === Node.TEXT_NODE) { + const newElement = document.createElement('span'); + newElement.innerHTML = state[key]; + const parent = element.parentElement || element.parentNode; + parent.replaceChild(newElement, element); + this._vars[key][j].element = newElement; + this._vars[key][j].field = 'innerHTML'; + } + else { + element.innerHTML = state[key]; + } + } + // With other properties + else { + const elementAsObj = /** @type {Object} */(element); + elementAsObj[field] = state[key]; + } + } + } + } + } + } + + /** + * Enables the component. + * @abstract + * @package + */ + __enable() { + window.addEventListener('resize', this.resize); + this.registerCallbacks(); + + if (this._parent) { + this._parent.appendChild(this._element); + this.triggerCallbacks('statuschange', [true, this]); + } + } + + /** + * Disables the component. + * @abstract + * @package + */ + __disable() { + if (this._parent && this._parent.contains(this._element)) { + this.triggerCallbacks('statuschange', [false, this]); + this._element = this._parent.removeChild(this._element); + } + window.removeEventListener('resize', this.resize); + this.removeCallbacks(); + } + + /** + * Destroy component. + */ + __destroy() { + this.__disable(); + this._element = null; + this._parent = null; + } + + /** + * Initialize callback list for all events. + */ + _initCallbacks() { + for (let i = 0; i < this._eventNames.length; i++) { + this._callbacks[this._eventNames[i]] = []; + } + } + + /** + * Registers a callback for a specific event. + * @param {string} eventName + * @param {(...args: any[]) => void} callback - A callback function to be called + */ + registerCallback(eventName, callback) { + if ((typeof (callback) !== 'function') || (this._eventNames.indexOf(eventName) < 0)) { + return; + } + + // Prevent multiple registrations of same event with same callback + if (!this._callbacks[eventName].includes(callback)) { + this._callbacks[eventName].push(callback); + } + } + + /** + * Remove a callback for an event. + * @param {string} eventName + * @param {(...args: any[]) => void} callback + */ + removeCallback(eventName, callback) { + if ((typeof (callback) !== 'function') || (this._eventNames.indexOf(eventName) < 0)) { + return; + } + + const index = this._callbacks[eventName].indexOf(callback); + if (index > -1) { + this._callbacks[eventName].splice(index, 1); + } + } + + /** + * Trigger all callbacks for an event. + * @param {string} eventName + * @param {any[]} [params=[]] - Parameters for callback + */ + triggerCallbacks(eventName, params = []) { + // Not sure why these are triggered in reverse order. + for (let i = this._callbacks[eventName].length - 1; i >= 0; i--) { + const callback = this._callbacks[eventName][i]; + callback(...params); + } + } + + /** + * Register all callbacks for component. + */ + registerCallbacks() { + for (let i = 0; i < this._callbackRegistry.length; i++) { + const { emitter, event, callback } = this._callbackRegistry[i]; + emitter.registerCallback(event, callback); + } + } + + /** + * Remove all callbacks for component. + */ + removeCallbacks() { + for (let i = 0; i < this._callbackRegistry.length; i++) { + const { emitter, event, callback } = this._callbackRegistry[i]; + emitter.removeCallback(event, callback); + } + } +} + +/** + * Helper function to create the component and add to app. + * @static + * @param {BaseApp} app - Application to add component + * @param {string} name - Component's unique name + * @param {typeof BaseComponent} TypeConstructor - Component's class to construct + * @param {boolean} hasPlaceholder - Component has a HTML placeholder or not + * @param {any[]} [args=[]] - Arguments to pass to constructor + * @param {object} [options={}] - Options to pass to constructor + * @returns {Promise} + */ +BaseComponent.create = async (app, name, TypeConstructor, hasPlaceholder = true, args = [], options = {}) => { + const component = hasPlaceholder + ? await app.addComponentWithPlaceholder({ type: TypeConstructor, name, args, options }) + : await app.addComponent(name, TypeConstructor, ...args, options); + + if (TypeConstructor.postCreationFunction) { + TypeConstructor.postCreationFunction(app, component); + } + return component; +}; + +/** + * The HTML that goes with the component. + * @type {string | undefined} + */ +BaseComponent.html = undefined; + +/** + * The HTML that goes with the component. + * @type {((app: BaseApp, component: BaseComponent) => void) | undefined} + */ +BaseComponent.postCreationFunction = undefined; + + +/***/ }), + +/***/ "../eyes/src/components/breadcrumb/breadcrumb.js": +/*!*******************************************************!*\ + !*** ../eyes/src/components/breadcrumb/breadcrumb.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Breadcrumb": function() { return /* binding */ Breadcrumb; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _breadcrumb_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./breadcrumb.html */ "../eyes/src/components/breadcrumb/breadcrumb.html"); +/* harmony import */ var _breadcrumb_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_breadcrumb_html__WEBPACK_IMPORTED_MODULE_1__); + + + + +/** + * Breadcrumb component. + * @extends BaseComponent + */ +class Breadcrumb extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options = { params: {} }) { + // Default params + options.params = { + title: '', + ...options.params + }; + super(app, null, options); + + this._class.isHomeActiveClass = { + true: 'active', + false: '' + }; + + /** + * Crumb text for crumbs. + * @type {object} + */ + this._crumbTexts = { + compare: 'Compare Size', + events: 'Mission Events' + }; + + // Set the crumb onclick handler. + this.setCrumbClickHandler(route => { + this._app.getManager('router').navigate(route, '', { __remove: 'all', keepTime: true }); + }); + + Object.assign(this._state, { + isHomeActive: false, + isHomeActiveClass: this._class.isHomeActiveClass.false + }); + + this.bindFunctions(['_goToHome']); + } + + /** + * Updates the breadcrumb trail. + * @param {Array} routeParts + */ + updateBreadcrumb(routeParts) { + this._element.innerHTML = ''; + const docFrag = document.createDocumentFragment(); + + // Add static part + if (this._app.getManager('router').configs.logo === false) { + this._children.staticLogo.classList.add('hidden'); + } + if (this._app.getManager('router').configs.locked) { + this._children.static.classList.remove('clickable'); + } + docFrag.appendChild(this._children.static); + + const isHomeActive = !routeParts || routeParts.length === 0 || (routeParts.length === 1 && routeParts[0] === 'home'); + if (isHomeActive) { + routeParts = null; + } + this.setState({ + isHomeActive, + isHomeActiveClass: this._class.isHomeActiveClass[isHomeActive] + }); + + // Add dynamic parts + if (routeParts && routeParts.length > 0) { + for (let i = 0; i < routeParts.length; i++) { + const routePart = routeParts[i]; + const route = routeParts.slice(0, i + 1).join('/'); + + const crumb = this._createCrumb(routePart, route); + docFrag.appendChild(crumb); + } + } + + this._element.appendChild(docFrag); + } + + /** + * Actions on route change. + * @param {object} params - Parameters and queries from url + * @param {Array} params.routeParts + */ + onRouteChange({ routeParts } = {}) { + this.updateBreadcrumb(routeParts); + } + + /** + * Sets the breadcrumb onclick handler function. It allows each app to set the handler dynamically. + * @param {Function} onCrumbClick + */ + setCrumbClickHandler(onCrumbClick) { + this._onCrumbClick = onCrumbClick; + } + + /** + * Navigate back to home page. + */ + _goToHome() { + const router = this._app.getManager('router'); + router.navigate({ __remove: 'all' }, '/home'); + } + + /** + * Get crumb text to display. + * @param {string} crumb + * @returns {string} + */ + _getCrumbText(crumb) { + // Lookup predefined texts + if (this._crumbTexts[crumb]) { + return this._crumbTexts[crumb]; + } + + // Lookup entity info + const entityInfo = this._app.getManager('content').getEntityInfo([crumb]); + if (entityInfo) { + return entityInfo.displayName || entityInfo.iauName; + } + + // Lookup event info + const eventInfo = this._app.getManager('content').events[crumb]; + if (eventInfo) { + return eventInfo.title; + } + + // Lookup story info + const storyInfo = this._app.getManager('content').getStoryList().stories[crumb]; + if (storyInfo) { + return storyInfo.title; + } + + return ''; + } + + /** + * Creates a crumb. + * @param {string} text + * @param {string} route + * @returns {HTMLElement} + */ + _createCrumb(text, route) { + const container = document.createElement('nav'); + const { locked } = this._app.getManager('router').configs; + container.className = `container ${locked ? '' : 'clickable'}`; + if (!locked) { + container.addEventListener('click', () => { + this._onCrumbClick(route); + }); + } + + const separator = document.createElement('span'); + separator.className = 'separator icon icon-greater'; + container.appendChild(separator); + + const textSpan = document.createElement('a'); + textSpan.innerHTML = this._getCrumbText(text) || text; + textSpan.className = 'text link'; + container.appendChild(textSpan); + + return container; + } +} + +Breadcrumb.html = (_breadcrumb_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/carousel/carousel.js": +/*!***************************************************!*\ + !*** ../eyes/src/components/carousel/carousel.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var tippy_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tippy.js */ "../eyes/node_modules/tippy.js/dist/tippy.esm.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _carousel_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./carousel.html */ "../eyes/src/components/carousel/carousel.html"); +/* harmony import */ var _carousel_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_carousel_html__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _slide_template_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./slide_template.html */ "../eyes/src/components/carousel/slide_template.html"); +/* harmony import */ var _slide_template_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_slide_template_html__WEBPACK_IMPORTED_MODULE_2__); + + + + + +/** + * General carousel with only previous/next navigation. + * @see {@link https://codepen.io/simonpatrat/pen/zeGYdo} - Modified from + */ +class Carousel extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {HTMLElement} element + * @param {object} [options={}] + */ + constructor(app, element, options = {}) { + /** + * Determine the hint's text based on device. + * @type {string} + */ + const hintAction = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isPrimaryTouch() ? 'Swipe/Tap' : 'Scroll/Click'; + + /** + * Configurations for carousel. + * @type {object} + * @private + * @default + * @property {boolean} [infinite=false] - Loop to start/end if reach limit + * @property {number} [initialSlideIndex=0] - Slide index to show on initilization. Must be an integer. + * @property {boolean} [vertical=true] - Scrolling direction is vertical + * @property {number} [timeout=1500] - Timeout between slide scroll + * @property {object} navigationButtons + * @property {object} navigationButtons.prev + * @property {string} [navigationButtons.prev.text='Prev'] - Text for previous navigation button + * @property {string} [navigationButtons.prev.text='icon-greater up'] - Icon for previous navigation button + * @property {object} navigationButtons.next + * @property {string} [navigationButtons.next.text='Next'] - Text for next navigation button + * @property {string} [navigationButtons.next.text='icon-greater down'] - Icon for next navigation button + * @property {object} navigationButtons.replay + * @property {string} [navigationButtons.replay.text='Back To Start'] - Text for replay navigation button + * @property {string} [navigationButtons.replay.text='icon-replay'] - Icon for replay navigation button + * @property {object} hintText - Hint text for each slide + * @property {string} hintText.default - Hint text for default slide + * @property {string} hintText.fist - Hint text for first slide + * @property {string} hintText.last - Hint text for last slide + */ + options.config = { + infinite: false, + initialSlideIndex: 0, + vertical: true, + timeout: 1000, + navigationButtons: { + prev: { + text: 'Prev', + icon: 'icon-greater up' + }, + next: { + text: 'Next', + icon: 'icon-greater down' + }, + replay: { + text: 'Back To Start', + icon: 'icon-replay' + } + }, + hintText: { + default: ``, + first: `Click arrows on phone to continue`, + last: `Click arrows on phone for previous` + }, + ...options.config + }; + + super(app, element, { + slideType: '', + previousIndex: -1, + currentIndex: options.config.initialSlideIndex || 0, + isScrolling: false, + isScrollingClass: '', + isTimeout: false, + collapseClass: 'expand', + isCollapsed: false, + collapseButtonClass: 'icon-collapse', + isCloseButtonVisible: false, + closeButtonText: 'Exit', + isControlsVisible: false, + ...options + }); + + Object.assign(this._state, { + isCloseButtonVisibleClass: this._class.isVisible[this._state.isCloseButtonVisible], + isControlsVisibleClass: this._class.isVisible[this._state.isControlsVisible] + }); + + this._children = { + track: null, + slides: [] + }; + + /** + * Tooltip for progress arrow. + * @type {tippy} + */ + this._progressTooltip = null; + + /** + * List of functions to call on entering a slide. + * @type {object} + */ + this._onEnter = {}; + + /** + * List of functions to call on leaving a slide. + * @type {object} + */ + this._onLeave = {}; + + /** + * Supported slide types. + * @type {Array} + */ + this._slideTypes = ['panel', 'overlay']; + + /** + * Current slide's info. + */ + this._currentInfo = null; + + /** + * Function to call on changing slide via button or scroll. + * @default + */ + this._onSlideChange = this.goToSlide; + + /** + * Function to call on clicking controls button. + * @type {Function} + */ + this._toggleControls = null; + + /** @inheritdoc */ + this._eventNames.push('slidechange', 'expandtoggle'); + this._initCallbacks(); + + // Binds + this.bindFunctions([ + '_setSlideTrackDimensions', + '_updateCarousel', + '_onScroll', + '_toggleCollapse', + '_onControlsToggle', + 'goToPrevSlide', + 'goToNextSlide', + 'close' + ]); + } + + /** + * Get current slide's info. + * @returns {object} + */ + get currentInfo() { + return this._currentInfo; + } + + /** + * Handle clicking controls button. + */ + _onControlsToggle() { + this._toggleControls(); + } + + /** + * Set function to call on clicking controls button. + * @param {Function} cb + */ + setOnControlsToggle(cb) { + this._toggleControls = cb; + } + + /** + * Initialize. + */ + init() { + super.init(); + + this._children.carousel.classList.add(this._config.vertical ? 'vertical' : 'horizontal'); + + this._createSlideTrack(); + this._updateCarousel(); + + this._children.carousel.classList.add('initialized'); + + // Edge case scenario fix + window.addEventListener('keydown', event => { + if (event.key === 'Tab' && this._state.isScrolling) { + event.preventDefault(); + } + }); + this._children.carousel.addEventListener('transitionstart', event => { + if (event.target === this._children.track && event.propertyName === 'transform') { + this.setState({ isScrolling: true, isScrollingClass: 'scrolling' }); + this._children.carousel.style.pointerEvents = 'all'; + } + }, true); + this._children.carousel.addEventListener('transitionend', event => { + if (event.target === this._children.track && event.propertyName === 'transform') { + this.setState({ isScrolling: false, isScrollingClass: 'scrolling-done' }); + this._children.carousel.style.pointerEvents = 'none'; + } + }, true); + + this._children.progress.addEventListener('wheel', this._onScroll, { passive: false }); + this._children.progress.addEventListener('touchstart', event => { + const touchEvent = event.changedTouches[0]; + this._touchStartY = touchEvent.pageY; + }); + this._children.progress.addEventListener('touchmove', event => { + const touchEvent = event.changedTouches[0]; + event.deltaY = touchEvent.pageY - this._touchStartY; + this._onScroll(event, 'touch'); + }, { passive: false }); + this._children.progress.addEventListener('touchend', event => { + const touchEvent = event.changedTouches[0]; + event.deltaY = touchEvent.pageY - this._touchStartY; + this._onScroll(event, 'touch'); + }, { passive: false }); + } + + /** @inheritdoc */ + resize() { + super.resize(); + setTimeout(this._setSlideTrackDimensions, 100); + + this._updateTooltipsProps(); + } + + /** + * Update tooltip props. + */ + _updateTooltipsProps() { + const { slideType } = this._state; + + this._progressTooltip.setProps({ + offset: slideType === 'overlay' + ? [0, -30] + : [0, 10] + }); + } + + /** + * Create slide track containing all slides. + */ + _createSlideTrack() { + this._children.slides.forEach(slide => { + this._children.track.appendChild(slide); + }); + this._setSlideTrackDimensions(); + } + + /** + * Set slide track width, height, and transition. + */ + _setSlideTrackDimensions() { + const { track, slides } = this._children; + const { vertical } = this._config; + + slides.forEach(slide => { + slide.style.transition = 'none'; + }); + + track.style.transition = 'none'; + if (vertical) { + const height = [...slides].reduce((acc, slide) => ( + acc + slide.getBoundingClientRect().height + ), 0); + track.style.height = height + 'px'; + } + else { + const width = [...slides].reduce((acc, slide) => ( + acc + slide.getBoundingClientRect().width + ), 0); + track.style.width = width + 'px'; + } + + track.style.transition = ''; + slides.forEach(slide => { + slide.style.transition = ''; + }); + this._updateTrackPosition(); + } + + /** + * Update track's position to current slide. + */ + _updateTrackPosition() { + const { currentIndex } = this._state; + + let trackOffset = 0; + for (let i = 0; i < currentIndex; i++) { + trackOffset += this._children.slides[i].getBoundingClientRect().height; + } + const translateValue = this._config.vertical + ? `translateY(-${trackOffset}px)` + : `translateX(-${trackOffset}px)`; + + this._children.track.style.transform = translateValue; + } + + /** + * Update slides' state. + */ + _updateSlides() { + const { previousIndex, currentIndex } = this._state; + + const previousSlide = this._children.slides[previousIndex]; + if (previousSlide) { + previousSlide.classList.remove('active'); + previousSlide.classList.add('hidden'); + } + + const currentSlide = this._children.slides[currentIndex]; + if (currentSlide) { + currentSlide.classList.remove('hidden'); + currentSlide.classList.add('active'); + } + } + + /** + * Update carousel. + */ + _updateCarousel() { + this._updateTrackPosition(); + this._updateSlides(); + } + + /** + * Handle scrolling. + * @param {Event} event + * @param {string} [type='mouse'] - Scroll type, can be 'mouse' or 'touch' + */ + _onScroll(event, type = 'mouse') { + if (this._state.isCollapsed && !this._state.isTimeout) { + this.expand(); + } + else if (!this._state.isScrolling && !this._state.isTimeout) { + // Since we use overlayscrollbars library, the scrolling element is os-viewport + const element = event.currentTarget.querySelector('.os-viewport') || event.currentTarget; + const scrollTop = element.scrollTop; + const scrolledToTop = scrollTop === 0; + // Ceiling is needed because the sum can be a float closed to scrollHeight + const scrolledToBottom = Math.ceil(element.getBoundingClientRect().height + scrollTop) >= element.scrollHeight; + + if (event.deltaY < 0) { + if (type === 'mouse') { + if (event.deltaY < -4 && scrolledToTop) { + this.goToPrevSlide(); + } + } + else { + if (event.deltaY < -5 && scrolledToBottom) { + this.goToNextSlide(); + } + } + } + else if (event.deltaY > 0) { + if (type === 'mouse') { + if (event.deltaY > 4 && scrolledToBottom) { + this.goToNextSlide(); + } + } + else { + if (event.deltaY > 5 && scrolledToTop) { + this.goToPrevSlide(); + } + } + } + } + + this.setState( + { isTimeout: true }, + () => setTimeout(() => this.setState({ isTimeout: false }), this._config.timeout) + ); + + // Need this to scroll inside panel + if (['wheel', 'touchmove'].includes(event.type)) { + event.stopPropagation(); + } + } + + /** + * Add a slide to carousel. + * @param {object} slideInfo + * @param {string} slideInfo.type - Slide type + * @param {HTMLElement} slideInfo.content - Content element of a slide + * @param {object} [options={}] + * @param {boolean} options.isFirst - Is first slide + * @param {boolean} options.isLast - Is last slide + */ + addSlide(slideInfo, { isLast = false, isFirst = false } = {}) { + const html = slideInfo.html || (_slide_template_html__WEBPACK_IMPORTED_MODULE_2___default()); + const { type, content } = slideInfo; + + if (!this._slideTypes.includes(type)) { + console.warn(`addSlide: Unknown slide type "${type}". Supported types: ${this._slideTypes}`); + } + + const slide = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.htmlWithParamsToElement(html, { + prevButtonText: this._config.navigationButtons.prev.text, + prevButtonIcon: this._config.navigationButtons.prev.icon, + nextButtonText: this._config.navigationButtons.next.text, + nextButtonIcon: this._config.navigationButtons.next.icon, + replayButtonText: this._config.navigationButtons.replay.text, + replayButtonIcon: this._config.navigationButtons.replay.icon, + hintText: () => { + if (isLast) { + return this._config.hintText.last; + } + else if (isFirst) { + return this._config.hintText.first; + } + else { + return this._config.hintText.default; + } + }, + type + }); + + slide.querySelector('.content').appendChild(content); + + if (isLast) { + slide.classList.add('last'); + } + if (isFirst) { + slide.classList.add('first'); + } + if (slideInfo.classList) { + slide.classList.add(...slideInfo.classList); + } + if (slideInfo.id) { + slide.dataset.id = slideInfo.id; + } + slide.dataset.type = slideInfo.type || ''; + this._children.track.appendChild(slide); + this._children.slides.push(slide); + + const slideContainer = slide.firstChild; + slideContainer.addEventListener('wheel', this._onScroll, { passive: false }); + slideContainer.addEventListener('touchstart', event => { + const touchEvent = event.changedTouches[0]; + this._touchStartY = touchEvent.pageY; + }); + slideContainer.addEventListener('touchmove', event => { + const touchEvent = event.changedTouches[0]; + event.deltaY = touchEvent.pageY - this._touchStartY; + this._onScroll(event, 'touch'); + }, { passive: false }); + slideContainer.addEventListener('touchend', event => { + const touchEvent = event.changedTouches[0]; + event.deltaY = touchEvent.pageY - this._touchStartY; + this._onScroll(event, 'touch'); + }, { passive: false }); + + this._setVariables(slide); + this._setEventHandlersFromAttributes(slide); + this._setSlideTrackDimensions(); + this._updateCarousel(); + + _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addScrollbar(slideContainer); + + this._progressTooltip = (0,tippy_js__WEBPACK_IMPORTED_MODULE_3__["default"])(this._children.progress.parentElement, { + theme: 'default', + onShow(instance) { + clearTimeout(instance.timeout); + instance.timeout = setTimeout(() => { + instance.hide(); + }, 2000); + } + }); + } + + /** + * Add multiple slides to carousel. + * @param {Array} slidesInfo + */ + addSlides(slidesInfo) { + for (let i = 0; i < slidesInfo.length; i++) { + this.addSlide(slidesInfo[i]); + } + } + + /** + * On entering a slide. + * @param {number} index + * @returns {Promise} + */ + async onEnter(index) { + const onEnter = this._onEnter[index]; + for (let i = 0; i < onEnter.length; i++) { + if (typeof onEnter[i] === 'function') { + await onEnter[i](); + } + } + } + + /** + * On leaving a slide. + * @param {number} index + * @returns {Promise} + */ + async onLeave(index) { + if (!(typeof index === 'number')) { + index = this._state.currentIndex; + } + const onLeave = this._onLeave[index]; + for (let i = 0; i < onLeave.length; i++) { + if (typeof onLeave[i] === 'function') { + await onLeave[i](); + } + } + } + + /** + * Go to slide using index. + * @param {number} currentIndex + * @returns {Promise} + */ + async goToSlide(currentIndex) { + const { spout, spoutFontSize } = this.app.getManager('router').configs; + + const previousIndex = this._state.currentIndex; + if (currentIndex !== previousIndex) { + await this.onLeave(previousIndex); + } + + const slideType = this._children.slides[currentIndex].dataset.type; + this.setState({ + currentIndex, + previousIndex, + slideType + }, () => { + this._updateCarousel(); + this._children.progress.style.top = `calc(${currentIndex * 100 / (this._children.slides.length - 1)}% - ${this._children.progress.offsetHeight / 2}px)`; + // Since we use overlayscrollbars library, the scrolling element is os-viewport + const element = this._children.slides[currentIndex].querySelector('.os-viewport'); + if (element) { + element.scrollTop = 0; + } + + this.triggerCallbacks('slidechange', [this._currentInfo]); + + // Update tooltip + this._progressTooltip.setContent(`${currentIndex + 1} of ${this._children.slides.length}`); + this._updateTooltipsProps(); + if (this._state.isVisible) { + // this._progressTooltip.show(); + } + }); + + await this.onEnter(currentIndex); + + if (spout === true) { + await this.app.getManager('spout').setUpSpoutLabels(spoutFontSize); + } + + } + + /** + * Go to previous slide. + */ + goToPrevSlide() { + const { currentIndex } = this._state; + const lastSlideIndex = this._children.slides.length - 1; + + const slideToGo = currentIndex - 1; + if (slideToGo < 0) { + if (this._config.infinite) { + this._onSlideChange(lastSlideIndex); + } + } + else { + this._onSlideChange(slideToGo); + } + } + + /** + * Go to next slide. + */ + goToNextSlide() { + const { currentIndex } = this._state; + const lastSlideIndex = this._children.slides.length - 1; + + const slideToGo = currentIndex + 1; + if (slideToGo > lastSlideIndex) { + if (this._config.infinite) { + this._onSlideChange(0); + } + } + else { + this._onSlideChange(slideToGo); + } + } + + /** + * Go to first slide. + */ + goToFirstSlide() { + this._onSlideChange(0); + } + + /** + * Returns visible state. + * @returns {boolean} + */ + isVisible() { + return this._state.isVisible; + } + + /** + * Collapses panel. + */ + collapse() { + this.setState({ isCollapsed: true, collapseClass: 'collapse', collapseButtonClass: 'icon-expand' }); + this.triggerCallbacks('expandtoggle', [false]); + } + + /** + * Expands panel. + */ + expand() { + this.setState({ isCollapsed: false, collapseClass: 'expand', collapseButtonClass: 'icon-collapse' }); + this.triggerCallbacks('expandtoggle', [true]); + } + + /** + * Close carousel. + */ + close() { + } + + /** + * @override + */ + show() { + super.show(); + this._updateCarousel(); + if ((this._progressTooltip !== null) && (this._children.slides.length > 1)) { + // this._progressTooltip.show(); + } + } + + /** + * Clear carousel slides. + */ + clear() { + this._children.track.innerHTML = ''; + this._children.slides = []; + this._onEnter = {}; + this._onLeave = {}; + this._currentInfo = null; + this._state.previousIndex = 1; + this._state.currentIndex = this._config.initialSlideIndex || 0; + } + + /** + * Toggles between expand and collapse states. + */ + _toggleCollapse() { + if (this._state.isCollapsed) { + this.expand(); + } + else { + this.collapse(); + } + } +} + +Carousel.html = (_carousel_html__WEBPACK_IMPORTED_MODULE_1___default()); + +/* harmony default export */ __webpack_exports__["default"] = (Carousel); + + +/***/ }), + +/***/ "../eyes/src/components/carousel/index.js": +/*!************************************************!*\ + !*** ../eyes/src/components/carousel/index.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _carousel_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./carousel.js */ "../eyes/src/components/carousel/carousel.js"); + + + + +/* harmony default export */ __webpack_exports__["default"] = (_carousel_js__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/carousel_panel/carousel_panel.js": +/*!***************************************************************!*\ + !*** ../eyes/src/components/carousel_panel/carousel_panel.js ***! + \***************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var swiper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! swiper */ "../eyes/node_modules/swiper/swiper.esm.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _carousel_panel_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./carousel_panel.html */ "../eyes/src/components/carousel_panel/carousel_panel.html"); +/* harmony import */ var _carousel_panel_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_carousel_panel_html__WEBPACK_IMPORTED_MODULE_2__); + + + + +swiper__WEBPACK_IMPORTED_MODULE_0__["default"].use([swiper__WEBPACK_IMPORTED_MODULE_0__.Navigation, swiper__WEBPACK_IMPORTED_MODULE_0__.Pagination, swiper__WEBPACK_IMPORTED_MODULE_0__.Keyboard, swiper__WEBPACK_IMPORTED_MODULE_0__.Mousewheel]); + +/** + * The carousel panel component is a collapsible panel with a swiper carousel. + * The content passed to this component determines the content of the carousel. It can either be a component, or pure HTML. + */ +class CarouselPanel extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseComponent { + /** + * Constructor + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options = {}) { + /** + * NOTE: + * It's important to be able to use multiple swiper carousels in the same app. + * Therefore we need to make sure we're using unique classes to pass to the Swiper config in order that it connects to the correct elements. + * Only the classes used for CSS styling should remain the same between multiple swiper carousel instances. + */ + + const { paginationClass, prevButtonClass, nextButtonClass } = options; + + options.config = { + direction: 'horizontal', + + speed: 600, + grabCursor: true, + + touchStartPreventDefault: false, + + slidesPerView: 1, + spaceBetween: 100, + keyboard: { + enabled: true + }, + mousewheel: { + forceToAxis: true, + thresholdDelta: 100 + }, + + // Navigation arrows + navigation: { + prevEl: `.${prevButtonClass}`, + nextEl: `.${nextButtonClass}` + }, + + // Conditional pagination if we have a pagination class + + ...paginationClass && { + pagination: { + el: `.${paginationClass}`, + type: 'custom', + renderCustom: (swiper, current, total) => `${current} of ${total}` + } + }, + + ...options.config + }; + + + super(app, null, { + isVisible: false, + // text + // note: despite these being fixed values, they only work in the HTML template if they're in state + preTitle: 'viewing', + title: 'Panel Title', + caption: 'This is the panel subtitle', + + // classes + carouselClass: '', + paginationClass: '', + prevButtonClass: '', + nextButtonClass: '', + isExpandedClass: 'collapsed', + tabsVisibleClass: 'hidden', + tabNumClass: '', + + ...options + }); + + /** + * Define swiper prop + */ + this._swiper = null; + + /** + * Define tab inidices. + */ + this._tabIndices = null; + + /** Define the active tab index */ + this._activeTabIndex = null; + + /** + * All tab elements + */ + this._tabElements = null; + + /** + * Class name props + */ + this._bulletClass = 'swiper-pagination-bullet'; + this._activeBulletClass = 'swiper-pagination-bullet-active'; + this._swiperSlideClass = 'swiper-slide'; + + /** + * Slide change callback + */ + this._onSlideChange = null; + + /** + * Does showing the panel also expand it + */ + this._expandOnShow = false; + + /** + * Orientation store + */ + this._orientation = null; + + /** + * Resize timeout + */ + this._resizeTimeout = null; + + /** + * _isInitialized boolean. + */ + this._isInitialized = null; + + /** + * Create an expandtoggle callback + */ + this._eventNames.push('expandtoggle'); + this._initCallbacks(); + + // Bind functions. + this.bindFunctions(['_onTabClick']); + } + + /** + * Add swiper events + * NOTE: + * Normally, when a components state is determined by the URL, buttons and gestures on the component itself should only update the URL. + * However, in the case of swiper, the draggable component needs to be animating BEFORE we know which URL to go to. Therefore we're instead allowing + * all of the built in swiping animations, and then changing the URL simultaneously. + * We have to be careful with this method to avoid letting the component and URL go out of sync. For unstance, if the user were to manually enter a URL. + */ + _addEvents() { + this._swiper.on('slideChange', params => { + const { realIndex, previousIndex } = params; + let bulletIndex = realIndex; + + // Call onSlideChange if set (in sub class) + typeof this._onSlideChange === 'function' && this._onSlideChange(params); + + // Check if the previous slide had a scrollbar, if so, scroll to top and make sure mousedown is false + const prevSlideEl = this._children.swiperSlides.childNodes[previousIndex]; + if (prevSlideEl?._scrollInstance) { + prevSlideEl._isMousedown = false; + prevSlideEl._scrollInstance.scroll(0); + } + + // If we have tabs, we may need to toggle the active class for all tab elements. + if (this._tabElements) { + const newTabIndex = this._tabIndices.findIndex(({ start, end }) => realIndex >= start && realIndex <= end); + + const { start } = this._tabIndices[newTabIndex]; + bulletIndex -= start; + + if (newTabIndex > -1 && newTabIndex !== this._activeTabIndex) { + this._tabElements.forEach((tabEl, i) => { + tabEl.classList.toggle('active', i === newTabIndex); + }); + + this._activeTabIndex = newTabIndex; + + // Make sure we re-create and replace the bullets. + this._createBullets(bulletIndex); + + return; + } + } + + // Update the active bullet + this._setActiveBullet(bulletIndex); + }); + + // Click event to handle definition overlays + this._children.swiperSlides.addEventListener('click', event => { + const definition = event?.target?.dataset?.def; + if (definition) { + this._app.getComponent('definitionOverlay').navigateToDefinition(definition); + } + }); + } + + /** + * Checks whether orientation has changed and sets new orientation. + * @returns {boolean} + */ + _hasOrientationChanged() { + const newOrientation = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.isPortrait() ? 'portrait' : 'landscape'; + const orientationChanged = this._orientation !== newOrientation; + this._orientation = newOrientation; + + return orientationChanged; + } + + /** + * Check the scroll height of each slide to determine whether it requires a scrollbar. + */ + _addScrollbars() { + // Test for orientation change and record orientation. + const orientationChanged = this._hasOrientationChanged(); + + this._children?.swiperSlides?.childNodes?.forEach(slideEl => { + const { clientHeight, scrollHeight, cHeight, sHeight } = slideEl; + + const heightUnchanged = (cHeight && cHeight === clientHeight) && (sHeight && sHeight === scrollHeight); + + + // Return if no height changes. + if (heightUnchanged && !orientationChanged) { + return; + } + + // Destroy old scrollbar if exists. + slideEl._scrollInstance?.destroy(); + + // Get new heights. + const { clientHeight: newClientHeight, scrollHeight: newScrollHeight } = slideEl; + slideEl.sHeight = newClientHeight; + slideEl.cHeight = newScrollHeight; + + + // Compare new element heights to see if we need a scrollbar again. + if (newScrollHeight > newClientHeight) { + slideEl.classList.add('scrollable'); + + slideEl._scrollInstance ??= _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.addScrollbar(slideEl); + + + // Add click and drag scrolling (seemingly not included in OverlayScrollbars) + slideEl._isMousedown = false; + slideEl._clientY = 0; + + const onMouseMove = ({ clientY }) => { + if (slideEl._isMousedown) { + const yDiff = slideEl._clientY - clientY; + slideEl._scrollInstance.scroll({ y: `+=${yDiff}` }); + slideEl._clientY = clientY; + } + }; + + slideEl.onmousedown = ({ clientY }) => { + slideEl._isMousedown = true; + slideEl._clientY = clientY; + + window.addEventListener('mousemove', onMouseMove); + window.addEventListener('mouseup', function onMouseUp() { + slideEl._isMousedown = false; + window.removeEventListener('mousemove', onMouseMove); + window.removeEventListener('mouseup', onMouseUp); + }); + }; + } + }); + } + + /** + * Create tabs with content + * @param {Array} allTabsContent + */ + createTabs(allTabsContent) { + // Set tab indices to empty array. + this._tabIndices = []; + this._activeTabIndex = 0; + let indexPointer = 0; + + // if we already have a panel, we need to destroy it. + if (this._swiper) { + this._destroy(); + } + + // Create the tab elements and append them to tab container. + this._tabElements = allTabsContent.map(({ title, content }, i) => { + const tabButtonEl = document.createElement('button'); + tabButtonEl.innerHTML = title; + tabButtonEl.className = `clickable ${i === this._activeTabIndex ? 'active' : ''}`; + tabButtonEl.addEventListener('click', this._onTabClick); + + // Add tab start and end indices. + this._tabIndices.push({ + start: indexPointer, + end: indexPointer + content.length - 1 + }); + indexPointer += content.length; + + + // Create the slide element from the tab data and add slide. + for (const tabData of content) { + const slideElements = this._createSlideElements(tabData); + this.addSlide(slideElements, tabData.onClick); + } + + return tabButtonEl; + }); + + this._children.tabsContainer.replaceChildren(...this._tabElements); + + + // Make sure we set the tabs class to be visible and num tabs class. + this.setState({ + tabsVisibleClass: '', + tabNumClass: `tabs-${this._tabElements.length}` + }); + } + + /** + * Create slide elements from tab data + * @param {object} tabData - content info + * @returns {HTMLElement} + */ + _createSlideElements(tabData) { + const { title, content, value } = tabData; + + const slideElements = []; + + if (title) { + const titleEl = document.createElement('h4'); + titleEl.className = 'title semi'; + titleEl.innerHTML = title; + slideElements.push(titleEl); + } + + if (content) { + const contentEl = document.createElement('div'); + contentEl.className = 'description'; + contentEl.innerHTML = content; + slideElements.push(contentEl); + } + + if (value) { + const valueEl = document.createElement('div'); + valueEl.className = 'value semi'; + valueEl.innerHTML = value; + slideElements.push(valueEl); + } + + return slideElements; + } + + /** + * Create bullet pagination + * @param {number} activeBullet + */ + _createBullets(activeBullet = 0) { + const { bullets } = this._children; + const { slides } = this._swiper; + + let slidesArray = [...slides]; + let startOffset = 0; + + if (this._tabElements) { + const { start, end } = this._tabIndices[this._activeTabIndex]; + startOffset = start; + slidesArray = slidesArray.slice(start, end + 1); + } + + const allBullets = [...slidesArray].map((slide, i) => { + const bullet = document.createElement('span'); + bullet.classList.add(this._bulletClass); + + // Set slide index. + bullet.setAttribute('data-slide-index', i + startOffset); + + // Add the click event + bullet.addEventListener('click', e => { + const { slideIndex } = e.target.dataset; + + this._swiper.slideTo(slideIndex); + }); + + return bullet; + }); + + + // Hide the bullets, replace them, then show them again. + const onHideFinish = transition => { + if (transition && transition.propertyName !== 'width') { + return; + } + + // Replace the bullets and unhide. + bullets.replaceChildren(...allBullets); + bullets.classList.remove('hidden'); + + // Set default active bullet to index 0 if initial create + this._setActiveBullet(activeBullet); + }; + + // Check if already hidden, if so call onHideFinish. + if (bullets.classList.contains('hidden')) { + onHideFinish(); + } + else { + bullets.classList.add('hidden'); + bullets.ontransitionend = onHideFinish; + bullets.ontransitioncancel = onHideFinish; + } + } + + /** + * Makes sure all bullets are deactivated except the passed index + * @param {number} activeIndex + */ + _setActiveBullet(activeIndex) { + const { bullets } = this._children; + + bullets.childNodes.forEach((bullet, i) => { + bullet.classList.remove(this._activeBulletClass); + if (i === activeIndex) { + bullet.classList.add(this._activeBulletClass); + } + }); + } + + /** + * Add an array of elements as a slide to the carousel + * @param {Array} elements + * @param {Function|null} onClick + */ + addSlide(elements = [], onClick) { + const slideEl = document.createElement('div'); + + // Determine classes. + slideEl.className = `${onClick ? 'clickable' : ''} ${this._swiperSlideClass}`; + + // Add click event listener if it exists + onClick && slideEl.addEventListener('click', onClick); + + slideEl.replaceChildren(...elements); + + this._children.swiperSlides.append(slideEl); + } + + /** + * Wait for slides DOM detection, + * create the swiper object, + * call post swiper init function + * @returns {Promise} + */ + initSwiper() { + const { carouselClass } = this._state; + + const selector = `.${carouselClass} .swiper-wrapper > div`; + + return _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.elementReady(selector) + .then(() => { + // If there's already a swiper, update it, add bullet and slide to zero. + if (this._swiper) { + this._swiper.update(); + + // Add scrollbars and bullets. + this._addScrollbars(); + this._createBullets(); + + this._swiper.slideTo(0); + } + else { + // Otherwise, create it. + this._swiper = new swiper__WEBPACK_IMPORTED_MODULE_0__["default"](`.${carouselClass}`, this._config); + this._postSwiperInitFunction(this._swiper); + } + }); + } + + + /** + * Called after swiper is initialized. + */ + _postSwiperInitFunction() { + // Add event handler + this._addEvents(); + + // Add scrollbars + this._addScrollbars(); + + // Add bullets + this._createBullets(); + + // Slide to zero. + this._swiper.update(); + this._swiper.slideTo(0); + } + + /** + * Destroy the slider + */ + _destroy() { + this._children.swiperSlides.innerHTML = ''; + clearTimeout(this._resizeTimeout); + } + + /** + * Handles a tab select + * @param {Event} e + */ + _onTabClick(e) { + // Slide to correct start index. + const activeTabIndex = this._tabElements.findIndex(tab => tab === e.target); + const { start } = this._tabIndices[activeTabIndex]; + this._swiper.slideTo(start); + } + + /** + * Expands panel + */ + expand() { + this.setState({ isExpanded: true, isExpandedClass: 'expanded' }); + this.triggerCallbacks('expandtoggle', [true]); + } + + /** + * Collapses panel + */ + collapse() { + this.setState({ isExpanded: false, isExpandedClass: 'collapsed' }); + this.triggerCallbacks('expandtoggle', [false]); + } + + /** + * Sets expand state and triggers callback + * @param {boolean} expanded + */ + setExpandState(expanded) { + this.setState({ isExpanded: expanded, isExpandedClass: expanded ? 'expanded' : 'collapsed' }); + this.triggerCallbacks('expandtoggle', [expanded]); + } + + + /** + * Show override can also conditionally expand the panel + * @param {boolean} initSwiper + */ + show(initSwiper = true) { + // Init the swiper if the UI is visible and there is content. + const visibleUI = this._app.getManager('layer').getLayer('ui').visible; + const hasSwiperContent = this._children.swiperSlides?.childNodes?.length; + + const showFunc = () => { + if (this._expandOnShow) { + this.setState({ + isVisible: true, + isVisibleClass: this._class.isVisible.true, + isExpanded: true, + isExpandedClass: 'expanded' + }); + + this.triggerCallbacks('expandtoggle', [true]); + this.triggerCallbacks('visiblechange', [true]); + } + else { + super.show(); + } + }; + + if (initSwiper && visibleUI && hasSwiperContent) { + this.initSwiper().then(() => showFunc()); + } + else { + showFunc(); + } + } + + + /** + * Hide override to also collapse the panel + */ + hide() { + this.setState({ + isVisible: false, + isVisibleClass: this._class.isVisible.false, + isExpanded: false, + isExpandedClass: 'collapsed' + }); + + this.triggerCallbacks('expandtoggle', [false, false]); + this.triggerCallbacks('visiblechange', [false]); + + // Set init boolean to false only if we're expandingOnShow + if (this._expandOnShow) { + this._isInitialized = false; + } + } + + /** + * Resize. + * Updating the scrollbars requires a timeout to wait for other components to finish moving / resizing. + */ + resize() { + // ToDo: Can also use lodash's debounced. + clearTimeout(this._resizeTimeout); + this._resizeTimeout = setTimeout(() => { + this._addScrollbars(); + }, 200); + } +} + +CarouselPanel.html = (_carousel_panel_html__WEBPACK_IMPORTED_MODULE_2___default()); +/* harmony default export */ __webpack_exports__["default"] = (CarouselPanel); + + +/***/ }), + +/***/ "../eyes/src/components/carousel_panel/index.js": +/*!******************************************************!*\ + !*** ../eyes/src/components/carousel_panel/index.js ***! + \******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _carousel_panel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./carousel_panel */ "../eyes/src/components/carousel_panel/carousel_panel.js"); + + + + + + + + +/* harmony default export */ __webpack_exports__["default"] = (_carousel_panel__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/checkbox/checkbox.js": +/*!***************************************************!*\ + !*** ../eyes/src/components/checkbox/checkbox.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Checkbox": function() { return /* binding */ Checkbox; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _checkbox_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./checkbox.html */ "../eyes/src/components/checkbox/checkbox.html"); +/* harmony import */ var _checkbox_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_checkbox_html__WEBPACK_IMPORTED_MODULE_1__); + + + +/** + * @inheritdoc + * @extends BaseComponent + */ +class Checkbox extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + super(app, null, { + config: { + key: '', + colorClass: '', + function: null + }, + isChecked: false, + text: '', + checkboxClass: '', + textClass: '', + ...options + }); + + // Storing class names + Object.assign(this._class, { + checkbox: { + true: 'checked', + false: '' + }, + color: { + true: this._config.colorClass, + false: '' + }, + checkmark: { + true: 'icon-checkmark', + false: 'checkbox-hover' + } + }); + + Object.assign(this._state, { + isCheckedClass: this._class.checkbox[this._state.isChecked], + colorClass: this._class.color[this._state.isChecked], + iconCheckmarkClass: this._class.checkmark[this._state.isChecked] + }); + + this.bindFunctions(['toggle']); + } + + /** @inheritdoc */ + init() { + super.init(); + + if (this._config.key) { + this._element.setAttribute('key', this._config.key); + } + + this._element.addEventListener('click', this.toggle); + } + + /** + * Called on clicking checkbox. + * @param {PointerEvent} e + * @param {boolean} [suppress=false] - Only update states, suppress the function call if True. + * @returns {Promise} + */ + async toggle(e, suppress = false) { + const isChecked = !this._state.isChecked; + const isCheckedClass = this._class.checkbox[isChecked]; + const colorClass = this._class.color[isChecked]; + const iconCheckmarkClass = this._class.checkmark[isChecked]; + + this.setState({ + isChecked, + isCheckedClass, + colorClass, + iconCheckmarkClass + }, async () => { + if (!suppress && this._config.function instanceof Function) { + await this._config.function(e); + } + }); + } +} + +Checkbox.html = (_checkbox_html__WEBPACK_IMPORTED_MODULE_1___default()); + +/* harmony default export */ __webpack_exports__["default"] = (Checkbox); + + +/***/ }), + +/***/ "../eyes/src/components/checkbox/index.js": +/*!************************************************!*\ + !*** ../eyes/src/components/checkbox/index.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _checkbox_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./checkbox.js */ "../eyes/src/components/checkbox/checkbox.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = (_checkbox_js__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/clock/clock.js": +/*!*********************************************!*\ + !*** ../eyes/src/components/clock/clock.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Clock": function() { return /* binding */ Clock; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _clock_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./clock.html */ "../eyes/src/components/clock/clock.html"); +/* harmony import */ var _clock_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_clock_html__WEBPACK_IMPORTED_MODULE_2__); + + + + +/** + * @inheritdoc + * @extends BaseComponent + */ +class Clock extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + super(app, null, { + isVisible: false, + isDateVisible: true, + isTimeVisible: true, + isMeridiemVisible: true, + allowEdit: true, + date: 'Date', + time: 'Time', + meridiem: '', + alert: '', + isKioskSessionTimer: false, + ...options + }); + + Object.assign(this._state, { + isDateVisibleClass: this._class.isVisible[this._state.isDateVisible], + isTimeVisibleClass: this._class.isVisible[this._state.isTimeVisible], + isMeridiemVisibleClass: this._class.isVisible[this._state.isMeridiemVisible] + }); + + this.bindFunctions(['update', 'onDateTimeClick']); + } + + /** @inheritdoc */ + init() { + super.init(); + const { allowEdit, isKioskSessionTimer } = this._state; + + this._app.getManager('time').setDateFormats({ + utc: { + date: 'MMM DD, YYYY', + time: 'HH[:]mm[:]ss' + }, + local: { + date: 'MMM DD, YYYY', + time: 'hh[:]mm[:]ss', + meridiem: 'a', + parse: ['MMM D, YYYY h:m:s a', 'MMM D, YYYY h:m a', 'MMM D, YYYY h a', 'MMM D, YYYY'] + } + }); + + this._app.getManager('time').setDisplayUTC(false); + + const { displayContainer, timeInput, timeForm } = this._children; + + // Time input + if (allowEdit) { + displayContainer.classList.add('editable'); + timeInput.addEventListener('keyup', event => { + event.stopPropagation(); + }); + timeInput.addEventListener('keydown', event => { + event.stopPropagation(); + }); + + // Time form + timeForm.classList.add('editable'); + timeForm.addEventListener('submit', event => { + timeInput.blur(); + this._parseTime(timeInput.value); + event.preventDefault(); + }); + timeInput.addEventListener('blur', _ => { + timeForm.classList.add('hidden'); + displayContainer.classList.remove('hidden'); + }); + } + + this._setVariables(this._element); + + this._children.date.classList.add('semi'); + this._children.time.classList.add('semi'); + this._children.meridiem.classList.add('semi'); + this._children.timeInput.classList.add('semi'); + this._children.timeForm.classList.add('semi'); + + if (!isKioskSessionTimer) { + this._callbackRegistry.push({ + emitter: this._app.getManager('time'), + event: 'update', + callback: this.update + }); + } + } + + /** + * Handle date/time click + */ + onDateTimeClick() { + const { displayContainer, timeInput, timeForm, date, time, meridiem } = this._children; + + const routeManager = this._app.getManager('router'); + const isStory = routeManager.currentRoute.url.includes('story'); + + if (!this._state.allowEdit || isStory) { + return; + } + const meridiemText = this._state.meridiem ? ` ${meridiem.innerHTML}` : ''; + timeInput.value = `${date.innerHTML} ${time.innerHTML}${meridiemText}`; + displayContainer.classList.add('hidden'); + timeForm.classList.remove('hidden'); + timeInput.focus(); + } + + /** + * Checks if time should be Earth Received Time. + * @returns {boolean} + */ + isERT() { + return this._isERT; + } + + /** + * Toggle clock field's visibility. + * @param {string} field - date, time, or meridiem + * @param {boolean} isVisible + */ + toggle(field, isVisible) { + switch (field) { + case 'date': + this.setState({ + isDateVisible: isVisible, + isDateVisibleClass: this._class.isVisible[isVisible] + }); + break; + case 'time': + this.setState({ + isTimeVisible: isVisible, + isTimeVisibleClass: this._class.isVisible[isVisible] + }); + break; + case 'meridiem': + this.setState({ + isMeridiemVisible: isVisible, + isMeridiemVisibleClass: this._class.isVisible[isVisible] + }); + break; + default: + break; + } + } + + /** + * Parse and set time from input value. + * @param {string} timeString + */ + _parseTime(timeString) { + const router = this._app.getManager('router'); + const time = this._app.getManager('time').parseTime(timeString, 'parse'); + if (time.isValid()) { + // If time is UTC, force to UTC + // Otherwise force to local + this._app.getManager('time').setDisplayUTC(time.isUTC()); + const timeUrl = this._app.getManager('time').getTimeUrl(time); + // Navigate to time + router.navigate({ time: timeUrl }, router.currentRoute.url); + } + else { + console.error('Invalid input: ' + timeString); + // Remove time from query, which will reset time to now. + // In case time is not in query, it won't do anything. + router.navigate({ __remove: ['time'] }, router.currentRoute.url); + } + } + + /** + * Update time display. + * @param {moment} time + * @param {boolean} kioskCountdown - if updating a kiosk session timer + */ + update(time, kioskCountdown = false) { + // Don't update if not visible + if (!this._state.isVisible) { + return; + } + + // If a kiosk countdown, only update the clock with the time passed in + if (kioskCountdown) { + this.setState({ time }); + } + else { + // Update with regular time and date + this.setState({ + date: time.format(this._app.getManager('time').getDateFormat('date')), + time: time.format(this._app.getManager('time').getDateFormat('time')), + meridiem: this._app.getManager('time').isUTC() ? '' : time.format(this._app.getManager('time').getDateFormat('meridiem')), + alert: this._app.getManager('time').forcedPause ? 'alert' : '' + }); + } + } + + /** + * Change time rate to 1s/s and time to real time. + */ + backToLive() { + const router = this._app.getManager('router'); + const timeManager = this._app.getManager('time'); + if (!timeManager.isNow()) { + const time = timeManager.getTimeUrl(timeManager.getNow()); + const oldTime = router.query.time; + + router.navigate({ + __remove: ['time', 'rate'] + }, router.currentRoute.url); + + if (oldTime !== time) { + timeManager.setTimeRate(1); + timeManager.setToNow(); + } + } + } + + /** + * Sets the limit message and calls show/hide. + * @param {number} limit - : 1 is max exceeded, -1 is min preceeded + * @param {string} message + */ + setLimitMessage(limit, message) { + // Set the limit message. + const messageTimeMs = 3000; + + let limitMessage; + + if (!message) { + // Determine limit message. + const { currentView } = this._app.getManager('router'); + const { _isSpacecraft } = this._app.getView(currentView); + let messageSuffix = `time ${limit === 1 ? 'maximum' : 'minimum'}`; + + if (currentView === 'event') { + messageSuffix = `event ${limit === 1 ? 'end' : 'start'}`; + } + else if (_isSpacecraft) { + messageSuffix = `mission ${limit === 1 ? 'end' : 'start'}`; + } + + limitMessage = limit === 1 ? `"cannot exceed ${messageSuffix}"` : `"cannot preceed ${messageSuffix}"`; + } + else { + limitMessage = `"${message}"`; + } + + this._children.displayContainer?.style.setProperty('--limit-message', limitMessage); + + // Display the message. + this._displayLimitMessage(true); + + // Allow time to read then hide the message. + this.limitMessageTimeout = setTimeout(() => { + this._displayLimitMessage(false); + }, messageTimeMs); + } + + /** + * Show or hide the limit message. + * @param {boolean} visible + */ + _displayLimitMessage(visible) { + this._children.displayContainer?.classList.toggle('limit', visible); + } + + /** + * Overwritten base __disable. + */ + __disable() { + this._displayLimitMessage(false); + clearTimeout(this.limitMessageTimeout); + + super.__disable(); + } +} + +Clock.html = (_clock_html__WEBPACK_IMPORTED_MODULE_2___default()); + +/* harmony default export */ __webpack_exports__["default"] = (Clock); + + +/***/ }), + +/***/ "../eyes/src/components/clock/index.js": +/*!*********************************************!*\ + !*** ../eyes/src/components/clock/index.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _clock_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./clock.js */ "../eyes/src/components/clock/clock.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = (_clock_js__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/clock_shortcut/clock_shortcut.js": +/*!***************************************************************!*\ + !*** ../eyes/src/components/clock_shortcut/clock_shortcut.js ***! + \***************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var tippy_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tippy.js */ "../eyes/node_modules/tippy.js/dist/tippy.esm.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _clock_shortcut_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./clock_shortcut.html */ "../eyes/src/components/clock_shortcut/clock_shortcut.html"); +/* harmony import */ var _clock_shortcut_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_clock_shortcut_html__WEBPACK_IMPORTED_MODULE_2__); + + + + + +/** + * @inheritdoc + * @extends BaseComponent + */ +class ClockShortcut extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + */ + constructor(app) { + super(app, null, { + hasHover: false, + liveContainerClass: 'hidden', + liveClass: 'live', + liveText: 'live', + liveIcon: 'icon-live', + replayClass: 'container', + replayIcon: 'icon-replay' + }); + + this._state.replayClass = 'hidden'; + this._class.fontSize.small = 'x-small'; + + /** + * Callback to override back to live behavior. + * @type {Function} + */ + this._liveCallback = null; + + this.bindFunctions(['_replay', 'backToLive', 'update']); + } + + /** @inheritdoc */ + init() { + super.init(); + + // This is not dynamic, so switching betweem desktop and mobile will not update these event listeners... + const { canHover, isTouch } = this._app; + if (canHover && !isTouch) { + this._children.liveContainer.addEventListener('mouseenter', () => { + this.setState({ + hasHover: true, + liveIcon: 'icon-live' + }); + }); + this._children.liveContainer.addEventListener('mouseleave', () => { + this.setState({ + hasHover: false, + liveIcon: 'icon-back-to-live' + }); + }); + } + + /** + * Set default tippy props + * See docs: https://atomiks.github.io/tippyjs/v6/methods/ + */ + tippy_js__WEBPACK_IMPORTED_MODULE_3__["default"].setDefaultProps({ + theme: 'default', + touch: ['hold', 2000], + delay: [600, null], + plugins: [tippy_js__WEBPACK_IMPORTED_MODULE_3__.followCursor] + }); + (0,tippy_js__WEBPACK_IMPORTED_MODULE_3__["default"])(this._children.liveContainer, { content: 'Reset time to live.', placement: 'top' }); + + this._children.live.classList.add('semi', 'color'); + this._children.replay.classList.add('semi', 'color'); + + // Remove replay element + this._element.removeChild(this._children.replayContainer); + + this._callbackRegistry.push({ + emitter: this._app.getManager('time'), + event: 'update', + callback: this.update + }); + } + + /** + * Sets a custom callback for the go back to live button. + * @param {Function} callback + */ + setCallback(callback) { + if (typeof callback === 'function') { + this._liveCallback = callback; + } + else { + this._liveCallback = null; + } + } + + /** + * Change time rate to 1s/s and time to real time. + */ + backToLive() { + if (typeof this._liveCallback === 'function') { + this._liveCallback(); + } + else { + const router = this._app.getManager('router'); + const timeManager = this._app.getManager('time'); + if (!timeManager.isNow()) { + const time = timeManager.getTimeUrl(timeManager.getNow()); + const oldTime = router.query.time; + + router.navigate({ + __remove: ['time', 'rate'] + }, router.currentRoute.url); + + if (oldTime !== time) { + timeManager.setTimeRate(1); + timeManager.setToNow(); + } + } + } + } + + /** + * Change time rate to 1s/s and time to start time. + */ + _replay() { + const navigated = this._app.getManager('router').navigate({ __remove: ['time', 'rate'] }); + if (!navigated) { + this._app.getManager('time').setTimeRate(1); + this._app.getManager('time').setToStart(); + } + } + + /** + * Update time display. + * @param {moment} time + */ + update(time) { + // Don't update if not visible + if (!this._state.isVisible) { + return; + } + const isNow = this._app.getManager('time').isNow(); + const now = this._app.getManager('time').getNow(); + const inBounds = this._app.getManager('time').isWithinLimits(now); + + const newState = { + liveContainerClass: (inBounds === 0) ? (isNow ? 'active' : 'clickable') : 'hidden', + liveClass: isNow ? 'live' : '', + replayClass: _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.isMobileMode() ? 'icon icon-box' : 'container' + }; + + if (!this._state.hasHover) { + newState.liveIcon = isNow ? 'icon-live' : 'icon-back-to-live'; + } + this.setState(newState); + } +} + +ClockShortcut.html = (_clock_shortcut_html__WEBPACK_IMPORTED_MODULE_2___default()); + +/* harmony default export */ __webpack_exports__["default"] = (ClockShortcut); + + +/***/ }), + +/***/ "../eyes/src/components/clock_shortcut/index.js": +/*!******************************************************!*\ + !*** ../eyes/src/components/clock_shortcut/index.js ***! + \******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _clock_shortcut_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./clock_shortcut.js */ "../eyes/src/components/clock_shortcut/clock_shortcut.js"); + + + + +/* harmony default export */ __webpack_exports__["default"] = (_clock_shortcut_js__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/kiosk_base/kiosk_base.js": +/*!*******************************************************!*\ + !*** ../eyes/src/components/kiosk_base/kiosk_base.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "KioskBase": function() { return /* binding */ KioskBase; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _kiosk_base_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./kiosk_base.html */ "../eyes/src/components/kiosk_base/kiosk_base.html"); +/* harmony import */ var _kiosk_base_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_kiosk_base_html__WEBPACK_IMPORTED_MODULE_2__); + + + + + +/** + * Base kiosk class with autoplay and session timer + */ +class KioskBase extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + static screenLastClicked = Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now()); + + /** + * Constructor + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options = {}) { + super(app, null, { + isVisible: false, + loadingTextVisibleClass: 'hidden', + sessionEndVisibleClass: 'hidden', + autoplayVisibleClass: 'hidden', + sessionTimerVisibleClass: 'hidden', + continueButtonVisibleClass: '', + forceRestartClass: '', + ...options + }); + + this._router = this.app.getManager('router'); + + this.inactivityInterval = null; + this.sessionInterval = null; + + this.timeOfDaySessionStarted = Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now()); + + this.componentDefaultVisibility = { + menu: false, + shareModal: false, + infoPanel: false, + layerPanel: false, + featuredStoriesPanel: true, + timecontrolsCollapsible: true + }; + } + + /** + * Initialize kiosk + */ + init() { + super.init(); + + const scene = this.app.pioneer.get('main'); + + scene.getLoadedPromise().then(() => { + this.resetLastClicked(); + this.validateQueries(); + const { maxSessionTime, maxInactivityTime, forceRestart } = this._router.configs; + + // Only start session/inactivity countdowns if maxSessionTime/maxInactivityTime is specified and valid + if (this._isValidTime(maxSessionTime)) { + this.maxSessionTime = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.minToSec(maxSessionTime); + + this.setUpSessionTimerComponent(); + this.startSessionTimer(); + + // Set up session end buttons + if (forceRestart === true) { + this.setState({ continueButtonVisibleClass: 'hidden', forceRestartClass: 'force-restart' }); + } + } + + if (this._isValidTime(maxInactivityTime) && !this.inactivityInterval) { + this.maxInactivityTime = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.minToSec(maxInactivityTime); + this.startInactivityTimer(); + } + + return true; + }).catch(error => { + console.warn(error); + }); + } + + /** + * Check for invalid queries + */ + validateQueries() { + const { maxSessionTime: maxSessionTimeFromURL, maxInactivityTime: maxInactivityTimeFromURL } = this._router.configs; + // Maintain current valid query values from router configs + const queryValues = {}; + for (const [key, value] of Object.entries(this._router.configs)) { + if (value) { + queryValues[key] = value; + } + } + + // Remove invalid time values from URL + for (const query in queryValues) { + if (query.toLowerCase().includes('time') && !this._isValidTime(queryValues[query])) { + delete queryValues[query]; + } + } + + const { maxSessionTime, maxInactivityTime } = queryValues; + + // Ensure that session time is always greater than inactivity time to avoid rogue session timer during autoplay + const bothTimersInURL = this._isValidTime(maxSessionTime) && this._isValidTime(maxInactivityTime); + + if (bothTimersInURL) { + // Add some time to inactivity time if they're too close in value + if (Math.abs(maxSessionTimeFromURL - maxInactivityTimeFromURL) <= 0.05 && maxSessionTimeFromURL > 0 && maxInactivityTimeFromURL > 0) { + queryValues['maxInactivityTime'] = maxSessionTimeFromURL + 0.1; + } + // Session timer should always be less than inactivity timer (aka autoplay timer) + else if (maxSessionTimeFromURL >= maxInactivityTimeFromURL) { + if (maxInactivityTimeFromURL === 0) { + // Zero both out if inactivity is 0 + delete queryValues['maxSessionTime']; + } + else { + // Set inactivity timer to be 1 minute longer than session time + queryValues['maxInactivityTime'] = maxSessionTimeFromURL + 1; + } + } + } + + this._router.setConfig('maxSessionTime', queryValues['maxSessionTime']); + this._router.setConfig('maxInactivityTime', queryValues['maxInactivityTime']); + } + + /** + * Determine whether the given URL time is a valid entry + * @param {number|string} time + * @returns {boolean} + */ + _isValidTime(time) { + return time !== '' && !isNaN(Number(time)) && Number(time) > -1; + } + + /** + * Override setEnabled so when the kiosk component is enabled, relevant sub-components are shown (timer, autoplay UI, etc.) + * @param {boolean} enabled + * @override + */ + setEnabled(enabled) { + super.setEnabled(enabled); + + const { kiosk, maxSessionTime, maxInactivityTime } = this._router.configs; + + if (enabled && (kiosk || this._isValidTime(maxSessionTime) || this._isValidTime(maxInactivityTime))) { + // Show Kiosk container + this.show(); + } + } + + /** + * Reset time window was last clicked + */ + resetLastClicked() { + KioskBase.screenLastClicked = Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now()); + } + + /** + * Reset session when 'start over' button clicked at the end of the session + */ + async sessionStartOverButtonClick() { + // Show loading text until transition is complete + this.setState({ loadingTextVisibleClass: '' }); + + await this.resetApp(); + + this.app.getManager('camera').waitForTransitionComplete().then(() => { + this.setState({ loadingTextVisibleClass: 'hidden' }); + return null; + }).catch(error => { + console.warn('error: ', error); + }); + } + + /** + * Handle behavior when user interacts with the window + */ + async onWindowInteract() { + const { maxSessionTime, maxInactivityTime, forceRestart } = this._router.configs; + const { kioskAutoplay, kioskSessionEnd } = this._children; + const inAutoplay = !this.isHidden(kioskAutoplay); + const sessionOver = !this.isHidden(kioskSessionEnd); + + this.setState({ autoplayVisibleClass: 'hidden' }); + this.setState({ sessionEndVisibleClass: 'hidden' }); + + // Don't show 'Starting Experience' while in autoplay or a session + if ((inAutoplay || sessionOver) && !forceRestart) { + this.setState({ loadingTextVisibleClass: '' }); + } + + clearInterval(this.inactivityInterval); + this.inactivityInterval = null; + + // Only do camera transition if clicking to end autoplay + if (inAutoplay) { + await this.app.cameraScripts.goToSystem('inner_solar_system'); + } + + // Hide kiosk components if window is interacted with + this.app.getManager('camera').waitForTransitionComplete().then(() => { + this.setState({ loadingTextVisibleClass: 'hidden' }); + return null; + }).catch(error => { + console.warn('error: ', error); + }); + + this.setState({ sessionEndVisibleClass: 'hidden' }); + + this.resetLastClicked(); + + // Start new session + if (this._isValidTime(maxSessionTime) && (inAutoplay || sessionOver)) { + this.resetSessionTimer(); + } + + if (this._isValidTime(maxInactivityTime)) { + this.startInactivityTimer(); + } + } + + /** + * Set up the visual session timer countdown component + */ + setUpSessionTimerComponent() { + const sessionClockComponent = this.app.getComponent('kioskSessionClock'); + const { kioskSessionTimer } = this._children; + + sessionClockComponent.setState({ isKioskSessionTimer: true }); + + // Show session countdown timer + sessionClockComponent.show(); + sessionClockComponent.setEnabled(true); + sessionClockComponent.setParent(kioskSessionTimer); + this.updateSessionTimerComponent(); + } + + /** + * Start session timer + */ + startSessionTimer() { + this.timeOfDaySessionStarted = Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now()); + + this.sessionInterval = setInterval(() => { + this.handleSessionTimer(); + }, 1000); + } + + /** + * Handle behavior after a certain amount of time in a session + */ + handleSessionTimer() { + const { kioskAutoplay } = this._children; + const inAutoplay = !this.isHidden(kioskAutoplay); + const now = Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now()); + this.timeElapsed = now - this.timeOfDaySessionStarted; + + this.setState({ sessionTimerVisibleClass: '' }); + + // Ongoing session + if (this.timeElapsed < this.maxSessionTime) { + this.updateSessionTimerComponent(); + } + else if (!inAutoplay) { + // Session end but before autoplay begins + this.endSession(); + } + } + + /** + * Behavior when the session ends/session timer runs out + */ + async endSession() { + const { forceRestart } = this._router.configs; + const { kioskSessionEnd } = this._children; + + clearInterval(this.sessionInterval); + this.sessionInterval = null; + + // Hide session timer and show start over screen + this.setState({ sessionTimerVisibleClass: 'hidden' }); + + if (this.isHidden(kioskSessionEnd)) { + this.setState({ sessionEndVisibleClass: '' }); + } + + // Only reset to home if force restart, else just reset overlays on session end + if (forceRestart === true) { + await this.resetApp(); + } + else { + this.resetComponents(this.componentDefaultVisibility); + } + } + + /** + * Reset the session timer + */ + resetSessionTimer() { + this.timeElapsed = 0; + + this.setUpSessionTimerComponent(); + + // Restart session timer + this.startSessionTimer(); + this.setState({ sessionEndVisibleClass: 'hidden' }); + this.setState({ sessionTimerVisibleClass: '' }); + } + + /** + * Update session timer component visually + */ + updateSessionTimerComponent() { + const sessionTimerComponent = this.app.getComponent('kioskSessionClock'); + + const formattedCountdownTime = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatCountdownTime(this.maxSessionTime * 1000, (this.maxSessionTime - this.timeElapsed) * 1000); + sessionTimerComponent.update(formattedCountdownTime, true); + } + + /** + * Start inactivity timer + */ + startInactivityTimer() { + this.inactivityInterval = setInterval(() => { + this.handleMaxInactivityTime(); + }, 1000); + } + + /** + * Handle behavior after a certain amount of time without any activity + */ + handleMaxInactivityTime() { + this.currentTimeWithoutActivity = Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now()) - KioskBase.screenLastClicked; + } + + /** + * Behavior when inactivity time runs out and autoplay begins + */ + async startAutoplay() { + // Hide session timer and session end and show autoplay + this.setState({ sessionTimerVisibleClass: 'hidden' }); + this.setState({ sessionEndVisibleClass: 'hidden' }); + + this.setState({ autoplayVisibleClass: '' }); + + await this.resetApp(); + + // Stop inactivity timer so it doesn't keep counting in the background + clearInterval(this.inactivityInterval); + this.inactivityInterval = null; + } + + /** + * Reset layers to default + * @param {object} layersToReset + */ + resetLayers(layersToReset) { + if (layersToReset) { + // Reset layers to defaults + for (const layer of Object.keys(layersToReset)) { + const { defaultVisibility } = this.app.getManager('layer').getLayer(layer); + this.app.getManager('layer').toggleLayer(layer, {}, defaultVisibility); + } + } + } + + /** + * Reset components to default visibility + * @param {object} componentsToReset + */ + resetComponents(componentsToReset) { + if (componentsToReset) { + // Hide/show components + for (const [componentName, showComponent] of Object.entries(componentsToReset)) { + const component = this.app.getComponent(componentName); + showComponent ? component?.show() : component?.hide(); + // Expand component if applicable (i.e., time controls) + this.app.getComponent(componentName)?.setExpanded?.(showComponent); + } + } + } + + /** + * Reset app to default state + */ + async resetApp() { + const uiLayers = this.app.getComponent('layerPanel').getCategoriesDisplay(); + const { currentView } = this._router; + const isAtSystem = this.app.getManager('camera').getContext().context === _internal__WEBPACK_IMPORTED_MODULE_0__.CameraScripts.CONTEXT.SYSTEM; + const isAtInnerSolarSystem = isAtSystem && this.app.getManager('camera').getContext().id === 'sun'; + const isTransitioning = this.app.getManager('camera').getIsTransitioning(); + + this.resetLayers(uiLayers); + this.resetComponents(this.componentDefaultVisibility); + + // Go to home if not there already + if (!isAtInnerSolarSystem) { + this._router.navigate('/home'); + } + else if (!isTransitioning) { + // Reset camera to inner solar system + await this.app.cameraScripts.goToSystem('inner_solar_system'); + + if (currentView === 'story') { + this.app.getComponent('story')?.close(); + } + } + + // Set time and rate back to real time + this.app.getManager('camera').waitForTransitionComplete().then(() => { + const clock = this.app.getComponent('clock'); + clock.backToLive(); + + this.app.getManager('layer').toggleLayer('planets', {}, true); + }).catch(error => { + console.warn('error: ', error); + }); + } + + /** + * Return if a component is hidden + * @param {Element} component + * @returns {boolean} + */ + isHidden(component) { + return component?.classList.contains('hidden'); + } +} + +KioskBase.html = (_kiosk_base_html__WEBPACK_IMPORTED_MODULE_2___default()); + + +/***/ }), + +/***/ "../eyes/src/components/layer_panel/layer_panel.js": +/*!*********************************************************!*\ + !*** ../eyes/src/components/layer_panel/layer_panel.js ***! + \*********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LayerPanel": function() { return /* binding */ LayerPanel; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _layer_panel_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./layer_panel.html */ "../eyes/src/components/layer_panel/layer_panel.html"); +/* harmony import */ var _layer_panel_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_layer_panel_html__WEBPACK_IMPORTED_MODULE_1__); + + + + +/** + * Layer panel component. + * @extends BaseComponent + */ +class LayerPanel extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + // Default configuration + options.config = { + layers: options.layers || [], + checkboxType: options.checkboxType || 'default', + ...options.config + }; + + // Add state options + super(app, null, { + isVisible: false, + ui: app.getManager('layer').getLayer('ui').defaultVisibility, + planets: app.getManager('layer').getLayer('planets').defaultVisibility, + asteroids: app.getManager('layer').getLayer('asteroids').defaultVisibility, + comets: app.getManager('layer').getLayer('comets').defaultVisibility, + dwarfPlanets: app.getManager('layer').getLayer('dwarfPlanets').defaultVisibility, + spacecraft: app.getManager('layer').getLayer('spacecraft').defaultVisibility, + trails: app.getManager('layer').getLayer('trails').defaultVisibility, + orbits: app.getManager('layer').getLayer('orbits').defaultVisibility, + labels: app.getManager('layer').getLayer('labels').defaultVisibility, + icons: app.getManager('layer').getLayer('icons').defaultVisibility, + starfield: app.getManager('layer').getLayer('starfield').defaultVisibility, + constellations: app.getManager('layer').getLayer('constellations').defaultVisibility, + ...options + }); + + this._eyesCheck = options.checkboxType === 'eyes'; + + // Storing class names + Object.assign(this._class, { + checkbox: { + true: this._eyesCheck ? 'active' : 'active icon-checkmark', + false: this._eyesCheck ? '' : 'checkbox-hover' + }, + boxColor: { + true: 'settings-alt', + false: '' + }, + isVisible: { + true: '', + false: '' + } + }); + + // Add default class to state + Object.assign(this._state, { + uiClass: this._class.checkbox[this._state.ui], + uiColorClass: this._class.boxColor[this._state.ui], + planetsClass: this._class.checkbox[this._state.planets], + planetsColorClass: this._class.boxColor[this._state.planets], + asteroidsClass: this._class.checkbox[this._state.asteroids], + asteroidsColorClass: this._class.boxColor[this._state.asteroids], + cometsClass: this._class.checkbox[this._state.comets], + cometsColorClass: this._class.boxColor[this._state.comets], + dwarfPlanetsClass: this._class.checkbox[this._state.dwarfPlanets], + dwarfPlanetsColorClass: this._class.boxColor[this._state.dwarfPlanets], + constellationsClass: this._class.checkbox[this._state.constellations], + constellationsColorClass: this._class.boxColor[this._state.constellations], + spacecraftClass: this._class.checkbox[this._state.spacecraft], + spacecraftColorClass: this._class.boxColor[this._state.spacecraft], + trailsClass: this._class.checkbox[this._state.trails], + trailsColorClass: this._class.boxColor[this._state.trails], + orbitsClass: this._class.checkbox[this._state.orbits], + orbitsColorClass: this._class.boxColor[this._state.orbits], + labelsClass: this._class.checkbox[this._state.labels], + labelsColorClass: this._class.boxColor[this._state.labels], + iconsClass: this._class.checkbox[this._state.icons], + iconsColorClass: this._class.boxColor[this._state.icons], + starfieldClass: this._class.checkbox[this._state.starfield], + starfieldColorClass: this._class.boxColor[this._state.starfield] + }); + + this._categories = { + ui: 'User Interface', + planets: 'Planet', + asteroids: 'Asteroid', + comets: 'Comet', + dwarfPlanets: 'Dwarf Planet', + spacecraft: 'Spacecraft', + trails: 'Trail', + labels: 'Label', + icons: 'Icons', + starfield: 'Star Field', + constellations: 'Constellations' + }; + + this._categoriesDisplay = { + ui: 'User Interface', + planets: 'Planets', + asteroids: 'Asteroids', + comets: 'Comets', + dwarfPlanets: 'Dwarf Planets', + constellations: 'Constellations', + spacecraft: 'Spacecraft', + trails: 'Trails', + orbits: 'Orbits', + labels: 'Labels', + icons: 'Icons', + starfield: 'Star Field' + }; + + this.bindFunctions([ + 'toggleLayer', + 'handleLayerToggle' + ]); + + // Store Web animations + this._fadeInRight = null; + this._fadeOutRight = null; + this._fadeInBottom = null; + this._fadeOutBottom = null; + + this._lastMode = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode(); + + this._initCallbacks(); + } + + /** + * Get display categories + * @returns {object} + */ + getCategoriesDisplay() { + return this._categoriesDisplay; + } + + /** @inheritdoc */ + resize() { + super.resize(); + this._updatePosition(); + } + + /** @inheritdoc */ + init() { + super.init(); + // TODO: This doesnt work for now + // We need to create the animation just before playing it + // this._createAnimations(); + + this._callbackRegistry.push({ + emitter: this._app.getManager('layer'), + event: 'toggleLayer', + callback: this.handleLayerToggle + }); + + const layerPanelBody = this._children.layerPanelBody; + if (layerPanelBody) { + layerPanelBody.textContent = ''; + + const container = document.createElement('div'); + container.className = 'container'; + this._config.layers.forEach(layerGroup => { + const blockDiv = document.createElement('div'); + blockDiv.classList.add('block'); + const layersUl = document.createElement('ul'); + layersUl.classList.add('layers'); + layerGroup.forEach(layer => { + if (this._eyesCheck) { + // Keep this for now until verify the new Checkbox against Asteroids + const layerLi = document.createElement('li'); + layerLi.setAttribute('key', layer); + layerLi.className = `layer-panel-layer item clickable {{${layer}Class}}`; + const checkboxDiv = document.createElement('div'); + checkboxDiv.classList.add('eyes-checkbox'); + checkboxDiv.innerHTML = ``; + layerLi.append(checkboxDiv); + + const nameSpan = document.createElement('span'); + nameSpan.classList.add('small'); + nameSpan.textContent = this._categoriesDisplay[layer]; + layerLi.append(nameSpan); + + layerLi.addEventListener('click', this.toggleLayer); + + layersUl.append(layerLi); + } + else { + const option = new _internal__WEBPACK_IMPORTED_MODULE_0__.Checkbox(this._app, { + config: { + key: layer, + colorClass: this._class.boxColor.true, + function: this.toggleLayer + }, + isChecked: this._app.getManager('layer').getLayer(layer).defaultVisibility, + text: this._categoriesDisplay[layer], + checkboxClass: 'layer-panel-layer item', + textClass: 'small' + }); + option.init(); + + this._components.push(option); + layersUl.appendChild(option.element); + } + }); + blockDiv.append(layersUl); + container.append(blockDiv); + }); + + layerPanelBody.append(container); + + this._setVariables(layerPanelBody); + } + } + + /** + * Creates animations. + */ + _createAnimations() { + this._fadeOutRight = _internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade( + this._element, + { direction: 'right', fade: 'out', yOffset: 0 } + ); + this._fadeInRight = _internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade( + this._element, + { direction: 'right', fade: 'in', yOffset: 0 } + ); + this._fadeOutBottom = _internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade( + this._element, + { direction: 'down', fade: 'out', yOffset: 0 } + ); + this._fadeInBottom = _internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade( + this._element, + { direction: 'down', fade: 'in', yOffset: 0 } + ); + } + + /** + * Resets animations. + */ + _resetAnimations() { + this._fadeInRight.currentTime = 0; + this._fadeOutRight.currentTime = 0; + this._fadeInBottom.currentTime = 0; + this._fadeOutBottom.currentTime = 0; + this._fadeInRight.pause(); + this._fadeOutRight.pause(); + this._fadeInBottom.pause(); + this._fadeOutBottom.pause(); + } + + /** + * Toggles layer and trigger callback. + * @param {string} key + */ + toggleLayer(key) { + const layerKey = key.target?.getAttribute('key') ?? key; + this._app.getManager('layer').toggleLayer(layerKey, { category: this._categories[layerKey] }); + } + + /** + * Handles any layer toggle. + * @param {string} id + * @param {boolean} visible + * @param {Array} params + */ + handleLayerToggle(id, visible, params) { + // Keep this for now until verify the new Checkbox against Asteroids + const keyClass = id + 'Class'; + const colorClass = id + 'ColorClass'; + // Check if layer id is in state. + if (this.getState(id) !== null) { + this.setState({ + [id]: visible, + [keyClass]: this._class.checkbox[visible], + [colorClass]: this._class.boxColor[visible] + }); + + if (this._eyesCheck) { + // setVariables doesn't seem to change attributes so we'll set it here + const layerCheckbox = document.getElementById(`layer-panel-checkbox-${id}`); + if (layerCheckbox) layerCheckbox.checked = visible; + } + } + + // Sync checkbox state in case the layer is toggled elsewhere + const checkbox = this._components.find(component => component.getConfig().key === id); + if (checkbox && checkbox.getState('isChecked') !== visible) { + checkbox.toggle(null, true); + } + } + + /** + * Check whether a category is enabled. + * @param {string} categoryName + * @returns {boolean} + */ + isCategoryEnabled(categoryName) { + return !this._children[categoryName]?.classList.contains('disabled'); + } + + /** + * Set whether a category is disabled + * @param {string} categoryName + * @param {boolean} enabled + */ + setCategoryEnabled(categoryName, enabled = true) { + this._children[categoryName]?.classList.toggle('disabled', !enabled); + } + + /** + * Overrides default hide. + */ + hide() { + if (!this.getState('isVisible')) { + return; + } + super.hide(); + if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode()) { + this._fadeOutBottom = _internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade( + this._element, + { direction: 'down', fade: 'out', yOffset: 0 } + ); + this._fadeOutBottom.play(); + } + else { + this._fadeOutRight = _internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade( + this._element, + { direction: 'right', fade: 'out', yOffset: 0 } + ); + this._fadeOutRight.play(); + } + } + + /** + * Overrides default show. + */ + show() { + super.show(); + if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode()) { + this._fadeInBottom = _internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade( + this._element, + { direction: 'down', fade: 'in', yOffset: 0 } + ); + this._fadeInBottom.play(); + } + else { + this._fadeInRight = _internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade( + this._element, + { direction: 'right', fade: 'in', yOffset: 0 } + ); + this._fadeInRight.play(); + } + } + + /** + * Updates the position of the panel depending on the resolution. + */ + _updatePosition() { + const currentMode = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode(); + if (currentMode !== this._lastMode) { + this._lastMode = currentMode; + if (this._state.isVisible) { + this.show(); + } + } + } + + /** + * Overrides default enable. + */ + __enable() { + super.__enable(); + this._createAnimations(); + } + + /** + * Overrides default disable. + */ + __disable() { + super.__disable(); + this._fadeInRight = null; + this._fadeOutRight = null; + this._fadeInBottom = null; + this._fadeOutBottom = null; + } +} + +LayerPanel.html = (_layer_panel_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/load_icon/index.js": +/*!*************************************************!*\ + !*** ../eyes/src/components/load_icon/index.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _load_icon_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./load_icon.js */ "../eyes/src/components/load_icon/load_icon.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = (_load_icon_js__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/load_icon/load_icon.js": +/*!*****************************************************!*\ + !*** ../eyes/src/components/load_icon/load_icon.js ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _load_icon_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./load_icon.html */ "../eyes/src/components/load_icon/load_icon.html"); +/* harmony import */ var _load_icon_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_load_icon_html__WEBPACK_IMPORTED_MODULE_1__); + + + +/** + * @inheritdoc + * @extends BaseComponent + */ +class LoadIcon extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** @inheritdoc */ + init() { + super.init(); + + this._callbackRegistry.push( + { + emitter: this._app.getManager('scene'), + event: 'loading', + callback: this.show + }, + { + emitter: this._app.getManager('scene'), + event: 'loaded', + callback: this.hide + } + ); + + this.hide(); + } +} + +LoadIcon.html = (_load_icon_html__WEBPACK_IMPORTED_MODULE_1___default()); + +/* harmony default export */ __webpack_exports__["default"] = (LoadIcon); + + +/***/ }), + +/***/ "../eyes/src/components/overlay/index.js": +/*!***********************************************!*\ + !*** ../eyes/src/components/overlay/index.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _overlay_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./overlay.js */ "../eyes/src/components/overlay/overlay.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = (_overlay_js__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/overlay/overlay.js": +/*!*************************************************!*\ + !*** ../eyes/src/components/overlay/overlay.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _overlay_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./overlay.html */ "../eyes/src/components/overlay/overlay.html"); +/* harmony import */ var _overlay_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_overlay_html__WEBPACK_IMPORTED_MODULE_2__); + + + + +/** + * Overlay component. + * @extends BaseComponent + */ +class Overlay extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + super(app, null, { + isVisible: false, + isOpenButtonVisible: true, + content: null, + ...options + }); + + this._class.isOpenButtonVisibleClass = { + true: '', + false: 'hidden' + }; + + Object.assign(this._state, { + isOpenButtonVisibleClass: this._class.isOpenButtonVisibleClass[this._state.isOpenButtonVisible] + }); + + /** + * Scrollbar library instance. + * @type {OverlayScrollbars} + */ + this._scrollbar = null; + } + + /** @inheritdoc */ + init() { + super.init(); + + if (this._state.content !== null) { + this._children.overlayContent.appendChild(this._state.content); + } + + // Hide overlay when clicking on it + this._element.addEventListener('click', this.hide); + + // Hide overlay after fading out completes + this._element.addEventListener('animationend', () => { + if (this._children.overlay.classList.contains('hidden')) { + this._children.overlay.style.display = 'none'; + } + }); + } + + /** + * Set content of overlay. + * @param {HTMLElement} element + */ + setContent(element) { + if (this._state.content === null) { + this._children.overlayContent.appendChild(element); + } + else { + this._children.overlayContent.replaceChild(element, this._state.content); + } + + this._state.content = element; + } + + /** + * Show overlay. + */ + show() { + this._element.classList.add('initialized'); + this._children.overlay.style.display = ''; + super.show(); + } + + /** + * Enables the component. + * @abstract + * @package + */ + __enable() { + super.__enable(); + + if (this._scrollbar === null) { + // Wait until element is attached to DOM, then add scrollbar + _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.onAttachElement(this._children.overlay, () => { + this._scrollbar = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.addScrollbar(this._children.overlay); + }); + } + else { + this._scrollbar.scroll(0); + } + } +} + +Overlay.html = (_overlay_html__WEBPACK_IMPORTED_MODULE_2___default()); + +/* harmony default export */ __webpack_exports__["default"] = (Overlay); + + +/***/ }), + +/***/ "../eyes/src/components/search/index.js": +/*!**********************************************!*\ + !*** ../eyes/src/components/search/index.js ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _search_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./search.js */ "../eyes/src/components/search/search.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = (_search_js__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/search/search.js": +/*!***********************************************!*\ + !*** ../eyes/src/components/search/search.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _search_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./search.html */ "../eyes/src/components/search/search.html"); +/* harmony import */ var _search_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_search_html__WEBPACK_IMPORTED_MODULE_1__); + + + + +/** + * @inheritdoc + * @extends BaseComponent + */ +class Search extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + * @param {object} [options.config={}] + */ + constructor(app, options = { config: {} }) { + /** + * @property {object} options.config + * @property {boolean} [options.config.initialOpen=false] + * @property {boolean} [options.config.allowFeatured=false] + * @property {boolean} [options.config.allowDetail=true] + * @property {boolean} [options.config.allowInfo=false] + * @property {boolean} [options.config.stopOnExactMatch=false] + * @property {object} options.config.infoText + * @property {string} [options.config.infoText.default='most popular'] + * @property {string} [options.config.infoText.results='result'] + * @property {string} [options.config.infoText.suggestions='suggestion'] + * @property {string} [options.config.infoText.nomatches='no matches'] + * @property {number} [options.config.maxSuggestions=1] + * @property {string} [options.config.placeholderText='Search...'] + * @property {string[]} [options.config.nameSearch=['id', 'name']] - Array of keys to try to search for item's name + * @property {string[]} [options.config.nameDisplay=['name', 'id']] - Array of keys to try to display item's name + */ + options.config = { + initialOpen: false, + allowFeatured: false, + allowDetail: true, + allowInfo: false, + stopOnExactMatch: false, + infoText: { + default: 'most popular', + results: 'result', + suggestions: 'suggestion', + nomatches: 'no matches' + }, + maxSuggestions: 1, + placeholderText: 'Search...', + nameSearch: ['iauName', 'displayName'], + nameDisplay: ['displayName', 'iauName'], + ...options.config + }; + + super(app, null, { + text: '', + searchInfo: options.config?.infoText?.default || '', + alwaysOpen: false, + magClass: 'mag-open', + searchClass: 'search-close', + focusedClass: '', + isFeaturedVisible: false, + ...options + }); + + this._class.isItemVisible = { + true: '', + false: 'hidden' + }; + + Object.assign(this._state, { + allowFeaturedClass: this._class.isItemVisible[this._config.allowFeatured], + isFeaturedVisibleClass: this._class.isItemVisible[this._config.allowFeatured && this._state.isFeaturedVisible], + allowInfoClass: this._class.isItemVisible[this._config.allowInfo] + }); + + this._eventNames.push('resultselected'); + this._initCallbacks(); + + /** + * Scrollbar for result list. + */ + this._resultsScrollbar = null; + + /** + * Scrollbar for featured list. + */ + this._featuredScrollbar = null; + + /** + * Function to call on window resize. + * @type {Function} + */ + this.onResize = null; + + /** + * Result list to display. + * @type {Array} + */ + this.results = []; + + /** + * A list of item ids to filter out of the search results + * @type {Array} + */ + this._excludeResults = []; + + /** + * Threshold for Fuse score of suggestions. + * @type {number} + */ + this._suggestionsThreshold = 0.05; + + /** + * Index of the selected entry. + * @type {number} + */ + this.index = -1; + + this.bindFunctions([ + '_find', + 'renderResults', + 'open', + 'close', + 'eraseInput', + 'onIconClick', + 'reset', + 'keydown', + 'onInputFocus', + '_getDetails', + '_handleClick' + ]); + + window.addEventListener('setupSearch', this.resize); + } + + /** @inheritdoc */ + init() { + super.init(); + + // Make sure placeholder text fully visible in the input + const size = this._children.input.getAttribute('placeholder').length * 0.9; + this._children.input.style.minWidth = `${size}ch`; + + + this._children.input.onkeyup = event => { + const isFeaturedVisible = this._children.input.value.length === 0; + if (this._config.allowFeatured && isFeaturedVisible !== this._state.isFeaturedVisible) { + // Scroll to the top. + this._featuredScrollbar?.scroll(0); + // Set visible and text states. + this.setState({ + isFeaturedVisible, + isFeaturedVisibleClass: this._class.isItemVisible[isFeaturedVisible], + ...isFeaturedVisible && { searchInfo: this._config.infoText.default } + }); + } + }; + + this.resize(); + + this.registerManager(this._app.getManager('search')); + } + + /** + * Execute actions when click on magnifier. + */ + onIconClick() { + const currentlyClosed = this._state.searchClass === 'search-close'; + + if (currentlyClosed) { + this._scrollbar?.scroll(0); + this.open(); + this._children.input.focus(); + } + else { + if (this._children.input.value === '') { + this.reset(); + } + else { + this._children.results.querySelector('.active')?.firstChild.click(); + } + } + } + + /** + * Triggers when window is resizing. + */ + resize() { + super.resize(); + + if (typeof this.onResize === 'function') { + this.onResize(); + } + } + + /** + * Clear input and close panel. + */ + reset() { + this.eraseInput(); + if (!this._config.initialOpen) { + this.close(); + } + } + + /** + * Handles keypress when focused on the search input field. + * @param {object} e - Keypress event + */ + keydown(e) { + const key = e.key; + + if (key === 'Escape') { + this.eraseInput(); + this.close(); + } + + const total = this.results.length; + if (!total) { + return; + } + + // Arrow Down + if (key === 'ArrowDown') { + this.index = (this.index + 1) % total; + e.preventDefault(); + } + // Arrow Up + else if (key === 'ArrowUp') { + this.index -= 1; + if (this.index < 0) { + this.index = total - 1; + } + e.preventDefault(); + } + // Enter + else if (key === 'Enter') { + // Fly to the selected search or the first one + this._handleClick(this.results[this.index]?.link || this.results[0]?.link, this._searchString); + e.preventDefault(); + } + this.setSelected(this.index); + } + + /** + * Set up selected index and state. + * @param {number} index - Current index of the selected element + */ + setSelected(index) { + this.index = index; + + for (let i = 0; i < this.results.length; i++) { + const element = this.results[i].element; + if (!element) { + continue; + } + if (i === this.index) { + element.classList.add('active'); + } + else { + element.classList.remove('active'); + } + } + } + + /** + * Execute actions when input has focus. + */ + onInputFocus() { + this.setState({ + focusedClass: 'input-focused' + }); + } + + /** + * Erase search input. + */ + eraseInput() { + this._resultsScrollbar?.destroy(); + this._resultsScrollbar = null; + + this._children.input.value = ''; + this._children.results.innerHTML = ''; + } + + /** + * Registers a search manager. + * @param {object} searchManager + */ + registerManager(searchManager) { + this._searchManager = searchManager; + } + + /** + * Applies search using either event from the window or text that is passed. + * @param {object} event + * @param {string} text + */ + _find(event, text) { + if (this._searchTimeout) { + clearTimeout(this._searchTimeout); + } + + if (event && event.target && event.target.value) { + text = event.target.value; + } + + const { maxEntries } = this._config; + + this._searchTimeout = setTimeout(async () => { + if (this._searchManager) { + const results = this._searchManager.find(text, maxEntries); + + // Filter results if we have anything in the excludeResults array. + const filteredResults = results?.length && this._excludeResults?.length ? + results.filter(({ item }) => !this._excludeResults.includes(item.id)) : + results; + + await this.renderResults(filteredResults, text); + } + }, 100); + } + + /** + * Renders html elements based on the results. + * @param {Fuse.FuseResult} results + * @param {string} text - text that was searched for the results + */ + async renderResults(results, text) { + this.index = -1; + this.results = []; + this._searchString = text; + + this._resultsScrollbar?.destroy(); + this._resultsScrollbar = null; + + this._children.results.innerHTML = ''; + this._children.results.classList.remove('no-results'); + + if (!results || !Array.isArray(results)) { + return; + } + + // Separate candidates from suggestions + const suggestions = []; + const candidates = []; + for (let i = 0; i < results.length; i++) { + const result = results[i]; + const { nameSearch } = this._config; + const name = result.item[nameSearch.find(key => result.item[key] !== undefined)]; + // Check for a perfect match on name + if (this._config.stopOnExactMatch && text.toLowerCase() === name.toLowerCase()) { + candidates.length = 0; + suggestions.length = 0; + candidates.push(result); + break; + } + + if (result.score < this._suggestionsThreshold) { + candidates.push(result); + } + else { + suggestions.push(result); + } + } + + // Perfect match + if (candidates.length === 1) { + if (this._config.allowDetail) { + // TODO: Do not re render if this is the same result + await this._renderResultCard(candidates[0], text); + } + else { + this._renderResultList(candidates, text); + } + } + else if (candidates.length === 0) { + // No results + this._renderSuggestions(suggestions, text); + } + else { + // Multiple matches + this._renderResultList(candidates, text); + } + + // Add scrollbar + if (candidates.length > 3) { + this._resultsScrollbar ??= this._createScrollbar(this._children.results); + } + + // Update info text if it's allowed. + const { allowInfo, infoText, maxSuggestions } = this._config; + + if (allowInfo) { + let searchInfo = infoText.nomatches; + + if (candidates.length) { + searchInfo = `${candidates.length} ${infoText.results}${candidates.length > 1 ? 's' : ''}`; + } + else if (suggestions.length) { + searchInfo = `${Math.min(suggestions.length, maxSuggestions)} ${infoText.suggestions}${suggestions.length > 1 ? 's' : ''}`; + } + + this.setState({ searchInfo }); + } + // select the first entry by default + this.setSelected(0); + } + + /** + * Renders a single detailed result card. + * @param {Fuse.FuseResult} result + * @param {string} text - the search string + */ + async _renderResultCard(result, text) { + try { + let details = await this._getDetails(result); + if (!details && result && result.item) { + const { nameDisplay } = this._config; + details = { + title: result.item[nameDisplay.find(key => result.item[key] !== undefined)] + }; + } + + // Card title + const div = document.createElement('div'); + div.className = 'card-title result-div'; + + const h4 = document.createElement('h4'); + h4.className = 'semi clickable'; + + let innerHTML = details.title; + if (typeof innerHTML === 'string') { + const index = innerHTML.toUpperCase().indexOf(text.toUpperCase()); + if (index > -1) { + const sub = innerHTML.substring(index, index + text.length); + const splitted = innerHTML.split(sub); + + if (splitted && splitted.length === 2) { + innerHTML = ''; + if (splitted[0].length > 0) { + innerHTML += `${splitted[0]}`; + } + innerHTML += sub; + if (splitted[1].length > 0) { + innerHTML += `${splitted[1]}`; + } + } + } + } + else { + innerHTML = ''; + } + + h4.innerHTML = innerHTML; + const link = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addStartToPath(result.item.id); + h4.addEventListener('mouseover', () => { + this.setSelected(0); + }, false); + h4.addEventListener('click', e => { + if (result.item) { + this._handleClick(result.item.id, text); + } + e?.stopPropagation?.(); + }, false); + div.appendChild(h4); + this.results.push({ link, element: div }); + + // TODO: Display icon instead of image + + this._children.results.innerHTML = ''; + this._children.results.appendChild(div); + + if (details.cards) { + this._createStoryBlock(details.cards); + } + + if (details.featuredEvents && details.featuredEvents.initial) { + this._createEventsBlock(details.featuredEvents.initial, result.item.id); + } + + if (details.exploration && details.exploration.initial) { + this._createExplorationBlock(details.exploration.initial); + } + + if (details.featuredMoons) { + this._createMoonsBlock(details.featuredMoons, result.item.id); + } + // TODO: No need for that right now + // if (details.custom) { + // for (let i = 0; i < details.custom.length; i++) { + // const custom = details.custom[i]; + // this._createChunk(custom.entries, custom.title, text); + // } + // } + } + catch (err) { + // Render one line if details not found + if (err.status !== undefined && err.status === 404) { + this._renderResultList([result], text); + } + else if (err) { + console.error(err); + } + } + } + + /** + * Creates a block of events in the results. + * @param {string[]} featuredItems + * @param {string} result + */ + _createEventsBlock(featuredItems, result) { + if (!Array.isArray(featuredItems) || featuredItems.length === 0) { + return; + } + const entityInfo = this._app.getManager('content').getEntityInfo(result); + if (entityInfo === null || !entityInfo.hasEvents) { + return; + } + + // Container + const container = this._createBlockContainer(); + container.classList.add('events'); + + // Title + const title = 'Featured Events'; + this._createHeaderBlock(title, container); + + // Items + for (let i = 0; i < featuredItems.length; i++) { + const event = featuredItems[i]; + const text = event.title; + const link = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addStartToPath(result + '/events/' + event.eventId); + const element = this._createSingleResult(text, link, container); + this.results.push({ link, element }); + } + } + + /** + * Creates a block of Moons in the results. + * @param {object[]} featuredItems + */ + _createMoonsBlock(featuredItems) { + if (!Array.isArray(featuredItems) || featuredItems.length === 0) { + return; + } + + // Container + const container = this._createBlockContainer(); + container.classList.add('moons'); + + // Title + const title = 'Featured Moons'; + this._createHeaderBlock(title, container); + + // Items + for (let i = 0; i < featuredItems.length; i++) { + const text = featuredItems[i]; + const link = featuredItems[i]; + const element = this._createSingleResult(text, link, container); + this.results.push({ link, element }); + } + } + + /** + * Creates a block of events in the results. + * @param {object[]} featuredItems + */ + _createExplorationBlock(featuredItems) { + if (!Array.isArray(featuredItems) || featuredItems.length === 0) { + return; + } + + // Container + const container = this._createBlockContainer(); + container.classList.add('exploration'); + + // Title + const title = 'Exploration'; + this._createHeaderBlock(title, container); + + // Items + for (let i = 0; i < featuredItems.length; i++) { + const event = featuredItems[i]; + let text = event.title; + if (event.info !== null && event.info !== undefined) { + text += ' (' + event.info + ')'; + } + const link = event.url; + const element = this._createSingleResult(text, link, container); + this.results.push({ link, element }); + } + } + + /** + * Creates a block of stories in the results. + * @param {object[]} cards + */ + _createStoryBlock(cards) { + if (!Array.isArray(cards) || cards.length === 0) { + return; + } + + // Container + const container = this._createBlockContainer(); + container.classList.add('stories'); + + // Title + const title = 'Stories'; + + // Items + let storyResults = false; + for (let i = 0; i < cards.length; i++) { + const card = cards[i]; + // Only populate stories for now + if (card.storyId !== undefined) { + const story = this._app.getManager('content').getStoryList().stories[card.storyId]; + if (story !== undefined) { + // Only create the header block if at least one story is being returned. + if (!storyResults) { + this._createHeaderBlock(title, container); + storyResults = true; + } + const text = story.title; + const link = '/story/' + card.storyId; + const element = this._createSingleResult(text, link, container); + this.results.push({ link, element }); + } + } + } + } + + /** + * Creates a block container to group results. + * @returns {HTMLElement} + */ + _createBlockContainer() { + const blockContainer = document.createElement('div'); + blockContainer.className = 'block-container'; + this._children.results.appendChild(blockContainer); + return blockContainer; + } + + /** + * Creates a header for each block of results. + * @param {string} title + * @param {HTMLElement} container + */ + _createHeaderBlock(title, container) { + const titleDiv = document.createElement('div'); + titleDiv.className = 'header'; + + const lineTitle = document.createElement('span'); + lineTitle.className = 'title small semi'; + lineTitle.innerHTML = title; + titleDiv.appendChild(lineTitle); + + container.appendChild(titleDiv); + } + + /** + * Creates a result data buttton. + * @param {string} title + * @param {string} link + * @param {HTMLElement} container + * @returns {HTMLElement} + */ + _createSingleResult(title, link, container) { + const entryDiv = document.createElement('div'); + entryDiv.className = 'result-div'; + const entryButton = document.createElement('button'); + entryButton.className = 'small clickable capitalize'; + entryButton.innerHTML = title; + const index = (this.results.length - 1) + 1; // Must take into account card title + + // Add click callback + entryDiv.addEventListener('click', e => { + this._handleClick(link, this._searchString); + e?.stopPropagation?.(); + }, false); + entryDiv.addEventListener('mouseover', () => { + this.setSelected(index); + }, false); + + entryDiv.appendChild(entryButton); + container.appendChild(entryDiv); + + return entryDiv; + } + + /** + * Renders a list of results. + * @param {Fuse.FuseResult} results + * @param {string} text + */ + _renderResultList(results, text) { + for (let i = 0; i < results.length; i++) { + const result = results[i].item; + const { nameSearch } = this._config; + const generalName = result[nameSearch.find(key => result[key] !== undefined)]; + + if (!generalName) { + continue; + } + + const button = document.createElement('button'); + button.className = 'entries clickable thin small'; + const url = result.url || result.id; + let innerHTML = generalName; + const index = generalName.toUpperCase().indexOf(text.toUpperCase()); + if (index > -1) { + const sub = innerHTML.substring(index, index + text.length); + innerHTML = innerHTML.replace(sub, `${sub}`); + } + button.innerHTML = innerHTML; + const link = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addStartToPath(url); + + const div = document.createElement('div'); + div.className = 'result-div'; + div.appendChild(button); + + div.addEventListener('mouseover', () => { + this.setSelected(i); + }, false); + div.addEventListener('click', e => { + this._handleClick(url, text); + e?.stopPropagation?.(); + }, false); + + this.results.push({ link, element: div }); + + this._children.results.appendChild(div); + } + } + + /** + * Renders suggested items. + * @param {Fuse.FuseResult} results + * @param {string} text + */ + _renderSuggestions(results, text) { + const div = document.createElement('div'); + div.className = 'suggestion'; + + // Add suggestions + if (results.length > 0) { + const label = document.createElement('label'); + label.className = 'title small semi'; + label.innerHTML = 'Did you mean...?'; + div.appendChild(label); + + for (let i = 0; i < Math.min(this._config.maxSuggestions, results.length); i++) { + const button = document.createElement('button'); + button.className = 'entries clickable'; + const result = results[i].item; + const { nameSearch } = this._config; + const generalName = result[nameSearch.find(key => result[key] !== undefined)]; + if (generalName) { + const url = result.url || result.id; + button.innerHTML = generalName; + const link = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addStartToPath(url); + button.addEventListener('mouseover', () => { + this.setSelected(i); + }, false); + button.addEventListener('click', e => { + this._handleClick(url, text); + e?.stopPropagation?.(); + }, false); + + const buttonDiv = document.createElement('div'); + buttonDiv.className = 'result-div small'; + buttonDiv.appendChild(button); + div.appendChild(buttonDiv); + this.results.push({ link, element: buttonDiv }); + } + } + } + else if (!this._config.allowInfo) { + const label = document.createElement('label'); + label.className = 'title no-match small'; + label.innerHTML = 'No matches.'; + div.appendChild(label); + this._children.results.classList.add('no-results'); + } + + this._children.results.appendChild(div); + } + + /** + * Open search bar. + */ + open() { + this.setState({ + magClass: 'mag-close', + searchClass: 'search-open', + isFeaturedVisible: this._config.allowFeatured, + isFeaturedVisibleClass: this._class.isItemVisible[this._config.allowFeatured], + ...this._config.allowFeatured && { searchInfo: this._config.infoText.default } + }); + + // Set isSearching to true. + this.app.isSearching = true; + } + + /** + * Close search bar. + */ + close() { + if (this.getState('alwaysOpen')) { + this.setState({ + magClass: 'mag-close', + searchClass: 'search-open', + focusedClass: '', + isFeaturedVisible: false, + isFeaturedVisibleClass: this._class.isItemVisible.false + }); + } + else { + this.setState({ + magClass: 'mag-open', + searchClass: 'search-close', + focusedClass: '', + isFeaturedVisible: false, + isFeaturedVisibleClass: this._class.isItemVisible.false + }); + } + // Take focus away from input. + this._children.input?.blur(); + + // Set isSearching to false. + this.app.isSearching = false; + } + + /** + * Setup featured suggestion panel. + * If no info, clear the panel. + * @param {Array} [info=[]] + */ + setupFeaturedSuggestion(info = []) { + // Clear the panel + this._children.featured.innerHTML = ''; + + // Populate the panel with info + for (let i = 0; i < info.length; i++) { + const { text, url } = info[i]; + const li = document.createElement('li'); + li.innerHTML = text; + li.className = 'clickable thin'; + li.addEventListener('click', e => { + this._handleClick(url, this._searchString); + e?.stopPropagation?.(); + }); + this._children.featured.appendChild(li); + } + } + + /** + * Create scrollbar. + * @param {HTMLElement} parentEl - the parent element of the overflowing element + * @returns {object} + */ + _createScrollbar(parentEl) { + return _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addScrollbar(parentEl, { + sizeAutoCapable: true + }); + } + + /** + * Gets parsed link if available. + * @param {string} link + * @returns {string|object} + */ + _getLink(link) { + return link; + } + + /** + * Handle click on the search result. + * @param {string} link - url link + * @param {string} text - search text + */ + _handleClick(link, text) { + // Check for link + if (!link) { + return; + } + + this.reset(); + this.triggerCallbacks('resultselected'); + + const router = this._app.getManager('router'); + + // Get parsed link if available. + const parsedLink = this._getLink(link); + + const linkPath = typeof parsedLink === 'string' ? parsedLink : (parsedLink.path ?? ''); + + if (linkPath.includes('events')) { + router.navigate({}, linkPath, { __remove: 'all' }); + } + else { + const { + options = { keepTime: true }, + query = {} + } = typeof parsedLink === 'object' && parsedLink; + + // Go to the object, maintaining time query if it exists. + router.navigate(query, linkPath, options); + } + } + + /** + * Manually simulate a search without typing + * @param {string} text + */ + simulate(text) { + const { input } = this._children; + + this.onIconClick(); + input.value = text; + this._find({}, text); + input.onkeyup(); + } + + /** + * Get details for a result. + * @param {Fuse.FuseResult} result + * @returns {Promise} + */ + async _getDetails(result) { + return this._app.getManager('content').getEntityDesc(result.item.id); + } + + /** + * Sets the this._excludeResults list + * @param {Array} excludeResults + */ + setExcludeResults(excludeResults) { + this._excludeResults = excludeResults; + } + + /** + * Enables the component. + * @abstract + * @package + */ + __enable() { + super.__enable(); + + // If allowFeatured and featured parent is in the DOM, create featured scrollbar. + const { allowFeatured } = this._config; + if (allowFeatured) { + const { parentElement: featuredParentEl } = this._children.featured || {}; + const parentInDOM = document.body.contains(featuredParentEl); + + if (parentInDOM) { + this._featuredScrollbar ??= this._createScrollbar(featuredParentEl); + } + } + } +} + +Search.html = (_search_html__WEBPACK_IMPORTED_MODULE_1___default()); + +/* harmony default export */ __webpack_exports__["default"] = (Search); + + +/***/ }), + +/***/ "../eyes/src/components/settings/index.js": +/*!************************************************!*\ + !*** ../eyes/src/components/settings/index.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _settings_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./settings.js */ "../eyes/src/components/settings/settings.js"); + + + + +/* harmony default export */ __webpack_exports__["default"] = (_settings_js__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/settings/settings.js": +/*!***************************************************!*\ + !*** ../eyes/src/components/settings/settings.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var screenfull__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! screenfull */ "../eyes/node_modules/screenfull/index.js"); +/* harmony import */ var tippy_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tippy.js */ "../eyes/node_modules/tippy.js/dist/tippy.esm.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _settings_html__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./settings.html */ "../eyes/src/components/settings/settings.html"); +/* harmony import */ var _settings_html__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_settings_html__WEBPACK_IMPORTED_MODULE_3__); + + + + + + + +/** + * @inheritdoc + * @extends BaseComponent + */ +class Settings extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + const config = { + isCollapsible: true, + allowToggleUnit: false, + allowLayers: true, + allowZoom: true, + allowFullscreen: screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].isEnabled, + allowPhotoMode: false, + allowInfoPanel: true, + allowLighting: true, + showLightOptions: false, + allowGuidedCamera: false, + zoomIn: app.getManager('camera').zoomIn, + zoomOut: app.getManager('camera').zoomOut, + ...options.config + }; + delete options.config; + + config.orientation = { + bigPortrait: { + check: config.orientation?.bigPortrait?.check || (() => _internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isPortrait() && !_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobilePortrait() && !_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isTabletPortrait()), + ori: config.orientation?.bigPortrait?.ori || 'vertical' + }, + tabletPortrait: { + check: config.orientation?.tabletPortrait?.check || (() => _internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isTabletPortrait()), + ori: config.orientation?.tabletPortrait?.ori || 'vertical' + }, + smallPortrait: { + check: config.orientation?.smallPortrait?.check || (() => _internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobilePortrait()), + ori: config.orientation?.smallPortrait?.ori || 'vertical' + }, + bigLandscape: { + check: config.orientation?.bigLandscape?.check || (() => _internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isLandscape() && !_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobileLandscape() && !_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isTabletLandscape()), + ori: config.orientation?.bigLandscape?.ori || 'vertical' + }, + tabletLandscape: { + check: config.orientation?.tabletPortrait?.check || (() => _internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isTabletLandscape() || _internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isPanorama()), + ori: config.orientation?.tabletPortrait?.ori || 'vertical' + }, + smallLandscape: { + check: config.orientation?.smallLandscape?.check || (() => _internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobileLandscape()), + ori: config.orientation?.smallLandscape?.ori || 'horizontal' + } + }; + + super(app, null, { + isMetric: false, + isVisible: true, + isFullscreen: false, + isPhotoMode: false, + isGuidedCamera: true, + showOrbitLines: true, + showLabels: true, + lightType: 'shadow', + config, + ...options + }); + + /** + * Manually set orientation for buttons. + * @type {string} + */ + this._ori = ''; + + this._isMobileMode = _internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobileMode(); + this._isHorizontal = null; + + Object.assign(this._class, { + container: { + collapse: 'hidden', + expand: 'active' + }, + isItemVisible: { + true: '', + false: 'hidden' + }, + icon: { + imperial: 'icon-mi', + metric: 'icon-km', + info: 'icon-info' + }, + fullscreen: { + true: 'fullscreen', + false: 'window' + }, + photo: { + true: 'active', + false: '' + }, + light: { + natural: 'icon-natural-light', + shadow: 'icon-shadow-light', + flood: 'icon-flood-light' + }, + camera: { + true: 'icon-free-cam', + false: 'icon-auto-cam' + }, + isHorizontal: { + true: 'horizontal', + false: 'vertical' + } + }); + + const isVisible = !this._isMobileMode; + const isCollapsed = this._isMobileMode; + const isHorizontal = this.isHorizontal(); + const CameraManager = /** @type {CameraManager} */ this.app.getManager('camera'); + this._fullLightColor = CameraManager.getFullLightColor(); + this._shadowLightColor = CameraManager.getShadowLightColor(); + + Object.assign(this._state, { + isVisible, + isCollapsed, + isVisibleClass: this._class.isVisible[isVisible], + containerClass: isCollapsed ? this._class.container.collapse : this._class.container.expand, + isCollapsibleClass: this._class.isItemVisible[this._config.isCollapsible], + allowInfoPanelClass: this._class.isItemVisible[this._config.allowInfoPanel], + allowToggleUnitClass: this._class.isItemVisible[this._config.allowToggleUnit], + allowPhotoModeClass: this._class.isItemVisible[this._config.allowPhotoMode], + allowZoomClass: this._class.isItemVisible[this._config.allowZoom], + allowLightingClass: this._class.isItemVisible[this._config.allowLighting], + showLightingOptionsClass: this._class.isItemVisible[this._config.showLightOptions], + allowGuidedCameraClass: this._class.isItemVisible[this._config.allowGuidedCamera], + allowFullscreenClass: this._class.isItemVisible[this._config.allowFullscreen], + allowLayersClass: this._class.isItemVisible[this._config.allowLayers], + unitButton: this._state.isMetric ? this._class.icon.imperial : this._class.icon.metric, + infoButton: this._class.icon.info, + fullscreenClass: this._class.fullscreen[this._state.isFullscreen], + photoModeClass: this._class.photo[this._state.isPhotoMode], + lightClass: this._class.light[this._state.lightType], + guidedClass: this._class.camera[this._state.isGuidedCamera], + isHorizontal, + orientationClass: this._class.isHorizontal[isHorizontal] + }); + + /** + * Array of possible event names. + * @type {string[]} + * @default + */ + this._eventNames.push('unitchange', 'photomodechange', 'guidedcamerachange', 'expandtoggle'); + this._initCallbacks(); + + /** + * Mouse is held down + * @type {boolean} + * @default + */ + this._isMouseHold = false; + + /** + * Zoom is continuous or not. + * @type {boolean} + * @default + */ + this._isContinuousZoom = false; + + /** + * Interval to zoom continuously. + */ + this._zoomInterval = null; + this._zoomTimeout = null; + + /** + * Array to store tippy tooltip instances. + */ + this._tooltips = []; + + /** + * Set default tippy props + * See docs: https://atomiks.github.io/tippyjs/v6/methods/ + */ + tippy_js__WEBPACK_IMPORTED_MODULE_4__["default"].setDefaultProps({ + theme: 'default', + touch: ['hold', 2000], + delay: [600, null], + plugins: [tippy_js__WEBPACK_IMPORTED_MODULE_4__.followCursor] + }); + + // Binds + this.bindFunctions([ + 'toggleCollapse', + 'toggleUnit', + 'toggleLayers', + 'toggleFullscreen', + 'togglePhotoMode', + 'hideLightingOptions', + 'toggleLightOptions', + 'toggleLight', + 'toggleGuidedCamera', + 'toggleInfoPanel', + 'startGuidedCamera', + 'stopGuidedCamera', + '_zoomIn', + '_zoomOut', + '_stopZooming', + '_updateSize' + ]); + } + + /** @inheritdoc */ + init() { + super.init(); + + const { + isCollapsible, + allowToggleUnit, + allowLayers, + allowZoom, + allowFullscreen, + allowPhotoMode, + allowInfoPanel, + allowLighting, + allowGuidedCamera + } = this._config; + + const newState = {}; + + // Desktop toggle button + if (isCollapsible) { + newState.isCollapsibleClass = this._class.isItemVisible[isCollapsible]; + } + + if (allowInfoPanel) { + newState.allowInfoPanelClass = this._class.isItemVisible[allowInfoPanel]; + } + + if (allowToggleUnit) { + newState.allowToggleUnitClass = this._class.isItemVisible[allowToggleUnit]; + } + + if (allowPhotoMode) { + newState.allowPhotoModeClass = this._class.isItemVisible[allowPhotoMode]; + } + + if (allowZoom) { + newState.allowZoomClass = this._class.isItemVisible[allowZoom]; + + // Zoom in + this._children.zoomInButton.addEventListener('mousedown', () => { + this._stopZooming(); + this._zoomIn(true); + }); + this._children.zoomInButton.addEventListener('mouseleave', this._stopZooming); + this._children.zoomInButton.addEventListener('mouseup', () => { + if (!this._isContinuousZoom) { + this._zoomIn(); + } + this._stopZooming(); + }); + this._children.zoomInButton.addEventListener('touchstart', event => { + event.preventDefault(); + this._stopZooming(); + this._zoomIn(true); + }); + this._children.zoomInButton.addEventListener('touchmove', event => { + event.preventDefault(); + const element = document.elementFromPoint(event.changedTouches[0].clientX, event.changedTouches[0].clientY); + if (element.getAttribute('key') !== 'zoomInButton') { + this._stopZooming(); + } + }); + this._children.zoomInButton.addEventListener('touchend', event => { + event.preventDefault(); + if (!this._isContinuousZoom) { + this._zoomIn(); + } + this._stopZooming(); + }); + + // Zoom out + this._children.zoomOutButton.addEventListener('mousedown', () => { + this._stopZooming(); + this._zoomOut(true); + }); + this._children.zoomOutButton.addEventListener('mouseleave', this._stopZooming); + this._children.zoomOutButton.addEventListener('mouseup', () => { + if (!this._isContinuousZoom) { + this._zoomOut(); + } + this._stopZooming(); + }); + this._children.zoomOutButton.addEventListener('touchstart', event => { + event.preventDefault(); + this._stopZooming(); + this._zoomOut(true); + }); + this._children.zoomOutButton.addEventListener('touchmove', event => { + event.preventDefault(); + const element = document.elementFromPoint(event.changedTouches[0].clientX, event.changedTouches[0].clientY); + if (element.getAttribute('key') !== 'zoomOutButton') { + this._stopZooming(); + } + }); + this._children.zoomOutButton.addEventListener('touchend', event => { + event.preventDefault(); + if (!this._isContinuousZoom) { + this._zoomOut(); + } + this._stopZooming(); + }); + } + + if (allowLighting) { + newState.allowLightingClass = this._class.isItemVisible[allowLighting]; + this._children.flood.onclick = this.toggleLightOptions.bind(this._children.flood, 'flood'); + this._children.shadow.onclick = this.toggleLightOptions.bind(this._children.shadow, 'shadow'); + this._children.natural.onclick = this.toggleLightOptions.bind(this._children.natural, 'natural'); + + // Turn on shadow light mode by default + this._children.shadow.classList.add('selected-lighting'); + + this.toggleLightOptions('shadow'); + } + + if (allowGuidedCamera) { + newState.allowGuidedCameraClass = this._class.isItemVisible[allowGuidedCamera]; + } + + if (allowFullscreen && screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].isEnabled) { + newState.allowFullscreenClass = this._class.isItemVisible[allowFullscreen]; + + // On fullscreen api change event + screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].on('change', () => { + const isFullscreen = screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].isFullscreen; + this.setState({ + isFullscreen, + fullscreenClass: this._class.fullscreen[isFullscreen] + }); + }); + } + + if (allowLayers) { + newState.allowLayersClass = this._class.isItemVisible[allowLayers]; + } + + this.setState(newState); + + // Add tooltips to elements + const tooltipElements = this._element.querySelectorAll('.settings button:not(.zoom), span[key="zoomInButton"], span[key="zoomOutButton"]'); + + this.addTooltips( + tooltipElements, + { + update: function (isHorizontal) { + /** + * Note: We don't want to use an arrow function to enclose the 'this' property + * because we want 'this' to reference the tippy instance itself + */ + // eslint-disable-next-line no-invalid-this + this.setProps({ placement: isHorizontal ? 'top' : 'left' }); + } + } + + ); + + this._updateSize(); + + this._callbackRegistry.push({ + emitter: this._app.getManager('time'), + event: 'ratechange', + callback: this.onRateChange + }); + } + + /** + * Use tippy library to create tooltip instances to add to the _toolips array + * @param {Array} elements + * @param {object} params + * @returns {Array|object} + */ + addTooltips(elements, params) { + const props = params.props || {}; + + const tippys = (0,tippy_js__WEBPACK_IMPORTED_MODULE_4__["default"])( + elements, + props + ); + + // If passed, add update function to each tippy instance. + if (typeof params.update === 'function') { + for (const tip of tippys) { + tip.update = params.update; + } + } + if (typeof params.onclick === 'function') { + for (const tip of tippys) { + tip.popper.onclick = params.onclick; + } + } + + this._tooltips.push(...tippys); + + return tippys.length === 1 ? tippys[0] : tippys; + } + + /** + * Loop through the tooltips and call their update function if it exists + * @param {boolean} isHorizontal + */ + updateTooltips(isHorizontal) { + for (const tooltip of this._tooltips) { + if (typeof tooltip.update === 'function') { + tooltip.update(isHorizontal); + } + } + } + + /** + * Update setting's config. + * @param {object} config + */ + setConfig(config) { + const { collapseSettingsOptions, hideFullScreenToggle, lighting } = this.app.getManager('router').configs; + // Only allow fullscreen if has capability + if (config.allowFullscreen && hideFullScreenToggle !== true) { + config.allowFullscreen = screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].isEnabled; + } + + // Update orientation + if (config.orientation) { + const oriConfig = this._config.orientation; + const orientations = ['bigPortrait', 'tabletPortrait', 'smallPortrait', 'bigLandscape', 'tabletLandscape', 'smallLandscape']; + for (let i = 0; i < orientations.length; i++) { + const ori = orientations[i]; + if (!config.orientation[ori]) { + config.orientation[ori] = oriConfig[ori]; + } + else { + config.orientation[ori].check ??= oriConfig[ori].check; + config.orientation[ori].ori ??= oriConfig[ori].ori; + } + } + } + + super.setConfig(config); + const newState = {}; + + for (const key in config) { + if (key === 'orientation') { + const isHorizontal = this.isHorizontal(); + newState.isHorizontal = isHorizontal; + newState[`${key}Class`] = this._class.isHorizontal[isHorizontal]; + } + else { + newState[`${key}Class`] = this._class.isItemVisible[config[key]]; + } + } + + this.setState(newState); + + // Override any set configs with embed queries + if (collapseSettingsOptions === true) { + this.collapse(); + } + if (hideFullScreenToggle === true) { + this.hideFullScreenOption(); + } + if (lighting === 'flood' || lighting === 'natural') { + this.toggleLightOptions(lighting); + } + + this._updateSize(true); + } + + /** + * Get manually set orientation. + * @returns {string} + */ + getOrientation() { + return this._ori; + } + + /** + * Manually set orientation to overwrite the auto orientation. + * Passing no orientation will reset to auto mode. + * @param {string} [ori=''] - Buttons' orientation: 'horizontal' or 'vertical' + */ + setOrientation(ori = '') { + this._ori = ori; + } + + /** + * Check if orientation should be horizontal or not. + * @returns {boolean} + */ + isHorizontal() { + // Manually set orietation + if (this._ori !== '') { + return this._ori === 'horizontal'; + } + + // Auto orientation + for (const key in this._config.orientation) { + const orientation = this._config.orientation[key]; + if (orientation.check()) { + return orientation.ori === 'horizontal'; + } + } + + return false; + } + + /** + * Update settings size dynamically according to mode and the numbers of visible buttons. + * @param {boolean} forceResize - force to resize regardless of isHorizontal + */ + _updateSize(forceResize = false) { + const isHorizontal = this.isHorizontal(); + if (!forceResize && this._isHorizontal === isHorizontal) { + return; + } + + this._isHorizontal = isHorizontal; + + // Collapse/expand button + let buttonCount = 1; + + // Visible settings buttons + const buttons = Array.from(this._children.content.querySelectorAll(':scope > button')); + for (let i = 0; i < buttons.length; i++) { + if (buttons[i].classList.contains('hidden')) { + continue; + } + buttonCount++; + } + if (this._config.allowZoom) { + // Add one because zoom buttons are grouped as one + buttonCount++; + } + + // Set size + if (this._isHorizontal) { + this._element.style.width = `calc(${buttonCount} * 30px + ${buttonCount} * 2px)`; + this._element.style.height = '30px'; + } + else { + this._element.style.width = '30px'; + this._element.style.height = `calc(${buttonCount} * 30px + ${buttonCount} * 2px)`; + } + + // Update tooltip placement + this.updateTooltips(isHorizontal); + } + + /** + * Execute zoom continuously. + * @param {Function} zoomFunction + */ + _zoomContinuously(zoomFunction) { + this._isMouseHold = true; + + if (this._zoomTimeout !== null) { + clearTimeout(this._zoomTimeout); + } + this._zoomTimeout = setTimeout(() => { + if (this._isMouseHold) { + this._isContinuousZoom = true; + // Mouse was held down for some time + if (this._zoomInterval !== null) { + clearInterval(this._zoomInterval); + } + this._zoomInterval = setInterval(() => { + if (this._isMouseHold) { + zoomFunction(true); + } + else { + clearInterval(this._zoomInterval); + } + }, 30); + } + }, 200); + } + + /** + * Handle zoom in discretely or continuously. + * @param {boolean} [isContinuous=false] - Zoom continuously + */ + _zoomIn(isContinuous = false) { + if (isContinuous) { + this._zoomContinuously(this._config.zoomIn); + } + else { + this._config.zoomIn(); + } + } + + /** + * Handle zoom out discretely or continuously. + * @param {boolean} [isContinuous=false] - Zoom continuously + */ + _zoomOut(isContinuous = false) { + if (isContinuous) { + this._zoomContinuously(this._config.zoomOut); + } + else { + this._config.zoomOut(); + } + } + + /** + * Stop continuous zoom. + */ + _stopZooming() { + clearInterval(this._zoomInterval); + this._isMouseHold = false; + this._isContinuousZoom = false; + } + + /** + * Show settings. + */ + show() { + this.setState({ + isVisible: true, + isVisibleClass: this._class.isVisible.true + }); + } + + /** + * Hide settings. + */ + hide() { + this.setState({ + isVisible: false, + isVisibleClass: this._class.isVisible.false, + showLightingOptionsClass: this._class.isVisible.false + }); + } + + /** + * Returns true if visible. + * @returns {boolean} + */ + isVisible() { + return this._state.isVisible; + } + + /** + * Show buttons. + */ + expand() { + this.setState({ + isCollapsed: false, + containerClass: this._class.container.expand + }); + } + + /** + * Hide buttons. + */ + collapse() { + this.setState({ + isCollapsed: true, + showLightingOptionsClass: this._class.isVisible.false, + containerClass: this._class.container.collapse + }); + } + + /** + * Toggle expand/collapse buttons. + */ + toggleCollapse() { + if (this._state.isCollapsed) { + this.expand(); + } + else { + this.collapse(); + } + this.triggerCallbacks('expandtoggle', [!this._state.isCollapsed, this._state.isPhotoMode]); + } + + /** + * Toggle unit between metric and imperial. + */ + toggleUnit() { + const isMetric = !this._state.isMetric; + this.setState({ + isMetric, + unitButton: isMetric ? this._class.icon.imperial : this._class.icon.metric + }, () => { + this.triggerCallbacks('unitchange', [this._state.isMetric]); + }); + } + + /** + * Toggle fullscreen. + */ + toggleFullscreen() { + if (screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].isEnabled) { + screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].toggle(); + } + } + + /** + * Toggle layers panel. + */ + toggleLayers() { + const layersPanelOpen = !this._app.getComponent('layerPanel').getState('isVisible'); + if (layersPanelOpen) { + this._app.getComponent('layerPanel').show(); + this.collapse(); + } + else { + this._app.getComponent('layerPanel').hide(); + } + } + + /** + * Toggle photo mode. + */ + togglePhotoMode() { + const isPhotoMode = !this._state.isPhotoMode; + this.setState({ + isPhotoMode, + photoModeClass: this._class.photo[isPhotoMode] + }, () => { + if (this._state.isPhotoMode) { + this.collapse(); + } + else { + this.expand(); + } + this.triggerCallbacks('photomodechange', [this._state.isPhotoMode]); + }); + } + + /** + * Hide the lighting options panel + * @param {Event} e + */ + hideLightingOptions(e) { + const checkList = [this._children.lightToggle, this._children.lightOptions, this._children.flood, this._children.natural, this._children.shadow]; + + if (!checkList.includes(e.target)) { + this.setState({ + showLightingOptionsClass: this._class.isVisible.false + }); + } + window.removeEventListener('mousedown', this.hideLightingOptions); + window.removeEventListener('touchstart', this.hideLightingOptions); + } + + /** + * Hide fullscreen option + */ + hideFullScreenOption() { + const newState = {}; + newState.allowFullscreenClass = this._class.isItemVisible[false]; + this.setState(newState); + } + + /** + * Toggle light options panel + * @param {string} type + */ + toggleLightOptions(type) { + this.setState({ + lightType: type, + lightClass: this._class.light[type], + showLightingOptionsClass: this._class.isVisible.false + }, () => { + if (type === 'flood') { + this._app.getManager('camera')?.toggleCameraLight(true, this._fullLightColor); + this._app.getManager('comparison')?.setCameraLight(true, this._fullLightColor); + } + else if (type === 'natural') { + this._app.getManager('camera')?.toggleCameraLight(false); + this._app.getManager('comparison')?.setCameraLight(false); + } + else if (type === 'shadow') { + this._app.getManager('camera')?.toggleCameraLight(true, this._shadowLightColor); + this._app.getManager('comparison')?.setCameraLight(true, this._shadowLightColor); + } + + for (const key in this._children) { + // Remove highlight from unselected light options + if (key !== type && (key === 'flood' || key === 'natural' || key === 'shadow')) { + this._children[key].classList.remove('selected-lighting'); + } + } + + // Add highlight to selected lighting option icon and title + this._children[`${type}`].classList.add('selected-lighting'); + }); + } + + /** + * Toggle lighting. + */ + toggleLight() { + this.setState({ + showLightingOptionsClass: this.getState('showLightingOptionsClass') === this._class.isVisible.true ? this._class.isVisible.false : this._class.isVisible.true + }); + + if (this.getState('showLightingOptionsClass') === this._class.isVisible.true) { + window.addEventListener('mousedown', this.hideLightingOptions); + window.addEventListener('touchstart', this.hideLightingOptions); + } + else { + window.removeEventListener('mousedown', this.hideLightingOptions); + window.removeEventListener('touchstart', this.hideLightingOptions); + } + } + + /** + * Start guided camera. + */ + startGuidedCamera() { + this.setState({ + isGuidedCamera: true, + guidedClass: this._class.camera.true + }, () => this.triggerCallbacks('guidedcamerachange', [this._state.isGuidedCamera])); + } + + /** + * Stop guided camera. + */ + stopGuidedCamera() { + this.setState({ + isGuidedCamera: false, + guidedClass: this._class.camera.false + }, () => this.triggerCallbacks('guidedcamerachange', [this._state.isGuidedCamera])); + } + + /** + * Toggle guided camera. + */ + toggleGuidedCamera() { + if (this._state.isGuidedCamera) { + this.stopGuidedCamera(); + } + else { + this.startGuidedCamera(); + } + } + + /** + * Toggles info panel. + */ + toggleInfoPanel() { + if (this._app.getComponent('infoPanel') !== null) { + this._app.getComponent('infoPanel').openPanel(); + } + } + + /** @inheritdoc */ + resize() { + super.resize(); + + // Reorient if needed + const isHorizontal = this.isHorizontal(); + if (this._isHorizontal !== isHorizontal) { + this.setState({ + isHorizontal, + orientationClass: this._class.isHorizontal[isHorizontal] + }); + } + + this._updateSize(); + } +} + +Settings.html = (_settings_html__WEBPACK_IMPORTED_MODULE_3___default()); + +/* harmony default export */ __webpack_exports__["default"] = (Settings); + + +/***/ }), + +/***/ "../eyes/src/components/share_modal/index.js": +/*!***************************************************!*\ + !*** ../eyes/src/components/share_modal/index.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _share_modal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./share_modal */ "../eyes/src/components/share_modal/share_modal.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = (_share_modal__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/share_modal/share_modal.js": +/*!*********************************************************!*\ + !*** ../eyes/src/components/share_modal/share_modal.js ***! + \*********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _share_modal_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./share_modal.html */ "../eyes/src/components/share_modal/share_modal.html"); +/* harmony import */ var _share_modal_html__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_share_modal_html__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var tippy_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tippy.js */ "../eyes/node_modules/tippy.js/dist/tippy.esm.js"); +/* harmony import */ var _data_embed_controls__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../data/embed_controls */ "../eyes/src/data/embed_controls.js"); + + + + + + + + +/** + * Share Modal component. + */ +class ShareModal extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options) { + super(app, null, { + isVisible: false, + iframeElements: true, + linkTitle: '', + previewDevice: '', + previewResolution: '', + previewVisibleClass: _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isiPhone() ? 'hidden' : '', + isWide: null, + ...options, + config: { + title: 'Share', + shareBtnParent: { + selector: '.header', + wideSelector: '.header', + threshold: 1025 + }, + linkAltText: 'Eyes', + linkImageSrc: '', + paramsToKeep: ['time', 'rate', 'slide', 'followId', ...options?.paramsToKeep ?? []], + resetOnClose: true, + + // Device resolution options. + deviceResolutions: { + desktop: { width: 1280, height: 720 }, + tablet: { width: 1024, height: 1366 }, + phone: { width: 375, height: 667 } + }, + ...options?.config + } + + }); + + this._activeTab = null; + this._srcURL = null; + + /** + * Options scrollbar instance. + * @type {OverlayScrollbars} + */ + this._embedOptionsScrollbar = null; + + // Tippy vars. + this._tippySingleton = null; + this._tippyItems = null; + this._tippyTimeout = null; + + this._embedQueries = {}; + + this._inputElements = {}; + + this.bindFunctions(['_iframeLoadEventListener']); + } + + /** + * Concatenated EMBED_DEFAULT_CONTROLS with this._config.controls. + * If the EMBED_DEFAULT_CONTROLS array has objects with matching groupName property to options.controls array, merge the items array. + * If options.controls contains new groupName properties, add them to the array. + */ + mergeEmbedControls() { + const { controls } = this._config; + const mergedControls = _data_embed_controls__WEBPACK_IMPORTED_MODULE_3__["default"].map(defaultControl => { + const { groupName: defaultGroupName, items: defaultItems } = defaultControl; + const newControl = controls.find(control => control.groupName === defaultGroupName); + + if (newControl) { + const { items: newItems } = newControl; + // Filter out default items that are already in the newItems array. + const mergedItems = defaultItems.filter(({ name }) => !newItems.some(({ name: newName }) => newName === name)); + return { ...defaultControl, items: [...newItems, ...mergedItems] }; + } + + return defaultControl; + }); + + // Add any new controls to the mergedControls array. + const newControls = controls.filter(control => !mergedControls.some(({ groupName }) => groupName === control.groupName)); + + // Set the embedO + this._config.embedOptions = [...mergedControls, ...newControls]; + } + + /** + * Initilizing the component + * @override + * @inheritdoc + */ + init() { + super.init(); + const { canHover } = this._app; + + // Merge the embed controls. + this.mergeEmbedControls(); + + // Set the embed parameters. + this.setEmbedParams(); + + // Generate the embed content. + this.generateEmbedContent(); + + // Set the wide selector state. + this.setIsWide(); + + // Scrollbar creation + this.createScrollbars(); + + // Create and add the share button to the parent. + this.createShareButton(); + this.addShareButtonToParent(); + + /** + * Set default tippy props + */ + tippy_js__WEBPACK_IMPORTED_MODULE_4__["default"].setDefaultProps({ + theme: 'default', + touch: true, + hideOnClick: false, + delay: [300, null], + placement: 'top', + trigger: 'mouseenter click', + // If we dont have hovering ability, hide the tooltip after a delay + onTrigger: instance => { + clearTimeout(this._tippyTimeout); + if (!canHover) { + this._tippyTimeout = setTimeout(() => { + instance?.hide(); + }, 3000); + } + }, + // Manual hide on outside click as hideOnClick is false and behaves oddly for touch when true. + onClickOutside: instance => { + instance.hide(); + }, + // Make sure the tippy elements are blurred (not focused) when hidden (doesnt happen by default on touch devices) + onHidden: _ => { + this._tippyItems?.forEach(({ reference }) => reference.blur()); + } + }); + } + + /** + * Create the scrollbars for the embed options. + */ + createScrollbars() { + const { embedOptsContent } = this._children; + const sectionParent = embedOptsContent.parentElement; + + _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.onAttachElement(sectionParent, () => { + this._embedOptionsScrollbar = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addScrollbar(sectionParent); + }); + } + + /** + * Get the current device. + * @returns {string} The current device. + */ + getCurrentDevice() { + if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isTablet()) { + return 'tablet'; + } + if (_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobile()) { + return 'phone'; + } + return 'desktop'; + } + + /** + * Creates the share button. + */ + createShareButton() { + this.shareButton = document.createElement('button'); + this.shareButton.className = 'share-button clickable'; + this.shareButton.innerText = 'Share'; + + const shareIcon = document.createElement('span'); + shareIcon.className = 'icon icon-share'; + this.shareButton.prepend(shareIcon); + + // Add the click event. + this.shareButton.addEventListener('click', () => { + // Set the src URL. + this.setSrcURL(); + + // Set the default preview device. + this.setPreviewDevice({ target: { value: this.getCurrentDevice() } }); + + // Always set the active tab to the link on open. + this.setActiveTab('link'); + + // Set the src and alt text attributes for the link image. + const { linkImage } = this._children; + const { linkAltText: backupAltText, linkImageSrc: backupImageSrc } = this._config; + + // For future when we have entity-specific SEO - we can use the title and og:image + const title = document.querySelector('title')?.innerText; + const ogImage = document.querySelector('meta[property="og:image"]')?.getAttribute('content'); + const altText = title || backupAltText; + const src = (ogImage !== '$OG_IMAGE' && ogImage) || backupImageSrc; + + // Set the link image attributes. + linkImage.setAttribute('alt', altText); + linkImage.setAttribute('src', src); + + // Set the link title state. + const { fullTitle } = this._app.getManager('title'); + const linkTitle = fullTitle ?? altText; + this.setState({ linkTitle }); + + // Show the modal. + this.show(); + }); + } + + /** + * Determine if the wide selector should be used for the share button parent. + * @returns {boolean} Whether the isWide state has been updated. + */ + setIsWide() { + const { isWide: currentIsWide } = this._state; + const { shareBtnParent } = this._config; + const { threshold } = shareBtnParent; + + const newIsWide = window.innerWidth >= threshold; + + if (currentIsWide !== newIsWide) { + this.setState({ isWide: newIsWide }); + return true; + } + + return false; + } + + /** + * Add the share button to the parent. + */ + addShareButtonToParent() { + const { shareBtnParent } = this._config; + const { isWide } = this._state; + const { selector, wideSelector } = shareBtnParent; + + // Remove it from its current parent. + this.shareButton.parentNode?.removeChild(this.shareButton); + + // Add it to the new parent, once it's ready. + const shareBtnParentSelector = isWide ? wideSelector : selector; + _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.elementReady(shareBtnParentSelector, 3000) + .then(shareButtonParent => { + // Append the button to the parent. + shareButtonParent.appendChild(this.shareButton); + return true; + }) + .catch(e => e); + } + + + /** + * Set the src URL and update the code text content. + * @param {string} href + * @param {boolean} updateCode + */ + setSrcURL(href = window.location.href, updateCode = true) { + const { linkCode } = this._children; + const { paramsToKeep } = this._config; + + // Determine the parameters to keep from config. + const splitHref = href.split('?'); + const params = splitHref[1] ? new URLSearchParams(splitHref[1]) : new URLSearchParams(); + const paramKeysArray = Array.from(params.keys()); + + // Iterate over all keys + for (const key of paramKeysArray) { + // If the key is not in the array, delete it + if (!paramsToKeep.includes(key)) { + params.delete(key); + } + } + + this._srcURL = `${splitHref[0]}${params.size ? '?' : ''}${params.toString()}`; + + // Set the basic link code text content - a direct copy of the href, with no params removed. + if (updateCode) { + linkCode.textContent = href; + } + } + + /** + * Sets the default embed parameters. + */ + setEmbedParams() { + const { embedOptions } = this._config; + + // Create the embed parameters. + embedOptions.forEach(({ items }) => { + items.forEach(option => { + const { query, inputDefault, invert } = option; + const value = invert ? !inputDefault : inputDefault; + this._embedQueries[query] = value; + }); + }); + } + + /** + * Update the embed parameters and the code text content. + * @param {string} query + * @param {string|boolean|number} value + */ + updateEmbedParams(query, value) { + if (this._embedQueries[query] === value || this._embedQueries[query] === undefined) { + return; + } + + // Update the embed param. + this._embedQueries[query] = value; + + // Update the embed code. + this.updateEmbedCode(); + } + + /** + * Set the embed preview and copy-able code text content. + * @param {object} params + */ + updateEmbedCode(params) { + const { force = false, updatePreview = true } = params || {}; + const { embedCode, embedPreviewParent } = this._children; + const { iframeElements } = this._state; + + // Get the embed code as a string. + const { srcURL, iframeString, noTrackingIframeString } = this.getEmbedCodeFromParams(); + + const embedCodeString = iframeElements ? iframeString : srcURL; + + // Update embed code text content. + if (embedCodeString !== embedCode.textContent || force) { + embedCode.textContent = embedCodeString; + } + + // Add the embed code to the parent element and subsequent nav listener. + if (updatePreview && !_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isiPhone() && (embedPreviewParent?.innerHTML.replace(/&/g, '&') !== noTrackingIframeString || force)) { + // Remove the previous load event listener. + const iframe = embedPreviewParent.querySelector('iframe'); + iframe?.removeEventListener('load', this._iframeLoadEventListener); + + // Reset the iframe's innerHTML + embedPreviewParent.innerHTML = noTrackingIframeString; + + // Add the load event listener to the new iframe. + const newIframe = embedPreviewParent.querySelector('iframe'); + newIframe.addEventListener('load', this._iframeLoadEventListener); + } + + /** + * TODO in preview iframe code: + * Turn off google analytics for the preview + */ + + // Force a resize to update the iframe transform. + this.resize(); + } + + /** + * Calculate the template size. + */ + calcTemplateWidth() { + const { deviceResolutions } = this._config; + const { embedPreviewParent } = this._children; + const { previewDevice, useBrowserTemplate } = this._state; + + if (!useBrowserTemplate) { + return; + } + + const { width, height } = deviceResolutions[previewDevice] || deviceResolutions.desktop; + + console.log('\ncalculating template size for', previewDevice); + console.log('width:', width); + console.log('height:', height); + } + + /** + * Calculate the iframe transform scale and offset-x according to its parent's dimensions. + */ + calcIframeTransform() { + console.log('calcIframeTransform: '); + const { previewResolution } = this._state; + const { width, height } = previewResolution; + + // Force a resize to update the iframe transform. + this.resize(); + } + + /** + * Define the load event listener function. + * @param {Event} e + */ + _iframeLoadEventListener(e) { + const { contentWindow } = e.target; + // Check if the iframe's contentWindow is accessible. + if (contentWindow) { + // Add a hashchange event listener to the iframe's window. + contentWindow.onhashchange = () => { + this.setSrcURL(contentWindow.location.href, false); + this.updateEmbedCode({ updatePreview: false }); + }; + } + } + + /** + * Calculate the iframe transform scale and offset-x according to its parent's dimensions. + */ + calcIframeTransforms() { + const { embedPreviewParent } = this._children; + const { deviceResolutions } = this._config; + + const { width, height } = deviceResolutions.desktop; + + const { paddingTop, paddingRight, paddingBottom, paddingLeft } = getComputedStyle(embedPreviewParent); + const { clientWidth: parentWidth, clientHeight: parentHeight } = embedPreviewParent; + + const paddedParentWidth = parentWidth - parseFloat(paddingLeft) - parseFloat(paddingRight); + const paddedParentHeight = parentHeight - parseFloat(paddingTop) - parseFloat(paddingBottom); + + // Set the width and height CSS vars. + this._element.style.setProperty('--iframe-width', `${width}px`); + this._element.style.setProperty('--iframe-height', `${height}px`); + + // Determine the scale based on the parent and iframe dimensions. + const widthScale = paddedParentWidth / width; + const heightScale = paddedParentHeight / height; + const iframeScale = Math.min(widthScale, heightScale); + + // Set the --iframe-scale CSS variable. + this._element.style.setProperty('--iframe-scale', iframeScale); + + // Determine the scaled offset-x and set the CSS variable. + const offsetX = (paddedParentWidth - (width * iframeScale)) / 2; + const scaledOffsetX = offsetX / iframeScale; + this._element.style.setProperty('--iframe-offset-x', `${scaledOffsetX}px`); + } + + /** + * Set the preview device. + * @param {Event} e + */ + setPreviewDevice(e) { + const { value: previewDevice } = e.target; + const { previewDevice: currPreviewDevice } = this._state; + + // If the current device is the same as the new device, return. + if (previewDevice === currPreviewDevice) { + return; + } + + // Update the previewDevice state. + this.setState({ previewDevice }); + + // Force update the embed code. + this.updateEmbedCode({ force: true }); + } + + /** + * Toggle the iframe elements. + * @param {Event} e + */ + toggleIframeElements(e) { + // Set the checked state. + const { checked } = e.target; + this.setState({ iframeElements: checked }); + + // Update the embed code. + this.updateEmbedCode({ updatePreview: false }); + } + + /** + * Get the embed code from the params. + * @returns {object} The embed code as a string. + */ + getEmbedCodeFromParams() { + const { embedOptions } = this._config; + const flattenedOptions = embedOptions.flatMap(({ items }) => items); + + // Start with the existing params (already know we need to keep them as set in setSrcURL) + const splitUrl = this._srcURL.split('?'); + const urlParams = new URLSearchParams(splitUrl[1]); + const noTrackingUrlParams = new URLSearchParams(splitUrl[1]); + + /** + * Include only the parameters that: + * have been changed from the appQueryDefaults + * have satisfied the dependencies + */ + const embedParamEntries = Object.entries(this._embedQueries).filter(([currQuery, currValue]) => { + // Get the app default value for the current query. + const { appQueryDefault, dependencies } = flattenedOptions.find(({ query }) => query === currQuery) ?? {}; + + // Determine if the depenedencies are satisfied. + const dependenciesSatisfied = !dependencies + || (dependencies?.length && dependencies.every(([depQuery, depValidFunc]) => depValidFunc(this._embedQueries[depQuery]))); + + return currValue !== appQueryDefault && dependenciesSatisfied; + }); + + // Create the URLSearchParams from the queries. + const embedParams = Object.fromEntries(embedParamEntries); + const noTrackingParams = { ...embedParams, tracking: 'false' }; + + // Add the embedParams to the urlParams. + Object.keys(embedParams).forEach(key => urlParams.set(key, embedParams[key])); + + // Add the noTrackingParams to the noTrackingUrlParams. + Object.keys(noTrackingParams).forEach(key => noTrackingUrlParams.set(key, noTrackingParams[key])); + + // Update the src URL with the new params. + const srcURL = `${splitUrl[0]}${urlParams.size ? '?' : ''}${urlParams.toString()}`; + const noTrackingSrcURL = `${splitUrl[0]}${noTrackingUrlParams.size ? '?' : ''}${noTrackingUrlParams.toString()}`; + + // Build iFrame string code, including the src attribute. + const iframeString = ``; + const noTrackingIframeString = ``; + + // Get the embed code as a string. + return { srcURL, iframeString, noTrackingIframeString }; + } + + /** + * Generate the embed content. + */ + generateEmbedContent() { + const { embedOptions } = this._config; + const { embedOptsContent, embedAdvOptsContent } = this._children; + + embedOptions.forEach(({ isAdvanced, groupName, items }) => { + // Create the group container. + const containerType = groupName ? 'fieldset' : 'div'; + const groupContainer = document.createElement(containerType); + groupContainer.className = 'embed-group'; + + // Add the legend header if the groupName exists + if (groupName) { + const groupLegend = document.createElement('legend'); + groupLegend.innerText = groupName; + groupContainer.appendChild(groupLegend); + } + + // Create the interactive group inputs. + this.createGroupInputs(items, groupContainer); + + // Append the header and container to the options parent. + const optionsParent = isAdvanced ? embedAdvOptsContent : embedOptsContent; + optionsParent.appendChild(groupContainer); + }); + } + + /** + * Create the group inputs. + * @param {Array} items + * @param {HTMLElement} groupContainer + */ + createGroupInputs(items, groupContainer) { + items.forEach(option => { + const { name, description, query, type, values, inputDefault, greyValue, appQueryDefault, invert, onChange } = option; + + const singleInput = type === 'checkbox' || type === 'number'; + const radioInput = type === 'radio'; + const greyedOut = inputDefault === greyValue; + + /** + * Currently this supports checkbox or number (single input), and radio inputs. + */ + if (singleInput) { + // Create the container. + const inputContainer = document.createElement('div'); + inputContainer.className = `input-container ${type}-container ${greyedOut ? 'greyed-out' : ''}`; + + // Create the label and input + const embedId = `input-${query}`; + const label = document.createElement('label'); + label.className = 'clickable'; + label.innerText = name; + label.setAttribute('for', embedId); + + const input = document.createElement('input'); + input.className = 'clickable'; + input.setAttribute('id', embedId); + input.setAttribute('type', type); + input.setAttribute('name', query); + + if (type === 'checkbox' && inputDefault === true) { + input.setAttribute('checked', ''); + } + else if (type === 'number') { + const [min, max, step] = values; + input.setAttribute('min', min); + input.setAttribute('max', max); + input.setAttribute('step', step ?? 1); + input.setAttribute('value', inputDefault); + input.setAttribute('inputmode', 'decimal'); + input.setAttribute('required', ''); + } + else { + input.setAttribute('value', inputDefault); + } + + // Prevent the click event from bubbling up (fixes weird no-cursor bug in chrome) + input.addEventListener('click', e => e.stopPropagation()); + + // Add the change event listener. + input.addEventListener('change', e => { + const { checked, value, validity } = e.target; + if (type === 'checkbox') { + const invertedValue = invert ? !checked : checked; + this.updateEmbedParams(query, invertedValue); + + // Call the onChange function if it exists. + typeof onChange === 'function' && onChange(checked); + } + else if (type === 'number') { + const valueFloat = parseFloat(value); + const setValue = validity.valid ? valueFloat : appQueryDefault; + + // Update the embed params (if the value is invalid, we still need to update to the app default (to potentially remove a previous value) + this.updateEmbedParams(query, setValue); + + // Toggle the greyed-out class based on the validity. + const isGreyedOut = !validity.valid || valueFloat === greyValue; + inputContainer.classList.toggle('greyed-out', isGreyedOut); + + // Call the onChange function if it exists. + typeof onChange === 'function' && onChange(value); + } + }); + + // Create the help icon and tippy. + const helpIcon = document.createElement('span'); + helpIcon.className = 'clickable icon icon-help'; + helpIcon.setAttribute('data-tippy-content', description); + helpIcon.setAttribute('aria-label', `Help: ${description}`); + // Make it focusable (spans are not focusable by default) + helpIcon.setAttribute('tabindex', '0'); + + // Add the input, label and icon to the container. + inputContainer.appendChild(input); + inputContainer.appendChild(label); + inputContainer.appendChild(helpIcon); + + // Append the inputContainer to the groupContainer. + groupContainer.appendChild(inputContainer); + } + else if (radioInput) { + // Create the radio fieldset. + const radioFieldset = document.createElement('fieldset'); + radioFieldset.className = `radio-fieldset ${type}-option`; + + // Create the radio legend. + const radioLegend = document.createElement('legend'); + radioLegend.innerText = name; + radioFieldset.appendChild(radioLegend); + + values.forEach(({ title, value, description }) => { + // Create the details and summary elements. + const inputContainer = document.createElement('div'); + inputContainer.className = `input-container ${type}-container`; + + // Create the radio label. + const radioId = `input-${query}-${value}`; + const radioLabel = document.createElement('label'); + radioLabel.className = 'clickable'; + radioLabel.innerText = title; + radioLabel.setAttribute('for', radioId); + + // Create the radio input. + const radioInput = document.createElement('input'); + radioInput.className = 'clickable'; + radioInput.setAttribute('id', radioId); + radioInput.setAttribute('type', type); + radioInput.setAttribute('name', query); + radioInput.setAttribute('value', value); + // Conditionally set the checked attribute. + if (value === inputDefault) { + radioInput.setAttribute('checked', ''); + } + + // Add the change event listener. + radioInput.addEventListener('change', e => { + const { value } = e.target; + this.updateEmbedParams(query, value); + }); + + // Create the help icon and tippy. + const helpIcon = document.createElement('span'); + helpIcon.className = 'clickable icon icon-help'; + helpIcon.setAttribute('data-tippy-content', description); + helpIcon.setAttribute('aria-label', `Help: ${description}`); + // Make it focusable (spans are not focusable by default) + helpIcon.setAttribute('tabindex', '0'); + + // Add the input, label and icon to the inputContainer. + inputContainer.appendChild(radioInput); + inputContainer.appendChild(radioLabel); + inputContainer.appendChild(helpIcon); + + // Append the inputContainer to the fieldset container. + radioFieldset.appendChild(inputContainer); + }); + + // Append the radio container to the group container. + groupContainer.appendChild(radioFieldset); + } + }); + } + + /** + * Destroy the embed content. + */ + destroyEmbedContent() { + const { embedOptsContent, embedAdvOptsContent } = this._children; + embedOptsContent.innerHTML = ''; + embedAdvOptsContent.innerHTML = ''; + } + + + /** + * Set the active tab. + * @param {string} tabName + */ + setActiveTab(tabName) { + const { tabHeaders, tabContent } = this._children; + + // Set the active class on the tab headers and content. + tabHeaders.childNodes.forEach(tabHeaderEl => { + const active = tabHeaderEl.classList.contains(tabName); + tabHeaderEl.classList.toggle('active', active); + }); + + tabContent.childNodes.forEach(tabContentEl => { + const active = tabContentEl.classList.contains(tabName); + tabContentEl.classList.toggle('active', active); + }); + + // If the embed tab is selected, update the embed code + if (tabName === 'embed') { + this.updateEmbedCode(); + + // Set the tippy tooltip content if not already set. + if (this._tippySingleton === null) { + this._tippyItems = (0,tippy_js__WEBPACK_IMPORTED_MODULE_4__["default"])('.icon-help'); + this._tippySingleton = (0,tippy_js__WEBPACK_IMPORTED_MODULE_4__.createSingleton)(this._tippyItems, { + moveTransition: 'transform 0.2s ease-out' + }); + } + } + + // Set the active tab state. + this._activeTab = tabName; + } + + /** + * Copy to clipboard method + * @param {Event} e + */ + copyToClipboard(e) { + const { linkCode, linkContainer, embedCode, copiedOverlay } = this._children; + + // Determine whether we're copying the link or the embed code. + const isLink = e.currentTarget.parentElement === linkContainer; + const codeText = isLink ? linkCode.textContent : embedCode?.textContent; + + if (!codeText) { + return; + } + + navigator.clipboard.writeText(codeText) + .then(() => { + // Add the active class to display the overlay. + copiedOverlay.classList.remove('flash'); + + // Trigger a reflow. + // eslint-disable-next-line no-unused-expressions, no-void + void copiedOverlay.offsetWidth; + + // Remove the active class to hide the overlay. + copiedOverlay.classList.add('flash'); + return true; + }) + .catch(err => { + console.error('Could not copy text: ', err); + }); + } + + // HANDLERS + + /** + * Click / close handler. + * @param {Event} e + */ + handleClick(e) { + const { resetOnClose } = this._config; + const shouldClose = e.target === this._element || e.target === this._children.closeButton; + if (shouldClose) { + this.hide(); + this.resetScrollbar(); + resetOnClose && this.resetEmbedOptions(); + this.destroyTooltips(); + } + + const shouldDeselectText = e.target?.nodeName !== 'CODE'; + shouldDeselectText && window.getSelection().removeAllRanges(); + } + + /** + * Tab click handler. + * @param {Event} e + */ + handleTabClick(e) { + const tabName = e.target?.innerText?.toLowerCase(); + const setActive = tabName === 'link' || tabName === 'embed'; + setActive && this.setActiveTab(tabName); + } + + /** + * Destroy the tippy instances. + */ + destroyTooltips() { + this._tippyItems = null; + + this._tippySingleton?.destroy(); + this._tippySingleton = null; + } + + /** + * Reset the embed options. + */ + resetEmbedOptions() { + this.setEmbedParams(); + + // Destroy, then re-create the embed content. + this.destroyEmbedContent(); + this.generateEmbedContent(); + } + + /** + * Reset the scrollbar. + */ + resetScrollbar() { + // Reset scroll to top + this._embedOptionsScrollbar.scroll(0); + } + + /** + * Called on every resize. + * @override + */ + resize() { + // Update the iframe transform + this.calcIframeTransforms(); + + // Determine if we need to update the share button parent. + const isWideHasUpdated = this.setIsWide(); + + if (isWideHasUpdated) { + this.addShareButtonToParent(); + this.resetScrollbar(); + } + } + + /** + * Manually hide the share button. + * @param {boolean} enabled + * @override + */ + setEnabled(enabled) { + super.setEnabled(enabled); + + // Toggle the share button visibility and parent. + this.shareButton.classList.toggle('hidden', !enabled); + const addToParent = enabled && !this.shareButton.parentNode; + addToParent && this.addShareButtonToParent(); + } + + /** + * Make sure the destroy also removes the share button. + */ + __destroy() { + super.__disable(); + + this.shareButton.parentNode?.removeChild(this.shareButton); + this.shareButton = null; + } +} + +ShareModal.html = (_share_modal_html__WEBPACK_IMPORTED_MODULE_2___default()); + +/* harmony default export */ __webpack_exports__["default"] = (ShareModal); + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/buttons_block/buttons_block.js": +/*!**************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/buttons_block/buttons_block.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ButtonsBlock": function() { return /* binding */ ButtonsBlock; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _buttons_block_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./buttons_block.html */ "../eyes/src/components/story/blocks/buttons_block/buttons_block.html"); +/* harmony import */ var _buttons_block_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_buttons_block_html__WEBPACK_IMPORTED_MODULE_1__); +//@ts-nocheck + + + + + + + +/** + * Block for buttons + */ +class ButtonsBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + super(app, { + ...options + }); + + this._app = app; + this._options = options; + + const scene = app.pioneer.get('main'); + scene.getLoadedPromise().then(() => { + this.setUpHTML(options); + return true; + }).catch(error => { + console.warn(error); + }); + } + + /** + * Set up html + * @param {object} options - options from story config file + */ + async setUpHTML(options) { + const { buttonContent } = options.config.info; + const buttonBlock = document.getElementsByClassName('buttons-block'); + + buttonContent.forEach((buttonInfo, index) => { + const { id, iconSrc, label } = buttonInfo; + // Create buttons depending on options given + const button = document.createElement('button'); + buttonBlock[0].appendChild(button); + + button.classList.add('clickable'); + button.classList.add('custom-button'); + button.classList.add(`${id}`); + + if (index === 0) { + // Add the "focused" class to the first button (i.e. eclipse earth view) + button.classList.add('focused'); + } + + const buttonIcon = document.createElement('img'); + button.appendChild(buttonIcon); + buttonIcon.classList.add('button-icon'); + buttonIcon.src = iconSrc; + + const buttonLabel = document.createTextNode(label); + button.appendChild(buttonLabel); + + button.onclick = this.buttonClick; + }); + + } + + /** + * Custom button click events + * @param {object} e - e.target for click event + */ + buttonClick = async e => { + const { buttonContent } = this._options.config.info; + const timeManager = this._app.getManager('time'); + + const selectedButton = Object.values(buttonContent).find(button => e.target.classList.contains(button.id)); + + // Remove the "focused" class from all buttons + const allButtons = document.querySelectorAll('.custom-button'); + allButtons.forEach(button => button.classList.remove('focused')); + + // Set custom time limits for each button view + if (selectedButton.timeLimits) { + timeManager.setMin(selectedButton.timeLimits.min); + timeManager.setMax(selectedButton.timeLimits.max); + } + else { + timeManager.resetLimits(); + } + // Get default time set in story to reset each view to desired time + const { _id: storyId } = this._app.getComponent('story'); + const currentStory = this._app.getManager('content').getStory(storyId); + const defaultTime = currentStory.slides[0].time; + + // If custom time for each button exists in [story_id].js, set that; If not, set default slide time on enter of new view + timeManager.setTime(selectedButton.startTime ?? defaultTime); + timeManager.setTimeRate(300); + + // Add the "focused" class to the clicked button + e.target.classList.add('focused'); + + // Passed in button click function from story + selectedButton.onClick(this._app); + }; +} + +ButtonsBlock.html = (_buttons_block_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/checkbox_block/checkbox_block.js": +/*!****************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/checkbox_block/checkbox_block.js ***! + \****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CheckboxBlock": function() { return /* binding */ CheckboxBlock; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _checkbox_block_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./checkbox_block.html */ "../eyes/src/components/story/blocks/checkbox_block/checkbox_block.html"); +/* harmony import */ var _checkbox_block_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_checkbox_block_html__WEBPACK_IMPORTED_MODULE_1__); +// @ts-nocheck + + + + + + + +/** + * Block for buttons + */ +class CheckboxBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + super(app, { + ...options + }); + + const scene = app.pioneer.get('main'); + scene.getLoadedPromise().then(() => { + this.setUpHTML(options); + return true; + }).catch(error => { + console.warn(error); + }); + + this.options = options; + } + + /** + * Set up html + * @param {object} options - options from story config file + */ + async setUpHTML(options) { + const { checkboxContent } = options.config.info; + const checkboxBlock = document.getElementsByClassName('checkboxes-block')[0]; + + checkboxContent.forEach(checkboxInfo => { + const { id, label, onChange } = checkboxInfo; + + // Create label element + const labelElement = document.createElement('label'); + labelElement.classList.add('cb-container'); + labelElement.classList.add('clickable'); + + // Create checkbox element + const checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + checkbox.checked = true; // Set default checked state + checkbox.id = `${id}-checkbox`; + + // Create span for custom checkmark + const span = document.createElement('span'); + span.classList.add('checkmark'); + + // Append elements + labelElement.appendChild(document.createTextNode(label)); + labelElement.appendChild(checkbox); + labelElement.appendChild(span); + checkboxBlock.appendChild(labelElement); + + // Listen to the "change" event + checkbox.addEventListener('change', e => { + onChange(e, this._app); + }); + }); + } + + /** + * Set checked or not + * @param {*} checkboxId + * @param {*} checked + */ + setChecked(checkboxId, checked) { + const checkbox = document.getElementById(`${checkboxId}-checkbox`); + if (checkbox) { + checkbox.checked = checked; + } + } +} + +CheckboxBlock.html = (_checkbox_block_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/description_block/description_block.js": +/*!**********************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/description_block/description_block.js ***! + \**********************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "DescriptionBlock": function() { return /* binding */ DescriptionBlock; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _description_block_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./description_block.html */ "../eyes/src/components/story/blocks/description_block/description_block.html"); +/* harmony import */ var _description_block_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_description_block_html__WEBPACK_IMPORTED_MODULE_1__); + + + + +/** + * Block for description. + */ +class DescriptionBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + super(app, { + hasMore: false, + isMoreVisible: false, + ...options + }); + + this._class.hasMoreClass = { + true: '', + false: 'hidden' + }; + + this._more = { + isVisible: { + moreMessage: 'Show Less', + moreIcon: 'icon-minus', + moreClass: '' + }, + isHidden: { + moreMessage: 'Show More', + moreIcon: 'icon-plus', + moreClass: 'hidden' + } + }; + + Object.assign(this._state, this._more.isHidden, { + hasMoreClass: this._class.hasMoreClass[this._state.hasMore] + }); + } + + /** @inheritdoc */ + init() { + super.init(); + + const hasMore = Boolean(this._config.info.more); + this.setState({ + hasMore, + hasMoreClass: this._class.hasMoreClass[hasMore] + }); + } + + /** + * Show more block. + */ + showMore() { + this.setState({ + isMoreVisible: true, + ...this._more.isVisible + }); + } + + /** + * Hide more block. + */ + hideMore() { + this.setState({ + isMoreVisible: false, + ...this._more.isHidden + }); + } + + /** + * Show/hide more block. + */ + toggleMore() { + if (this._state.isMoreVisible) { + this.hideMore(); + } + else { + this.showMore(); + } + } +} + +DescriptionBlock.html = (_description_block_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/hint_block/hint_block.js": +/*!********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/hint_block/hint_block.js ***! + \********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "HintBlock": function() { return /* binding */ HintBlock; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _hint_block_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./hint_block.html */ "../eyes/src/components/story/blocks/hint_block/hint_block.html"); +/* harmony import */ var _hint_block_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_hint_block_html__WEBPACK_IMPORTED_MODULE_1__); + + + + +/** + * Block for description. + */ +class HintBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + super(app, { + iconBefore: 'icon-greater', + iconAfter: 'icon-greater', + ...options + }); + + Object.assign(this._state, { + text: this._config.info.text || 'Scroll to continue', + isIconBeforeVisibleClass: this._class.isVisible[this._config.info.iconBeforeText || false], + isIconAfterVisibleClass: this._class.isVisible[this._config.info.iconAfterText || false] + }); + } +} + +HintBlock.html = (_hint_block_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/image_block/image_block.js": +/*!**********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/image_block/image_block.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ImageBlock": function() { return /* binding */ ImageBlock; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _image_block_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./image_block.html */ "../eyes/src/components/story/blocks/image_block/image_block.html"); +/* harmony import */ var _image_block_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_image_block_html__WEBPACK_IMPORTED_MODULE_1__); + + + + +/** + * Block for description. + */ +class ImageBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock { + /** + * Called on clicking block. + * Expand the thumbnail to fullscreen. + * @override + */ + onClick() { + // Set overlay's content to image + const image = this._element.cloneNode(true); + image.classList.add('fullscreen'); + image.classList.remove('clickable'); + + this._app.getComponent('overlay').setContent(image); + this._app.getComponent('overlay').show(); + } +} + +ImageBlock.html = (_image_block_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/replay_button_block/replay_button_block.js": +/*!**************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/replay_button_block/replay_button_block.js ***! + \**************************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ReplayButtonBlock": function() { return /* binding */ ReplayButtonBlock; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _replay_button_block_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./replay_button_block.html */ "../eyes/src/components/story/blocks/replay_button_block/replay_button_block.html"); +/* harmony import */ var _replay_button_block_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_replay_button_block_html__WEBPACK_IMPORTED_MODULE_1__); + + + + +/** + * Block for button. + */ +class ReplayButtonBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock { + /** @inheritdoc */ + init() { + if (!this._config.info.text) { + this._config.info.text = this._config.info.fromStart ? 'Restart Story' : 'Replay Animation'; + } + super.init(this._config.info); + } + + /** + * @inheritdoc + */ + async onClick() { + const router = this._app.getManager('router'); + if (this._config.info.fromStart) { + // Replay from start + router.navigate(router.currentRoute.url); + } + else { + // Replay current slide + router.reload(); + } + } +}; + +ReplayButtonBlock.html = (_replay_button_block_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/story_base_content_block/story_base_content_block.js": +/*!************************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/story_base_content_block/story_base_content_block.js ***! + \************************************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "StoryBaseContentBlock": function() { return /* binding */ StoryBaseContentBlock; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../internal */ "../eyes/src/internal.js"); + + + +/** + * A base class for a block of content. + */ +class StoryBaseContentBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={config:{info:{}}}] + */ + constructor(app, options = { config: { info: {} } }) { + options.isVisible = true; + super(app, null, options); + + if (this._config.info.onEnter) { + this.onEnter = async () => await this._config.info.onEnter(app, this); + } + + if (this._config.info.onLeave) { + this.onLeave = async () => await this._config.info.onLeave(app, this); + } + + this.bindFunctions(['onEnter', 'onLeave', 'onClick']); + } + + /** @inheritdoc */ + init() { + super.init(this._config.info); + this._element.classList.add('content-block', '{{isVisibleClass}}'); + if (Array.isArray(this._config.info.classList)) { + this._element.classList.add(...this._config.info.classList); + } + this._setVariables(this._element, false); + + if (this._config.info.clickable || this._config.info.func) { + this._element.classList.add('clickable'); + this._element.addEventListener('click', this.onClick); + } + } + + /** + * Called on entering the slide containing block. + * @returns {Promise} + */ + async onEnter() { + } + + /** + * Called on leaving the slide containing block. + * @returns {Promise} + */ + async onLeave() { + } + + /** + * Called on clicking block. + * @returns {Promise} + */ + async onClick() { + const { type } = this._config.info; + // Buttons get custom onClick functions passed in + if (type !== 'buttons') { + await this._config.info.func(this._app, this); + } + } +} + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/title_block/title_block.js": +/*!**********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/title_block/title_block.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TitleBlock": function() { return /* binding */ TitleBlock; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _title_block_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./title_block.html */ "../eyes/src/components/story/blocks/title_block/title_block.html"); +/* harmony import */ var _title_block_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_title_block_html__WEBPACK_IMPORTED_MODULE_1__); + + + +/** + * Block for description. + */ +class TitleBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock { +} + +TitleBlock.html = (_title_block_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/story/blocks/toggle_block/toggle_block.js": +/*!************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/toggle_block/toggle_block.js ***! + \************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ToggleBlock": function() { return /* binding */ ToggleBlock; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _toggle_block_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./toggle_block.html */ "../eyes/src/components/story/blocks/toggle_block/toggle_block.html"); +/* harmony import */ var _toggle_block_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_toggle_block_html__WEBPACK_IMPORTED_MODULE_1__); + + + + +/** + * Block for description. + */ +class ToggleBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + super(app, { + isSelected: false, + ...options + }); + + this._class.isSelectedClass = { + true: 'selected', + false: '' + }; + + // Make sure this is a boolean value + this._config.info.selected = Boolean(this._config.info.selected); + + Object.assign(this._state, { + isSelectedClass: this._class.isSelectedClass[this._state.isSelected] + }); + } + + /** + * Called on entering the slide containing block. + * @returns {Promise} + */ + async onEnter() { + await super.onEnter(); + if (this._config.info.selected !== this._state.isSelected) { + await this.onClick(); + } + } + + /** + * Called on leaving the slide containing block. + * @returns {Promise} + */ + async onLeave() { + await super.onLeave(); + if (this._state.isSelected) { + await this.onClick(); + } + } + + /** + * Called on clicking block. + * @returns {Promise} + */ + async onClick() { + await super.onClick(); + if (this._state.isSelected) { + this.unselect(); + console.log('unselect'); + } + else { + this.select(); + console.log('select'); + } + } + + /** + * Select button. + */ + select() { + this.setState({ + isSelected: true, + isSelectedClass: this._class.isSelectedClass.true + }); + } + + /** + * Unselect button. + */ + unselect() { + this.setState({ + isSelected: false, + isSelectedClass: this._class.isSelectedClass.false + }); + } +} + +ToggleBlock.html = (_toggle_block_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/story/story.js": +/*!*********************************************!*\ + !*** ../eyes/src/components/story/story.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Story": function() { return /* binding */ Story; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); + + + +/** + * Story component. + * @class + * @extends Carousel + */ +class Story extends _internal__WEBPACK_IMPORTED_MODULE_0__.Carousel { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options) { + super(app, null, { + isCloseButtonVisible: true, + closeButtonText: 'Close', + ...options + }); + + /** + * Story ID. + * @type {string} + */ + this._id = ''; + + /** + * Story info, containing all slides in story. + * @type {Array} + */ + this._info = []; + + this._blocks = {}; + + this._config.navigationButtons.next.text = _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isPrimaryTouch() + ? 'Swipe to continue' + : 'Scroll to continue'; + + /** + * Function to call on changing slide via button or scroll. + * @type {Function} + */ + this._onSlideChange = async (index, includeTime = false) => { + const query = { + slide: this._children.slides[index].dataset.id + }; + // Include the time so when we go back in time + // we start at the end of the phase instead of start + if (includeTime) { + query.time = this._app.getManager('time').getTimeUrl(); + } + else { + query.__remove = ['time']; + } + + const router = this._app.getManager('router'); + const currentRoute = router.currentRoute; + await router.navigate(query, currentRoute.url); + }; + } + + /** @inheritdoc */ + init() { + super.init(); + + // Set close button aria-label. + const closeBtn = this._element.querySelector('.close-button'); + closeBtn?.setAttribute('aria-label', 'Close story'); + + this._setVariables(this._children.carousel, false); + } + + /** + * Set aria label depending on isCollapsed state. + */ + _setExpandToggleAriaLabel() { + const toggleBtns = this._element.querySelectorAll('.mobile-collapse'); + const labelText = this._state.isCollapsed ? 'Collapse story panel' : 'Expand story panel'; + + toggleBtns.forEach(el => el.setAttribute('aria-label', labelText)); + } + + /** + * Overriding toggleCollapse method to update aria label + * @override + */ + _toggleCollapse() { + this._setExpandToggleAriaLabel(); + + super._toggleCollapse(); + } + + /** + * Update story on route change. + * @param {object} storyInfo + * @param {object} [params={}] - Route parameters + * @param {CancelToken} params.cancelToken + * @param {string} params.slide - Slide ID + * @param {string} params.id - Story ID + */ + async onRouteChange(storyInfo, { cancelToken, slide, id } = {}) { + // Check if route was canceled + if (cancelToken && cancelToken.isCanceled) { + return; + } + this.clear(); + this._info = storyInfo; + this._id = id; + + // Hide navigation UI in locked mode + if (this._app.getManager('router').configs.locked) { + const isCloseButtonVisible = false; + this.setState({ + isCloseButtonVisible, + isCloseButtonVisibleClass: this._class.isVisible[isCloseButtonVisible] + }); + } + + // Set up story UI + await this.setUp(); + + // Set expand toggle aria labels. + this._setExpandToggleAriaLabel(); + + // Find slide index using id, or default to first slide + const index = slide + ? this._children.slides.findIndex(x => x.dataset.id === slide) || 0 + : 0; + + // Update time rate + if (storyInfo[index]?.rate !== undefined) { + this._app.getManager('time').setTimeRate(storyInfo[index].rate); + } + + // Go to slide + await this.goToSlide(index); + } + + /** + * Execute actions on query change. + * @param {object} params + * @param {object} params.cancelToken + * @param {string} params.slide + */ + async onQueryChange({ cancelToken, slide } = {}) { + // Check if route was canceled + if (cancelToken && cancelToken.isCanceled) { + return; + } + + // Find slide index using id, or default to first slide + const index = slide + ? this._children.slides.findIndex(x => x.dataset.id === slide) || 0 + : 0; + + // Update time rate + if (this._info[index]?.rate !== undefined) { + this._app.getManager('time').setTimeRate(this._info[index].rate); + } + + // Go to slide + await this.goToSlide(index); + } + + /** + * Create content element for a block. + * @param {object} blockInfo + * @param {number} slideIndex + * @returns {HTMLElement} + */ + async createBlockContent(blockInfo, slideIndex) { + const { hideExternalLinks } = this.app.getManager('router').configs; + + let block; + + switch (blockInfo.type) { + case 'title': { + const storyBlockInfo = { ...blockInfo }; + storyBlockInfo.title = hideExternalLinks === true ? this.app.getManager('content').hideExternalLinksInText(storyBlockInfo.title) : storyBlockInfo.title; + block = new _internal__WEBPACK_IMPORTED_MODULE_0__.TitleBlock(this._app, { config: { info: storyBlockInfo } }); + break; + } + case 'description': { + const storyBlockInfo = { ...blockInfo }; + storyBlockInfo.description = hideExternalLinks === true ? this.app.getManager('content').hideExternalLinksInText(storyBlockInfo.description) : storyBlockInfo.description; + block = new _internal__WEBPACK_IMPORTED_MODULE_0__.DescriptionBlock(this._app, { config: { info: storyBlockInfo } }); + break; + } + case 'image': + case 'diagram': { + block = new _internal__WEBPACK_IMPORTED_MODULE_0__.ImageBlock(this._app, { config: { info: blockInfo } }); + break; + } + case 'toggle': { + block = new _internal__WEBPACK_IMPORTED_MODULE_0__.ToggleBlock(this._app, { config: { info: blockInfo } }); + break; + } + case 'hint': { + block = new _internal__WEBPACK_IMPORTED_MODULE_0__.HintBlock(this._app, { config: { info: blockInfo } }); + break; + } + case 'replay': { + block = new _internal__WEBPACK_IMPORTED_MODULE_0__.ReplayButtonBlock(this._app, { config: { info: blockInfo } }); + break; + } + case 'buttons': { + block = new _internal__WEBPACK_IMPORTED_MODULE_0__.ButtonsBlock(this._app, { config: { info: blockInfo } }); + break; + } + case 'checkboxes': { + block = new _internal__WEBPACK_IMPORTED_MODULE_0__.CheckboxBlock(this._app, { config: { info: blockInfo } }); + break; + } + default: + break; + } + + await block.init(); + this._onEnter[slideIndex].push(block.onEnter); + this._onLeave[slideIndex].push(block.onLeave); + this._blocks[blockInfo.type] = block; + return block.element; + } + + /** + * Get block + * @param {string} blockType + * @returns {any} block + */ + getStoryBlock(blockType) { + return this._blocks[blockType] || console.warn(`Block ${blockType} is not available`); + } + + /** + * Create content element for a slide. + * @param {object} slide + * @param {number} index + * @returns {HTMLElement} + */ + async createSlideContent(slide, index) { + if (slide.htmlFile) { + // TODO: Load html from a file + } + else { + const content = document.createDocumentFragment(); + + for (let i = 0; i < slide.content.length; i++) { + const blockInfo = slide.content[i]; + const block = await this.createBlockContent(blockInfo, index); + if (block) { + content.appendChild(block); + } + } + + return content; + } + } + + /** + * Set up story UI with story info. + */ + async setUp() { + for (let i = 0; i < this._info.length; i++) { + const { id, type, classList = [], onEnter, onLeave } = this._info[i]; + this._onEnter[i] = []; + this._onLeave[i] = []; + + if (onEnter) { + this._onEnter[i].push(() => onEnter(this._app, this)); + } + const content = await this.createSlideContent(this._info[i], i); + classList.push('grid-layout', 'simple-grid'); + + if (onLeave) { + this._onLeave[i].push(() => onLeave(this._app, this)); + } + + this.addSlide({ + id, + type, + classList, + content + }, + { + isFirst: i === 0, + isLast: i === this._info.length - 1 + }); + } + } + + /** + * Close carousel. + * @override + */ + close() { + const router = this._app.getManager('router'); + router.navigate(router.homeRoute); + } + + /** + * @inheritdoc + */ + async onLeave(index) { + await super.onLeave(index); + + // Reset on leaving story + if (!(typeof index === 'number')) { + const router = this._app.getManager('router'); + router.removeQuery(['slide']); + } + } + + /** + * Update tooltip props. + */ + _updateTooltipsProps() { + const { slideType } = this._state; + + const style = getComputedStyle(document.body); + const offsetHeight = -(parseFloat(style.getPropertyValue('--gridHeaderHeight')) + 20); + + if (this._progressTooltip !== null) { + this._progressTooltip.setProps({ + offset: slideType === 'overlay' + ? [0, offsetHeight] + : [0, 10] + }); + } + } +} + + +/***/ }), + +/***/ "../eyes/src/components/time_controller/index.js": +/*!*******************************************************!*\ + !*** ../eyes/src/components/time_controller/index.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _time_controller_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./time_controller.js */ "../eyes/src/components/time_controller/time_controller.js"); + + + + +/* harmony default export */ __webpack_exports__["default"] = (_time_controller_js__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/time_controller/time_controller.js": +/*!*****************************************************************!*\ + !*** ../eyes/src/components/time_controller/time_controller.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var tippy_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tippy.js */ "../eyes/node_modules/tippy.js/dist/tippy.esm.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _time_controller_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./time_controller.html */ "../eyes/src/components/time_controller/time_controller.html"); +/* harmony import */ var _time_controller_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_time_controller_html__WEBPACK_IMPORTED_MODULE_1__); + + + + +/** + * @inheritdoc + * @extends BaseComponent + * TODO: This is only used by Mars2020 app. Discuss what to do. + */ +class TimeController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * @inheritdoc + * @param {BaseApp} app + */ + constructor(app) { + super(app, null, { + isPlay: false, + playClass: '', + rate: 0, + rateDisplay: 0 + }); + + this._class.fontSize.small = 'tiny'; + this._class.isPlay = { + true: 'icon-pause', + false: 'icon-play' + }; + + /** + * List of allowed rates. + * @type {Array} + */ + this._rates = [ + -94608000, // 3 years + -31536000, // 1 year + -6048000, // 10 weeks + -604800, // 1 week + -86400, // 1 day + -36000, // 10 hours + -3600, // 1 hour + -600, // 10 mins + -60, + -10, + -1, + 0, + 1, + 10, + 60, + 600, + 3600, + 36000, + 86400, + 604800, + 6048000, + 31536000, + 94608000 + ]; + + this._manager = this._app.getManager('time'); + this._router = this._app.getManager('router'); + this._manager.setDefaultTimeRate(1); + + const rate = this._manager.getTimeRate(); + const isPlay = rate !== 0; + + this.setState({ + isPlay, + playClass: this._class.isPlay[isPlay], + rate, + rateDisplay: this.getRateDisplay() + }); + + this.bindFunctions([ + 'getRateLimits', + 'setRateLimits', + 'setRate', + 'setDefaultRate', + 'setRealRate', + 'decreaseRate', + 'increaseRate', + 'togglePlayPause', + 'onRateChange', + 'onForcedPause', + 'onForcedPauseResume' + ]); + } + + /** @inheritdoc */ + init() { + super.init(); + + /** + * Set default tippy props + * See docs: https://atomiks.github.io/tippyjs/v6/methods/ + */ + tippy_js__WEBPACK_IMPORTED_MODULE_2__["default"].setDefaultProps({ + theme: 'default', + touch: ['hold', 2000], + delay: [600, null], + plugins: [tippy_js__WEBPACK_IMPORTED_MODULE_2__.followCursor] + }); + (0,tippy_js__WEBPACK_IMPORTED_MODULE_2__["default"])(this._children.toggleBtn, { placement: 'top' }); + (0,tippy_js__WEBPACK_IMPORTED_MODULE_2__["default"])(this._children.increaseBtn, { placement: 'top' }); + (0,tippy_js__WEBPACK_IMPORTED_MODULE_2__["default"])(this._children.decreaseBtn, { placement: 'top' }); + + this._children.decreaseContainer.classList.add('bg-color', 'gray', 'dark'); + this._children.increaseContainer.classList.add('bg-color', 'gray', 'dark'); + this._children.label.classList.add('semi'); + this._children.rateDisplay.classList.add('semi'); + + this._callbackRegistry.push({ + emitter: this._app.getManager('time'), + event: 'ratechange', + callback: this.onRateChange + }); + } + + /** + * Get available time rates. + * @returns {Array} + */ + getRateLimits() { + return this._rates; + } + + /** + * Set available time rates; + * @param {Array} rates + */ + setRateLimits(rates) { + this._rates = rates; + } + + /** + * Navigate to url with rate. + * @param {number} rate + */ + setRate(rate) { + this._router.navigate({ + time: this._manager.getTimeUrl(), + rate + }, this._router.currentRoute.url); + } + + /** + * Decrease time rate to previous in available rates list. + */ + decreaseRate() { + // List is empty + if (this._rates.length === 0) { + return; + } + const index = this._rates.indexOf(this._manager.getTimeRate()); + // Already at lower bound + if (index === 0) { + return; + } + this.setRate(this._rates[index - 1]); + } + + /** + * Increase time rate to next in available rates list. + */ + increaseRate() { + // List is empty + if (this._rates.length === 0) { + return; + } + const index = this._rates.indexOf(this._manager.getTimeRate()); + // Already at upper bound + if (index === this._rates.length - 1) { + return; + } + this.setRate(this._rates[index + 1]); + } + + /** + * Toggle time play/pause. + */ + togglePlayPause() { + const isPlay = !this._state.isPlay; + if (isPlay) { + this._manager.play(); + } + else { + this._manager.pause(); + } + this.setRate(this._manager.getTimeRate()); + } + + /** + * Set rate to default rate. + */ + setDefaultRate() { + this.setRate(this._manager.getDefaultTimeRate()); + } + + /** + * Set rate to real rate. + */ + setRealRate() { + this.setRate(1); + } + + /** + * Update UI on rate change. + */ + onRateChange() { + const rate = this._manager.getTimeRate(); + const isPlay = rate !== 0; + + // No state change + if (isPlay === this._state.isPlay && this._state.rate === rate) { + return; + } + // Enforce rate inside list + if (this._rates.length > 0) { + if (!this._rates.includes(rate)) { + this.setRate(this._manager.getDefaultTimeRate()); + return; + } + } + + this.setState({ + isPlay, + rate, + playClass: this._class.isPlay[isPlay], + rateDisplay: this.getRateDisplay(rate) + }); + } + + /** + * Update time rate on forced pause. + */ + onForcedPause() { + this.setRate(0); + } + + /** + * Update time rate on forced pause resume. + */ + onForcedPauseResume() { + this.setDefaultRate(); + } + + /** + * Get info for time rate. + * @param {number|null} rate + * @returns {object} Rate and unit (per sec). E.g. `{ rate: 1, unit: ' sec' }`, `{ rate: 1, unit: ' min' }` + */ + getRateUnit(rate = null) { + if (rate === null) { + rate = this._manager.getTimeRate(); + } + + const yrs = rate / 31536000; + const months = rate / 2592000; + const weeks = rate / 604800; + const days = rate / 86400; + const hrs = rate / 3600; + const mins = rate / 60; + let unit = ''; + + // Only get rate as whole number + if ((yrs >= 1 || yrs <= -1) && yrs % 1 === 0) { + rate = yrs; + unit = ' yr'; + } + else if ((months >= 1 || months <= -1) && months % 1 === 0) { + rate = months; + unit = ' mth'; + } + else if ((weeks >= 1 || weeks <= -1) && weeks % 1 === 0) { + rate = weeks; + unit = ' wk'; + } + else if ((days >= 1 || days <= -1) && days % 1 === 0) { + rate = days; + unit = ' day'; + } + else if ((hrs >= 1 || hrs <= -1) && hrs % 1 === 0) { + rate = hrs; + unit = ' hr'; + } + else if ((mins >= 1 || mins <= -1) && mins % 1 === 0) { + rate = mins; + unit = ' min'; + } + else { + rate %= 60; + unit = ' sec'; + } + + return { rate, unit }; + } + + /** + * Get text display for rate. + * @param {number} input + * @returns {string} + */ + getRateDisplay(input) { + const { rate, unit } = this.getRateUnit(input); + if (rate !== 0) { + return rate + unit + '(s)/sec'; + } + else { + return 'paused'; + } + } +} + +TimeController.html = (_time_controller_html__WEBPACK_IMPORTED_MODULE_1___default()); + +/* harmony default export */ __webpack_exports__["default"] = (TimeController); + + +/***/ }), + +/***/ "../eyes/src/components/toast/toast.js": +/*!*********************************************!*\ + !*** ../eyes/src/components/toast/toast.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Toast": function() { return /* binding */ Toast; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _toast_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./toast.html */ "../eyes/src/components/toast/toast.html"); +/* harmony import */ var _toast_html__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_toast_html__WEBPACK_IMPORTED_MODULE_1__); + + + + +/** + * Toast component. + * + * A toast is essentially an alert that appears on the screen for a short period of time. + * Currently we can only display one toast at a time. + * @extends BaseComponent + */ +class Toast extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + // Add state options + super(app, null, { + isVisible: false, + iconClass: 'icon-locked', + toastContent: 'TOAST!', + hideDelay: 2000, + ...options + }); + + /** + * The hideTimeout is the timeout that will hide the toast. + * @type {number|null} + * @private + */ + this._hideTimeout = null; + } + + /** + * Sets the icon class + * @param {string} iconClass + */ + setIcon(iconClass) { + this.setState({ + iconClass + }); + } + + /** + * Set the toast content + * @param {string} content + */ + setContent(content) { + this.setState({ + toastContent: content + }); + } + + /** @override */ + show() { + super.show(); + + // Set the hide timeout if we have a hide delay. + const { hideDelay } = this._state; + if (hideDelay) { + clearTimeout(this._hideTimeout); + + this._hideTimeout = setTimeout(() => { + this.hide(); + }, hideDelay); + } + } + + /** @override */ + hide() { + super.hide(); + // Clear the hide timeout. + clearTimeout(this._hideTimeout); + } +} + +Toast.html = (_toast_html__WEBPACK_IMPORTED_MODULE_1___default()); + + +/***/ }), + +/***/ "../eyes/src/components/tutorial_overlay/index.js": +/*!********************************************************!*\ + !*** ../eyes/src/components/tutorial_overlay/index.js ***! + \********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _tutorial_overlay_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./tutorial_overlay.js */ "../eyes/src/components/tutorial_overlay/tutorial_overlay.js"); + + + +/* harmony default export */ __webpack_exports__["default"] = (_tutorial_overlay_js__WEBPACK_IMPORTED_MODULE_0__["default"]); + + +/***/ }), + +/***/ "../eyes/src/components/tutorial_overlay/tutorial_overlay.js": +/*!*******************************************************************!*\ + !*** ../eyes/src/components/tutorial_overlay/tutorial_overlay.js ***! + \*******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var swiper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! swiper */ "../eyes/node_modules/swiper/swiper.esm.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _tutorial_overlay_html__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./tutorial_overlay.html */ "../eyes/src/components/tutorial_overlay/tutorial_overlay.html"); +/* harmony import */ var _tutorial_overlay_html__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_tutorial_overlay_html__WEBPACK_IMPORTED_MODULE_6__); + + + + + + + + + +swiper__WEBPACK_IMPORTED_MODULE_0__["default"].use([swiper__WEBPACK_IMPORTED_MODULE_0__.Navigation, swiper__WEBPACK_IMPORTED_MODULE_0__.Keyboard, swiper__WEBPACK_IMPORTED_MODULE_0__.Mousewheel]); + +const DISMISS_TEXT = { + DEFAULT: 'OK, got it. Thanks!', + LAST: "OK, let's go!" +}; + +/** + * Tutorial overlay component. + * @extends BaseComponent + */ +class TutorialOverlay extends _internal__WEBPACK_IMPORTED_MODULE_5__.BaseComponent { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + /** + * Swiper options + */ + options.config = { + direction: 'horizontal', + + speed: 600, + + slidesPerView: 1, + spaceBetween: 100, + keyboard: { + enabled: true + }, + mousewheel: { + forceToAxis: true, + thresholdDelta: 100 + }, + + // Navigation arrows + navigation: { + prevEl: '.tutorial-carousel-prev', + nextEl: '.tutorial-carousel-next' + }, + + ...options.config + }; + + // TODO: Make this more general for reuse, like allow changing footer text + super(app, null, { + isVisible: false, + carouselClass: 'tutorial-carousel', + slideClass: '', + dismissText: DISMISS_TEXT.DEFAULT, + ...options + }); + + /** + * Define swiper prop + */ + this._swiper = null; + + /** + * Array of tutorial data + */ + this._allTutorials = null; + + /** + * Array of measurements for targeted elements + */ + this._elementMeasures = null; + + /** + * Define startIndex + */ + this._currIndex = null; + + /** + * Define slide viewed timeout + */ + this._slideViewedTimeout = null; + + /** + * For some reason, it takes some extra time for some elements to be measureed as in the correct position. + * Setting a timeout before initialization fixes this (badly) but it is cleared on exit (query undefined). + */ + this._initTimeout = null; + + /** + * Class name props + */ + this._bulletClass = 'swiper-pagination-bullet'; + this._activeBulletClass = 'swiper-pagination-bullet-active'; + this._swiperSlideClass = 'swiper-slide'; + + /** + * Local storage item name + */ + this._storageName = 'EoA_Tutorials'; + } + + /** + * Sets the all tutorials prop, and create carousel slides + * @param {Array} tutorials + */ + setTutorials(tutorials) { + this._allTutorials = tutorials; + + this._createSlides(); + } + + /** + * Return tutorials list after hiding tutorial slides in slideshow + * @param {string} slideId + * @returns {Array} + */ + hideTutorialSlide(slideId) { + const { tutorials } = this.app; + return tutorials.filter(({ id }) => id !== slideId); + } + + /** + * Add slide change to update active bullet (as we're not using the built-in swiper bullets...cant remember why). + * Also allowing clicking to navigate to definition if data-def attr including in clickable links in tutorials.json. + */ + _addEvents() { + this._swiper.on('slideChange', ({ realIndex }) => { + // Update the highlighted element. + this._setHighlightedElement(realIndex); + + // Update the active bullet + this._setActiveBullet(realIndex); + + // Update the URL if necessary. + if (this._currIndex !== realIndex) { + this.navigateToTutorial(realIndex); + } + + // Set the dismisss text and slideClass states. + const { id: slideName } = this._allTutorials[realIndex] || {}; + const lastSlide = realIndex === this._allTutorials.length - 1; + const slideClass = slideName ? `tutorial-slide-${slideName}` : ''; + + this.setState({ + dismissText: lastSlide ? DISMISS_TEXT.LAST : DISMISS_TEXT.DEFAULT, + slideClass + }); + }); + + // Click event to handle definition overlays + this._children.swiperSlides.addEventListener('click', event => { + const definition = event?.target?.dataset?.def; + if (definition) { + this._app.getComponent('definitionOverlay').navigateToDefinition(definition); + } + }); + } + + + /** + * Use the tutorial data to build the swiper slides + */ + _createSlides() { + const { isTouch } = this._app; + + this._allTutorials.forEach(({ id, title, description, extra }) => { + const slideElements = []; + + if (title) { + const titleEl = document.createElement('h2'); + titleEl.innerHTML = title; + slideElements.push(titleEl); + } + + if (description) { + // Assumes only touch and desktop keys. + const html = typeof description === 'object' ? + (isTouch ? description.touch : description.desktop) : + description; + + // Make sure we have HTML to apply. + if (typeof html === 'string') { + const descriptionEl = document.createElement('p'); + descriptionEl.innerHTML = html; + slideElements.push(descriptionEl); + } + } + + if (extra) { + // Assumes only touch and desktop keys. + const html = typeof extra === 'object' ? + (isTouch ? extra.touch : extra.desktop) : + extra; + + // Make sure we have HTML to apply. + if (typeof html === 'string') { + const extraEl = document.createElement('div'); + extraEl.className = 'tutorial-extra'; + extraEl.innerHTML = html; + slideElements.push(extraEl); + } + } + + const slideClass = `${this._swiperSlideClass} tutorial-slide-${id}`; + + slideElements.length && this._addSlide(slideElements, slideClass); + }); + } + + /** + * Add an array of elements as a slide to the carousel + * @param {Array} elements + * @param {string} slideClass + */ + _addSlide(elements = [], slideClass) { + // Create element. + const slideEl = document.createElement('div'); + + slideEl.className = slideClass; + + // Add elements as children. + slideEl.replaceChildren(...elements); + + // Append to swiper slides. + this._children.swiperSlides.append(slideEl); + } + + /** + * Create bullet pagination + */ + _createBullets() { + const { bullets } = this._children; + const { slides } = this._swiper; + + + const allBullets = [...slides].map((slide, i) => { + const bullet = document.createElement('span'); + bullet.classList.add(this._bulletClass); + + // Add the click event + bullet.addEventListener('click', e => this._swiper.slideTo(i)); + + return bullet; + }); + + bullets.replaceChildren(...allBullets); + } + + /** + * Makes sure all bullets are deactivated except the passed index + * @param {number} activeIndex + */ + _setActiveBullet(activeIndex = this._currIndex) { + const { bullets } = this._children; + + bullets.childNodes.forEach((bullet, i) => { + bullet.classList.remove(this._activeBulletClass); + if (i === activeIndex) { + bullet.classList.add(this._activeBulletClass); + } + }); + } + + + /** + * Unhighlights all targeted elements except passed index + * @param {number} highlightIndex + * @param {boolean} forceMeasure + */ + _setHighlightedElement(highlightIndex = this._currIndex, forceMeasure = false) { + const calcMeasures = !this._elementMeasures || forceMeasure; + + if (calcMeasures) { + this._elementMeasures = this._calcElementMeasures(); + } + + const measures = this._elementMeasures[highlightIndex]; + const { mask } = this._allTutorials[highlightIndex]; + + if (measures) { + // Destructure vars. + const { xPos, yPos, relWidth, relHeight } = measures; + const { xSizeMult = 1, ySizeMult = 1 } = mask || {}; + + + // Calc size, range and pos values. + const sizeCoeff = 15; // Correlated to the black percent value in radial gradient css. + const sizeXaddition = relWidth * sizeCoeff * 100; + const sizeYaddition = relHeight * sizeCoeff * 100; + + const xSize = (200 + sizeXaddition) * xSizeMult; + const ySize = (200 + sizeYaddition) * ySizeMult; + + const xSizeValid = Math.max(200, xSize); + const ySizeValid = Math.max(200, ySize); + + const rangeXcoeff = 100 / (xSizeValid - 100); + const rangeYcoeff = 100 / (ySizeValid - 100); + + const relX = (0.5 - rangeXcoeff * 0.5) + xPos * rangeXcoeff; + const relY = (0.5 - rangeYcoeff * 0.5) + yPos * rangeYcoeff; + + const percX = (relX * 100).toFixed(2); + const percY = (relY * 100).toFixed(2); + + // Set the CSS vars. + this._element.style.setProperty('--tutorial-mask-grad', 'radial-gradient(transparent, black 5%)'); + this._element.style.setProperty('--tutorial-mask-pos', `${percX}% ${percY}%`); + this._element.style.setProperty('--tutorial-mask-size', `${xSizeValid}% ${ySizeValid}%`); + } + else { + this._element.style.setProperty('--tutorial-mask-grad', null); + this._element.style.setProperty('--tutorial-mask-pos', null); + this._element.style.setProperty('--tutorial-mask-size', null); + } + + // Potential fallback if we test and find cases where masks dont work + // this._targetElements.forEach((element, i) => { + // if (element) { + // element.style.zIndex = i === highlightIndex ? 1001 : null; + // } + // }); + } + + + /** + * Called when the url get params change. Wraps _updateDefinition + * @param {object} params + * @param {CancelToken} params.cancelToken + * @param {string} params.tutorial + */ + onQueryChange({ cancelToken, tutorial } = {}) { + // Cancel slider viewed timeout no matter what. + clearTimeout(this._slideViewedTimeout); + + // Should only show if we're on the home route. Return if we're not there. + const { currentRoute, homeRoute } = this.app.getManager('router'); + const notHome = currentRoute.url !== homeRoute; + + // Check if route was canceled + if (notHome || cancelToken?.isCanceled) { + return; + } + + const newCurrIndex = this._getIndexByTutorialId(tutorial); + + + // Return if we're already on the correct index. + if (newCurrIndex === this._currIndex) { + return; + } + + this._currIndex = newCurrIndex; + + /** + * Determine whether we: + * 1) Try to slide to the current index (will only work if user directly changes url) + * 2) Show / potentially initialize the swiper if it's not visible + * 3) Hide the slider as there was no passed tutorialId + */ + if (this._currIndex > -1) { + if (this._state.isVisible) { + this._swiper.slideTo(this._currIndex); + } + else { + this.show(); + } + this._setSlideViewedTimeout(newCurrIndex); + } + else { + this.hide(); + } + } + + /** + * Initialize the swiper carousel. + */ + _initSwiper() { + const { carouselClass } = this._state; + + const selector = `.${carouselClass} .swiper-wrapper > div`; + + _internal__WEBPACK_IMPORTED_MODULE_5__.AppUtils.elementReady(selector) + .then(() => { + this._initTimeout = setTimeout(() => { + // If there's already a swiper, update it and slide to first index. + if (this._swiper) { + this._swiper.update(); + this._swiper.slideTo(this._currIndex); + } + else { + // Otherwise, create it. + this._swiper = new swiper__WEBPACK_IMPORTED_MODULE_0__["default"](`.${carouselClass}`, this._config); + this._postSwiperInitFunction(this._swiper); + } + + // Set active bullets and highlight target elements if slideTo doesnt trigger event (if index is 0) + if (this._currIndex === 0) { + this._setActiveBullet(); + this._setHighlightedElement(); + } + + // Show it now it's ready. + super.show(); + }, 500); + }); + } + + /** + * Called after swiper is initialized. + */ + _postSwiperInitFunction() { + // Add event handler + this._addEvents(); + + // Add bullets + this._createBullets(); + + // Slide to firstIndex. + this._swiper.slideTo(this._currIndex); + } + + /** + * Get the tutorial index by id + * @param {string} tutorialId + * @returns {number} + */ + _getIndexByTutorialId(tutorialId) { + return this._allTutorials?.findIndex(({ id }) => id === tutorialId); + } + + /** + * Start a timer which, when reached, will record that this view has been "viewed" in the localStorage + * @param {boolean} viewIndex + */ + _setSlideViewedTimeout(viewIndex) { + /** + * A slide is recorded as viewed after 3 seconds + */ + this._slideViewedTimeout = setTimeout(() => { + const viewedTutorials = localStorage?.getItem(this._storageName)?.split(',') || []; + + /** + * Check if stored tutorial list contains the current view index. + * If not, add it, sort it and store it back to localStorage. + */ + if (!viewedTutorials.includes(viewIndex.toString())) { + viewedTutorials.push(viewIndex); + viewedTutorials.sort(); + localStorage?.setItem(this._storageName, viewedTutorials); + } + }, 3000); + } + + /** + * Calculate the center points and size of the target elements, relative to the height and width of the body + * @returns {Array} + */ + _calcElementMeasures() { + const { clientWidth, clientHeight } = document.body; + + return this._allTutorials.map(({ targetSelector }) => { + // If parent is not null, it means it's visible in the DOM. + const elements = [...document.body.querySelectorAll(targetSelector)].filter(el => el.offsetParent !== null); + + if (!elements.length) { + return false; + } + + const { left, width, top, height } = elements[0].getBoundingClientRect(); + + return { + xPos: 1 - ((left + (width * 0.5)) / clientWidth), + yPos: 1 - ((top + (height * 0.5)) / clientHeight), + relWidth: width / clientWidth, + relHeight: height / clientHeight + }; + }); + } + + /** + * @inheritdoc + */ + show() { + // Make sure we display UI if it's hidden. + const layerManager = this._app.getManager('layer'); + if (!layerManager.getLayer('ui').visible) { + layerManager.toggleLayer('ui'); + } + + const hasSwiperContent = this._children.swiperSlides?.childNodes?.length; + hasSwiperContent && this._initSwiper(); + + // Remove external links from slide footer + const routeManager = this._app.getManager('router'); + if (routeManager.configs.hideExternalLinks === true) { + const smallprint = document.getElementsByClassName('tutorial-smallprint')[0].innerHTML; + document.getElementsByClassName('tutorial-smallprint')[0].innerHTML = this._app.getManager('content').hideExternalLinksInText(smallprint); + } + } + + /** + * @inheritdoc + */ + hide() { + // Clear init timeout and reset currIndex + clearTimeout(this._initTimeout); + this._currIndex = null; + + super.hide(); + } + + /** + * Look at previous displayed tutorials in localStorage to determine whether to show and which index to prioritize. + * @returns {boolean|null} + */ + calcPriorityIndex() { + const viewedTutorials = localStorage?.getItem(this._storageName)?.split(',') || []; + + const remainingTutorials = this._allTutorials.filter((_, index) => !viewedTutorials.includes(index.toString())); + + return remainingTutorials.length ? this._getIndexByTutorialId(remainingTutorials[0].id) : null; + } + + /** + * Update the router query. + * @param {number} tutorialIndex + * @param {boolean} goHome + */ + navigateToTutorial(tutorialIndex, goHome = false) { + const { homeRoute, currentRoute, navigate } = this.app.getManager('router'); + + const path = goHome ? homeRoute : (currentRoute.url ?? ''); + const validIndex = typeof tutorialIndex === 'number' && tutorialIndex > -1 && tutorialIndex < this._allTutorials.length; + + if (validIndex) { + const { id: tutorial } = this._allTutorials[tutorialIndex]; + navigate({ tutorial }, path); + } + } + + /** + * Update the query to close the tutorial overlay. + */ + close() { + this.app.getManager('router').navigate({ __remove: ['tutorial'] }); + } + + /** + * On resize we need to update our element measures and call _setHighlightedElement again + */ + resize() { + if (this._state.isVisible && this._currIndex !== null) { + this._setHighlightedElement(this._currIndex, true); + } + } +} + +TutorialOverlay.html = (_tutorial_overlay_html__WEBPACK_IMPORTED_MODULE_6___default()); + +/* harmony default export */ __webpack_exports__["default"] = (TutorialOverlay); + + +/***/ }), + +/***/ "../eyes/src/data/embed_controls.js": +/*!******************************************!*\ + !*** ../eyes/src/data/embed_controls.js ***! + \******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/** + * Some default controls for the embed modal. + * Should hypothetically apply to all apps dependent on Eyess + * Defaults will be overridden (via deep merge) by the app-specific embed controls (see EotSS component info for example) + */ +const embedDefaultControls = [ + { + groupName: 'User Interface', + isAdvanced: false, + items: [ + { + name: 'Show Detail Panel', + description: 'Displays the detail panel for an entity on the left side of the screen', + query: 'detailPanel', + type: 'checkbox', + inputDefault: true, + appQueryDefault: true + }, + { + name: 'Show NASA logo', + description: 'Displays the NASA logo in the top left corner', + query: 'logo', + type: 'checkbox', + inputDefault: true, + appQueryDefault: true + }, + { + name: 'Show Search', + description: 'Determines whether the search bar is visible', + query: 'search', + type: 'checkbox', + inputDefault: true, + appQueryDefault: true + }, + { + name: 'Show Share Button', + description: 'Determines whether the share button is visible', + query: 'shareButton', + type: 'checkbox', + inputDefault: true, + appQueryDefault: true + }, + { + name: 'Show Main Menu', + description: 'Determines whether the main menu is visible in the top right', + query: 'menu', + type: 'checkbox', + inputDefault: true, + appQueryDefault: true + }, + { + name: 'Show Expanded Settings Bar', + description: 'Determines whether the settings bar is expanded upon first load', + query: 'collapseSettingsOptions', + type: 'checkbox', + inputDefault: true, + appQueryDefault: false, + invert: true + }, + { + name: 'Show Fullscreen Button', + description: 'Include the fullscreen button in the settings bar', + query: 'hideFullScreenToggle', + type: 'checkbox', + inputDefault: true, + appQueryDefault: false, + invert: true + } + ] + }, + { + groupName: 'Navigation', + isAdvanced: false, + items: [ + { + name: 'Allow Navigation', + description: 'Allows the user to navigate to other entities', + query: 'locked', + type: 'checkbox', + inputDefault: true, + appQueryDefault: false, + invert: true + }, + { + name: 'Allow External Links', + description: 'Allows all external links to navigate away from the app to outside resources', + query: 'hideExternalLinks', + type: 'checkbox', + inputDefault: true, + appQueryDefault: false, + invert: true + } + ] + }, + { + groupName: '3D', + isAdvanced: false, + items: [ + { + name: 'Trail Width (pixels)', + description: 'Change the width of all entity path trails', + query: 'trailWidth', + type: 'number', + values: [0.5, 5, 0.5], // min, max, step + inputDefault: 1, + appQueryDefault: 1 + }, + { + name: 'Lighting', + query: 'lighting', + type: 'radio', + values: [ + { + title: 'Flood', + value: 'flood', + description: 'Flood lighting allows for even lighting across all 3D entities' + }, + { + title: 'Natural', + value: 'natural', + description: 'Natural lighting allows for realistic lighting based on the sun\'s position' + }, + { + title: 'Shadow', + value: 'shadow', + description: 'Shadow lighting allows for somewhat realistic lighting based on the sun\'s position, but highlights the shadows so they are not completely dark' + } + ], + inputDefault: 'shadow', + appQueryDefault: 'shadow' + } + ] + } +]; + +/* harmony default export */ __webpack_exports__["default"] = (embedDefaultControls); + + +/***/ }), + +/***/ "../eyes/src/data/entity_spheroid_features.js": +/*!****************************************************!*\ + !*** ../eyes/src/data/entity_spheroid_features.js ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ({ + jupiter: [ + { + id: 'magnetosphere', + title: 'Jupiter\'s Magnetic Field', + description: 'DESCRIPTION' + }, + { + id: 'auroras', + title: 'Jupiter\'s Auroras', + description: 'DESCRIPTION' + }, + { + id: 'radiationBelt', + title: 'Jupiter\'s Radiation Belt', + description: 'DESCRIPTION' + } + ], + saturn: [ + { + id: 'magnetosphere', + title: 'Saturn\'s Magnetic Field', + description: 'DESCRIPTION' + } + ] +}); + + +/***/ }), + +/***/ "../eyes/src/data/entity_spheroid_layers.js": +/*!**************************************************!*\ + !*** ../eyes/src/data/entity_spheroid_layers.js ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony default export */ __webpack_exports__["default"] = ({ + earth: [ + { + id: 'viirs', + title: 'High-quality global mosaic from yesterday', + description: 'This daily global mosaic is from the Visible Infrared Imaging Radiometer Suite (VIIRS), which is one of the key instruments onboard the Suomi National Polar-Orbiting Partnership (Suomi NPP) spacecraft.', + type: 'wmts', + features: ['shadowEntities', 'atmosphere'], + endPoint: 'assets/wmts_xml', + layer: 'VIIRS_SNPP_CorrectedReflectance_TrueColor', + tile: '250m', + time: 'yesterday' + } + ], + mars: [ + { + id: 'vikingMosaic', + title: 'Global mosaic from the Viking missions to Mars.', + description: 'The two Mars Viking Orbiters imaged the entire surface of Mars at a resolution of 150 to 300 meters.', + type: 'wmts', + features: ['shadowEntities', 'atmosphere'], + endPoint: 'https://trek.nasa.gov/tiles/Mars/EQ/corrected/Mars_Viking_MDIM21_ClrMosaic_global_232m', + layer: 'Mars_Viking_MDIM21_ClrMosaic_global_232m' + } + ], + moon: [ + { + id: 'lroMosaic', + title: 'Global mosaic from the Lunar Reconnaissance Orbiter mission', + description: 'The wide-angle camera on LRO mapped the entire moon at 100 meters/pixel.', + type: 'wmts', + features: ['shadowEntities'], + endPoint: 'https://trek.nasa.gov/tiles/Moon/EQ/corrected/LRO_WAC_Mosaic_Global_303ppd_v02', + layer: 'LRO_WAC_Mosaic_Global_303ppd_v02' + } + ], + titan: [ + { + id: 'surface', + title: 'Surface imagery of Titan from Cassini\'s Imaging Science Subsystem camera', + description: 'This global mosaic is at 4 km/pixel, combining one hundred flybys of Titan by the Cassini mission', + type: 'texture', + features: ['shadowEntities'], + textures: { + color: { + url: 'titan/surface_$SIZE_$FACE.png', + sizes: [16, 512, 2048] + } + } + }, + { + id: 'radar', + title: 'Radar Map of Titan\'s Surface', + description: 'This 351 meters/pixel map incorporates 104 Titan flybys by the Cassini mission.', + type: 'texture', + features: ['shadowEntities'], + textures: { + color: { + url: 'titan/radar_$SIZE_$FACE.png', + sizes: [16, 512, 2048] + } + } + } + ], + venus: [ + { + id: 'surface', + title: 'Radar Map of the Surface of Venus', + description: 'The Magellan mission used radar to see beneath the smog of Venus.', + type: 'texture', + features: ['shadowEntities'], + textures: { + color: { + url: 'venus/surface_$SIZE_$FACE.png', + sizes: [16, 512, 1024] + } + } + } + ] +}); + + +/***/ }), + +/***/ "../eyes/src/index.js": +/*!****************************!*\ + !*** ../eyes/src/index.js ***! + \****************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AnimationUtils": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils; }, +/* harmony export */ "AppUtils": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils; }, +/* harmony export */ "BaseApp": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.BaseApp; }, +/* harmony export */ "BaseComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent; }, +/* harmony export */ "BaseManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.BaseManager; }, +/* harmony export */ "BaseView": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.BaseView; }, +/* harmony export */ "Breadcrumb": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Breadcrumb; }, +/* harmony export */ "ButtonsBlock": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ButtonsBlock; }, +/* harmony export */ "CameraFollowManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CameraFollowManager; }, +/* harmony export */ "CameraManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CameraManager; }, +/* harmony export */ "CameraScripts": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CameraScripts; }, +/* harmony export */ "CancelToken": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CancelToken; }, +/* harmony export */ "Carousel": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Carousel; }, +/* harmony export */ "CarouselPanel": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CarouselPanel; }, +/* harmony export */ "Checkbox": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Checkbox; }, +/* harmony export */ "CheckboxBlock": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CheckboxBlock; }, +/* harmony export */ "Clock": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Clock; }, +/* harmony export */ "ClockShortcut": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ClockShortcut; }, +/* harmony export */ "ComparisonManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ComparisonManager; }, +/* harmony export */ "ContentManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ContentManager; }, +/* harmony export */ "DescriptionBlock": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.DescriptionBlock; }, +/* harmony export */ "DistanceLineComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.DistanceLineComponent; }, +/* harmony export */ "ERTManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ERTManager; }, +/* harmony export */ "EyesVersion": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.EyesVersion; }, +/* harmony export */ "HintBlock": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.HintBlock; }, +/* harmony export */ "ImageBlock": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ImageBlock; }, +/* harmony export */ "KioskBase": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.KioskBase; }, +/* harmony export */ "LabelManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.LabelManager; }, +/* harmony export */ "LayerManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.LayerManager; }, +/* harmony export */ "LayerPanel": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.LayerPanel; }, +/* harmony export */ "LoadIcon": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.LoadIcon; }, +/* harmony export */ "OrbiterLineOfSightComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.OrbiterLineOfSightComponent; }, +/* harmony export */ "Overlay": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Overlay; }, +/* harmony export */ "ReplayButtonBlock": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ReplayButtonBlock; }, +/* harmony export */ "RouteManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.RouteManager; }, +/* harmony export */ "SceneManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SceneManager; }, +/* harmony export */ "Search": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Search; }, +/* harmony export */ "SearchManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SearchManager; }, +/* harmony export */ "SelectionManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SelectionManager; }, +/* harmony export */ "Settings": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Settings; }, +/* harmony export */ "ShareModal": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ShareModal; }, +/* harmony export */ "SpoutManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SpoutManager; }, +/* harmony export */ "Story": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Story; }, +/* harmony export */ "StoryBaseContentBlock": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock; }, +/* harmony export */ "TimeController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TimeController; }, +/* harmony export */ "TimeManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TimeManager; }, +/* harmony export */ "TitleBlock": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TitleBlock; }, +/* harmony export */ "TitleManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TitleManager; }, +/* harmony export */ "Toast": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Toast; }, +/* harmony export */ "ToggleBlock": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ToggleBlock; }, +/* harmony export */ "TrailManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TrailManager; }, +/* harmony export */ "TutorialOverlay": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TutorialOverlay; }, +/* harmony export */ "Types": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Types; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal */ "../eyes/src/internal.js"); + + + +/***/ }), + +/***/ "../eyes/src/internal.js": +/*!*******************************!*\ + !*** ../eyes/src/internal.js ***! + \*******************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "EyesVersion": function() { return /* reexport safe */ _version__WEBPACK_IMPORTED_MODULE_0__.version; }, +/* harmony export */ "OrbiterLineOfSightComponent": function() { return /* reexport safe */ _lib_orbiter_line_of_sight_component__WEBPACK_IMPORTED_MODULE_1__.OrbiterLineOfSightComponent; }, +/* harmony export */ "DistanceLineComponent": function() { return /* reexport safe */ _lib_distance_line_component__WEBPACK_IMPORTED_MODULE_2__.DistanceLineComponent; }, +/* harmony export */ "CancelToken": function() { return /* reexport safe */ _utils_cancel_token__WEBPACK_IMPORTED_MODULE_3__.CancelToken; }, +/* harmony export */ "AppUtils": function() { return /* reexport safe */ _utils_app_utils__WEBPACK_IMPORTED_MODULE_4__.AppUtils; }, +/* harmony export */ "AnimationUtils": function() { return /* reexport safe */ _utils_animation_utils__WEBPACK_IMPORTED_MODULE_5__.AnimationUtils; }, +/* harmony export */ "BaseComponent": function() { return /* reexport safe */ _components_base_component__WEBPACK_IMPORTED_MODULE_6__.BaseComponent; }, +/* harmony export */ "Settings": function() { return /* reexport safe */ _components_settings__WEBPACK_IMPORTED_MODULE_7__["default"]; }, +/* harmony export */ "LoadIcon": function() { return /* reexport safe */ _components_load_icon__WEBPACK_IMPORTED_MODULE_8__["default"]; }, +/* harmony export */ "Overlay": function() { return /* reexport safe */ _components_overlay__WEBPACK_IMPORTED_MODULE_9__["default"]; }, +/* harmony export */ "Search": function() { return /* reexport safe */ _components_search__WEBPACK_IMPORTED_MODULE_10__["default"]; }, +/* harmony export */ "Clock": function() { return /* reexport safe */ _components_clock__WEBPACK_IMPORTED_MODULE_11__["default"]; }, +/* harmony export */ "ClockShortcut": function() { return /* reexport safe */ _components_clock_shortcut__WEBPACK_IMPORTED_MODULE_12__["default"]; }, +/* harmony export */ "Carousel": function() { return /* reexport safe */ _components_carousel__WEBPACK_IMPORTED_MODULE_13__["default"]; }, +/* harmony export */ "TutorialOverlay": function() { return /* reexport safe */ _components_tutorial_overlay__WEBPACK_IMPORTED_MODULE_14__["default"]; }, +/* harmony export */ "CarouselPanel": function() { return /* reexport safe */ _components_carousel_panel__WEBPACK_IMPORTED_MODULE_15__["default"]; }, +/* harmony export */ "ShareModal": function() { return /* reexport safe */ _components_share_modal__WEBPACK_IMPORTED_MODULE_16__["default"]; }, +/* harmony export */ "TimeController": function() { return /* reexport safe */ _components_time_controller__WEBPACK_IMPORTED_MODULE_17__["default"]; }, +/* harmony export */ "Checkbox": function() { return /* reexport safe */ _components_checkbox__WEBPACK_IMPORTED_MODULE_18__["default"]; }, +/* harmony export */ "LayerPanel": function() { return /* reexport safe */ _components_layer_panel_layer_panel__WEBPACK_IMPORTED_MODULE_19__.LayerPanel; }, +/* harmony export */ "Breadcrumb": function() { return /* reexport safe */ _components_breadcrumb_breadcrumb__WEBPACK_IMPORTED_MODULE_20__.Breadcrumb; }, +/* harmony export */ "StoryBaseContentBlock": function() { return /* reexport safe */ _components_story_blocks_story_base_content_block_story_base_content_block__WEBPACK_IMPORTED_MODULE_21__.StoryBaseContentBlock; }, +/* harmony export */ "HintBlock": function() { return /* reexport safe */ _components_story_blocks_hint_block_hint_block__WEBPACK_IMPORTED_MODULE_22__.HintBlock; }, +/* harmony export */ "ToggleBlock": function() { return /* reexport safe */ _components_story_blocks_toggle_block_toggle_block__WEBPACK_IMPORTED_MODULE_23__.ToggleBlock; }, +/* harmony export */ "TitleBlock": function() { return /* reexport safe */ _components_story_blocks_title_block_title_block__WEBPACK_IMPORTED_MODULE_24__.TitleBlock; }, +/* harmony export */ "ImageBlock": function() { return /* reexport safe */ _components_story_blocks_image_block_image_block__WEBPACK_IMPORTED_MODULE_25__.ImageBlock; }, +/* harmony export */ "DescriptionBlock": function() { return /* reexport safe */ _components_story_blocks_description_block_description_block__WEBPACK_IMPORTED_MODULE_26__.DescriptionBlock; }, +/* harmony export */ "ReplayButtonBlock": function() { return /* reexport safe */ _components_story_blocks_replay_button_block_replay_button_block__WEBPACK_IMPORTED_MODULE_27__.ReplayButtonBlock; }, +/* harmony export */ "ButtonsBlock": function() { return /* reexport safe */ _components_story_blocks_buttons_block_buttons_block__WEBPACK_IMPORTED_MODULE_28__.ButtonsBlock; }, +/* harmony export */ "CheckboxBlock": function() { return /* reexport safe */ _components_story_blocks_checkbox_block_checkbox_block__WEBPACK_IMPORTED_MODULE_29__.CheckboxBlock; }, +/* harmony export */ "Story": function() { return /* reexport safe */ _components_story_story__WEBPACK_IMPORTED_MODULE_30__.Story; }, +/* harmony export */ "KioskBase": function() { return /* reexport safe */ _components_kiosk_base_kiosk_base__WEBPACK_IMPORTED_MODULE_31__.KioskBase; }, +/* harmony export */ "Toast": function() { return /* reexport safe */ _components_toast_toast__WEBPACK_IMPORTED_MODULE_32__.Toast; }, +/* harmony export */ "BaseManager": function() { return /* reexport safe */ _managers_base_manager__WEBPACK_IMPORTED_MODULE_33__.BaseManager; }, +/* harmony export */ "SelectionManager": function() { return /* reexport safe */ _managers_selection_manager__WEBPACK_IMPORTED_MODULE_34__.SelectionManager; }, +/* harmony export */ "LabelManager": function() { return /* reexport safe */ _managers_label_manager__WEBPACK_IMPORTED_MODULE_35__.LabelManager; }, +/* harmony export */ "RouteManager": function() { return /* reexport safe */ _managers_route_manager__WEBPACK_IMPORTED_MODULE_36__.RouteManager; }, +/* harmony export */ "ContentManager": function() { return /* reexport safe */ _managers_content_manager__WEBPACK_IMPORTED_MODULE_37__.ContentManager; }, +/* harmony export */ "SceneManager": function() { return /* reexport safe */ _managers_scene_manager__WEBPACK_IMPORTED_MODULE_38__.SceneManager; }, +/* harmony export */ "LayerManager": function() { return /* reexport safe */ _managers_layer_manager__WEBPACK_IMPORTED_MODULE_39__.LayerManager; }, +/* harmony export */ "TrailManager": function() { return /* reexport safe */ _managers_trail_manager__WEBPACK_IMPORTED_MODULE_40__.TrailManager; }, +/* harmony export */ "CameraManager": function() { return /* reexport safe */ _managers_camera_manager__WEBPACK_IMPORTED_MODULE_41__.CameraManager; }, +/* harmony export */ "CameraScripts": function() { return /* reexport safe */ _managers_camera_scripts__WEBPACK_IMPORTED_MODULE_42__.CameraScripts; }, +/* harmony export */ "ERTManager": function() { return /* reexport safe */ _managers_ert_manager__WEBPACK_IMPORTED_MODULE_43__.ERTManager; }, +/* harmony export */ "TimeManager": function() { return /* reexport safe */ _managers_time_manager__WEBPACK_IMPORTED_MODULE_44__.TimeManager; }, +/* harmony export */ "ComparisonManager": function() { return /* reexport safe */ _managers_comparison_manager__WEBPACK_IMPORTED_MODULE_45__.ComparisonManager; }, +/* harmony export */ "SearchManager": function() { return /* reexport safe */ _managers_search_manager__WEBPACK_IMPORTED_MODULE_46__.SearchManager; }, +/* harmony export */ "TitleManager": function() { return /* reexport safe */ _managers_title_manager__WEBPACK_IMPORTED_MODULE_47__.TitleManager; }, +/* harmony export */ "SpoutManager": function() { return /* reexport safe */ _managers_spout_manager__WEBPACK_IMPORTED_MODULE_48__.SpoutManager; }, +/* harmony export */ "CameraFollowManager": function() { return /* reexport safe */ _managers_camera_follow_manager__WEBPACK_IMPORTED_MODULE_49__.CameraFollowManager; }, +/* harmony export */ "BaseView": function() { return /* reexport safe */ _base_view__WEBPACK_IMPORTED_MODULE_50__.BaseView; }, +/* harmony export */ "BaseApp": function() { return /* reexport safe */ _app__WEBPACK_IMPORTED_MODULE_51__.BaseApp; }, +/* harmony export */ "Types": function() { return /* reexport safe */ _types__WEBPACK_IMPORTED_MODULE_52__.Types; } +/* harmony export */ }); +/* harmony import */ var _version__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./version */ "../eyes/src/version.js"); +/* harmony import */ var _lib_orbiter_line_of_sight_component__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lib/orbiter_line_of_sight_component */ "../eyes/src/lib/orbiter_line_of_sight_component.js"); +/* harmony import */ var _lib_distance_line_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lib/distance_line_component */ "../eyes/src/lib/distance_line_component.js"); +/* harmony import */ var _utils_cancel_token__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils/cancel_token */ "../eyes/src/utils/cancel_token.js"); +/* harmony import */ var _utils_app_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./utils/app_utils */ "../eyes/src/utils/app_utils.js"); +/* harmony import */ var _utils_animation_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils/animation_utils */ "../eyes/src/utils/animation_utils.js"); +/* harmony import */ var _components_base_component__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/base_component */ "../eyes/src/components/base_component.js"); +/* harmony import */ var _components_settings__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/settings */ "../eyes/src/components/settings/index.js"); +/* harmony import */ var _components_load_icon__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/load_icon */ "../eyes/src/components/load_icon/index.js"); +/* harmony import */ var _components_overlay__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/overlay */ "../eyes/src/components/overlay/index.js"); +/* harmony import */ var _components_search__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/search */ "../eyes/src/components/search/index.js"); +/* harmony import */ var _components_clock__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./components/clock */ "../eyes/src/components/clock/index.js"); +/* harmony import */ var _components_clock_shortcut__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/clock_shortcut */ "../eyes/src/components/clock_shortcut/index.js"); +/* harmony import */ var _components_carousel__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./components/carousel */ "../eyes/src/components/carousel/index.js"); +/* harmony import */ var _components_tutorial_overlay__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./components/tutorial_overlay */ "../eyes/src/components/tutorial_overlay/index.js"); +/* harmony import */ var _components_carousel_panel__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./components/carousel_panel */ "../eyes/src/components/carousel_panel/index.js"); +/* harmony import */ var _components_share_modal__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./components/share_modal */ "../eyes/src/components/share_modal/index.js"); +/* harmony import */ var _components_time_controller__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./components/time_controller */ "../eyes/src/components/time_controller/index.js"); +/* harmony import */ var _components_checkbox__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./components/checkbox */ "../eyes/src/components/checkbox/index.js"); +/* harmony import */ var _components_layer_panel_layer_panel__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./components/layer_panel/layer_panel */ "../eyes/src/components/layer_panel/layer_panel.js"); +/* harmony import */ var _components_breadcrumb_breadcrumb__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./components/breadcrumb/breadcrumb */ "../eyes/src/components/breadcrumb/breadcrumb.js"); +/* harmony import */ var _components_story_blocks_story_base_content_block_story_base_content_block__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./components/story/blocks/story_base_content_block/story_base_content_block */ "../eyes/src/components/story/blocks/story_base_content_block/story_base_content_block.js"); +/* harmony import */ var _components_story_blocks_hint_block_hint_block__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./components/story/blocks/hint_block/hint_block */ "../eyes/src/components/story/blocks/hint_block/hint_block.js"); +/* harmony import */ var _components_story_blocks_toggle_block_toggle_block__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./components/story/blocks/toggle_block/toggle_block */ "../eyes/src/components/story/blocks/toggle_block/toggle_block.js"); +/* harmony import */ var _components_story_blocks_title_block_title_block__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./components/story/blocks/title_block/title_block */ "../eyes/src/components/story/blocks/title_block/title_block.js"); +/* harmony import */ var _components_story_blocks_image_block_image_block__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./components/story/blocks/image_block/image_block */ "../eyes/src/components/story/blocks/image_block/image_block.js"); +/* harmony import */ var _components_story_blocks_description_block_description_block__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./components/story/blocks/description_block/description_block */ "../eyes/src/components/story/blocks/description_block/description_block.js"); +/* harmony import */ var _components_story_blocks_replay_button_block_replay_button_block__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./components/story/blocks/replay_button_block/replay_button_block */ "../eyes/src/components/story/blocks/replay_button_block/replay_button_block.js"); +/* harmony import */ var _components_story_blocks_buttons_block_buttons_block__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./components/story/blocks/buttons_block/buttons_block */ "../eyes/src/components/story/blocks/buttons_block/buttons_block.js"); +/* harmony import */ var _components_story_blocks_checkbox_block_checkbox_block__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./components/story/blocks/checkbox_block/checkbox_block */ "../eyes/src/components/story/blocks/checkbox_block/checkbox_block.js"); +/* harmony import */ var _components_story_story__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./components/story/story */ "../eyes/src/components/story/story.js"); +/* harmony import */ var _components_kiosk_base_kiosk_base__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./components/kiosk_base/kiosk_base */ "../eyes/src/components/kiosk_base/kiosk_base.js"); +/* harmony import */ var _components_toast_toast__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./components/toast/toast */ "../eyes/src/components/toast/toast.js"); +/* harmony import */ var _managers_base_manager__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./managers/base_manager */ "../eyes/src/managers/base_manager.js"); +/* harmony import */ var _managers_selection_manager__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./managers/selection_manager */ "../eyes/src/managers/selection_manager.js"); +/* harmony import */ var _managers_label_manager__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./managers/label_manager */ "../eyes/src/managers/label_manager.js"); +/* harmony import */ var _managers_route_manager__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./managers/route_manager */ "../eyes/src/managers/route_manager.js"); +/* harmony import */ var _managers_content_manager__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./managers/content_manager */ "../eyes/src/managers/content_manager.js"); +/* harmony import */ var _managers_scene_manager__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./managers/scene_manager */ "../eyes/src/managers/scene_manager.js"); +/* harmony import */ var _managers_layer_manager__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ./managers/layer_manager */ "../eyes/src/managers/layer_manager.js"); +/* harmony import */ var _managers_trail_manager__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ./managers/trail_manager */ "../eyes/src/managers/trail_manager.js"); +/* harmony import */ var _managers_camera_manager__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ./managers/camera_manager */ "../eyes/src/managers/camera_manager.js"); +/* harmony import */ var _managers_camera_scripts__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ./managers/camera_scripts */ "../eyes/src/managers/camera_scripts.js"); +/* harmony import */ var _managers_ert_manager__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ./managers/ert_manager */ "../eyes/src/managers/ert_manager.js"); +/* harmony import */ var _managers_time_manager__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ./managers/time_manager */ "../eyes/src/managers/time_manager.js"); +/* harmony import */ var _managers_comparison_manager__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ./managers/comparison_manager */ "../eyes/src/managers/comparison_manager.js"); +/* harmony import */ var _managers_search_manager__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! ./managers/search_manager */ "../eyes/src/managers/search_manager.js"); +/* harmony import */ var _managers_title_manager__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! ./managers/title_manager */ "../eyes/src/managers/title_manager.js"); +/* harmony import */ var _managers_spout_manager__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(/*! ./managers/spout_manager */ "../eyes/src/managers/spout_manager.js"); +/* harmony import */ var _managers_camera_follow_manager__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(/*! ./managers/camera_follow_manager */ "../eyes/src/managers/camera_follow_manager.js"); +/* harmony import */ var _base_view__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(/*! ./base_view */ "../eyes/src/base_view.js"); +/* harmony import */ var _app__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(/*! ./app */ "../eyes/src/app.js"); +/* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(/*! ./types */ "../eyes/src/types.js"); +/* eslint-disable import/first */ + + + +// Custom Pioneer components + + + +// Utils + + + + +// Components + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// Managers + + + + + + + + + + + + + + + + + + +// Base View + + +// App + + +// Types + + + +/***/ }), + +/***/ "../eyes/src/lib/distance_line_component.js": +/*!**************************************************!*\ + !*** ../eyes/src/lib/distance_line_component.js ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "DistanceLineComponent": function() { return /* binding */ DistanceLineComponent; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); + + +/** + * @typedef LineAnimationOptions + * @property {boolean} isAnimating whether we're currently animating + * @property {number} duration length of animation in ms + * @property {number} sourceStartTime starting time returned from Date.now() at start + * @property {number} targetStartTime starting time returned from Date.now() at start + */ + +/** + * @typedef AnimationProgress + * @property {number} sourceProgress source progress 0 - 1 + * @property {number} targetProgress target progress 0 - 1 + */ + +/** + * The line component. + * @extends BaseComponent + */ +class DistanceLineComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + * @package + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * Target entity for the end of the line. + * @type {Entity} + * @private + */ + this._targetEntity = null; + + /** + * The color to draw. + * @type {Color} + * @private + */ + this._color = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(0.48, 0.56, 0.66); + + /** + * The distance between the center of the two entities (km) + * @type {number} + * @private + */ + this._distance = null; + + /** + * The source's radius relative to total distance (0-1) + * @type {number} + * @private + */ + this._sourceRelRadius = null; + + /** + * The targets's radius relative to total distance (0-1) + * @type {number} + * @private + */ + this._targetRelRadius = null; + + /** + * The source's measuring start point is center or surface (defaults to center) + * @type {boolean} + * @private + */ + this._sourceMpIsSurface = false; + + /** + * The target's measuring start point is center or surface (defaults to center) + * @type {boolean} + * @private + */ + this._targetMpIsSurface = false; + + /** + * Whether to switch the start position of the line to the target + * @type {boolean} + * @private + */ + this._switchStartPos = null; + + /** + * Sets depth test to false by default. + * @type {boolean} + * @private + */ + this._depthTest = false; + + + /** + * Animation object options + * @type {LineAnimationOptions} + * @private + */ + this._animation = { + isAnimating: false, + duration: 300, + sourceStartTime: null, + targetStartTime: null + }; + + /** + * The width to draw. + * @type {number} + * @private + */ + this._width = 2; + + /** + * The LineMesh object used to do the drawing. + * @type {LineMesh} + * @private + */ + this._lineMesh = null; + + // Set the radius + this.__setRadius(Number.POSITIVE_INFINITY); + } + + /** + * Sets the source and target entities for the line. + * @param {Entity} targetEntity + */ + setTargetEntity(targetEntity) { + this._targetEntity = targetEntity; + } + + /** + * Sets the source measure point. + * @param {string} measurePoint + */ + setSourceMeasurePoint(measurePoint) { + const newIsSurface = measurePoint === 'surface'; + const hasChanged = this._sourceMpIsSurface !== newIsSurface; + + if (!hasChanged) { + return; + } + + this._sourceMpIsSurface = newIsSurface; + + this._animation.isAnimating = true; + this._animation.sourceStartTime = Date.now(); + } + + /** + * Sets the target measure point. + * @param {string} measurePoint + */ + setTargetMeasurePoint(measurePoint) { + const newIsSurface = measurePoint === 'surface'; + const hasChanged = this._targetMpIsSurface !== newIsSurface; + + if (!hasChanged) { + return; + } + + this._targetMpIsSurface = newIsSurface; + + this._animation.isAnimating = true; + this._animation.targetStartTime = Date.now(); + } + + /** + * Sets the color for the line. + * @param {Color} color + */ + setColor(color) { + this._color = color; + } + + /** + * Sets the width of the line. + * @param {number} width + */ + setWidth(width) { + this._width = width; + } + + /** + * Sets the distance props (distance, source and target relative radii) + * @param {object} params + * @param {number} params.distance + * @param {number} params.sourceRadius + * @param {number} params.targetRadius + */ + setDistanceProps({ distance, sourceRadius, targetRadius }) { + this._distance = distance; + this._sourceRelRadius = Math.max(Math.min(sourceRadius / this._distance, 1), 0); + this._targetRelRadius = Math.max(Math.min(targetRadius / this._distance, 1), 0); + } + + /** + * Applies animation easing-in-out function. + * https://github.com/d3/d3-ease/tree/main/src + * @param {number} progress + * @returns {number} + */ + _applyEasing(progress) { + const e = 4; + const easedProgress = progress * 2; + + return (easedProgress <= 1 ? Math.pow(easedProgress, e) : 2 - Math.pow(2 - easedProgress, e)) / 2; + } + + /** + * Updates the lineStart and lineEnd position vectors when animating between center and surface for source or target. + * @param {Vector3} lineStart + * @param {Vector3} lineEnd + * @param {Vector3} startCenterPos + * @param {Vector3} startSurfacePos + * @param {Vector3} endCenterPos + * @param {Vector3} endSurfacePos + */ + _updateAnimation(lineStart, lineEnd, startCenterPos, startSurfacePos, endCenterPos, endSurfacePos) { + // Return if not animating. + if (!this._animation.isAnimating) { + return; + } + + + const { sourceStartTime, targetStartTime, duration } = this._animation; + + // Calculate progress lerps. This logic could be condensed but it's perhaps easier to read like this. + + if (sourceStartTime) { + const sourceDiff = Date.now() - sourceStartTime; + const sourceProgress = sourceDiff > duration ? 1 : sourceDiff / duration; + + if (sourceProgress !== 1) { + // Apply easing. + const sourceProgressEased = this._applyEasing(sourceProgress); + + // Determine vector lerp. + if (this._sourceMpIsSurface) { + if (this._switchStartPos) { + lineEnd.lerp(endCenterPos, endSurfacePos, sourceProgressEased); + } + else { + lineStart.lerp(startCenterPos, startSurfacePos, sourceProgressEased); + } + } + else { + if (this._switchStartPos) { + lineEnd.lerp(endSurfacePos, endCenterPos, sourceProgressEased); + } + else { + lineStart.lerp(startSurfacePos, startCenterPos, sourceProgressEased); + } + } + } + else { + // Source animation is complete. + this._animation.isAnimating = false; + this._animation.sourceStartTime = null; + } + } + + if (targetStartTime) { + const targetDiff = Date.now() - targetStartTime; + const targetProgress = targetDiff > duration ? 1 : targetDiff / duration; + + if (targetProgress !== 1) { + // Apply easing. + const targetProgressEased = this._applyEasing(targetProgress); + + // Determine vector lerp. + if (this._targetMpIsSurface) { + if (this._switchStartPos) { + lineStart.lerp(startCenterPos, startSurfacePos, targetProgressEased); + } + else { + lineEnd.lerp(endCenterPos, endSurfacePos, targetProgressEased); + } + } + else { + if (this._switchStartPos) { + lineStart.lerp(startSurfacePos, startCenterPos, targetProgressEased); + } + else { + lineEnd.lerp(endSurfacePos, endCenterPos, targetProgressEased); + } + } + } + else { + // Target animation is complete. + this._animation.isAnimating = false; + this._animation.targetStartTime = null; + } + } + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + this._lineMesh = new pioneer__WEBPACK_IMPORTED_MODULE_0__.LineMesh(this); + + // Set colors. + this._lineMesh.setColors([ + this._color, + this._color + ]); + + // Set widths. + this._lineMesh.setWidths([ + this._width, + this._width + ]); + + // Set opacity. + this.setOpacity(1); + + return Promise.resolve(); + } + + /** + * Sets the line opacity + * @param {number} opacity + */ + setOpacity(opacity) { + this._lineMesh.setAlphaMultiplier(opacity); + } + + /** + * Sets whether we use a depth test for the mesh line. + * @param {boolean} depthTest + */ + setDepthTest(depthTest) { + this._depthTest = depthTest; + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + this._lineMesh = null; + } + + /** + * Prepare the component for rendering. + * @param {CameraComponent} camera + * @override + * @package + */ + __prepareForRender(camera) { + const [lineMesh] = this.getThreeJsObjects(); + + if (this._targetEntity === null) { + if (lineMesh) { + lineMesh.visible = false; + } + return; + } + + if (lineMesh?.material) { + lineMesh.material.depthTest = this._depthTest; + } + + // Determine start pos. + this._calcStartPos(camera); + + // Update the points and set the calculated positions and colors. + this._updatePoints(camera); + + // Set the Three.js object position the entity's camera-space position + const startEntity = this._switchStartPos ? this._targetEntity : this.getEntity(); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(lineMesh, startEntity, camera); + + this._lineMesh.prepareForRender(camera); + } + + /** + * Determine the start position + * @param {CameraComponent} camera + */ + _calcStartPos(camera) { + const switchThreshold = 0.001; + const targetToCamera = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + + // Get camera distance to targetEntity. + camera.getEntity().getPositionRelativeToEntity(targetToCamera, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, this._targetEntity); + + // Cam distance to target relative to total distance. + const relDistance = targetToCamera.magnitude() / this._distance; + const switchStartPos = relDistance < switchThreshold; + + // Update _switchStartPos if needed. + if (this._switchStartPos !== switchStartPos) { + this._switchStartPos = switchStartPos; + } + + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(targetToCamera); + } + + /** + * Updates the points array. + * + * The start center is normally the source (this.getEntity) entity center, with the end being the target (this._targetEntity) center. + * However, if the camera is close to the target, we want to switch so the start is the target and the end is the source. + * This way, we wont get any erratically moving lines from long distance accuracy issues. + * For this, we're using this._switchStartPos as the determining boolean. + * @param {CameraComponent} camera + * @private + */ + _updatePoints(camera) { + if (this._targetEntity === null) { + return; + } + + // Get 4 vectors. + const startCenterPos = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const startSurfacePos = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const endSurfacePos = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const endCenterPos = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + + + // Start center is set to zero. + startCenterPos.copy(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero); + + // Set target entity center vector. + endCenterPos.sub(this._targetEntity.getCameraSpacePosition(camera), this.getEntity().getCameraSpacePosition(camera)); + if (this._switchStartPos) { + endCenterPos.neg(endCenterPos); + } + + const startSurfaceU = this._switchStartPos ? this._targetRelRadius : this._sourceRelRadius; + const endSurfaceU = 1 - (this._switchStartPos ? this._sourceRelRadius : this._targetRelRadius); + + // Get lerped surface vectors. + startSurfacePos.lerp(startCenterPos, endCenterPos, startSurfaceU); + endSurfacePos.lerp(startCenterPos, endCenterPos, endSurfaceU); + + // Determine line start and end vectors. + const startMpIsSurface = this._switchStartPos ? this._targetMpIsSurface : this._sourceMpIsSurface; + const endMpIsSurface = this._switchStartPos ? this._sourceMpIsSurface : this._targetMpIsSurface; + const lineStart = startMpIsSurface ? startSurfacePos : startCenterPos; + const lineEnd = endMpIsSurface ? endSurfacePos : endCenterPos; + + // Update animation. + this._updateAnimation(lineStart, lineEnd, startCenterPos, startSurfacePos, endCenterPos, endSurfacePos); + + // Update positions. + const positions = [ + lineStart, + lineEnd + ]; + this._lineMesh.setPositions(positions); + + + // Release vector3s + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(startCenterPos); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(startSurfacePos); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(endSurfacePos); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(endCenterPos); + } +} + + +/***/ }), + +/***/ "../eyes/src/lib/orbiter_line_of_sight_component.js": +/*!**********************************************************!*\ + !*** ../eyes/src/lib/orbiter_line_of_sight_component.js ***! + \**********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "OrbiterLineOfSightComponent": function() { return /* binding */ OrbiterLineOfSightComponent; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); + + +/** + * The line component. + * @extends Pioneer.BaseComponent + */ +class OrbiterLineOfSightComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Pioneer.Entity} entity - the parent entity + * @package + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * Target point A for the line. + * @type {Pioneer.Entity} + */ + this._targetA = null; + + /** + * Target point B for the line. + * @type {Pioneer.Entity} + */ + this._targetB = null; + + /** + * Ignore distance flag. + * @type {boolean} + */ + this._ignoreDistance = false; + + /** + * Ignore distance threshold. + * Will fade in between min (a:0) and max (a:1). + * @type {object} + */ + this._distanceThreshold = { min: 2, max: 20 }; + + /** + * The positions to draw. Sent to the line mesh. + * @type {Array} + * @private + */ + this._positions = []; + + /** + * The colors to draw. Sent to the line mesh. + * @type {Array} + * @private + */ + this._colors = []; + + /** + * The widths to draw. Sent to the line mesh. + * @type {Array} + * @private + */ + this._widths = []; + + /** + * The color to draw. + * @type {Pioneer.Color} + * @private + */ + this._color = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 0); + + /** + * The width to draw. + * @type {number} + * @private + */ + this._width = 2; + + // Setup ThreeJS + this._threeJsScene = entity.getScene().getThreeJsScene(); + + /** + * The LineMesh object used to do the drawing. + * @type {Pioneer.LineMesh} + * @private + */ + this._lineMesh = null; + + // Set the radius + this.__setRadius(Number.POSITIVE_INFINITY); + } + + /** + * Sets the target entity for the line. + * @param {Pioneer.Entity} entityA + * @param {Pioneer.Entity} entityB + */ + setTargets(entityA, entityB) { + if (typeof entityA === 'string') { + entityA = this.getEntity().getScene().get(entityA); + } + if (typeof entityB === 'string') { + entityB = this.getEntity().getScene().get(entityB); + } + + this._targetA = entityA; + this._targetB = entityB; + } + + /** + * Sets the color for the line. + * @param {Pioneer.Color} color + */ + setColor(color) { + this._color = color; + } + + /** + * Sets the width of the line. + * @param {number} width + */ + setWidth(width) { + this._width = width; + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @protected + */ + __loadResources() { + this._lineMesh = new pioneer__WEBPACK_IMPORTED_MODULE_0__.LineMesh(this); + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @protected + */ + __unloadResources() { + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + this._lineMesh = null; + } + + /** + * Prepare the component for rendering. + * @param {Pioneer.CameraComponent} camera + * @package + */ + __prepareForRender(camera) { + if (this._targetA === null || this._targetB === null) { + if (this.getThreeJsObjects().length > 0) { + this.getThreeJsObjects()[0].visible = false; + } + return; + } + + // Update the points and set the calculated positions and colors. + this._updatePoints(camera); + let alphaMultiplier = 1.0; + if (!this._ignoreDistance) { + const cameraDistance = camera.getEntity().getPosition().magnitude(); + const f = (cameraDistance - this._distanceThreshold.min) / (this._distanceThreshold.max - this._distanceThreshold.min); + alphaMultiplier *= f; + } + + // Set the Three.js object position the entity's camera-space position. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + + this._lineMesh.setAlphaMultiplier(alphaMultiplier); + this._lineMesh.prepareForRender(camera); + } + + /** + * Updates the points array. + * @private + */ + _updatePoints() { + // Get target positions in Mars frame + const targetAPos = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const targetBPos = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + + this._targetA.getPositionRelativeToEntity(targetAPos, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, this.getEntity()); + this._targetB.getPositionRelativeToEntity(targetBPos, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, this.getEntity()); + + // Update positions + this._positions = []; + this._positions.push(targetAPos); + this._positions.push(targetBPos); + this._lineMesh.setPositions(this._positions); + + // Update colors + const color = this._color; + this._colors = []; + this._colors.push(color); + this._colors.push(color); + this._lineMesh.setColors(this._colors); + + // Update widths + this._widths = []; + this._widths.push(this._width); + this._widths.push(this._width); + this._lineMesh.setWidths(this._widths); + + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(targetAPos); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(targetBPos); + } +} + + +/***/ }), + +/***/ "../eyes/src/lib/quadtree.js": +/*!***********************************!*\ + !*** ../eyes/src/lib/quadtree.js ***! + \***********************************/ +/***/ (function() { + +/* + * Javascript Quadtree + * @version 1.1.1 + * @licence MIT + * @author Timo Hausmann + * https://github.com/timohausmann/quadtree-js/ + */ + +/* + Copyright © 2012 Timo Hausmann + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENthis. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +;(function(window, Math) { + + /* + * Quadtree Constructor + * @param Object bounds bounds of the node, object with x, y, width, height + * @param Integer max_objects (optional) max objects a node can hold before splitting into 4 subnodes (default: 10) + * @param Integer max_levels (optional) total max levels inside root Quadtree (default: 4) + * @param Integer level (optional) deepth level, required for subnodes + */ + function Quadtree( bounds, max_objects, max_levels, level ) { + + this.max_objects = max_objects || 10; + this.max_levels = max_levels || 4; + + this.level = level || 0; + this.bounds = bounds; + + this.objects = []; + this.nodes = []; + }; + + + /* + * Split the node into 4 subnodes + */ + Quadtree.prototype.split = function() { + + var nextLevel = this.level + 1, + subWidth = Math.round( this.bounds.width / 2 ), + subHeight = Math.round( this.bounds.height / 2 ), + x = Math.round( this.bounds.x ), + y = Math.round( this.bounds.y ); + + //top right node + this.nodes[0] = new Quadtree({ + x : x + subWidth, + y : y, + width : subWidth, + height : subHeight + }, this.max_objects, this.max_levels, nextLevel); + + //top left node + this.nodes[1] = new Quadtree({ + x : x, + y : y, + width : subWidth, + height : subHeight + }, this.max_objects, this.max_levels, nextLevel); + + //bottom left node + this.nodes[2] = new Quadtree({ + x : x, + y : y + subHeight, + width : subWidth, + height : subHeight + }, this.max_objects, this.max_levels, nextLevel); + + //bottom right node + this.nodes[3] = new Quadtree({ + x : x + subWidth, + y : y + subHeight, + width : subWidth, + height : subHeight + }, this.max_objects, this.max_levels, nextLevel); + }; + + + /* + * Determine which node the object belongs to + * @param Object pRect bounds of the area to be checked, with x, y, width, height + * @return Integer index of the subnode (0-3), or -1 if pRect cannot completely fit within a subnode and is part of the parent node + */ + Quadtree.prototype.getIndex = function( pRect ) { + + var index = -1, + verticalMidpoint = this.bounds.x + (this.bounds.width / 2), + horizontalMidpoint = this.bounds.y + (this.bounds.height / 2), + + //pRect can completely fit within the top quadrants + topQuadrant = (pRect.y < horizontalMidpoint && pRect.y + pRect.height < horizontalMidpoint), + + //pRect can completely fit within the bottom quadrants + bottomQuadrant = (pRect.y > horizontalMidpoint); + + //pRect can completely fit within the left quadrants + if( pRect.x < verticalMidpoint && pRect.x + pRect.width < verticalMidpoint ) { + if( topQuadrant ) { + index = 1; + } else if( bottomQuadrant ) { + index = 2; + } + + //pRect can completely fit within the right quadrants + } else if( pRect.x > verticalMidpoint ) { + if( topQuadrant ) { + index = 0; + } else if( bottomQuadrant ) { + index = 3; + } + } + + return index; + }; + + + /* + * Insert the object into the node. If the node + * exceeds the capacity, it will split and add all + * objects to their corresponding subnodes. + * @param Object pRect bounds of the object to be added, with x, y, width, height + */ + Quadtree.prototype.insert = function( pRect ) { + + var i = 0, + index; + + //if we have subnodes ... + if( typeof this.nodes[0] !== 'undefined' ) { + index = this.getIndex( pRect ); + + if( index !== -1 ) { + this.nodes[index].insert( pRect ); + return; + } + } + + this.objects.push( pRect ); + + if( this.objects.length > this.max_objects && this.level < this.max_levels ) { + + //split if we don't already have subnodes + if( typeof this.nodes[0] === 'undefined' ) { + this.split(); + } + + //add all objects to there corresponding subnodes + while( i < this.objects.length ) { + + index = this.getIndex( this.objects[ i ] ); + + if( index !== -1 ) { + this.nodes[index].insert( this.objects.splice(i, 1)[0] ); + } else { + i = i + 1; + } + } + } + }; + + + /* + * Return all objects that could collide with the given object + * @param Object pRect bounds of the object to be checked, with x, y, width, height + * @Return Array array with all detected objects + */ + Quadtree.prototype.retrieve = function( pRect ) { + + var index = this.getIndex( pRect ), + returnObjects = this.objects; + + //if we have subnodes ... + if( typeof this.nodes[0] !== 'undefined' ) { + + //if pRect fits into a subnode .. + if( index !== -1 ) { + returnObjects = returnObjects.concat( this.nodes[index].retrieve( pRect ) ); + + //if pRect does not fit into a subnode, check it against all subnodes + } else { + for( var i=0; i < this.nodes.length; i=i+1 ) { + returnObjects = returnObjects.concat( this.nodes[i].retrieve( pRect ) ); + } + } + } + + return returnObjects; + }; + + + /* + * Clear the quadtree + */ + Quadtree.prototype.clear = function() { + + this.objects = []; + + for( var i=0; i < this.nodes.length; i=i+1 ) { + if( typeof this.nodes[i] !== 'undefined' ) { + this.nodes[i].clear(); + } + } + + this.nodes = []; + }; + + //make Quadtree available in the global namespace + window.Quadtree = Quadtree; + +})(window, Math); + + +/***/ }), + +/***/ "../eyes/src/managers/base_manager.js": +/*!********************************************!*\ + !*** ../eyes/src/managers/base_manager.js ***! + \********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "BaseManager": function() { return /* binding */ BaseManager; } +/* harmony export */ }); + + + +/** + * Base manager class. + */ +class BaseManager { + /** + * Constructor. + * @param {BaseApp} app + */ + constructor(app) { + /** + * Application. + * @type {BaseApp} + * @private + */ + this._app = app; + + /** + * Pioneer engine. + * @type {Pioneer.Engine} + * @private + */ + this._pioneer = app.pioneer; + + /** + * Array of possible event names. + * @type {string[]} + * @default + */ + this._eventNames = []; + + /** + * Callbacks reference object. + * @type {Object void>>} + * @default + */ + this._callbacks = {}; + } + + /** + * Gets Pioneer engine. + * @returns {Pioneer.Engine} + */ + get pioneer() { + return this._pioneer; + } + + /** + * Gets application object. + * @returns {BaseApp} + */ + get app() { + return this._app; + } + + /** + * Initialize callback list for all events. + * @protected + */ + _initCallbacks() { + for (let i = 0; i < this._eventNames.length; i++) { + this._callbacks[this._eventNames[i]] = []; + } + } + + /** + * Registers a callback for a specific event. + * @param {string} eventName + * @param {(...params: any[]) => void} callback - A callback function to be called + */ + registerCallback(eventName, callback) { + if ((typeof (callback) !== 'function') || (this._eventNames.indexOf(eventName) < 0)) { + return; + } + + // Prevent multiple registrations of same event with same callback + if (!this._callbacks[eventName].includes(callback)) { + this._callbacks[eventName].push(callback); + } + } + + /** + * Remove a callback for an event. + * @param {string} eventName + * @param {(...params: any[]) => void} callback + */ + removeCallback(eventName, callback) { + if ((typeof (callback) !== 'function') || (this._eventNames.indexOf(eventName) < 0)) { + return; + } + + const index = this._callbacks[eventName].indexOf(callback); + if (index > -1) { + this._callbacks[eventName].splice(index, 1); + } + } + + /** + * Trigger all callbacks for an event. + * @param {string} eventName + * @param {any[]} [params=[]] - Parameters for callback + */ + triggerCallbacks(eventName, params = []) { + for (let i = this._callbacks[eventName].length - 1; i >= 0; i--) { + const callbackFn = this._callbacks[eventName][i]; + callbackFn(...params); + } + } + + /** + * Bind functions to class. + * @param {string[]} [fns=[]] - Names of functions. + */ + bindFunctions(fns = []) { + const thisAsObject = /** @type {Object} */(this); + for (let i = 0; i < fns.length; i++) { + const fn = fns[i]; + thisAsObject[fn] = thisAsObject[fn].bind(this); + } + } + + /** + * Destroy the manager. + */ + destroy() { + this.__destroy(); + } + + /** + * Destroy the manager. + * @private + */ + __destroy() { + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/camera_follow_manager.js": +/*!*****************************************************!*\ + !*** ../eyes/src/managers/camera_follow_manager.js ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CameraFollowManager": function() { return /* binding */ CameraFollowManager; } +/* harmony export */ }); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + + + +/** + * Camera-Follow is when you're on a space object or event view and you want the camera to automatically align / follow an additional object. + * This tracking is remains dynamic whilst the followId is set. + * Although there are UI components for this (Search and Toast), the follow logic will be determined here. + * + * State notes: + * The followId, followEntity, and followName states are all set when the follow function is called. + * The targetId and targetEntity are not technically states as they are always directly attached to the current view. + */ + +/** + * CameraFollowOptions type. + * @typedef CameraFollowOptions + * @property {string} placeholder - The placeholder text for the search component. + * @property {number} maxFeatured - The maximum number of featured items to show. + * @property {number} hideSearchDelay - The delay in milliseconds to hide the search component. + * @property {number} cameraDuration - The duration in seconds for the camera animation. + */ + +/** + * + */ +class CameraFollowManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} options + */ + constructor(app, options = {}) { + super(app); + + /** + * @type {CameraFollowOptions} + * @private + */ + this._options = { + placeholder: 'Search target to follow...', + maxFeatured: 5, + hideSearchDelay: 1000, + cameraDuration: 1.5, + ...options + }; + + /** + * @type {boolean} + * @private + */ + this._isEnabled = null; + + /** + * @type {string} + * @public + */ + this.followId = null; + + /** + * @type {string} + * @public + */ + this.followName = null; + + /** + * @type {HTMLElement} + * @public + */ + this.optionElement = null; + + /** + * @type {BaseComponent} + * @public + */ + this.search = null; + + /** + * @type {Function} + * @private + */ + this._returnToPreviousCamView = null; + + /** + * Hide search timeout. + * @type {number} + * @private + */ + this._hideSearchTimeout = null; + + /** + * Store the previous entity label weights. + * @type {object} + * @private + */ + this._prevValues = { + weights: {}, + occRadii: {}, + labelsClickable: {}, + occlusion: {}, + timeLimits: { min: null, max: null } + }; + + /** + * Monitor screen resizes + */ + this._resizeObserver = new ResizeObserver(() => { + this.setYawPitchLimits(); + }); + + + /** + * We're going to add a mutation observer to the body to see when the offset has changed. + * This is because the existing callback system is not called in the expected order. + * Instead of adding a callback to the offsetPanel, we're going to add a callback to the body when the class changes. + */ + this._offsetObserver = new MutationObserver(mutations => { + mutations.forEach(mutation => { + if (mutation.attributeName === 'class') { + this.setYawPitchLimits(); + } + }); + }); + + // Create the sum parent entity. + this._sumParent = this._createSumParent(); + + // Create the reframing element. + this._createReframeElement(); + + this.bindFunctions(['update', 'setSearchOptions', 'goToPreviousCamView', 'updateOccludedEntities']); + + this.pioneer.addCallback(this.update, true); + } + + + /** + * Sets the local followId, followEntity and followName. + * Also updates the search input. + * @param {string} followId + */ + setFollowVars(followId) { + const contentManager = this.app.getManager('content'); + const { input: searchInput } = this.search?._children || {}; + + // Determine DistanceEntity properties. + const { altName, displayName, iauName } = contentManager.getEntityInfo(followId) ?? {}; + const followName = altName || displayName || iauName || ''; + + if (searchInput) { + searchInput.value = followName; + } + + // Set the local follow id and name. + this.followId = followId; + this.followEntity = followId ? this.app.scene.get(followId) : null; + this.followName = followName; + } + + /** + * Sets the toast content. + * @param {object} options + * @param {boolean} options.reset + */ + setToastContent({ reset = false } = {}) { + const toast = this.app.getComponent('toast'); + + if (reset) { + toast.hide(); + toast.setContent(''); + return; + } + + // Determine the content. + const prefix = ['Sun', 'Moon', 'ISS'].includes(this.followName) ? 'the ' : ''; + const textHtmlStr = `Camera is following ${prefix}${this.followName}`; + const buttonHtmlStr = ''; + toast.setContent(`
      ${textHtmlStr}${buttonHtmlStr}
      `); + + + // Add event listener to the button. + const { toastContent } = toast._children; + const undoButton = toastContent.querySelector('button'); + + undoButton?.addEventListener('click', () => { + this.setEnabled(false); + }); + } + + /** + * Show the toast. + */ + showToast() { + const toast = this.app.getComponent('toast'); + toast.show(); + } + + /** + * Determine whether the time limits are valid. + * Re-directs if necessary. + * @returns {object} + */ + validateTimeLimits() { + const timeManager = this.app.getManager('time'); + const currentTime = timeManager.getTime(); + const { currentView } = this.app.getManager('router'); + + // Get the position coverage for the target and follow entities in ET. + const { min: targetMinET, max: targetMaxET } = this.targetEntity?.getPositionCoverage() || {}; + const { min: followMinET, max: followMaxET } = this.followEntity?.getPositionCoverage() || {}; + + // Make sure we have all the values. + if (!targetMinET || !targetMaxET || !followMinET || !followMaxET) { + return { isValid: false }; + } + + // Get moment values. + let targetMin = isFinite(targetMinET) ? timeManager.etToMoment(targetMinET) : targetMinET; + let targetMax = isFinite(targetMaxET) ? timeManager.etToMoment(targetMaxET) : targetMaxET; + const followMin = isFinite(followMinET) ? timeManager.etToMoment(followMinET) : followMinET; + const followMax = isFinite(followMaxET) ? timeManager.etToMoment(followMaxET) : followMaxET; + + // Determine if we use the event limits. + const useEventLimits = currentView === 'event' && this.app.getView('event')._eventName; + + if (useEventLimits) { + const { min: limitMin, max: limitMax } = timeManager.getLimits() || {}; + targetMin = limitMin; + targetMax = limitMax; + } + + + // Determine the min and max times. + const minTime = Math.max(followMin, targetMin); + const maxTime = Math.min(followMax, targetMax); + + // If there is no overlap between the target limits and the followEntity limits, we cannot follow the entity. + const noOverlap = followMin > targetMax || followMax < targetMin; + if (noOverlap) { + // Display limit message + this.app.getComponent('clock')?.setLimitMessage(null, 'Entity timelines do not overlap'); + this.setEnabled(false); + return { isValid: false }; + } + + // If the current time is not within the followMin and followMax, go to the min time. + const updateTime = currentTime < followMin || currentTime > followMax; + if (updateTime) { + const time = timeManager.getTimeUrl(minTime); + this.app.getManager('router').navigate({ time }); + } + + return { + isValid: true, + minTime, + maxTime + }; + } + + /** + * Activates the camera follow, given the followId. + * @param {string} followId + */ + async follow(followId) { + // Get current and prev targets. + const { currentRoute, previousRoute } = this.app.getManager('router'); + const { params: prevParams } = previousRoute || {}; + const { params } = currentRoute || {}; + const { spaceObject: prevTargetId } = prevParams || {}; + const { spaceObject: targetId } = params || {}; + const { cameraDuration } = this._options; + + // Set enabled. + this._isEnabled = true; + + // Make sure the search is initialized. + !this.search && this.initSearch(); + + // If there was a previous followId, reset the label weight. + this.followId && this.setLabelWeight(this.followId, true); + + // If there was a previous followId, reset the time limits. + this.setTimeLimits({ reset: true }); + + // If there was a different previous targetId, reset the occlusion radius, and clickable state. + if (prevTargetId && prevTargetId !== targetId) { + this.setTargetNotClickable(prevTargetId, true); + } + + // Force entity visible. + this.app.getManager('scene').setEntitiesForceVisible([followId]); + + // Update the follow vars. + this.setFollowVars(followId); + + // Make sure it doesn't fade. + const divComponent = this.followEntity?.get('div'); + divComponent.setFadeWhenCloseToEntity(false); + + /** + * Trigger the radio button selection in the content panel + * (when just changing the query, onRouteChange in the view options block is not triggered) + */ + this.triggerViewOptionUpdate(); + + // Set the toast content. + this.setToastContent(); + + // Start observing the body for offset class changes. + this._offsetObserver.observe(document.body, { attributes: true }); + + // Start observing the body for resize changes. + this._resizeObserver.observe(document.body); + + // Wait for the entities to be in place. + await this.entitiesInPlace(); + + // Determine validity of the time limits. + const { isValid, minTime, maxTime } = this.validateTimeLimits(); + + // Return if not valid or no longer enabled. + if (!isValid || !this.isEnabled) { + return; + } + + // Add parentChanged callbacks. + this.setParentsChangedCallbacks(); + + + const startAnimation = () => { + // We need to pause time to prevent weird offsets. + const timeManager = this.app.getManager('time'); + timeManager.pause(); + + // Show the toast. + if (this.followName) { + this.showToast(); + } + + + // Animate camera and apply remaining settings. + this.animateCamera(cameraDuration) + .then(() => { + // Resume time. + timeManager.play(); + + // If it's been disabled, return early. + if (!this._isEnabled) { + return false; + } + + // Set the time limits. + this.setTimeLimits({ minTime, maxTime }); + + // Set the yaw and pitch limits. + this.setYawPitchLimits(); + + // Set higher label weight for the followId. + this.setLabelWeight(this.followId); + + // Update occluded entities. + this.updateOccludedEntities(); + + // Make sure target is not clickable + this.setTargetNotClickable(this.targetId); + + // Hide content panel of we're on mobile. + _internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobile() && this.app.getComponent('contentPanel')?.hide(); + + // Hide the search. + this.hideSearch(); + + return true; + }) + .catch(e => e); + }; + + // If viewOptionsBlock is already loaded, trigger animation, otherwise wait for it to load. + const { isLoaded, onLoaded } = this.app.getComponent('viewOptionsBlock'); + isLoaded ? startAnimation() : onLoaded.push(startAnimation); + } + + /** + * Stop the follow and reset the state. + */ + unfollow() { + const { previousRoute, currentView } = this.app.getManager('router'); + const { params } = previousRoute || {}; + const { spaceObject: prevTargetId } = params || {}; + + // Reset the toast. + this.setToastContent({ reset: true }); + + // Reset label weights. + this.setLabelWeight(this.followId, true); + + // Reset occluded entities + this.updateOccludedEntities({ reset: true }); + + // Reset target clickable. + this.setTargetNotClickable(prevTargetId, true); + + // Remove parentChanged callbacks. + const prevTargetEntity = this.app.scene.get(prevTargetId); + this.setParentsChangedCallbacks({ targetEntity: prevTargetEntity, reset: true }); + + // Reset follow vars. + this.setFollowVars(null); + + // Reset search options + this.setSearchOptions({ reset: true }); + + // Stop observing the body for offset class changes. + this._offsetObserver.disconnect(); + + // Stop observing the body for resize changes. + this._resizeObserver.disconnect(); + } + + /** + * There are 2 animations that occur simultaneously. + * The first is animating the position, alignment, and parenting of the sum parent. + * The second is calling followEntity from the camera manager. + * @param {number} duration + * @returns {Promise} + */ + animateCamera(duration) { + // Clear controllers. + this._sumParent.clearControllers(); + + // Calculate the sumParent distance according to the target entity's extents radius + const sumParentDist = this.targetEntity?.getExtentsRadius() || 0.1; + + // Add a position sum controller to the sumParent, using the target and follow entities + const psController = this._sumParent.addControllerByClass(pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.PositionSumController); + psController.addEntity(this.targetId, 1, 0); + psController.addEntity(this.followId, 0, -sumParentDist); + + // Add an align controller to the camLockParent, using the source entity + const alignController = this._sumParent.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController); + alignController.setPrimaryAlignType('point'); + alignController.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis); + alignController.setPrimaryTargetEntity(this.targetId); + + // Add and setup the transition controller. + const transitionController = this._sumParent.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TransitionController); + transitionController.setTransitionTime(duration); + transitionController.setParent(this.targetId); + + const { _easeOutExpoTransition: transitionFunction } = this.app.cameraScripts; + transitionController.setTransitionFunction(transitionFunction); + + // Call followEntity + const camManager = this.app.getManager('camera'); + return camManager.followTheEntity(this.targetId, this.followId, this._sumParent.getName(), duration); + } + + + /** + * When the parent of the followEntity changes, we need to update the sumParent. + * @param {object} options + * @param {Entity} options.targetEntity + * @param {boolean} options.reset + */ + setParentsChangedCallbacks({ targetEntity = this.targetEntity, reset = false } = {}) { + if (reset) { + // Remove the parent changed callback for the targetEntity. + targetEntity?.removeParentChangedCallback(this.updateOccludedEntities); + this.followEntity?.removeParentChangedCallback(this.updateOccludedEntities); + return; + } + + // Set the parent changed callback for the targetEntity. + targetEntity?.addParentChangedCallback(this.updateOccludedEntities); + this.followEntity?.addParentChangedCallback(this.updateOccludedEntities); + } + + /** + * Sets the label weight to high value or previous value + * @param {string} id + * @param {boolean} resetToPrevious + * @param {string} weight + */ + setLabelWeight(id, resetToPrevious = false, weight = '201') { + const labelManager = this.app.getManager('label'); + const currWeight = labelManager.getWeight(id); + + // Create the weight if it doesn't exist. + if (currWeight === 0) { + labelManager._weights[id] = {}; + } + + if (resetToPrevious) { + if (this._prevValues.weights[id]) { + labelManager._weights[id].weight = this._prevValues.weights[id]; + delete this._prevValues.weights[id]; + } + } + else { + labelManager._weights[id].weight = weight; + this._prevValues.weights[id] = currWeight; + } + } + + /** + * Update the occluded and unnoccluded entities. + * @param {object} options + * @param {boolean} options.reset + */ + updateOccludedEntities({ reset = false } = {}) { + const entitiesToUnocclude = !reset && this.getEntitiesToUnocclude(); + this.setOcclusionProps(entitiesToUnocclude); + } + + /** + * Determine which entities should not be occluding. + * @returns {string[]} + */ + getEntitiesToUnocclude() { + const followParent = this.followEntity?.getParent()?.getName(); + const targetParent = this.app.scene.get(this.targetId)?.getParent()?.getName(); + const entitiesToSet = [this.followId, followParent, this.targetId, targetParent]; + + // Return unique entities. + return [...new Set(entitiesToSet)].filter(Boolean); + } + + /** + * Store the canOcclude value for the entity, then set it to false. + * If resetting, set the canOcclude value back to the stored value. + * @param {string[]} entitiesToUnocclude + */ + setOcclusionProps(entitiesToUnocclude) { + const { occlusion } = this._prevValues; + + // Reset all stored occlusion values. + Object.keys(occlusion).forEach(entityId => { + const entity = this.app.scene.get(entityId); + entity?.setCanOcclude(occlusion[entityId]); + }); + + // Clear the occlusion object. + this._prevValues.occlusion = {}; + + // Store the canOcclude value for the entity, then set it to false. + entitiesToUnocclude?.length && entitiesToUnocclude.forEach(entityId => { + const entity = this.app.scene.get(entityId); + if (!entity) { + return; + } + + // Store the canOcclude value. + this._prevValues.occlusion[entityId] = entity.canOcclude(); + + // Set the canOcclude value to false. + entity.setCanOcclude(false); + }); + } + + /** + * The current target should not be clickable as the follow target. + * @param {string} entityId + * @param {boolean} resetToPrevious + */ + setTargetNotClickable(entityId, resetToPrevious = false) { + const labelManager = this.app.getManager('label'); + const label = labelManager._labels[entityId]; + if (!label) { + return; + } + + const { labelsClickable } = this._prevValues; + + if (resetToPrevious) { + if (labelsClickable[entityId] !== undefined) { + labelManager.setLabelClickable(entityId, labelsClickable[entityId]); + delete labelsClickable[entityId]; + } + } + else { + // Make sure the label is not clickable. + labelsClickable[entityId] = label.isClickable; + labelManager.setLabelClickable(entityId, false); + } + } + + /** + * Create a reframing element. + */ + _createReframeElement() { + const { staticElement } = this.app; + + const elementExists = staticElement.querySelector('.follow-reframe'); + if (elementExists) { + return; + } + + this._reframeElement = document.createElement('div'); + this._reframeElement.classList.add('follow-reframe'); + + staticElement.appendChild(this._reframeElement); + } + + /** + * Create the camLockParent entity. + * @returns {Entity} + */ + _createSumParent() { + const sumParentName = 'follow_sum_parent'; + + // Create the between position entity. + const sumParentEntity = pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.Entity.createFromOptions(sumParentName, { parents: [] }, this.app.scene); + + // Make sure it's positioned at zero (the source). + sumParentEntity.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero); + sumParentEntity.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity); + + return sumParentEntity; + } + + + /** + * Appends the search component element to the optionElement. + * @param {HTMLElement} optionElement + */ + initSearch(optionElement) { + if (!this.search) { + this.search = this.app.getComponent('cameraFollowSearch'); + + // Add a listener to the search element so we can catch the event before it bubbles up. + this.search.element.addEventListener('click', e => { + e.stopPropagation(); + }); + + // Set the placeholder text. + const { placeholder } = this._options; + const { input: searchInput } = this.search._children; + searchInput && searchInput.setAttribute('placeholder', placeholder); + + // Set the default info text. + const defaultInfo = 'related'; + this.search._config.infoText.default = defaultInfo; + this.search.setState({ searchInfo: defaultInfo }); + } + + // Append the search element to the optionElement if passed. + if (optionElement) { + optionElement.appendChild(this.search.element); + this.search.setParent(optionElement); + } + } + + /** + * Show and open the search component. + */ + showSearch() { + this.stopHideTimeout(); + this.search?.show(); + this.search?.open(); + } + + /** + * Hide and close the search component. + */ + hideSearch() { + this.search?.hide(); + this.search?.close(); + } + + /** + * Trigger radio button selection in viewOptionsBlock once it's loaded. + */ + triggerViewOptionUpdate() { + const viewOptionsBlock = this.app.getComponent('viewOptionsBlock'); + const { isLoaded, onLoaded } = viewOptionsBlock; + + const triggerSelection = () => { + const { _currentView: currentSelection, selectCameraView, setOptionInnerHTML } = viewOptionsBlock; + currentSelection !== 'cameraFollow' && selectCameraView('cameraFollow'); + // Update the inner HTML. + setOptionInnerHTML('cameraFollow', this.followInnerHtml); + }; + + // If viewOptionsBlock is already loaded, trigger radio button selection. + isLoaded ? triggerSelection() : onLoaded.push(triggerSelection); + } + + /** + * Set the previous camera view return function. + */ + setReturnToPreviousCamView() { + // Set reference to previous view if it's not already cameraFollow + const viewOptionsBlock = this.app.getComponent('viewOptionsBlock'); + const { _currentView: prevView } = viewOptionsBlock; + if (prevView !== 'cameraFollow') { + const { optionTitle } = viewOptionsBlock._viewOptionsList.find(({ id }) => id === prevView) || {}; + + // Set function to return to previous view. + this._returnToPreviousCamView = () => viewOptionsBlock.selectCameraView(optionTitle); + } + } + + /** + * Navigate to the previous camera view and reset the function to null. + */ + goToPreviousCamView() { + typeof this._returnToPreviousCamView === 'function' && this._returnToPreviousCamView(); + this._returnToPreviousCamView = null; + } + + /** + * Sets time limits. + * @param {object} params + * @param {import('moment').Moment} params.minTime + * @param {import('moment').Moment} params.maxTime + * @param {boolean} params.reset + */ + setTimeLimits({ minTime, maxTime, reset = false } = {}) { + const timeManager = this.app.getManager('time'); + + if (!reset) { + // Store the current time limits. + const { min, max } = timeManager.getLimits(); + this._prevValues.timeLimits = { min, max }; + + // Set time limits. + timeManager.setMin(minTime); + timeManager.setMax(maxTime); + } + else { + // Reset the time limits. + const { min, max } = this._prevValues.timeLimits; + + if (min !== null && max !== null) { + timeManager.setMin(min); + timeManager.setMax(max); + } + } + } + + + /** + * Set the yaw and pitch limits for the orbit controller. + */ + setYawPitchLimits() { + const isOffsetRight = document.body.classList.contains('offset-right'); + const isOffsetUp = document.body.classList.contains('offset-up'); + + const cameraEntity = this.app.scene.get('camera'); + // Camera field of view. + const camComponent = cameraEntity.getComponentByType('camera'); + const hFov = camComponent.getHorizontalFieldOfView(); + const vFov = camComponent.getVerticalFieldOfView(); + const orbitController = cameraEntity.getControllerByType('orbit'); + + if (!orbitController) { + return; + } + + // If the content is expanded, we need to know if it's offset vertically of horizontally. + const yawOffset = isOffsetRight ? hFov * 0.05 : 0; + const pitchOffset = isOffsetUp ? vFov * 0.2 : 0; + + // YaW center-point is -Math.PI/2 + const yawCP = Math.PI * -0.5; + const yawLimitDiff = hFov * 0.45; + const pitchLimitDiff = vFov * 0.4; + + const yawMin = yawCP - yawLimitDiff + yawOffset; + const yawMax = yawCP + yawLimitDiff - yawOffset; + const pitchMin = -pitchLimitDiff + pitchOffset; + const pitchMax = pitchLimitDiff - pitchOffset; + + orbitController.setYawAngleLimits(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(yawMin, yawMax)); + orbitController.setPitchAngleLimits(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(pitchMin, pitchMax)); + } + + /** + * Set specific search options for current target. + * @param {object} options + * @param {string} options.targetId + * @param {string} options.followId + * @param {boolean} options.reset + */ + async setSearchOptions({ targetId = this.targetId, followId = this.followId, reset = false } = {}) { + if (reset) { + // Set search excludeResults list. + this.search?.setExcludeResults([]); + return; + } + + // Await entities. + await this.entitiesInPlace(); + + // Determine entity list. + const entityList = [targetId, followId].filter(Boolean); + + const { maxFeatured } = this._options; + // Build list of featured suggestions. + const allRelated = []; + + // Get the parent/ancestor and featured moon details at the current time if available. + const timeManager = this.app.getManager('time'); + const time = timeManager.getTime(); + const etTime = timeManager.momentToET(time); + const targetEntity = this.targetEntity || this.app.scene.get(targetId); + + const ancestorId = this.followEntity + ? targetEntity.getLowestCommonAncestorAtTime(this.followEntity, etTime)?.getName() + : targetEntity.getParentAtTime(etTime); + + const contentManager = this.app.getManager('content'); + const { featuredMoons = [] } = ancestorId ? await contentManager.getEntityDesc(ancestorId).catch(() => ({})) : {}; + + // After the await, return early if no entities or if we're no longer enabled. + if (!entityList.length || !this.isEnabled) { + return; + } + + allRelated.push(ancestorId, ...featuredMoons); + + // Get the entity description from the current view. + const { currentView } = this.app.getManager('router'); + const { _entityDesc, _eventDesc } = this.app.getView(currentView); + const { related: descRelated = [] } = _entityDesc || {}; + const { related: eventRelated = [] } = _eventDesc || {}; + allRelated.push(...descRelated, ...eventRelated); + + // Always add the sun at the end. + allRelated.push('sun'); + + // Remove duplicates. + const uniqueRelated = [...new Set(allRelated)]; + + // Remove the targetId and followId from the list. + const filteredRelated = uniqueRelated.filter(entityName => ![targetId, followId].includes(entityName)); + + // Limit the number of featured items. + const limitedRelated = filteredRelated.slice(0, maxFeatured); + + // Map to text and url. + const featuredItems = limitedRelated.map(entityName => { + const { id, iauName, displayName } = this.app.getManager('content')?.getEntityInfo(entityName) || {}; + const text = displayName || iauName; + + // Rreturn false if no id or text. + if (!id || !text) { + return false; + } + + return { text, url: `/${id}` }; + }).filter(Boolean); + + // Set search excludeResults list. + this.search?.setExcludeResults(entityList); + + // Set search featured suggestions. + this.search?.setupFeaturedSuggestion(featuredItems); + } + + /** + * Awaits for target and follow entities to be in place. + * Maybe be required multiple times, as some functions are called from different places. + */ + async entitiesInPlace() { + const entityList = [this.targetId, this.followId].filter(Boolean); + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.SceneHelpers.waitTillEntitiesInPlace(this.app.scene, entityList); + } + + /** + * Update is called every frame. + */ + update() { + const offset = this._pioneer.getInput().getDraggedOffset(); + const isDragging = !offset.isZero(); + const isFollowing = this.followId; + + if (!isFollowing) { + return; + } + + // Toggle the following-dragging class on the dynamicElement. + const { staticElement } = this.app; + staticElement.classList.toggle('follow-dragging', isDragging); + + // Show the toast again if dragging. + isDragging && this.showToast(); + } + + /** + * Sets whether the cam follow is enabled and ready to follow. + * This will essentially show or hide the search component. + * The boolean is also used in the link manager to determine how to handle links. + * @param {boolean} enabled + * @param {object} params + * @param {boolean} params.resetCam + * @param {boolean} params.resetLimits + * @param {boolean} params.removeQueries + */ + setEnabled(enabled, { resetCam = true, resetLimits = true, removeQueries = true } = {}) { + const alreadyEnabled = this._isEnabled; + this._isEnabled = enabled; + + const { currentRoute, currentView } = this.app.getManager('router'); + const { params } = currentRoute || {}; + + // Make sure the search is initialized. + !this.search && this.initSearch(); + + if (enabled) { + // Set the return to previous view function + this.setReturnToPreviousCamView(); + + // Determine whether to show the search. + const showSearch = !this.followId || alreadyEnabled; + showSearch && this.showSearch(); + + // If we're already following something, we can trigger the hideSearch timeout. + this.followId && this.setHideTimeout(); + } + else if (alreadyEnabled) { + // Go to the previous cam view if resetCam + resetCam && this.goToPreviousCamView(); + + // If we're following something, unfollow it. + this.followId && this.unfollow(); + + // Reset stored time limits + resetLimits && this.setTimeLimits({ reset: true }); + + // Remove the followId, tie and rate queries from the URL. + removeQueries && this.app.getManager('router').navigate({ __remove: ['followId', 'time', 'rate'] }); + + // Hide the search + this.hideSearch(); + + // Reset the viewOptionsBlock inner HTML. + this.app.getComponent('viewOptionsBlock').setOptionInnerHTML('cameraFollow', this.followInnerHtml); + } + } + + /** + * Set a timeout to hide the search. + */ + setHideTimeout() { + // Stop the existing timeout. + this.stopHideTimeout(); + + // Set a new timeout. + this._hideSearchTimeout = setTimeout(() => { + this.hideSearch(); + this.stopHideTimeout(); + }, this._options.hideSearchDelay); + } + + /** + * Stop the hide search timeout. + */ + stopHideTimeout() { + clearTimeout(this._hideSearchTimeout); + this._hideSearchTimeout = null; + } + + /** + * Gets the targetId from the current view. + * @returns {string} + */ + get targetId() { + const { currentView } = this.app.getManager('router'); + const { _target } = this.app.getView(currentView); + return _target; + } + + /** + * Gets the target entity from the current view. + * @returns {Entity} + */ + get targetEntity() { + return this.app.scene.get(this.targetId); + } + + /** + * Returns the inner html for the follow name. + * @returns {string} + */ + get followInnerHtml() { + return this.followName ? `Following ${this.followName}` : 'Follow Target'; + } + + /** + * Gets whether the cam follow is enabled. + * @returns {boolean} + */ + get isEnabled() { + return this._isEnabled; + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/camera_manager.js": +/*!**********************************************!*\ + !*** ../eyes/src/managers/camera_manager.js ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CameraManager": function() { return /* binding */ CameraManager; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + + +/** + * Callback for 3D object selection. + * @callback selectionCallback + * @callback TransitionFunction + * @param {Pioneer.Entity} entity + */ + +/** + * Callback for after camera transition. + * @callback transitionCallback + * @param {string} id + * @param {Pioneer.Scene} scene + */ + +/** + * @typedef ContextBase + * @property {string} id + * @property {number} [context] + */ + +/** + * @typedef {ContextBase & Object} Context + */ + +/** + * @typedef OrbitKeyframePositionOption + * @property {number} frame + * @property {Pioneer.Vector3} position + * @property {string} relativeTo + */ + +/** + * @typedef OrbitKeyframeUpOption + * @property {number} frame + * @property {Pioneer.Vector3} up + */ + +/** + * @typedef OrbitKeyframeFocusOption + * @property {number} frame + * @property {string} name + */ + +/** + * @typedef OrbitKeyframeOptions + * @property {OrbitKeyframePositionOption[]} position + * @property {OrbitKeyframeUpOption[]} up + * @property {OrbitKeyframeFocusOption[]} focus + */ + +/** + * Camera Manager class. + * @extends BaseManager + */ +class CameraManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app - Main app + * @param {Pioneer.Scene} scene - The default scene to use + */ + constructor(app, scene) { + super(app); + + /** + * Default viewport. + * @type {Pioneer.Viewport} + */ + this._viewport = null; + + /** + * Default scene to use in the camera. + * Can be overriden in some functions. + * @type {Pioneer.Scene} + */ + this._defaultScene = scene; + + /** + * The default camera Entity. + * @type {Pioneer.Entity} + */ + this._cameraEntity = null; + + /** + * // TODO: We should update this in this class + * Camera target id. + * @type {string} + */ + this._id = null; + + /** + * // TODO: We should update this in this class + * Camera previous target id. + * @type {string} + */ + this._previousId = null; + + /** + * Camera context object + * @type {Context} - context.id is required + */ + this._context = { id: '' }; + + /** + * Internal variable to keep track of the transition status of the camera. + * @type {boolean} + */ + this._isTransitioning = false; + + /** + * The default maximum distance for zooming out. + * @type {number} + */ + this._defaultMaxDistance = 2.0e18; + + /** + * A selection callback to be called on an object click after camera transition. + * @type {selectionCallback} + */ + this._selectionCallback = null; + + /** + * Dynamic environment map component. + * @type {Pioneer.DynamicEnvironmentMapComponent} + */ + this._dynEnvMap = null; + + /** + * Camera is in free fly. + * @type {boolean} + * @default + */ + this._isFreeFly = false; + + /** + * Zoom sensitivity for zoom functions. + * @type {{ click: number, hold: number }} + * @default + */ + this._zoomSensitivity = { + click: 0.3, + hold: 0.1 + }; + + this._fullLightColor = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1); + this._shadowLightColor = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(0.15, 0.15, 0.15, 1); + + this.bindFunctions(['zoomIn', 'zoomOut', 'addDynamicEnvMap', 'getShadowLightColor', 'getFullLightColor']); + } + + /** + * Creates camera and viewport. + * @param {Pioneer.Scene} scene + */ + createViewportAndCamera(scene) { + if (scene) { + this._defaultScene = scene; + } + + // Create main viewport + if (this.pioneer.getViewport('main-viewport') === null) { + this._viewport = this.pioneer.addViewport('main-viewport'); + this._viewport.getDiv().style.width = '100%'; + this._viewport.getDiv().style.height = '100%'; + this._viewport.getDiv().style.left = '0'; + this._viewport.getDiv().style.top = '0'; + } + + // Create camera entity + if (this._defaultScene.get('camera') === null) { + this._cameraEntity = this._defaultScene.addEntity('camera'); + } + + // Create camera component + this._cameraEntity.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + let camera = /** @type {Pioneer.CameraComponent} */(this._cameraEntity.getComponentByType('camera')); + if (camera === null) { + camera = /** @type {Pioneer.CameraComponent} */(this._cameraEntity.addComponent('camera')); + } + this._viewport.setCamera(camera); + + // Create camera light component + this._cameraLight = /** @type {Pioneer.LightSourceComponent} */(this._cameraEntity.get('lightSource')); + if (this._cameraLight === null) { + this._cameraLight = /** @type {Pioneer.LightSourceComponent} */(this._cameraEntity.addComponent('lightSource')); + this._cameraLight.setEnabled(false); + this.toggleCameraLight(true, this._shadowLightColor); + } + + // Add dynamic env map + if (this._dynEnvMap === null) { + this._dynEnvMap = /** @type {Pioneer.DynamicEnvironmentMapComponent} */(this._cameraEntity.addComponent('dynEnvMap')); + } + } + + /** + * Returns camera context object. + * @returns {object} + */ + getContext() { + return this._context; + } + + /** + * Return isTransitioning + * @returns {boolean} + */ + getIsTransitioning() { + return this._isTransitioning; + } + + /** + * set isTransitioning + * @param {boolean} isTransitioning + */ + setIsTransitioning(isTransitioning) { + this._isTransitioning = isTransitioning; + } + + /** + * Wait until transition completes + * @returns {Promise} + */ + waitForTransitionComplete() { + return new Promise(resolve => { + let transitionCheckInterval = setInterval(() => { + // Resolve once transition is complete + if (!this._isTransitioning) { + clearInterval(transitionCheckInterval); + transitionCheckInterval = null; + + resolve(true); + } + }, 1000); + }); + } + + /** + * Sets camera context. + * @param {Object & { id: string }} context - id required + */ + setContext(context) { + this._context = context; + this._previousId = this._id; + this._id = this._context.id; + + const event = new CustomEvent('cameraupdate', { detail: { target: this._id, context: this._context } }); + window.dispatchEvent(event); + } + + /** + * Gets the current camera target id. + * @returns {string} + */ + getCurrentId() { + return this._id; + } + + /** + * Gets the shadow light color + * @returns {Pioneer.Color} Returns the shadow light color + */ + getShadowLightColor() { + return this._shadowLightColor; + } + + /** + * Gets the full light color + * @returns {Pioneer.Color} Returns the full light color + */ + getFullLightColor() { + return this._fullLightColor; + } + + /** + * Gets the default main scene. + * @returns {Pioneer.Scene} + */ + get defaultScene() { + return this._defaultScene; + } + + /** + * Gets the main camera entity. + * @returns {Pioneer.Entity} + */ + get cameraEntity() { + return this._cameraEntity; + } + + /** + * Gets default camera light + * @returns {Pioneer.LightSourceComponent} + */ + get cameraLight() { + return this._cameraLight; + } + + /** + * Gets dynamic environment map + * @returns {Pioneer.DynamicEnvironmentMapComponent} + */ + get dynamicEnvMap() { + return this._dynEnvMap; + } + + /** + * Toggles main camera light. + * @param {boolean} active + * @param {Pioneer.Color} color + */ + toggleCameraLight(active, color) { + if (this._cameraLight !== null) { + this._cameraLight.setEnabled(active); + if (color !== undefined) { + this._cameraLight.setColor(color); + } + } + } + + /** + * Gets the selection callback on an object click after camera transition. + * @returns {Function} + */ + getSelectionCallback() { + return this._selectionCallback; + } + + /** + * Sets the selection callback to be called on an object click after camera transition. + * @param {selectionCallback} callback - Callback function with parameter entity clicked + */ + setSelectionCallback(callback) { + if (typeof callback === 'function') { + this._selectionCallback = callback; + } + } + + /** + * Enter free fly mode. + */ + enterFreeFly() { + if (this._context && this._context.id && this._context.id != "") cameraFreeFlyParameters.context = this._context; + else cameraFreeFlyParameters.context.id = "inner_solar_system"; + this._isFreeFly = true; + this._cameraEntity.clearControllers(); + this._cameraEntity.addController('freeFly'); + this._cameraEntity.addController('look'); + this._cameraEntity.addController('roll'); + } + + // /** + // * Exit free fly mode. + // */ + // async exitFreeFly() { + // this._isFreeFly = false; + // switch (this._context.context) { + // case CameraScripts.CONTEXT.CELESTIAL_OBJECT: + // await this.app.cameraScripts.goToCelestialObject(this._id); + // break; + // case CameraScripts.CONTEXT.SPACECRAFT: + // await this.app.cameraScripts.goToSpacecraft(this._id); + // break; + // case CameraScripts.CONTEXT.INSTRUMENT: + // await this.app.cameraScripts.goToInstrument(this._id); + // break; + // case CameraScripts.CONTEXT.ALIGN_SPACECRAFT: + // await this.app.cameraScripts.alignSpacecraftPlanet(this._id); + // break; + // case CameraScripts.CONTEXT.LOCATION: + // await this.app.cameraScripts.showLocation(this._id, '', '', this._context['options']); + // break; + // case CameraScripts.CONTEXT.SYSTEM: + // await this.app.cameraScripts.goToSystem(this._id); + // break; + // case CameraScripts.CONTEXT.LOOK_AT: + // await this.app.cameraScripts.spacecraftLookAtTarget(this._id, this._context['target']); + // break; + // case CameraScripts.CONTEXT.LOCKED_ON: + // await this.app.cameraScripts.spacecraftLockedOnTarget(this._id, this._context['target']); + // break; + // default: + // console.error('exitFreeFly: Unsupported camera context - ' + this._context.context); + // break; + // } + // } + + exitFreeFly() { + this._isFreeFly = false; + this._cameraEntity.clearControllers(); + flyTo(cameraFreeFlyParameters.context.id); + } + + /** + * Toggle free fly mode. + */ + toggleFreeFly() { + if (this._isFreeFly) { + this.exitFreeFly(); + } + else { + this.enterFreeFly(); + } + } + + /** + * Internal go to entity function. + * Must be called by all other camera transitions. + * @param {string} id + * @param {object} options + * @param {Pioneer.Entity} [options.camera = undefined] - Camera entity to use + * @param {Pioneer.Scene} [options.scene = undefined] - Scene to use + * @param {Pioneer.Vector3} [options.destination = undefined] - Custom position vector for the camera + * @param {number} [options.distance = undefined] - Specify distance from target + * @param {boolean} [options.cinematic = false] - Activate cinematic component + * @param {number} [options.minRadius = undefined] - Specify minimum distance from target + * @param {number} [options.maxRadius = undefined] - Specify maximum distance from target + * @param {number} [options.duration = undefined] - Duration of the transition + * @param {Pioneer.Vector3} [options.destinationUp = undefined] - Custom up vector + * @param {boolean} [options.zoom = true] - Activate zoom component + * @param {boolean} [options.select = true] - Activate selection component + * @param {boolean} [options.slowWhenCloseToParent = true] - Activate selection component + * @param {boolean} [options.useSpheroidRadiusForDistance = false] - Activate selection component + * @param {boolean} [options.roll = false] - Activate selection component + * @param {OrbitKeyframeOptions} [options.keyframes = undefined] - Custom orbit key frames + * @param {TransitionFunction} [options.transitionFunction = undefined] + */ + async goToEntity(id, { + camera = undefined, scene = undefined, destination = undefined, distance = undefined, cinematic = false, minRadius = 0.001, maxRadius = this._defaultMaxDistance, duration = 0.75, destinationUp = undefined, zoom = true, select = true, + slowWhenCloseToParent = true, useSpheroidRadiusForDistance = false, roll = false, keyframes = undefined, transitionFunction = undefined + } = {}) { + // Pre transition checks + const cameraEntity = camera || this._cameraEntity; + const currentScene = scene || this._defaultScene; + + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(currentScene, [id]); + + this._isTransitioning = true; + if (destination !== undefined) { + const checkDist = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + checkDist.sub(cameraEntity.getPosition(), destination); + + const cameraParent = cameraEntity.getParent(); + if (cameraParent !== null) { + const cameraParentName = cameraParent.getName(); + + // Adjust duration + if (!isNaN(checkDist.magnitude())) { + // Use the distance to reach the new destination compared to the distance to target ratio + const factor = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(checkDist.magnitude() / cameraEntity.getPosition().magnitude()); + // Do not use less than the original duration divided by 5 + duration = Math.max(duration / 5, duration * factor); + } + + // If already at destination dont launch transition + if (!isNaN(checkDist.magnitude()) && checkDist.magnitude() <= 0.001 && id === cameraParentName) { + this._isTransitioning = false; + return; + } + } + } + + try { + // Run through keyframes + if (keyframes !== undefined) { + // Setup the orbit keyframe controller + cameraEntity.clearControllers(); + const orbitKeyframe = /** @type {Pioneer.OrbitKeyframeController} */(cameraEntity.addController('orbitKeyframe')); + if (keyframes.position) { + for (let i = 0; i < keyframes.position.length; i++) { + const frameData = keyframes.position[i]; + orbitKeyframe.setPositionKeyframe(frameData.frame, frameData.position, frameData.relativeTo); + } + } + if (keyframes.up) { + for (let i = 0; i < keyframes.up.length; i++) { + const frameData = keyframes.up[i]; + orbitKeyframe.setUpKeyframe(frameData.frame, frameData.up); + } + } + if (keyframes.focus) { + for (let i = 0; i < keyframes.focus.length; i++) { + const frameData = keyframes.focus[i]; + orbitKeyframe.setFocusKeyframe(frameData.frame, frameData.name); + } + } + await orbitKeyframe.getEndPromise(); + cameraEntity.clearControllers(); + } + + // Go to entity + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.goToEntity(cameraEntity, currentScene.getEntity(id), { + destination, + distance, + up: false, + duration, + destinationUp, + zoom, + transitionFunction + }); + + // Add a select controller for selection + if (select) { + const selectController = /** @type {Pioneer.SelectController} */(cameraEntity.addController('select')); + // Set callback on 3D object click + if (this._selectionCallback !== null) { + selectController.setCallback(this._selectionCallback); + } + } + + const orbit = cameraEntity.get('orbit'); + if (orbit instanceof pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitController) { + orbit.slowWhenCloseToParent(slowWhenCloseToParent); + } + + const zoomController = cameraEntity.get('zoom'); + // Zoom clamping + if (zoomController) { + if (zoomController instanceof pioneer__WEBPACK_IMPORTED_MODULE_0__.ZoomController) { + zoomController.setDistanceClamp(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(minRadius, maxRadius)); + zoomController.setUseSpheroidRadiusForDistance(useSpheroidRadiusForDistance); + } + } + + if (roll) { + const rollController = cameraEntity.get('roll'); + if (!(rollController instanceof pioneer__WEBPACK_IMPORTED_MODULE_0__.RollController)) { + cameraEntity.addController('roll'); + } + } + + // Cinematic controller + if (cinematic) { + const align = cameraEntity.getControllerByType('align'); + const spin = cameraEntity.addController('spin', undefined, align); + if (spin instanceof pioneer__WEBPACK_IMPORTED_MODULE_0__.SpinController) { + spin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, true); + spin.setRate(0.01); + spin.setUsingRealTime(true); + spin.setRotatingPosition(true); + } + const tap = cameraEntity.addController('tap'); + if (tap instanceof pioneer__WEBPACK_IMPORTED_MODULE_0__.TapController) { + tap.setTapCallback(() => { + cameraEntity.removeController(spin); + cameraEntity.removeController(tap); + }); + } + } + } + catch (err) { + if (err) { + console.error(err); + } + } + finally { + this._isTransitioning = false; + } + } + + /** + * Make camera follow the followId entity. + * Assumes entities are in place. + * @param {string} targetId + * @param {string} followId + * @param {string} sumParentId + * @param {number} duration + */ + async followTheEntity(targetId, followId, sumParentId, duration) { + const targetEntity = this._defaultScene.getEntity(targetId); + const followEntity = this._defaultScene.getEntity(followId); + + + // Clear controllers. + this.cameraEntity.clearControllers(); + + const dest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + // Get norm vector from followEntity to target + targetEntity.getPositionRelativeToEntity(dest, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, followEntity); + + /** + * Calculate the up distance - it needs to be high enough to view the followed entity. + * The tan of the angle is the extents radius divided by the distance. + * The larger the extents radius, the further up the camera needs to be to see the followed entity. + */ + const camHeight = targetEntity.getExtentsRadius() * 1.25; + const distanceBetween = dest.magnitude(); + const angleRadians = Math.atan(camHeight / distanceBetween); + + const closestCamDistance = targetEntity.getExtentsRadius() * 5; + const camDistFromFollowed = distanceBetween + closestCamDistance; + const upDistance = Math.tan(angleRadians) * camDistFromFollowed; + + + dest.normalize(dest); + + + const scUp = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 1); + + const scParent = targetEntity.getParent(); + if (scParent) { + scParent.getOrientation().getAxis(scUp, 2); + if (scParent.getName() === followId) { + const objectOrbitOri = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + const dynController = /** @type {Pioneer.DynamoController} */(this.pioneer.get('main', followId, 'dynamo')); + + // If we have dynamo for the parent take the orbit orientation for the up vector. + if (dynController) { + dynController.getOrbitOrientation(objectOrbitOri, this.pioneer.getTime()); + objectOrbitOri.getAxis(scUp, 2); + } + + // Reset up vector if it's NaN + scUp.isNaN() && scUp.copy(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 1)); + } + else { + // Get parent up + scParent.getOrientation().getAxis(scUp, 2); + } + } + scUp.normalize(scUp); + + // If destination vector is too close to zero + if (dest.magnitude() < 0.0001) { + targetEntity.getOrientation().getAxis(dest, 0); + dest.normalize(dest); + } + + + /** + * The up distance is related to the target entity's extents radius. + * The larger the extents radius, the further up the camera needs to be to see the followed entity. + */ + + // Mult up by upDistance. + scUp.mult(scUp, upDistance); + + dest.mult(dest, closestCamDistance); + + // Add up distance to dest. + dest.add(dest, scUp); + + scUp.normalize(scUp); + + const fixedController = this.cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.FixedController); + fixedController.setPosition(dest); + + // Set the destination orientation for the end of the transition. + const destinationForward = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const destUp = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + destinationForward.neg(dest); + destinationForward.normalize(destinationForward); + destUp.setNormalTo(destinationForward, scUp); + const orientation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + orientation.setFromAxes(undefined, destinationForward, destUp); + fixedController.setOrientation(orientation); + + + pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.focusOnEntity(this.cameraEntity, followEntity, { up: false }); + + + // Add and setup the transition controller. + const transitionController = this.cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.TransitionController); + transitionController.setTransitionTime(duration); + transitionController.setParent(sumParentId); + + const { _easeOutExpoTransition: transitionFunction } = this.app.cameraScripts; + if (transitionFunction) { + transitionController.setTransitionFunction(transitionFunction); + } + await transitionController.getEndPromise(); + + // Clear controllers. + this.cameraEntity.clearControllers(); + + // Add orbit controller. + const orbitController = this.cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitController); + orbitController.setDragSensitivity(0.0005); + + // // Add fixedToParent, roll, and zoom controllers. + this.cameraEntity.addController('fixedToParent'); + this.cameraEntity.addController('roll'); + + // Determine zoom limits + const zoomCoeff = 10; + const zoomMin = targetEntity.getExtentsRadius(); + const zoomMax = Math.max(targetEntity.getExtentsRadius() * zoomCoeff, followEntity.getExtentsRadius() * zoomCoeff, zoomMin * zoomCoeff); + const zoomInterval = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(zoomMin, zoomMax); + + // Add zoom controller and set distance clamps. + const zoomController = this.cameraEntity.addController('zoom'); + zoomController.setDistanceClamp(zoomInterval); + + // Add select controller. + const selectController = /** @type {Pioneer.SelectController} */(this.cameraEntity.addController('select')); + // Set callback on 3D object click + if (this._selectionCallback !== null) { + selectController.setCallback(this._selectionCallback); + } + + pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.focusOnEntity(this.cameraEntity, followEntity, { up: false }); + } + + /** + * Currently just for the distance tool. + * Transitions the camera to a position where we're focused on between entity, + * and zoom out far enough to see the source and target. + * @param {Pioneer.Entity} betweenEntity - the entity that the camera will focus on + * @param {object} options - the options used to setup the camera + * @param {number} [options.duration] - seconds to do the transition + * @param {Pioneer.Vector3} [options.destination] - the location relative to the focus entity to transition to; if undefined it goes to the nearest spot from the camera's current position; this overrides distance + * @param {Pioneer.Vector3} [options.destinationUp] - where the camera up vector ends up + * @param {TransitionFunction} [options.transitionFunction] - a manual transition function to use + * @param {Pioneer.Interval} [options.zoomInterval] - a min and max zoom + * @returns {Promise} + */ + async goToBetweenPos(betweenEntity, { duration, destination, destinationUp, transitionFunction, zoomInterval }) { + const cameraEntity = this._cameraEntity; + + // Set the destination position for the end of the transition. + cameraEntity.clearControllers(); + const fixedController = /** @type {Pioneer.FixedController} */(cameraEntity.addController('fixed')); + fixedController.setPosition(destination); + + // Make sure orientation is so source entity is on top to match the UI panel. + const destinationForward = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const destUp = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + destinationForward.neg(destination); + destinationForward.normalize(destinationForward); + destUp.setNormalTo(destinationForward, destinationUp); + const orientation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + orientation.setFromAxes(undefined, destinationForward, destUp); + fixedController.setOrientation(orientation); + + pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.focusOnEntity(cameraEntity, betweenEntity, { up: false, orbiter: false }); + + // Setup the transition. + const transitionController = /** @type {Pioneer.TransitionController} */(cameraEntity.addController('transition')); + transitionController.setTransitionTime(duration); + transitionController.setParent(betweenEntity.getName()); + if (transitionFunction) { + transitionController.setTransitionFunction(transitionFunction); + } + await transitionController.getEndPromise(); + + cameraEntity.clearControllers(); + + // Add select controller. + const selectController = /** @type {Pioneer.SelectController} */(cameraEntity.addController('select')); + // Set callback on 3D object click + if (this._selectionCallback !== null) { + selectController.setCallback(this._selectionCallback); + } + + // Add orbit controller. + cameraEntity.addController('orbit'); + + // Add roll controller. + cameraEntity.addController('roll'); + + // Add zoom controller and set distance clamps. + const zoomController = /** @type {Pioneer.ZoomController} */(cameraEntity.addController('zoom')); + zoomInterval && zoomController.setDistanceClamp(zoomInterval); + + pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.focusOnEntity(cameraEntity, betweenEntity, { up: false, orbiter: false }); + } + + /** + * Zoom camera according to some amount. + * @param {number} zoomChange + * @param {Pioneer.Entity} cameraEntity + */ + zoom(zoomChange, cameraEntity = this._cameraEntity) { + let currentDistance = cameraEntity.getPosition().magnitude(); + if (Number.isNaN(currentDistance)) { + currentDistance = 1.0; + } + + // Update the current distance. + currentDistance *= zoomChange; + + // Set the position from the current distance. + const currentPosition = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + currentPosition.normalize(cameraEntity.getPosition()); + currentPosition.mult(currentPosition, currentDistance); + cameraEntity.setPosition(currentPosition); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(currentPosition); + } + + /** + * Zoom camera in 1 step. + * @param {boolean} [isContinuous=false] - Zoom continuously + */ + zoomIn(isContinuous = false) { + let zoomChange = 1.0; + const zoomSensitivity = isContinuous ? this._zoomSensitivity.hold : this._zoomSensitivity.click; + zoomChange /= Math.pow(2, zoomSensitivity); + this.zoom(zoomChange); + } + + /** + * Zoom camera out 1 step. + * @param {boolean} [isContinuous=false] - Zoom continuously + */ + zoomOut(isContinuous = false) { + let zoomChange = 1.0; + const zoomSensitivity = isContinuous ? this._zoomSensitivity.hold : this._zoomSensitivity.click; + zoomChange *= Math.pow(2, zoomSensitivity); + this.zoom(zoomChange); + } + + /** + * Gets default max distance. + * @returns {number} + */ + get defaultMaxDistance() { + return this._defaultMaxDistance; + } + + /** + * Set default max distance. + * @param {number} distance + */ + set defaultMaxDistance(distance) { + this._defaultMaxDistance = distance; + } + + /** + * Adds the dynamic environment map to the entity model. + * @param {Pioneer.Entity} entity + */ + addDynamicEnvMap(entity) { + if (!this.dynamicEnvMap) { + return; + } + // Activate dynamic env map on models + const model = /** @type {Pioneer.ModelComponent} */(entity.get('model')); + if (model !== null) { + model.setDynamicEnvironmentMapComponent(this.dynamicEnvMap); + } + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/camera_scripts.js": +/*!**********************************************!*\ + !*** ../eyes/src/managers/camera_scripts.js ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CameraScripts": function() { return /* binding */ CameraScripts; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + + + +/** + * Camera helper scripts class. + * @extends BaseManager + */ +class CameraScripts extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + */ + constructor(app) { + super(app); + + /** + * @type {CameraManager} + * @private + */ + this._cameraManager = null; + + /** + * Stores custom system distances. + * @type {object} + */ + this._customSystemDistances = { + mercury: 425648, + venus: 862136, + earth: 1040264, + mars: 80000, + jupiter: 7157638, + saturn: 4869142, + uranus: 1886367, + neptune: 2407045, + '134340_pluto': 122231, + '136199_eris': 180309, + '1_ceres': 87225, + '136108_haumea': 126609, + '136472_makemake': 118584 + }; + + /** + * Function that is called during a camera move that is using a custom transition function + */ + this._onCameraTransition = null; + + this._easeInOutExpoTransition = this._easeInOutExpoTransition.bind(this); + this._easeOutExpoTransition = this._easeOutExpoTransition.bind(this); + } + + /** + * Setup the camera scripts with a camera manager. + * @param {CameraManager} cameraManager + */ + setCameraManager(cameraManager) { + this._cameraManager = cameraManager; + } + + /** + * Gets Pioneer scene. + * @returns {Pioneer.Scene} + */ + get scene() { + return this._scene; + } + + /** + * Sets Pioneer scene. + * @param {Pioneer.Scene} scene + */ + set scene(scene) { + this._scene = scene; + } + + /** + * Gets the main camera entity. + * @returns {Pioneer.Entity} + */ + get cameraEntity() { + return this._cameraEntity; + } + + /** + * Sets the main camera entity. + * @param {Pioneer.Entity} cameraEntity + */ + set cameraEntity(cameraEntity) { + this._cameraEntity = cameraEntity; + } + + /** + * Get normal to ecliptic plane. + * @param {Pioneer.Vector3} outNormal - The normal vector that will be modified + * @param {string} id - Target entity id + */ + getNormalToEcliptic(outNormal, id) { + const objectOrbitOri = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + /** @type {Pioneer.DynamoController} */(this._cameraManager.pioneer.get('main', id, 'dynamo')).getOrbitOrientation(objectOrbitOri, this._cameraManager.pioneer.getTime()); + objectOrbitOri.getAxis(outNormal, 2); + } + + /** + * Returns true if the entity id has barycenter. + * @param {string} id - The entity id. + * @returns {boolean} + */ + isBarycenter(id) { + if (id.includes('_barycenter')) { + return true; + } + return false; + } + + /** + * Returns a string stripped of the barycenter keyword. + * @param {string} id - The entity id. + * @returns {string} + */ + removeBarycenter(id) { + if (this.isBarycenter(id)) { + return id.replace('_barycenter', ''); + } + return id; + } + + /** + * Go to a planet, sunny side and rotates around it + * @param {string} id - Target entity id + * @param {object} options + * @param {Pioneer.Scene} [options.scene = undefined] - Custom scene, default to main + * @param {string} [options.starId = 'sun'] - A star id to include in the view + * @param {boolean} [options.cinematic = true] - Cinematic mode + * @param {number} [options.duration = 1.5] - Duration of transition + * @param {number} [options.distance = 1.3] - Distance of the camera + */ + async goToCelestialObject(id, { scene = undefined, starId = 'sun', cinematic = true, duration = 1.5, distance = 1.3 } = {}) { + // Always update context first + this._cameraManager.setContext({ id, context: CameraScripts.CONTEXT.CELESTIAL_OBJECT }); + + if (scene === undefined) { + scene = this._scene; + } + + const planet = scene.getEntity(id); + const star = scene.getEntity(starId); + + let dest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + planet.getPositionRelativeToEntity(dest, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, star); + + if (dest.magnitude() === 0) { // If the magnitude is zero due to object-is-root or objects-overlap + dest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 1, 0); // set the vector to be along the Y-Axis and allow rest of logic to continue calculation + } + + // Get planet up + const planetUp = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + planet.getOrientation().getAxis(planetUp, 2); + + // Calculate destination + dest.neg(dest); + dest.normalize(dest); + let radius = planet.getOcclusionRadius(); + const spheroid = planet.getComponentByType('spheroid'); + if (spheroid !== null) { + radius = /** @type {Pioneer.SpheroidComponent} */(planet.getComponentByType('spheroid')).getEquatorialRadius(); + } + const minRadius = 1.2 * radius; + + // Determine distance + const cameraOrientation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + cameraOrientation.setFromAxes(undefined, dest, planetUp); + let dist = pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.getDistanceToFitEntities(this._cameraEntity, cameraOrientation, planet, [planet]); + + dist *= distance; + dest.mult(dest, dist); + + + // Go to planet straight and then align camera with sun + await this._cameraManager.goToEntity(id, { distance: dist, duration: duration / 2 }); + await this._cameraManager.goToEntity(id, { destination: dest, cinematic, minRadius, destinationUp: planetUp, duration: duration / 2 }); + } + + /** + * Ease-out cam transition function + * @param {Pioneer.Entity} entity + * @param {Pioneer.Vector3} initialPosition + * @param {Pioneer.Vector3} finalPosition + * @param {Pioneer.Quaternion} initialOrientation + * @param {Pioneer.Quaternion} finalOrientation + * @param {number} u + */ + _easeOutExpoTransition(entity, initialPosition, finalPosition, initialOrientation, finalOrientation, u) { + const position = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const orientation = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + + // Apply exponent ease-out function. // https://github.com/d3/d3-ease/tree/main/src + const e = 4; + const easedT = 1 - Math.pow(1 - u, e); + + position.lerp(initialPosition, finalPosition, easedT); + orientation.slerp(initialOrientation, finalOrientation, easedT); + + // Call _onCameraTransition if exists. + this._onCameraTransition?.(easedT); + + // Set the new position and orientation. + entity.setPosition(position); + entity.setOrientation(orientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + } + + /** + * Ease in-out expo cam transition function - TODO: need a cleaner way to apply transition with just basic function code + * @param {Pioneer.Entity} entity + * @param {Pioneer.Vector3} initialPosition + * @param {Pioneer.Vector3} finalPosition + * @param {Pioneer.Quaternion} initialOrientation + * @param {Pioneer.Quaternion} finalOrientation + * @param {number} u + */ + _easeInOutExpoTransition(entity, initialPosition, finalPosition, initialOrientation, finalOrientation, u) { + const position = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const orientation = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + + // Apply ease-in-out function. // https://github.com/d3/d3-ease/tree/main/src + const e = 4; + const easedT = ((u *= 2) <= 1 ? Math.pow(u, e) : 2 - Math.pow(2 - u, e)) / 2; + + position.lerp(initialPosition, finalPosition, easedT); + orientation.slerp(initialOrientation, finalOrientation, easedT); + + // Call _onCameraTransition if exists. + this._onCameraTransition?.(easedT); + + // Set the new position and orientation. + entity.setPosition(position); + entity.setOrientation(orientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + } + + /** + * Go to spacecraft, with planet in background. + * Or from Sun point of view if Sun is parent. + * @param {string} id - Target entity id + * @param {object} options + * @param {Pioneer.Scene} [options.scene = undefined] - Custom scene, default to main + * @param {string} [options.starId = 'sun'] - A star id to include in the view + * @param {string} [options.planeId = 'earth'] - A planet id used to calculate normal to ecliptic + * @param {number} [options.distance = undefined] - Distance of the camera + * @param {boolean} [options.cinematic = true] - Cinematic mode + * @param {number} [options.duration = 1.5] - Duration of transition + * @param {number} [options.verticalOffset=0] - Offset camera up/down along horizontal axis + * @param {number} [options.horizontalOffset=0] - Offset camera left/right along vertical axis + */ + async goToSpacecraft(id, { scene = undefined, starId = 'sun', planeId = 'earth', distance = undefined, cinematic = true, duration = 1.5, verticalOffset = 0, horizontalOffset = 0 } = {}) { + // Always update context first + this._cameraManager.setContext({ id, context: CameraScripts.CONTEXT.SPACECRAFT }); + + // Get default scene + if (scene === undefined) { + scene = this._scene; + } + + // Get camera distance + const entityInfo = this._app.getManager('content').getEntityInfo(id); + const camDistance = entityInfo?.customDistance || distance; + + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(scene, [id]); + + const sc = scene.getEntity(id); + const scRadius = sc.getOcclusionRadius(); + const minRadius = 1.2 * scRadius; + const dest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + dest.normalize(sc.getPosition()); + const scUp = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + // Todo: scParent is sometimes null. Why? + const scParent = sc.getParent(); + // If spacecraft parent is star + // look at spacecraft from star perspective + if (scParent) { + if (scParent.getName() === starId && scene.get(planeId) !== null) { + this.getNormalToEcliptic(scUp, planeId); + if (scUp.isNaN()) { + scUp.copy(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 1)); + } + } + else { + // Get parent up + scParent.getOrientation().getAxis(scUp, 2); + } + } + scUp.normalize(scUp); + + // If destination vector is too close to zero + if (dest.magnitude() < 0.0001) { + sc.getOrientation().getAxis(dest, 0); + dest.normalize(dest); + } + + // Cross between dest and planet up + const horizontal = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + horizontal.cross(dest, scUp); + horizontal.normalize(horizontal); + + // Rotate fwd + const rotation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + rotation.setFromAxisAngle(horizontal, pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(verticalOffset)); + dest.rotate(rotation, dest); + + // Rotate up + rotation.setFromAxisAngle(scUp, pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(horizontalOffset)); + dest.rotate(rotation, dest); + + // Calculate distance + let dist = 0.0; + if (camDistance !== undefined) { + dist = camDistance; + } + else { + const cameraOrientation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + cameraOrientation.setFromAxes(undefined, dest, scUp); + const distToFit = pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.getDistanceToFitEntities(this._cameraEntity, cameraOrientation, sc, [sc]); + dist = distToFit * 1.3; + } + + dest.mult(dest, dist); + + // Go to spacecraft and then align with parent or sun + await this._cameraManager.goToEntity(id, { distance: dist }); + await this._cameraManager.goToEntity(id, { destination: dest, cinematic, minRadius, destinationUp: scUp, duration }); + } + + /** + * Go to spacecraft, with planet in background. + * Or from Sun point of view if Sun is parent. + * @param {string} id - Target entity id + * @param {object} options + * @param {Pioneer.Scene} [options.scene = undefined] - Custom scene, default to main + * @param {number} [options.distance = undefined] - Distance of the camera + * @param {number} [options.duration = 1.5] - Duration of transition + * @param {string} [options.upVector = 'y-axis'] - Which axis of spacecraft to set up vector + * @param {string} [options.forwardVector = 'x-axis'] - Which axis of spacecraft to set forward vector + */ + async goToInstrument(id, { scene = undefined, distance = undefined, duration = 1.5, upVector = 'z-axis', forwardVector = 'y-axis' } = {}) { + // Always update context first + this._cameraManager.setContext({ id, context: CameraScripts.CONTEXT.INSTRUMENT }); + + if (scene === undefined) { + scene = this._scene; + } + + // Get camera distance + const entityInfo = this._app.getManager('content').getEntityInfo(id); + const camDistance = entityInfo?.customDistance || distance; + + const instrument = scene.getEntity(id); + const spacecraft = instrument.getParent(); + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(scene, [spacecraft.getName(), id]); + + const iRadius = instrument.getOcclusionRadius(); + const sRadius = spacecraft.getOcclusionRadius(); + + const minRadius = 1.2 * iRadius; + const dest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + instrument.getPositionRelativeToEntity(dest, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, spacecraft); + + // Get parent forward + const forward = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const forwardVectorIndex = forwardVector.endsWith('y-axis') + ? 1 + : forwardVector.endsWith('z-axis') + ? 2 + : 0; + spacecraft.getOrientation().getAxis(forward, forwardVectorIndex); + if (forwardVector.startsWith('-')) { + forward.mult(forward, -1); + } + dest.mult(forward, -1); + + // Get parent up + const scUp = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + let upVectorIndex = forwardVector.endsWith('y-axis') ? 2 : 1; + if (upVector.endsWith('x-axis')) { + upVectorIndex = 0; + } + else if (upVector.endsWith('z-axis')) { + upVectorIndex = 2; + } + spacecraft.getOrientation().getAxis(scUp, upVectorIndex); + if (upVector.startsWith('-')) { + scUp.mult(scUp, -1); + } + + // Calculate distance + let dist = minRadius * 4.0; + if (camDistance !== undefined) { + dist = camDistance; + } + dest.mult(dest, dist); + + // Go to spacecraft and then align + await this._cameraManager.goToEntity(spacecraft.getName(), { destinationUp: scUp, distance: sRadius * 1.2 }); + await this._cameraManager.goToEntity(id, { destination: dest, minRadius, destinationUp: scUp, duration }); + } + + /** + * Compare two objects. + * @param {string} left - Left object id + * @param {string} right - Right object id + * @param {object} options + * @param {Pioneer.Entity} [options.cameraLeft = undefined] + * @param {Pioneer.Entity} [options.cameraRight = undefined] + * @param {Pioneer.Vector3} [options.cameraLeftPosition = undefined] + * @param {Pioneer.Vector3} [options.cameraRightPosition = undefined] + * @param {Pioneer.Vector3} [options.cameraUp = undefined] + * @param {Pioneer.Scene} [options.scene = undefined] + * @param {number} [options.minRadius = undefined] + * @param {number} [options.maxRadius = undefined] + * @param {number} [options.duration = 0.75] + */ + async compareObjects(left, right, { cameraLeft = undefined, cameraRight = undefined, cameraLeftPosition = undefined, cameraRightPosition = undefined, cameraUp = undefined, scene = undefined, minRadius = undefined, maxRadius = undefined, duration = 0.75 }) { + // Always update context first + this._cameraManager.setContext({ id: left, context: CameraScripts.CONTEXT.COMPARE, to: right }); + + const event = new CustomEvent('cameracompare', { detail: { left, right } }); + window.dispatchEvent(event); + + const leftTransition = this._cameraManager.goToEntity( + left, + { + minRadius, + maxRadius, + camera: cameraLeft, + destination: cameraLeftPosition, + destinationUp: cameraUp, + scene, + select: false, + duration, + zoom: true, + cinematic: true + } + ); + + const rightTransition = this._cameraManager.goToEntity( + right, + { + minRadius, + maxRadius, + camera: cameraRight, + destination: cameraRightPosition, + destinationUp: cameraUp, + scene, + select: false, + duration, + zoom: true, + cinematic: true + } + ); + + await Promise.all([leftTransition, rightTransition]); + } + + /** + * Show where object is located in the system. + * @param {string} targetEntityName - Target entity id + * @param {string} forwardEntityName - A parent id used to calculate normal to ecliptic or north pole + * @param {string} upOrRightEntityName - An entity used to orient the up or right of the camera (depending on aspect ratio). + * @param {string} [mode='northPole'] - Whether to have the forward be based on the north pole or the orbital plane normal of the forwardEntity ('northPole' or 'planeNormal'). + * @param {object} options + * @param {number} [options.duration=1.5] - How long to do the transition + * @param {string[]} [options.otherEntityNames=[]] - Other entities to include in the view. + * @param {number} [options.distance=undefined] - Distance of the camera + * @param {boolean} [options.rotateByScreenRatio=true] - Rotate up vector -90 degree if the view is wider than it is tall + * @returns {Promise} + */ + async showLocation(targetEntityName, forwardEntityName, upOrRightEntityName, mode = 'northPole', { duration = 2, otherEntityNames = [], distance = undefined, rotateByScreenRatio = true } = {}) { + // Always update context first + this._cameraManager.setContext({ id: '', targetEntityName, context: CameraScripts.CONTEXT.LOCATION, options: { otherEntityNames } }); + + // Get the various entities. + const targetEntity = this._scene.getEntity(targetEntityName); + const forwardEntity = this._scene.getEntity(forwardEntityName); + const upOrRightEntity = this._scene.getEntity(upOrRightEntityName); + if (targetEntity === null || forwardEntity === null || upOrRightEntity === null) { + return; + } + + // Push all of the involved entities into a giant list. It'll be used for fitting them all into view. + const entities = []; + entities.push(targetEntity); + entities.push(forwardEntity); + entities.push(upOrRightEntity); + for (let i = 0, l = otherEntityNames.length; i < l; i++) { + const otherEntity = this._scene.getEntity(otherEntityNames[i]); + if (otherEntity !== null) { + entities.push(otherEntity); + } + } + + // Get the final position direction. + const position = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + if (mode === 'northPole') { + forwardEntity.getOrientation().getAxis(position, 2); + } + else if (mode === 'planeNormal') { + position.cross(forwardEntity.getPosition(), forwardEntity.getVelocity()); + position.normalize(position); + } + + // Get the forward vector. + const forward = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + forward.neg(position); + + // Get the up vector. + const up = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + targetEntity.getPositionRelativeToEntity(up, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, upOrRightEntity); + up.normalize(up); + up.setNormalTo(forward, up); + up.neg(up); + + // If the view is wider than it is tall, rotate the up by -90 degrees. + const cameraComponent = /** @type {Pioneer.CameraComponent} */(this._cameraEntity.getComponentByType('camera')); + if (rotateByScreenRatio && cameraComponent.getHorizontalFieldOfView() > cameraComponent.getVerticalFieldOfView()) { + up.cross(up, forward); + } + + // Set the orientation based on the forward and up vectors. + const orientation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + orientation.setFromAxes(undefined, forward, up); + + // Using the orientation and entity list, set the position to a good distance to see all of the entities. + let dist = distance || pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.getDistanceToFitEntities(this._cameraEntity, orientation, targetEntity, entities); + // If the view is taller than it is wide, increase distance. + if (cameraComponent.getHorizontalFieldOfView() < cameraComponent.getVerticalFieldOfView()) { + dist *= cameraComponent.getVerticalFieldOfView() * 1.3; + } + dist *= 2; + position.setMagnitude(position, dist); + + // If camera's parent is null, fly to target first. + if (this._cameraEntity.getParent() === null) { + await this._cameraManager.goToEntity(targetEntityName, { distance: dist }); + } + + // Setup keyframes + const keyframes = /** @type {import('./managers/camera_manager').OrbitKeyframeOptions} */({ + up: [{ frame: duration, up }], + position: [{ frame: duration, position, relativeTo: targetEntity.getName() }], + focus: [{ frame: duration, name: targetEntityName }] + }); + + await this._cameraManager.goToEntity(targetEntityName, { keyframes, destination: position, destinationUp: up, cinematic: false, duration: 0.2 }); + } + + /** + * Align an object with another. + * @param {string} targetEntityName - Camera's target + * @param {string} focusEntityName - Entity to align with + * @param {object} [options={}] + * @param {number} [options.duration=1.5] - Duration for both transition and alignment + * @param {number} [options.transitionDuration=undefined] - Duration of transition + * @param {number} [options.alignDuration=undefined] - Duration of alignment + * @param {number} [options.distance=1] - Distance from default position + * @param {boolean} [options.cinematic=false] + * @param {number} [options.verticalOffset=0] - Offset camera up/down along horizontal axis + * @param {number} [options.horizontalOffset=0] - Offset camera left/right along vertical axis + * @param {boolean} [options.useEase=false] - Use ease in transitions + */ + async alignObjects(targetEntityName, focusEntityName, { verticalOffset = 0, horizontalOffset = 0, duration = 1.5, transitionDuration = undefined, alignDuration = undefined, distance = 1, cinematic = false, useEase = true } = {}) { + // Always update context first + this._cameraManager.setContext({ id: '', targetEntityName, context: CameraScripts.CONTEXT.ALIGN_OBJECTS, focus: focusEntityName }); + + const targetEntity = this._scene.getEntity(targetEntityName); + const focusEntity = this._scene.getEntity(focusEntityName); + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(this._scene, [targetEntityName, focusEntityName]); + + const minRadius = targetEntity.getOcclusionRadius(); + + // Get destination vector + const dest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const time = this._cameraManager.pioneer.getTime(); + targetEntity.getPositionRelativeToEntity(dest, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, focusEntity, time); + if (dest.isNaN()) { + dest.copy(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, -1, 0)); + } + else { + dest.normalize(dest); + } + + dest.mult(dest, distance); + + // Get up vector + const up = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + focusEntity.getOrientation().getAxis(up, 2); + + // Cross between dest and planet up + const horizontal = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + horizontal.cross(dest, up); + horizontal.normalize(horizontal); + + // Rotate fwd + const rotation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + rotation.setFromAxisAngle(horizontal, pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(verticalOffset)); + dest.rotate(rotation, dest); + + // Rotate up + rotation.setFromAxisAngle(up, pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(horizontalOffset)); + dest.rotate(rotation, dest); + + // Go to focus entity first and then align target entity with it + await this._cameraManager.goToEntity(targetEntityName, { distance, destinationUp: up, duration: transitionDuration || duration * 0.5, transitionFunction: useEase ? this._easeOutExpoTransition : undefined }); + await this._cameraManager.goToEntity(targetEntityName, { destination: dest, cinematic, minRadius, destinationUp: up, duration: alignDuration || duration * 0.5, transitionFunction: useEase ? this._easeOutExpoTransition : undefined }); + } + + /** + * Align spacecraft and planet. + * @param {string} id - Target entity id + * @param {object} options + * @param {number} [options.duration = 1.5] - Duration of transition + * @param {number} [options.minRadius = 50] + * @param {number} [options.distanceMultiplier = 3] - Multiply the parent's radius as distance + */ + async alignSpacecraftPlanet(id, { duration = 1.5, minRadius = 50, distanceMultiplier = 3 } = {}) { + // Always update context first + this._cameraManager.setContext({ id, context: CameraScripts.CONTEXT.ALIGN_SPACECRAFT }); + + const sc = this._scene.getEntity(id); + let planet = sc.getParent(); + while (planet !== null && planet.getComponentByType('spheroid') === null && planet.getComponentByType('model') === null) { + planet = planet.getParent(); + } + + let radius = planet.getOcclusionRadius(); + const spheroid = planet.getComponentByType('spheroid'); + if (spheroid !== null) { + radius = /** @type {Pioneer.SpheroidComponent} */(planet.getComponentByType('spheroid')).getEquatorialRadius(); + } + + const dest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + sc.getPositionRelativeToEntity(dest, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, planet); + dest.normalize(dest); + // If destination vector is too close to zero + if (dest.magnitude() < 0.0001) { + sc.getOrientation().getAxis(dest, 0); + dest.normalize(dest); + } + dest.mult(dest, Math.max(minRadius, distanceMultiplier * radius)); + + const planetUp = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + planet.getOrientation().getAxis(planetUp, 2); + + // Go to parent first and then align object with parent + await this._cameraManager.goToEntity(planet.getName()); + await this._cameraManager.goToEntity(id, { destination: dest, cinematic: false, minRadius: Math.min(radius, minRadius), destinationUp: planetUp, duration }); + } + + /** + * View from side of entity. + * @param {string} id + * @param {object} [options={}] + * @param {string} [options.planeId='earth'] + * @param {number} [options.distance=undefined] + * @param {boolean} [options.cinematic=false] + * @param {number} [options.duration=0.75] + * @param {number} [options.verticalOffset=0] + * @param {number} [options.horizontalOffset=0] + * @param {string} [options.forwardVector='x-axis'] + * @param {string} [options.upVector=''] - Get up vector from position by default. Otherwise from parent's axis. + */ + async viewFromSide(id, { planeId = 'earth', distance = undefined, cinematic = false, duration = 0.75, verticalOffset = 0, horizontalOffset = 0, forwardVector = 'x-axis', upVector = '' } = {}) { + // Entities + const targetEntity = this._scene.get(id); + const planeEntity = this._scene.get(planeId) || targetEntity.getParent(); + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(this._scene, [id, planeId]); + + const targetRadius = targetEntity.getOcclusionRadius(); + const minRadius = 1.2 * targetRadius; + + // View from side + const dest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const forward = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + let forwardIndex = 0; + if (forwardVector === 'z-axis') { + forwardIndex = 2; + } + else if (forwardVector === 'y-axis') { + forwardIndex = 1; + } + targetEntity.getOrientation().getAxis(forward, forwardIndex); + forward.normalize(forward); + const targetPosition = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + targetEntity.getPositionRelativeToEntity(targetPosition, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, planeEntity); + targetPosition.normalize(targetPosition); + dest.cross(forward, targetPosition); + dest.normalize(dest); + dest.mult(dest, -1); + + const up = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + if (upVector) { + // Parent up + let upVectorIndex = 1; + if (upVector.includes('x-axis')) { + upVectorIndex = 0; + } + else if (upVector.includes('z-axis')) { + upVectorIndex = 2; + } + targetEntity.getOrientation().getAxis(up, upVectorIndex); + if (upVector.startsWith('-')) { + up.mult(up, -1); + } + } + else { + // Position up + targetEntity.getPositionRelativeToEntity(up, targetEntity, planeEntity); + up.normalize(up); + } + + // Horizontal + const horizontal = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + horizontal.cross(dest, up); + horizontal.normalize(horizontal); + + // Make sure up is orthogonal + up.cross(horizontal, dest); + + // Offset dest vector so target is below or above + if (verticalOffset !== 0) { + const orientationOffset = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + const angleOffset = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(verticalOffset); + orientationOffset.setFromAxisAngle(horizontal, angleOffset); + dest.rotate(orientationOffset, dest); + } + + // TODO: Optional: Update up after rotation + up.cross(horizontal, dest); + + // Offset dest vector so target is on the left or right + if (horizontalOffset !== 0) { + const orientationOffset = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + const angleOffset = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(horizontalOffset); + orientationOffset.setFromAxisAngle(up, angleOffset); + dest.rotate(orientationOffset, dest); + } + + // Update horizontal axis + horizontal.cross(dest, up); + horizontal.normalize(horizontal); + + // Distance + if (distance === undefined) { + dest.mult(dest, 10 * targetRadius); + } + else { + dest.mult(dest, distance); + } + + await this._cameraManager.goToEntity(id, { destination: dest, cinematic, minRadius, destinationUp: up, duration }); + } + + /** + * Go to spacecraft look at a target. + * @param {string} id - Spacecraft entity id + * @param {string} target - Target entity id + */ + async spacecraftLookAtTarget(id, target) { + // Always update context first + this._cameraManager.setContext({ id, context: CameraScripts.CONTEXT.LOOK_AT, target }); + // TODO: Add function & params + } + + /** + * Go to spacecraft locked on a target. + * @param {string} id - Spacecraft entity id + * @param {string} target - Target entity id + */ + async spacecraftLockedOnTarget(id, target) { + // Always update context first + this._cameraManager.setContext({ id, context: CameraScripts.CONTEXT.LOCKED_ON, target }); + // TODO: Add function & params + } + + /** + * Go to a system sideway (looking at terminator line instead of sunny side). + * @param {string} id + * @param {object} options + * @param {number} [options.distance = undefined] - Distance from the target + * @param {number} [options.minDistance = 0] - Minimum distance the camera can be from target + * @param {number} [options.duration = 1] - Duration of the transition and alignment + * @param {string[]} [options.otherEntityNames = []] - Other entities to include in the view + * @param {boolean} [options.includeChildren = true] - Include children in the view + * @param {number} [options.angleInDegree = 0] - Angle of the camera + * @param {boolean} [options.cinematic = false] - Cinematic mode + */ + async goToSystemSideway(id, { distance = undefined, minDistance = 0, duration = 1, otherEntityNames = [], includeChildren = true, angleInDegree = 0, cinematic = false } = {}) { + // Always update context first + this._cameraManager.setContext({ id, context: CameraScripts.CONTEXT.SYSTEM }); + + const systemObject = this._scene.getEntity(id); + + // Get min distance + const systemId = this.isBarycenter(id) + ? this.removeBarycenter(id) + : id; + const minDist = systemId in this._customSystemDistances + ? this._customSystemDistances[systemId] + : 0; + + // List entities that have to be displayed on screen + const entities = [systemObject]; + for (let i = 0; i < otherEntityNames.length; i++) { + entities.push(this._scene.getEntity(otherEntityNames[i])); + } + if (includeChildren) { + for (let i = 0; i < systemObject.getNumChildren(); i++) { + const child = systemObject.getChild(i); + // Ignore camera + if (child.getComponentByType('camera') !== null) { + continue; + } + // Ignore spacecraft + if (child.getName().startsWith('sc')) { + continue; + } + // Ignore objects without valid positions + if (child.getPosition().isNaN()) { + continue; + } + entities.push(child); + } + } + + // Create an xyz frame from the object's velocity and position + // Get y-axis + const yAxis = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + yAxis.normalize(systemObject.getVelocity()); + + // Get x-axis + const xAxis = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + xAxis.normalize(systemObject.getPosition()); + + // Force x-axis to be normal to y-axis + xAxis.setNormalTo(yAxis, xAxis); + + // Get z-axis + const zAxis = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + zAxis.cross(xAxis, yAxis); + + // Get negative of y-axis + fraction of z-axis + const dest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + dest.mult(yAxis, -1); + dest.addMult(dest, zAxis, Math.tan(pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(angleInDegree))); + + // Determine min radius + let radius = systemObject.getOcclusionRadius(); + const spheroid = /** @type {Pioneer.SpheroidComponent} */(systemObject.getComponentByType('spheroid')); + if (spheroid !== null) { + radius = spheroid.getEquatorialRadius(); + } + else if (this.isBarycenter(id)) { + const newId = this.removeBarycenter(id); + const newSystemObject = this._scene.getEntity(newId); + const newSpheroid = /** @type {Pioneer.SpheroidComponent} */(newSystemObject.getComponentByType('spheroid')); + if (spheroid !== null) { + radius = newSpheroid.getEquatorialRadius(); + } + } + const minRadius = 1.2 * radius; + + // Determine viewing distance + let dist = distance; + if (dist === undefined) { + const cameraOrientation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + cameraOrientation.setFromAxes(xAxis, dest, undefined); + dist = pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.getDistanceToFitEntities(this._cameraEntity, cameraOrientation, systemObject, entities); + dist *= 1.3; + } + dist = Math.max(minDist, dist); + // If the view is taller than it is wide, increase distance. + const cameraComponent = /** @type {Pioneer.CameraComponent} */(this._cameraEntity.getComponentByType('camera')); + if (cameraComponent.getHorizontalFieldOfView() < cameraComponent.getVerticalFieldOfView()) { + dist *= cameraComponent.getVerticalFieldOfView() * 1.3; + } + dest.setMagnitude(dest, dist); + + // Go to system view + await this._cameraManager.goToEntity(id, { destination: dest, cinematic, minRadius, destinationUp: zAxis, duration }); + } + + /** + * Go to a system, sunny side and rotates around it + * @param {string} id - Target entity id + * @param {object} options + * @param {number} [options.distance = undefined] - Distance from the target + * @param {number} [options.angle = 25] - Angle of the camera + * @param {number} [options.minDistance = 0] - Minimum distance the camera can be from target + * @param {number} [options.duration = 1] - Duration of the transition and alignment (x2) + * @param {string} [options.planeId = ''] - A planet id used to calculate normal to ecliptic + * @param {string[]} [options.otherEntityNames = []] - Other entities to include in the view + * @param {boolean} [options.includeChildren = true] - Include children in the view + * @param {boolean} [options.isRelativeToPreviousCamera = false] - Align to previous camera + */ + async goToSystem(id, options = {}) { + if (id === 'inner_solar_system') { + Object.assign(options, { distance: 7e8, angle: 25, planeId: 'earth' }); + await this._goToSystem('sun', options); + } + else if (id === 'outer_solar_system') { + Object.assign(options, { distance: 1e10, angle: 25, planeId: 'earth' }); + await this._goToSystem('sun', options); + } + else { + const systemId = this.isBarycenter(id) + ? this.removeBarycenter(id) + : id; + const minDist = systemId in this._customSystemDistances + ? this._customSystemDistances[systemId] + : 0; + const entityInfo = this._app.getManager('content').getEntityInfo(id); + const planeId = 'planeId' in options + ? options.planeId + : (entityInfo?.planeEntity || ''); + Object.assign(options, { minDistance: minDist, planeId }); + await this._goToSystem(id, options); + } + } + + /** + * Go to a system, sunny side and rotates around it. + * @param {string} id - Target entity id + * @param {object} options + * @param {number} [options.distance = undefined] - Distance from the target + * @param {number} [options.angle = 25] - Angle of the camera + * @param {number} [options.minDistance = 0] - Minimum distance the camera can be from target + * @param {number} [options.duration = 1] - Duration of the transition and alignment (x2) + * @param {string} [options.planeId = ''] - A planet id used to calculate normal to ecliptic + * @param {string[]} [options.otherEntityNames = []] - Other entities to include in the view + * @param {boolean} [options.includeChildren = true] - Include children in the view + * @param {boolean} [options.isRelativeToPreviousCamera = false] - Align to previous camera + */ + async _goToSystem(id, { distance = undefined, angle = 25, minDistance = 0, duration = 1, planeId = '', otherEntityNames = [], includeChildren = true, isRelativeToPreviousCamera = true } = {}) { + // Always update context first + this._cameraManager.setContext({ id, context: CameraScripts.CONTEXT.SYSTEM }); + + this.app.getManager('camera').setIsTransitioning(true); + + const systemObject = this._scene.getEntity(id); + + // List entities that have to be displayed on screen + const entities = [systemObject]; + for (let i = 0; i < otherEntityNames.length; i++) { + entities.push(this._scene.getEntity(otherEntityNames[i])); + } + if (includeChildren) { + for (let i = 0; i < systemObject.getNumChildren(); i++) { + const child = systemObject.getChild(i); + // Ignore camera + if (child.getComponentByType('camera') !== null) { + continue; + } + // Ignore spacecraft + if (child.getName().startsWith('sc')) { + continue; + } + // Ignore objects without valid positions + if (child.getPosition().isNaN()) { + continue; + } + entities.push(child); + } + } + + // Fwd vector from previous camera position + const dest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const camPosition = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + if (isRelativeToPreviousCamera) { + this._cameraEntity.getPositionRelativeToEntity(camPosition, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, systemObject); + // If no camera position + // force position to this vector + if (camPosition.isNaN()) { + dest.copy(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, -1, 0)); + dest.mult(dest, 1e10); + } + else { + dest.copy(camPosition); + } + } + else { + dest.normalize(systemObject.getPosition()); + dest.mult(dest, -1); + } + + // Get the up vector + const up = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + if (planeId !== '' && this._scene.get(planeId) !== null) { + this.getNormalToEcliptic(up, planeId); + if (up.isNaN()) { + up.copy(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 1)); + } + } + else { + systemObject.getOrientation().getAxis(up, 2); + } + + // Cross between dest and planet up + const horizontal = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + horizontal.cross(dest, up); + horizontal.normalize(horizontal); + + // Update dest to be normal to up + dest.setNormalTo(up, dest); + dest.normalize(dest); + + // Rotate fwd + const rotation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + rotation.setFromAxisAngle(horizontal, pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(angle)); + dest.rotate(rotation, dest); + + // Determine min radius + let radius = systemObject.getOcclusionRadius(); + const spheroid = /** @type {Pioneer.SpheroidComponent} */(systemObject.getComponentByType('spheroid')); + if (spheroid !== null) { + radius = spheroid.getEquatorialRadius(); + } + else if (this.isBarycenter(id)) { + const newId = this.removeBarycenter(id); + const newSystemObject = this._scene.getEntity(newId); + const newSpheroid = /** @type {Pioneer.SpheroidComponent} */(newSystemObject.getComponentByType('spheroid')); + if (spheroid !== null) { + radius = newSpheroid.getEquatorialRadius(); + } + } + const minRadius = 1.2 * radius; + + // Determine viewing distance + let dist = distance; + if (dist === undefined) { + const cameraOrientation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + cameraOrientation.setFromAxes(horizontal, dest, undefined); + dist = pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.getDistanceToFitEntities(this._cameraEntity, cameraOrientation, systemObject, entities); + dist *= 1.3; + } + dist = Math.max(minDistance, dist); + // If the view is taller than it is wide, increase distance. + const cameraComponent = /** @type {Pioneer.CameraComponent} */(this._cameraEntity.getComponentByType('camera')); + if (cameraComponent.getHorizontalFieldOfView() < cameraComponent.getVerticalFieldOfView()) { + dist *= cameraComponent.getVerticalFieldOfView() * 1.3; + } + + if (isRelativeToPreviousCamera) { + // Determine first destination + // Look at the system object first + const firstDest = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._cameraEntity.getPositionRelativeToEntity(camPosition, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, systemObject); + if (camPosition.isNaN()) { + firstDest.copy(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, -1, 0)); + firstDest.setNormalTo(up, firstDest); + firstDest.mult(firstDest, 1e10); + firstDest.rotate(rotation, firstDest); + } + else { + firstDest.copy(camPosition); + } + + // Align camera with target first + await this._cameraManager.goToEntity(id, { destination: firstDest, destinationUp: up, duration }); + } + else { + // Go to object at system distance first + await this._cameraManager.goToEntity(id, { distance, duration: duration / 2 }); + } + + // Go to system view + dest.mult(dest, dist); + await this._cameraManager.goToEntity(id, { destination: dest, cinematic: false, minRadius, destinationUp: up, duration }); + this.app.getManager('camera').setIsTransitioning(false); + } + + /** + * Go to a location in center of entities. + * @param {string[]} entityNames + * @param {string} parentName + * @param {number} time - Pioneer time + * @param {Object} options - Options for goToSystem function + */ + async goToCenter(entityNames, parentName, time, options = {}) { + // Always update context first + this._cameraManager.setContext({ id: 'centerSystem', context: CameraScripts.CONTEXT.CENTER_SYSTEM }); + + const position = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const parent = this._scene.getEntity(parentName); + const tempPosition = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const entities = []; + + // Get position in center of entities + for (let i = 0; i < entityNames.length; i++) { + const entity = this._scene.getEntity(entityNames[i]); + entities.push(entity); + entity.getPositionRelativeToEntity(tempPosition, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, parent, time); + position.addMult(position, tempPosition, 1 / entityNames.length); + } + + // Create center entity + let center = this._scene.getEntity('center'); + if (center === null) { + center = this._scene.addEntity('center'); + center.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + center.setParent(parent); + center.setPosition(position); + await this._scene.getLoadedPromise(); + await this._cameraManager.pioneer.waitUntilNextFrame(); + + // Go to system view at center + options['otherEntityNames'] = entityNames; + await this._goToSystem(center.getName(), options); + } + + /** + * Show center location of multiple entities. + * @param {string[]} entityNames + * @param {string} parentName + * @param {number} time - Pioneer time + * @param {string} forwardEntityName - A parent id used to calculate normal to ecliptic or north pole + * @param {string} upOrRightEntityName - An entity used to orient the up or right of the camera (depending on aspect ratio). + * @param {string} mode - Whether to have the forward be based on the north pole or the orbital plane normal of the forwardEntity ('northPole' or 'planeNormal'). + * @param {Object} options - Options for showLocation function + */ + async showLocationCenter(entityNames, parentName, time, forwardEntityName, upOrRightEntityName, mode, options = {}) { + // Always update context first + this._cameraManager.setContext({ id: 'centerLocation', context: CameraScripts.CONTEXT.CENTER_LOCATION }); + + const position = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const parent = this._scene.getEntity(parentName); + const tempPosition = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const entities = []; + + // Get position in center of entities + for (let i = 0; i < entityNames.length; i++) { + const entity = this._scene.getEntity(entityNames[i]); + entities.push(entity); + entity.getPositionRelativeToEntity(tempPosition, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, parent, time); + position.addMult(position, tempPosition, 1 / entityNames.length); + } + + // Create center entity + let center = this._scene.getEntity('center'); + if (center === null) { + center = this._scene.addEntity('center'); + center.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + center.setParent(parent); + center.setPosition(position); + await this._scene.getLoadedPromise(); + await this._cameraManager.pioneer.waitUntilNextFrame(); + + // Go to location view at center + options['otherEntityNames'] = entityNames; + await this.showLocation(center.getName(), forwardEntityName, upOrRightEntityName, mode, options); + } + + /** + * Show where object is located in the parent's system. + * @param {string} id - Target entity id + * @param {object} [options={}] + */ + async showLocationInParentSystem(id, options = {}) { + const parentId = this._app.getManager('scene').getParent(id); + await this.showLocation(id, parentId, parentId, 'northPole', options); + } + + /** + * Show where object is located in the Solar system. + * @param {string} id - Target entity id + * @param {object} [options={}] + */ + async showLocationInSolarSystem(id, options = {}) { + let parent = this._scene.getEntity(id).getParent(); + if (parent.getName() !== 'sun') { + while (parent.getParent().getName() !== 'sun') { + parent = parent.getParent(); + } + } + else { + parent = this._scene.getEntity('earth'); + } + + await this.showLocation(id, parent.getName(), 'sun', 'planeNormal', options); + } +} + +CameraScripts.CONTEXT = { + CELESTIAL_OBJECT: 0, + SPACECRAFT: 1, + ALIGN_SPACECRAFT: 2, + LOCATION: 3, + SYSTEM: 4, + COMPARE: 5, + LOOK_AT: 6, + LOCKED_ON: 7, + INSTRUMENT: 8, + ALIGN_OBJECTS: 9, + CENTER_SYSTEM: 10, + CENTER_LOCATION: 11 +}; + + +/***/ }), + +/***/ "../eyes/src/managers/comparison_manager.js": +/*!**************************************************!*\ + !*** ../eyes/src/managers/comparison_manager.js ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ComparisonManager": function() { return /* binding */ ComparisonManager; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); + + + + +/** + * The Comparison Manager class. + */ +class ComparisonManager extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + */ + constructor(app) { + super(app); + + /** + * The left viewport. + * @type {Pioneer.Viewport} + * @private + */ + this._viewportLeft = null; + + /** + * The right viewport. + * @type {Pioneer.Viewport} + * @private + */ + this._viewportRight = null; + + /** + * The left scene. + * @type {Pioneer.Scene} + * @private + */ + this._sceneLeft = null; + + /** + * The right scene. + * @type {Pioneer.Scene} + * @private + */ + this._sceneRight = null; + + /** + * The left anchor entity. + * @type {Pioneer.Entity} + * @private + */ + this._anchorEntityLeft = null; + + /** + * The right anchor entity. + * @type {Pioneer.Entity} + * @private + */ + this._anchorEntityRight = null; + + /** + * The left entity. + * @type {Pioneer.Entity} + * @private + */ + this._entityLeft = null; + + /** + * The right entity. + * @type {Pioneer.Entity} + * @private + */ + this._entityRight = null; + + /** + * The left sun. + * @type {Pioneer.Entity} + * @private + */ + this._sunLeft = null; + + /** + * The right sun. + * @type {Pioneer.Entity} + * @private + */ + this._sunRight = null; + + /** + * A list of viewports that were active before comparison started, so they can be re-enabled later. + * @type {number[]} + * @private + */ + this._activeViewports = []; + + /** + * Custom rotations for comparing objects. + * @type {Record} + * @private + */ + this._customRotations = { + rose_bowl: [['x', 45], ['z', 180]], + sc_juno: [['x', 45], ['z', 180]], + saturn: [['x', 25]], + sc_lucy: [['z', -90], ['y', -25]], + sc_ixpe: [['z', -90], ['y', 180]], + sc_hubble_space_telescope: [['x', 90], ['z', 90]], + sc_jwst: [['x', 180], ['y', 180]], + sc_psyche: [['x', 90], ['z', 90]], + sc_stardust: [['x', 90]], + sc_osiris_rex_src: [['x', 90]], + sc_stardust_src: [['z', 90]], + sc_acs3: [['x', 90]] + }; + + /** + * Zoom sensitivity for zoom functions. + * @type {{click: number, hold: number}} + * @private + */ + this._zoomSensitivity = { + click: 0.3, + hold: 0.1 + }; + + // Setup the bind functions. + this.bindFunctions(['_adjustZoomFromViewport', 'zoomIn', 'zoomOut']); + + // Create the left and right scenes. + this._sceneLeft = this.pioneer.addScene('comparisonLeft'); + this._sceneLeft.setAmbientLightColor(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(0.005, 0.005, 0.005)); + this._sceneRight = this.pioneer.addScene('comparisonRight'); + this._sceneRight.setAmbientLightColor(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(0.005, 0.005, 0.005)); + + // Create scene backgrounds. + pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create('observable_universe', this._sceneLeft); + pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create('milky_way', this._sceneLeft); + pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create('observable_universe', this._sceneRight); + pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create('milky_way', this._sceneRight); + + // Create the suns. + this._sunLeft = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create('sun', this._sceneLeft, { nameSuffix: '_compare' }); + this._sunRight = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create('sun', this._sceneRight, { nameSuffix: '_compare' }); + + // Create the compare entity locations. + this._anchorEntityLeft = this._sceneLeft.addEntity('anchorLeft'); + this._anchorEntityLeft.setParent(this._sceneLeft.getEntity('sun_compare')); + this._anchorEntityLeft.setPosition(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(1e8, 0, 0)); + this._anchorEntityLeft.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity); + this._anchorEntityRight = this._sceneRight.addEntity('anchorRight'); + this._anchorEntityRight.setParent(this._sceneRight.getEntity('sun_compare')); + this._anchorEntityRight.setPosition(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(1e8, 0, 0)); + this._anchorEntityRight.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity); + + // Create the left and right cameras. + this._cameraEntityLeft = this._sceneLeft.addEntity('cameraLeft'); + this._cameraEntityLeft.setParent(this._anchorEntityLeft); + this._cameraLeft = /** @type {Pioneer.CameraComponent} */(this._cameraEntityLeft.addComponent('camera')); + this._cameraLightLeft = /** @type {Pioneer.LightSourceComponent} */(this._cameraEntityLeft.addComponent('lightSource')); + this._cameraLightLeft.setEnabled(false); + this._cameraEntityRight = this._sceneRight.addEntity('cameraRight'); + this._cameraEntityRight.setParent(this._anchorEntityRight); + this._cameraRight = /** @type {Pioneer.CameraComponent} */(this._cameraEntityRight.addComponent('camera')); + this._cameraLightRight = /** @type {Pioneer.LightSourceComponent} */(this._cameraEntityRight.addComponent('lightSource')); + this._cameraLightRight.setEnabled(false); + + // Create left and right viewports + this._viewportLeft = this.pioneer.addViewport('left-viewport'); + this._viewportLeft.getDiv().className = 'compare-viewport left-desktop'; + this._viewportLeft.setEnabled(false); + this._viewportLeft.setCamera(this._cameraLeft); + this._viewportRight = this.pioneer.addViewport('right-viewport'); + this._viewportRight.getDiv().className = 'compare-viewport right-desktop'; + this._viewportRight.setEnabled(false); + this._viewportRight.setCamera(this._cameraRight); + + // Add a callback to adjust the zooms. + this.pioneer.addCallback(this._adjustZoomFromViewport.bind(this), true); + } + + /** + * Gets the left entity. + * @returns {Pioneer.Entity} + */ + get entityLeft() { + return this._entityLeft; + } + + /** + * Gets the right entity. + * @returns {Pioneer.Entity} + */ + get entityRight() { + return this._entityRight; + } + + /** + * Zooms In + * @param {boolean} isContinuous + */ + zoomIn(isContinuous = false) { + let zoomChange = 1.0; + const zoomSensitivity = isContinuous ? this._zoomSensitivity.hold : this._zoomSensitivity.click; + zoomChange /= Math.pow(2, zoomSensitivity); + + const camera = /** @type {CameraManager} */(this.app.getManager('camera')); + camera.zoom(zoomChange, this._cameraEntityLeft); + camera.zoom(zoomChange, this._cameraEntityRight); + } + + /** + * Zooms Out + * @param {boolean} isContinuous + */ + zoomOut(isContinuous = false) { + let zoomChange = 1.0; + const zoomSensitivity = isContinuous ? this._zoomSensitivity.hold : this._zoomSensitivity.click; + zoomChange *= Math.pow(2, zoomSensitivity); + + const camera = /** @type {CameraManager} */(this.app.getManager('camera')); + camera.zoom(zoomChange, this._cameraEntityLeft); + camera.zoom(zoomChange, this._cameraEntityRight); + } + + /** + * Compare two objects. + * @param {string} entityNameLeft + * @param {string} entityNameRight + */ + async compare(entityNameLeft, entityNameRight) { + // Remove any old entities, if needed. + if (this._entityLeft && this._entityLeft.getName() !== entityNameLeft) { + this._sceneLeft.removeEntity(this._entityLeft); + this._entityLeft = null; + } + if (this._entityRight && this._entityRight.getName() !== entityNameRight) { + this._sceneRight.removeEntity(this._entityRight); + this._entityRight = null; + } + + // Create the entities, if needed. + const contentManager = this.app.getManager('content'); + const labelManager = this.app.getManager('label'); + if (!this._entityLeft) { + this._entityLeft = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create(entityNameLeft, this._sceneLeft); + this._entityLeft.clearParentingTableEntries(); + this._entityLeft.clearControllers(); + this._entityLeft.setParent(this._anchorEntityLeft); + this._entityLeft.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero); + const orientation = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(); + this._getCustomRotation(orientation, entityNameLeft, 'left'); + this._entityLeft.setOrientation(orientation); + this._entityLeft.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent).setFadeWhenCloseToEntity('sun'); + + labelManager.setLabelProps({ + getLabelClass: entityName => `no-select ${contentManager.getClassName(entityName, '') ?? ''}`, + handleTouch: null, + handleClick: null + }, [entityNameLeft], this._sceneLeft, this._cameraEntityLeft); + } + if (!this._entityRight) { + this._entityRight = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create(entityNameRight, this._sceneRight); + this._entityRight.clearParentingTableEntries(); + this._entityRight.clearControllers(); + this._entityRight.setParent(this._anchorEntityRight); + this._entityRight.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero); + const orientation = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(); + this._getCustomRotation(orientation, entityNameRight, 'right'); + this._entityRight.setOrientation(orientation); + this._entityRight.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent).setFadeWhenCloseToEntity('sun'); + + labelManager.setLabelProps({ + getLabelClass: entityName => `no-select ${contentManager.getClassName(entityName, '') ?? ''}`, + handleTouch: null, + handleClick: null + }, [entityNameRight], this._sceneRight, this._cameraEntityRight); + } + + // Update the suns based on the lighting and if an entity is the sun. + this._updateSuns(); + + // Activate viewports, if needed. + if (!this._viewportLeft.isEnabled()) { + // Disable all other active viewports. + for (let i = 0, l = this.pioneer.getNumViewports(); i < l; i++) { + const viewport = this.pioneer.getViewport(i); + if (viewport.isEnabled()) { + this._activeViewports.push(i); + viewport.setEnabled(false); + } + } + // Enable compare viewports + this._viewportLeft.setEnabled(true); + this._viewportRight.setEnabled(true); + // Turn off the camera light for default. + this.setCameraLight(true); + // Send out an event. + const event = new CustomEvent('comparisonenter', { detail: { } }); + window.dispatchEvent(event); + } + + // Calculate a good initial distance. + const distLeft = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Cameras.getDistanceToFitEntities(this._cameraEntityLeft, pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity, this._entityLeft, [this._entityLeft]); + const distRight = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Cameras.getDistanceToFitEntities(this._cameraEntityRight, pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity, this._entityRight, [this._entityRight]); + let dist = Math.max(distRight, distLeft); + dist *= 1.6; + + // Calculate positions from the distance. + const cameraPositionLeft = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(); + cameraPositionLeft.setMagnitude(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg, dist); + const cameraPositionRight = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(); + cameraPositionRight.setMagnitude(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg, dist); + + // Clear out the camera controllers so that any existing transition doesn't continue. + this._cameraEntityLeft.clearControllers(); + this._cameraEntityRight.clearControllers(); + + // Send out an event. + const event = new CustomEvent('cameracompare', { detail: { left: entityNameLeft, right: entityNameRight } }); + window.dispatchEvent(event); + + // Do the camera transitions. + const cameraManager = /** @type {CameraManager} */(this.app.getManager('camera')); + const transitionLeftPromise = cameraManager.goToEntity('anchorLeft', { + minRadius: dist * 0.5, + maxRadius: dist * 10, + camera: this._cameraEntityLeft, + destination: cameraPositionLeft, + destinationUp: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + scene: this._sceneLeft, + select: false, + zoom: true, + cinematic: true + }); + const transitionRightPromise = cameraManager.goToEntity('anchorRight', { + minRadius: dist * 0.5, + maxRadius: dist * 10, + camera: this._cameraEntityRight, + destination: cameraPositionRight, + destinationUp: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + scene: this._sceneRight, + select: false, + zoom: true, + cinematic: true + }); + await Promise.all([transitionLeftPromise, transitionRightPromise]); + + // Wait until everything is loaded. + const sceneManager = /** @type {SceneManager} */(this.app.getManager('scene')); + sceneManager.addLoading(this._entityLeft.getName(), 'compare'); + sceneManager.addLoading(this._entityRight.getName(), 'compare'); + await Promise.all([this._entityLeft.getLoadedPromise(), this._entityRight.getLoadedPromise()]); + sceneManager.removeLoading(this._entityLeft.getName(), 'compare'); + sceneManager.removeLoading(this._entityRight.getName(), 'compare'); + } + + /** + * Toggles between camera and sun lights + * @param {boolean} active + * @param {Pioneer.Color} [color] + */ + setCameraLight(active, color) { + this._cameraLightLeft.setEnabled(active); + this._cameraLightRight.setEnabled(active); + if (color !== undefined) { + this._cameraLightLeft.setColor(color); + this._cameraLightRight.setColor(color); + } + this._updateSuns(); + } + + /** + * Exit comparison + */ + exit() { + // Remove any old entities. + if (this._entityLeft) { + this._sceneLeft.removeEntity(this._entityLeft); + this._entityLeft = null; + } + if (this._entityRight) { + this._sceneRight.removeEntity(this._entityRight); + this._entityRight = null; + } + + // Disable compare viewports + this._viewportLeft.setEnabled(false); + this._viewportRight.setEnabled(false); + + // Enable previously active viewports + for (let i = 0; i < this._activeViewports.length; i++) { + const viewportNum = this._activeViewports[i]; + const viewport = this.pioneer.getViewport(viewportNum); + viewport.setEnabled(true); + } + this._activeViewports = []; + + // Send the event. + const event = new CustomEvent('comparisonexit', { detail: { } }); + window.dispatchEvent(event); + } + + /** + * Update the suns based on the camera light and if the comparison object is the sun. + * @private + */ + _updateSuns() { + // If one of them is the sun, turn off the background sun. + const sunLeftEnabled = this._entityLeft?.getName() !== 'sun' && (!this._cameraLightLeft.isEnabled() || this._cameraLightLeft.getColor().min() < 1); + const sunRightEnabled = this._entityRight?.getName() !== 'sun' && (!this._cameraLightRight.isEnabled() || this._cameraLightRight.getColor().min() < 1); + this._sunLeft.getComponentByType('spheroidLOD').setEnabled(sunLeftEnabled); + this._sunLeft.getComponentByType('atmosphere').setEnabled(sunLeftEnabled); + this._sunLeft.getComponentByType('sprite').setEnabled(sunLeftEnabled); + this._sunLeft.getComponentByType('lightSource').setEnabled(sunLeftEnabled); + this._sunRight.getComponentByType('spheroidLOD').setEnabled(sunRightEnabled); + this._sunRight.getComponentByType('atmosphere').setEnabled(sunRightEnabled); + this._sunRight.getComponentByType('sprite').setEnabled(sunRightEnabled); + this._sunRight.getComponentByType('lightSource').setEnabled(sunRightEnabled); + } + + /** + * Adjust both viewport distances based on the camera distance. + * @private + */ + _adjustZoomFromViewport() { + // If the viewports are disabled, return. + if (!this._viewportLeft.isEnabled()) { + return; + } + if (!this._viewportRight.isEnabled()) { + return; + } + // Get the current distance of the left camera. + let currentDistance = this._cameraEntityLeft.getPosition().magnitude(); + if (Number.isNaN(currentDistance)) { + currentDistance = 1.0; + } + const activeViewport = this.app.pioneer.getInput().getActiveViewport(); + if (activeViewport && activeViewport.getName() === 'right-viewport') { + currentDistance = this._cameraEntityRight.getPosition().magnitude(); + if (Number.isNaN(currentDistance)) { + currentDistance = 1.0; + } + } + // Set the positions to be the current distance. + const currentLeftPosition = pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.get(); + currentLeftPosition.setMagnitude(this._cameraEntityLeft.getPosition(), currentDistance); + const currentRightPosition = pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.get(); + currentRightPosition.setMagnitude(this._cameraEntityRight.getPosition(), currentDistance); + this._cameraEntityLeft.setPosition(currentLeftPosition); + this._cameraEntityRight.setPosition(currentRightPosition); + pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.release(currentLeftPosition); + pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.release(currentRightPosition); + } + + /** + * Applies custom rotations to certain entities, so they look good. + * @param {Pioneer.Quaternion} outRotation + * @param {string} entityName + * @param {'left' | 'right'} side + * @private + */ + _getCustomRotation(outRotation, entityName, side) { + outRotation.set(1, 0, 0, 0); + if (this._customRotations[entityName] !== undefined) { + const customRotation = this._customRotations[entityName]; + for (let i = 0, l = customRotation.length; i < l; i++) { + let axis; + if (customRotation[i][0] === 'x') { + axis = pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis; + } + else if (customRotation[i][0] === 'y') { + axis = pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis; + } + else if (customRotation[i][0] === 'z') { + axis = pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis; + } + else { + throw new Error(`Invalid model rotate axis "${customRotation[i][0]}".`); + } + let angle = customRotation[i][1]; + + angle = pioneer__WEBPACK_IMPORTED_MODULE_1__.MathUtils.degToRad(angle); + const rotation = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(); + rotation.setFromAxisAngle(axis, angle); + outRotation.mult(outRotation, rotation); + } + } + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/content_manager.js": +/*!***********************************************!*\ + !*** ../eyes/src/managers/content_manager.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ContentManager": function() { return /* binding */ ContentManager; } +/* harmony export */ }); +/* harmony import */ var moment_timezone__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! moment-timezone */ "../eyes/node_modules/moment-timezone/index.js"); +/* harmony import */ var moment_timezone__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(moment_timezone__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + +/** + * @typedef EntityInfo + * @property {string} id + * @property {string} displayName + * @property {string} category + * @property {string} [iauName] + * @property {string} [subcategory] + * @property {boolean} [searchable] + * @property {string[]} [keywords] + * @property {boolean} [hasMoons] + * @property {Object} [related] + * @property {string} [landingDate] + * @property {number} [customDistance] + * @property {boolean} [hasEvents] + * @property {string[]} [forceVisibleEntities] + * @property {string[]} [ignoreDependentWhenUnloading] + */ + +/** + * Content Manager class. + * @extends BaseManager + */ +class ContentManager extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseManager { + /** + * Constructor + * @param {BaseApp} app + * @private + */ + constructor(app) { + super(app); + + /** + * The list of all entities. + * @type {Object} + * @private + */ + this._entityList = null; + + /** + * The list of entities grouped by categories. + * @type {Object>} + * @private + */ + this._entitiesByCategory = {}; + + /** + * The list of entities grouped by sub-categories. + * @type {Object>} + * @private + */ + this._entitiesBySubCategory = {}; + + /** + * Content of all stories. + * @type {object} + * @private + */ + this._stories = {}; + + /** + * The list of all available story cards. + * @type {object} + * @private + */ + this._storyList = null; + + /** + * The target to load corresponding contents. + * Mostly used to prevent duplicated fetch. + * @type {string} + * @private + */ + this._target = null; + + /** + * Context of current target. + * @type {object} + * @private + */ + this._context = {}; + + /** + * All events of a target. + * @type {object} + * @private + */ + this._context.events = {}; + + /** + * All events of a target, ordered by start date. + * @type {object} + * @private + */ + this._context.orderedEvents = {}; + + /** + * Description of an event. + * @type {object} + * @private + */ + this._context.eventDesc = {}; + + /** + * Currently loaded story. + * @type {object} + * @private + */ + this._context.story = {}; + + /** + * Folders to fetch files from. + * @type {object} + * @property {string} [description='/'] - Folder containing description files + * @property {string} [event='/'] - Folder containing event files + * @private + */ + this._folders = { + description: '/', + event: '/', + stories: '/' + }; + } + + /** + * Gets the entity list. + * @returns {object} + */ + getEntityList() { + return this._entityList; + } + + /** + * Sets the entity list. + * @param {object} entityList - List of entities + */ + setEntityList(entityList) { + for (const [key, value] of Object.entries(entityList)) { + if (value.disabled === true) { + delete entityList[key]; + } + } + this._entityList = entityList; + + Object.keys(this._entityList).forEach(k => { + const { category } = this._entityList[k]; + + // Category + if (this._entitiesByCategory[category]) { + // Populate category list + this._entitiesByCategory[category].push(this._entityList[k]); + } + else { + // Create category list + this._entitiesByCategory[category] = [this._entityList[k]]; + } + + // Subcategory + let { subcategory } = this._entityList[k]; + if (!subcategory || subcategory === '') { + subcategory = category; + } + if (this._entitiesBySubCategory[subcategory]) { + // Populate subcategory list + this._entitiesBySubCategory[subcategory].push(this._entityList[k]); + } + else { + // Create subcategory list + this._entitiesBySubCategory[subcategory] = [this._entityList[k]]; + } + }); + } + + /** + * Returns the entity global information from the entity list file, or null if it is not found. + * @param {string} id - The entity id. + * @returns {EntityInfo | null} + */ + getEntityInfo(id) { + if (id in this._entityList) { + return this._entityList[id]; + } + else { + return null; + } + } + + /** + * Returns an entity description. + * @param {string} id - The entity id. + * @returns {object} + */ + async getEntityDesc(id) { + let entityDesc = null; + try { + entityDesc = await _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.loadJSON("https://eyes.nasa.gov/apps/asteroids/descriptions/" + id + '.json'); + } + catch (err) { + entityDesc = null; + } + return entityDesc; + } + + /** + * Sets/Updates folders for fetching files. + * @param {object} [folders={}] + */ + setFolders(folders = {}) { + for (const key in folders) { + if (Object.prototype.hasOwnProperty.call(folders, key)) { + folders[key] = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.addEndToPath(folders[key]); + this._folders[key] = folders[key]; + } + } + } + + /** + * Gets the list of cards. + * @returns {object} + */ + getStoryList() { + return this._storyList; + } + + /** + * Set the cards + * @param {object} allStories - List of cards + */ + setStoryList(allStories) { + this._storyList = allStories; + } + + /** + * Get a story from story list. + * @param {string} id - Story ID + * @returns {object} + */ + getStory(id) { + if (!id) { + throw new Error('[ContentManager.getStory]: id is required.'); + } + if (!this._stories[id]) { + throw new Error(`[ContentManager.getStory]: Cannot find story with id ${id}.`); + } + + this._context.story = this._stories[id]; + return this._context.story; + } + + /** + * Set stories content. + * @param {object} stories + */ + setStories(stories) { + this._stories = stories; + } + + /** + * Load multiple description files. + * @param {string[]} itemsList - a name or a list of names + * @param {CancelToken} cancelToken + * @returns {Promise} + */ + async loadDescriptions(itemsList, cancelToken) { + for (let i = 0; i < itemsList.length; i++) { + const item = itemsList[i]; + const desc = await this.getEntityDesc(item); + if (cancelToken && cancelToken.isCanceled) { + return; + } + this._context[item] = desc; + } + } + + /** + * Load event files of a target. + * @param {string} target + * @param {string} [fileNames={}] - JSON files + * @param {CancelToken} cancelToken + */ + async loadEvents(target, fileNames = {}, cancelToken) { + if (!target) { + return; + } + + const eventFolder = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.addEndToPath(this._folders.event + target); + + if (fileNames.all) { + if (this._target !== target || _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.isEmptyObject(this._context.events)) { + let allEvents = null; + try { + allEvents = await _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.loadJSON(eventFolder + fileNames.all); + } + catch (err) { + allEvents = null; + } + if (cancelToken && cancelToken.isCanceled) { + return; + } + + this._context.events = allEvents; + + if (this._context.events !== null) { + // Convert object to array + const orderedEvents = []; + for (const [key, value] of Object.entries(this._context.events)) { + if (value.start) { + value.start = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().tz(value.start, 'Etc/UTC'); + } + else { + console.error('[Content Manager] Error: event missing start date ' + target + ' ' + key); + continue; + } + if (value.end) { + value.end = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().tz(value.end, 'Etc/UTC'); + } + orderedEvents.push(value); + } + + // Sort by start time + orderedEvents.sort((a, b) => a.start.valueOf() - b.start.valueOf()); + this._context.orderedEvents = orderedEvents; + } + else { + this._context.orderedEvents = null; + } + } + } + + if (fileNames.event) { + // Check for template file + const event = this._context.events[fileNames.event]; + const eventFile = (event && event.template) ? event.template : fileNames.event; + + let eventDesc = null; + try { + eventDesc = await _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.loadJSON(eventFolder + eventFile); + } + catch (err) { + eventDesc = null; + } + if (cancelToken && cancelToken.isCanceled) { + return; + } + this._context.eventDesc = eventDesc; + } + + this._target = target; + } + + /** + * Returns an array of spheroidLayers for an entity (or undefined) + * @param {string} entityId + * @returns {object} + */ + getSpheroidLayers(entityId) { + return this._entityShperoidLayersList[entityId]; + } + + /** + * Load WMTS, CMS and surface map info + * @param {object} layersArray + */ + setSpheroidLayers(layersArray) { + this._entityShperoidLayersList = layersArray; + } + + /** + * Returns an array of spheroidFeatures for an entity (or empty array if none exist for the entity). + * @param {string} entityId + * @returns {object} + */ + getSpheroidFeatures(entityId) { + return this._entityShperoidFeaturesList[entityId] || []; + } + + /** + * Load Features info (Magnetosphere, Auroras, radiation belts). + * @param {object} featuresArray + */ + setSpheroidFeatures(featuresArray) { + this._entityShperoidFeaturesList = featuresArray; + } + + /** + * Returns the css classname of the color associated with this entityId in color.css + * @param {string} entityId + * @returns {string} + */ + getColorClass(entityId) { + let colorClass = ''; + if (!this.getEntityInfo(entityId)) { + return colorClass; + } + + const entityInfoCategory = this.getEntityInfo(entityId).category; + + switch (entityInfoCategory) { + case 'Asteroid': { + colorClass = 'asteroid'; + break; + } + case 'Instrument': + case 'Spacecraft': { + colorClass = 'spacecraft'; + break; + } + case 'Planet': { + colorClass = entityId; + break; + } + case 'Dwarf Planet': { + colorClass = 'dwarf-planet'; + break; + } + case 'Comet': { + colorClass = 'comet'; + break; + } + case 'Barycenter': + case 'Moon': { + colorClass = 'moon'; + break; + } + case 'Universe': + case 'Galaxy': + case 'Star': { + colorClass = 'sun'; + break; + } + default: { + colorClass = ''; + } + } + + return colorClass; + } + + /** + * Returns true if the entity has a landed. + * @param {object} entityInfo + * @returns {boolean} + */ + hasLanded(entityInfo) { + if (!entityInfo.landingDate || entityInfo.landingDate === '') { + return false; + } + + // Check if category match lander categories + const categories = ['Lander', 'Rover']; + if (categories.indexOf(entityInfo.subcategory) < 0) { + return false; + } + + // Check if landing date is after current time + const landing = this._app.getManager('time').parseTime(entityInfo.landingDate); + const current = this._app.getManager('time').getTime(); + if (current.isSameOrAfter(landing)) { + return true; + } + else { + return false; + } + } + + // TODO: Rework / currently used by labels + /** + * getClassName + * @param {*} id + * @param {string} category - optional category + * @returns {string} + */ + getClassName(id, category) { + const entityInfo = this.getEntityInfo(id); + + let className = id; + + // Add category + if (category) { + className += ' ' + category.toLowerCase().replace(/ /g, '-'); + } + else if (entityInfo !== null && entityInfo.category !== undefined) { + const category = entityInfo.category.toLowerCase().replace(/ /g, '-'); + className += ' ' + category; + } + + // Cant start with a number + if (className.match(/^\d/)) { + className = '_' + className; + } + + return className; + } + + /** + * Returns true if the entity information has a specific keyword. + * @param {string} id - The entity id. + * @param {string} keyword - The keyword searched. + * @returns {boolean} + */ + hasKeyword(id, keyword) { + if (this.getEntityInfo(id) !== undefined) { + return this.getEntityInfo(id).keywords.includes(keyword); + } + } + + /** + * Resets the context. + */ + resetContext() { + this._context = {}; + this._context.events = {}; + this._context.eventDesc = {}; + this._context.orderedEvents = {}; + this._context.story = {}; + } + + /** + * Hide external links + * @param {string} text + * @returns {string} + */ + hideExternalLinksInText(text) { + // Remove all external links/replcae them with the text that was already there + return text.replaceAll(/]*>(.*?)<\/a>/g, '$2'); + } + + /** + * Hide external link stories from story list + */ + hideExternalLinkStoryList() { + const stories = this.getStoryList(); + const internalStories = {}; + const externalStoryIds = stories['external'] ? Object.keys(stories['external']) : []; + + for (const [category, storyListItems] of Object.entries(stories)) { + if (category !== 'external') { + internalStories[category] = storyListItems; + + // Remove any external story from other story categories in list, such as 'featured' + const storyListIsArray = Array.isArray(storyListItems); + if (storyListIsArray) { + const listWithoutExternal = storyListItems.filter(id => !externalStoryIds.includes(id)); + if (listWithoutExternal.length > 0) { + internalStories[category] = listWithoutExternal; + } + } + else { + // If the story list item is an object, remove any keys that match the external stories + const externalStoriesInKeys = Object.keys(storyListItems).filter(key => externalStoryIds.includes(key)); + for (let i = 0; i < externalStoriesInKeys.length; i++) { + delete storyListItems[externalStoriesInKeys[i]]; + } + } + } + } + + this.setStoryList(internalStories); + } + + /** + * Display error message and throw previous url. + * @param {string} err - Original error message + * @param {string} [message=''] - Message to concate in front of error message + * @throws {string} + */ + _handleError(err, message = '') { + console.error(message + err); + let url = this.app.getManager('router').previousRoute.url; + if (!url) { + url = this.app.getManager('router').homeRoute; + } + err.previousRoute = url; + throw err; + } + + /** + * Get entities grouped by category. + * @returns {object} + */ + get entitiesByCategory() { + return this._entitiesByCategory; + } + + /** + * Get entities grouped by category. + * @returns {object} + */ + get entitiesBySubCategory() { + return this._entitiesBySubCategory; + } + + /** + * Get context of current target. + * @returns {object} + */ + get context() { + return this._context; + } + + /** + * Get all events for current target. + * @returns {object} + */ + get events() { + return this._context.events; + } + + /** + * Get all events for current target ordered by start date. + * @returns {object} + */ + get orderedEvents() { + return this._context.orderedEvents; + } + + /** + * Get description for current event. + * @returns {object} + */ + get eventDesc() { + return this._context.eventDesc; + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/ert_manager.js": +/*!*******************************************!*\ + !*** ../eyes/src/managers/ert_manager.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ERTManager": function() { return /* binding */ ERTManager; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + +/** @typedef {import('moment-timezone')} moment */ + +/** + * ERT manager class. + * @extends BaseManager + */ +class ERTManager extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseManager { + /** + * @inheritdoc + * @param {BaseApp} app + * @param {object} [options={}] + * @param {boolean} [options.isERT=false] + * @param {string} [options.ertTarget=''] + * @param {SceneManager} [options.sceneMgr=null] + */ + constructor(app, { isERT = false, ertTarget = '', sceneMgr = null } = {}) { + super(app); + + this._isERT = isERT; + this._ertTarget = ertTarget; + this._sceneMgr = sceneMgr; + + this.getNow = this.getNow.bind(this); + } + + /** + * Get status on/off of Earth Received Time mode. + * @returns {boolean} + */ + isERT() { + return this._isERT; + } + + /** + * Sets Earth Received Time mode on/off for time display. + * @param {boolean} isERT - on/off + */ + setERT(isERT) { + this._isERT = isERT; + } + + /** + * Get target for Earth Received Time. + * @returns {string} + */ + getERTTarget() { + return this._ertTarget; + } + + /** + * Set target for Earth Received Time. + * @param {string} target + */ + setERTTarget(target) { + this._ertTarget = target; + } + + /** + * Get scene manager for Earth Received Time. + * @returns {SceneManager} + */ + getERTScene() { + return this._sceneMgr; + } + + /** + * Set scene manager for Earth Received Time. + * @param {SceneManager} sceneMgr + */ + setERTScene(sceneMgr) { + this._sceneMgr = sceneMgr; + } + + /** + * Get ERT offset in seconds. + * @returns {number} + */ + getERTOffset() { + if (this._sceneMgr !== null) { + const distance = this._sceneMgr.getDistance(this._ertTarget, 'earth', { subtractRadius: true }); + return distance / _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.constants.speedOfLight; + } + else { + console.warn('Clock: could not get scene manager.'); + return 0; + } + } + + /** + * Get ERT from time. + * @param {moment} time - Time at target + * @returns {moment} + */ + getERTFromTime(time) { + const offset = this.getERTOffset(); + time.add(offset, 's'); + return time; + } + + /** + * Get time at target from ERT. + * @param {moment} time - Earth Received Time + * @returns {moment} + */ + getTimeFromERT(time) { + const offset = this.getERTOffset(); + time.subtract(offset, 's'); + return time; + } + + /** + * Get now time based on ERT mode. + * @param {moment} time + * @returns {moment} + */ + getNow(time) { + if (this._isERT) { + return this.getTimeFromERT(time); + } + else { + return time; + } + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/label_manager.js": +/*!*********************************************!*\ + !*** ../eyes/src/managers/label_manager.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LabelManager": function() { return /* binding */ LabelManager; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); +/* harmony import */ var _lib_quadtree__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../lib/quadtree */ "../eyes/src/lib/quadtree.js"); + +// Import locals + + + +/** + * Label Manager class. + * @extends BaseManager + */ +class LabelManager extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + * @param {Pioneer.Scene} scene + */ + constructor(app, scene) { + super(app); + + /** + * Main Pioneer scene. + * @type {Pioneer.Scene} + */ + this._scene = scene; + + this._eventNames.push('hoverchange', 'labelclicked'); + this._initCallbacks(); + + /** + * Classname for icons based on category. + * @type {Object} + */ + this._iconMap = { + Universe: 'no-icon', + Galaxy: 'no-icon', + Star: 'no-icon', + Barycenter: 'icon-circle-white-small', + 'Landing site': 'icon-hexagon', + Moon: 'icon-circle-white-small', + Asteroid: 'icon-circle-white-small', + 'Dwarf Planet': 'icon-circle-white-small', + Comet: 'icon-circle-white-small', + Spacecraft: 'icon-hexagon', + Planet: 'icon-circle-', + Default: 'icon-circle-white-small' + }; + + /** + * Weight map for label priority. + * @type {Object} + */ + this._weightMap = { + Universe: '100', + Galaxy: '100', + Star: '100', + Barycenter: '0', + 'Landing site': '5', + Asteroid: '15', + Comet: '15', + Moon: '25', + 'Dwarf Planet': '28', + Spacecraft: '30', + Planet: '50' + }; + + /** + * An object storing weights of labels. + * @type {object} - { id: { weight: num }} + */ + this._weights = {}; + + /** + * TODO: Seems to be unused + * Method for finding conflicting labels + * @type {number} + */ + this._algorithm = this.Quadtree; + + /** + * Quadtree object. + * @type {Quadtree} + * @private + */ + this._quadTree = new Quadtree({ // TODO: Quadtree is not defined nearby. + x: 0, + y: 0, + width: window.innerWidth, + height: window.innerHeight + }, 2, 8); + + /** + * Custom label object storing various label information. + * @type {object} + */ + this._labels = {}; + + /** + * Array to store collinding labels ordered by weight. + * @type {string[]} + */ + this._collidingLabels = []; + + // Manage multiple frame operations + this._frameCount = 0; + this._frameStep = 1; + this._frameCycle = this._frameStep * 3; + + /** + * Sets name for active label class. + * @type {string} + */ + this._activeClass = 'active'; + + /** + * Sets name for hidden label class. + * @type {string} + */ + this._hiddenClass = 'hidden'; + + /** + * Sets default overlap percentage threshold to hide conflicting labels. + * @type {number} - between 0.0 and 1.0 + */ + this._overlapThreshold = 0.25; + + /** + * All labels are clickable or not. + * @type {boolean} + */ + this._isClickable = true; + + /** + * Update loop is stopped or not. + * @type {boolean} + */ + this._isPaused = false; + + /** + * Stores if the label was clicked to prevent conflict with select controller. + * @type {boolean} + */ + this._allLabelsHidden = false; + + /** + * Exceptions on hiding labels. + * @type {Set} + */ + this._exceptions = new Set(); + + /** + * Center bouding rect object. + * @type {object} + */ + this._centerBoundingRect = { + name: 'center', + x: 0, + y: 0, + width: 50, + height: 50 + }; + + this.bindFunctions([ + 'update', + 'toggleLabels', + 'toggleLabelForEntity', + 'toggleIcons', + 'toggleIconForEntity', + '_clickCallback', + 'setUpLabel', + 'removeLabel', + 'setUpIcon' + ]); + } + + /** + * Sets the list of all entities. + * @param {Pioneer.Collection} entities + */ + setEntities(entities) { + this._labels = {}; + for (let i = entities.size - 1; i >= 0; i--) { + const entity = entities.get(i); + this.addEntity(entity); + } + } + + /** + * Adds an entity to the label manager. + * @param {Pioneer.Entity} entity + */ + addEntity(entity) { + if (entity.getComponentByType('div')) { + this._labels[entity.getName()] = { + name: entity.getName(), + el: entity.getComponentByType('div').getDiv(), + x: 0, + y: 0, + width: 0, + height: 0, + check: false, + collisions: [], + isHidden: false, + isClickable: true + }; + } + } + + /** + * Removes an entity to the label manager. + * @param {Pioneer.Entity} entity + */ + removeEntity(entity) { + if (this._labels[entity.getName()] !== undefined) { + delete this._labels[entity.getName()]; + } + } + + /** + * TODO Variable is not used anywhere + * Sets type of algorithm to use. + * @param {number} algo + */ + setAlgorithm(algo) { + this._algorithm = algo; + } + + /** + * Sets the scene. + * @param {Pioneer.Scene} scene + */ + setScene(scene) { + this._scene = scene; + } + + /** + * Sets weights for labels. + * @param {object} weights + * @param {boolean} reset + */ + setWeights(weights, reset = true) { + if (reset) this._weights = {}; + for (const name of Object.keys(weights)) { + // Use category weight + const category = weights[name].category; + this._weights[name] = {}; + if (this._weightMap[category] !== undefined) { + this._weights[name].weight = this._weightMap[category]; + } + else { + this._weights[name].weight = 1; + } + } + } + + /** + * Removes label weights. + * @param {object} weights + */ + removeWeights(weights) { + for (const name of Object.keys(weights)) { + if (this._weights[name]) { + delete this._weights[name]; + } + } + } + + /** + * Gets weight for a label. + * @param {string} name + * @returns {number} + */ + getWeight(name) { + if (Object.keys(this._weights).length <= 0) { + return 0; + } + if (this._weights[name] !== undefined) { + return this._weights[name].weight; + } + return 0; + } + + /** + * Check if a label exists. + * @param {string} name + * @returns {boolean} + */ + isExisting(name) { + if (this._labels[name] === undefined) { + delete this._labels[name]; + return false; + } + return true; + } + + /** + * Setup labels. + * @param {Pioneer.Entity} entity + * @private + */ + setUpLabel(entity) { + const contentManager = /** @type {ContentManager} */ (this._app.getManager('content')); + const layerManager = /** @type {LayerManager} */ (this._app.getManager('layer')); + this.addEntity(entity); + this.setLabelProps({ + getLabelClass: entityName => `no-select ${contentManager.getClassName(entityName) ?? ''}` + }, [entity.getName()]); + + const targetId = entity.getName(); + const labelsLayer = layerManager.getLayer('labels'); + + // Reset visibility of trails + if (labelsLayer !== null && !labelsLayer.visible) { + this.toggleLabelForEntity(false, targetId); + } + } + + /** + * Removes the label on an entity. + * @param {Pioneer.Entity} entity + * @private + */ + removeLabel(entity) { + this.removeEntity(entity); + } + + /** + * Callback to execute custom code for icons after entity is created. + * @param {Pioneer.Entity} entity + * @private + */ + setUpIcon(entity) { + // Check status of icons with the layer manager + // Whatever custom code for icons we need to call after entity is created. + const layerManager = /** @type {LayerManager} */ (this._app.getManager('layer')); + const targetId = entity.getName(); + const iconsLayer = layerManager.getLayer('icons'); + + // Reset visibility of trails + if (iconsLayer !== null && !iconsLayer.visible) { + this.toggleIconForEntity(false, targetId); + } + } + + /** + * Sets the clickable boolean flag for a label of given label name. + * @param {string} labelName + * @param {boolean} clickable + */ + setLabelClickable(labelName, clickable) { + if (this._labels[labelName]) { + this._labels[labelName].isClickable = clickable; + this._labels[labelName].el.classList.toggle('clickable', clickable); + } + } + + /** + * Enable/disable all labels click. + * @param {boolean} isClickable + */ + setClickable(isClickable) { + this._isClickable = isClickable; + + for (let i = 0, l = this._scene.getNumEntities(); i < l; i++) { + const entity = this._scene.getEntity(i); + const divComponent = entity.get('div'); + if (divComponent !== null) { + const div = divComponent.getDiv(); + if (isClickable) { + div.classList.remove('unclickable'); + } + else { + div.classList.add('unclickable'); + } + } + } + } + + /** + * Add label to hiding exceptions. + * @param {string} label + */ + addException(label) { + this._exceptions.add(label); + } + + /** + * Remove label from hiding exceptions. + * @param {string} label + */ + removeException(label) { + this._exceptions.delete(label); + } + + /** + * Add labels to hiding exceptions. + * @param {string[]} labels + */ + addExceptions(labels) { + labels.forEach(label => this._exceptions.add(label)); + } + + /** + * Remove labels from hiding exceptions. + * @param {string[]} labels + */ + removeExceptions(labels) { + labels.forEach(label => this._exceptions.delete(label)); + } + + /** + * Toggles all the label names in the scene. + * @param {boolean} active + * @param {object} options + * @param {Pioneer.Scene} [options.scene = undefined] + */ + toggleLabels(active, { scene = undefined } = {}) { + if (scene === undefined) { + scene = this._scene; + } + + for (let i = 0; i < scene.getNumEntities(); i++) { + this.toggleLabelForEntity(active, scene.getEntity(i).getName(), { scene }); + } + } + + /** + * Toggles the label name for the specified entity. + * @param {boolean} active + * @param {string} entityId + * @param {object} options + * @param {Pioneer.Scene} [options.scene = undefined] + */ + toggleLabelForEntity(active, entityId, { scene = undefined } = {}) { + let currentScene = scene; + if (currentScene === undefined) { + currentScene = this._scene; + } + const entity = currentScene.getEntity(entityId); + const div = entity.get('div'); + if (this._exceptions.has(entity.getName())) { + return; + } + if (div !== null) { + if (active) { + div.getDiv().lastElementChild?.classList.remove('hidden'); + } + else { + div.getDiv().lastElementChild?.classList.add('hidden'); + } + } + } + + /** + * Toggles all the icons in the scene. + * @param {boolean} active + * @param {object} options + * @param {Pioneer.Scene} [options.scene = undefined] + */ + toggleIcons(active, { scene = undefined } = {}) { + if (scene === undefined) { + scene = this._scene; + } + for (let i = 0; i < scene.getNumEntities(); i++) { + this.toggleIconForEntity(active, scene.getEntity(i).getName(), { scene }); + } + } + + /** + * Toggles the icon for the specified entity. + * @param {boolean} active + * @param {string} entityId + * @param {object} options + * @param {Pioneer.Scene} [options.scene = undefined] + */ + toggleIconForEntity(active, entityId, { scene = undefined } = {}) { + let currentScene = scene; + if (currentScene === undefined) { + currentScene = this._scene; + } + const entity = currentScene.getEntity(entityId); + const div = entity.get('div'); + if (this._exceptions.has(entity.getName())) { + return; + } + if (div !== null) { + if (active) { + div.getDiv().firstElementChild?.classList.remove('hidden'); + } + else { + div.getDiv().firstElementChild?.classList.add('hidden'); + } + } + } + + /** + * Gets link from entity's name. + * @param {string} entityName + * @returns {string} + */ + _getLink(entityName) { + return `/${entityName}`; + } + + /** + * Callback to handle label click. + * @param {Pioneer.Entity} entity + */ + _clickCallback(entity) { + const router = this._app.getManager('router'); + + // Get parsed link if available. + const parsedLink = this._getLink(entity.getName()); + + const linkPath = typeof parsedLink === 'string' ? parsedLink : (parsedLink.path ?? ''); + + const { + options = { keepTime: true }, + query = {} + } = typeof parsedLink === 'object' && parsedLink; + + // Go to the object, maintaining time query if it exists. + router.navigate(query, linkPath, options); + } + + /** + * setLabelProps (previously Prepare labels) + * @param {object} options + * @param {(name: string) => string} [options.getLabelClass] + * @param {(name: string) => string} [options.getIconClass] + * @param {(name: string) => string} [options.getTextClass] + * @param {(event: MouseEvent, name: string) => void} [options.handleClick] + * @param {(event: TouchEvent, name: string) => void} [options.handleTouch] + * @param {(event: MouseEvent, name: string) => void} [options.handleMouseEnter] + * @param {(event: MouseEvent, name: string) => void} [options.handleMouseLeave] + * @param {Array} labelNames + * @param {Pioneer.Scene} sceneParam + * @param {Pioneer.Entity} cameraParam + */ + setLabelProps({ getLabelClass, getIconClass, getTextClass, handleClick, handleTouch, handleMouseEnter, handleMouseLeave } = {}, labelNames = Object.keys(this._labels), sceneParam, cameraParam) { + let scene = sceneParam; + if (!scene) { + scene = this._scene; + } + + let cameraEntity = cameraParam; + if (!cameraEntity) { + cameraEntity = scene.get('camera'); + } + + const camera = cameraEntity.getComponentByType('camera'); + + // Create labels + for (const name of labelNames) { + const entity = scene.getEntity(name); + const entityInfo = this._app.getManager('content').getEntityInfo(name); + const divComponent = entity.get('div'); + + if (divComponent === null) continue; + + // Set active camera + divComponent.setActiveCamera(camera); + + // Get label element. + const labelEl = divComponent.getDiv(); + + // Call the getLabelClass if it's passed. + const labelClass = typeof getLabelClass === 'function' ? getLabelClass(name) : ''; + labelEl.className += ` ${labelClass} clickable`; + + // Create icon and text child elements. + const iconEl = document.createElement('span'); + const textEl = document.createElement('span'); + + // Determine icon classes. + const iconMapClass = this._iconMap[entityInfo?.category] ?? this._iconMap.Default; + const iconNameClass = entityInfo?.category === 'Planet' ? name : ''; + const iconCallbackClass = typeof getIconClass === 'function' ? getIconClass(name) : ''; + iconEl.className = `icon ${iconMapClass}${iconNameClass} ${iconCallbackClass}`; + // Determine textEl classes and inner html. + textEl.className = `text ${typeof getTextClass === 'function' ? getTextClass(name) : ''}`; + textEl.innerHTML = entityInfo?.displayName || entityInfo?.iauName || labelEl.innerHTML; + + // Clear any labelEl html. + labelEl.innerHTML = ''; + + // Append the babes. + labelEl.appendChild(iconEl); + labelEl.appendChild(textEl); + + // Define default click/touch/hover handlers + const defaultOnClick = async event => { + const labelInfo = this._labels[name]; + + if (!this._isClickable || !labelInfo?.isClickable) { + return; + } + + if (this._clickCallback !== null) { + console.log(this._clickCallback) + this._clickCallback(entity); + event.preventDefault(); + this.triggerCallbacks('labelclicked', [true]); + } + }; + + const defaultOnTouchEnd = async event => { + const labelInfo = this._labels[name]; + + if (!this._isClickable || !labelInfo?.isClickable) { + return; + } + if (!this.app.isDragging() && !this.app.isTouchMax() && this._clickCallback !== null) { + this._clickCallback(entity); + event.preventDefault(); + this.triggerCallbacks('labelclicked', [true]); + } + }; + + // Prevent touch or mouse conflict, trigger callbacks for labelclicked state. + labelEl.addEventListener('mousedown', event => { + event.preventDefault(); + this.triggerCallbacks('labelclicked', [false]); + }); + labelEl.addEventListener('touchstart', event => { + event.preventDefault(); + this.triggerCallbacks('labelclicked', [false]); + }); + + const defaultOnMouseEnter = () => this.triggerCallbacks('hoverchange', [name, true]); + const defaultOnMouseLeave = () => this.triggerCallbacks('hoverchange', [name, false]); + + // Determine handlers if they are passed as options + const onClick = typeof handleClick === 'function' ? event => handleClick(event, name) : defaultOnClick; + const onTouchEnd = typeof handleTouch === 'function' ? event => handleTouch(event, name) : defaultOnTouchEnd; + const onMouseEnter = typeof handleMouseEnter === 'function' ? event => handleMouseEnter(event, name) : defaultOnMouseEnter; + const onMouseLeave = typeof handleMouseLeave === 'function' ? event => handleMouseLeave(event, name) : defaultOnMouseLeave; + + // There's probably a neater way to do this. + if (handleClick !== null && labelEl.getAttribute('hasClickListener') !== 'true') { + labelEl.setAttribute('hasClickListener', 'true'); + labelEl.addEventListener('click', onClick); + } + if (handleTouch !== null && labelEl.getAttribute('hasTouchEndListener') !== 'true') { + labelEl.setAttribute('hasTouchEndListener', 'true'); + labelEl.addEventListener('touchend', onTouchEnd); + } + if (handleMouseEnter !== null && labelEl.getAttribute('hasMouseEnterListener') !== 'true') { + labelEl.setAttribute('hasMouseEnterListener', 'true'); + labelEl.addEventListener('mouseenter', onMouseEnter); + } + if (handleMouseLeave !== null && labelEl.getAttribute('hasMouseLeaveListener') !== 'true') { + labelEl.setAttribute('hasMouseLeaveListener', 'true'); + labelEl.addEventListener('mouseleave', onMouseLeave); + } + if (labelEl.getAttribute('hasMouseMoveListener') !== 'true') { + labelEl.setAttribute('hasMouseMoveListener', 'true'); + labelEl.addEventListener('mousemove', event => { + event.preventDefault(); + }, true); + } + } + } + + /** + * Adds specific class to list of label divs + * @param {string} className + * @param {Array} labelNames + */ + addClassToLabels(className, labelNames) { + for (const name of labelNames) { + const entity = this._scene.getEntity(name); + const labelEl = entity?.get('div')?.getDiv(); + + labelEl?.classList.add(className); + } + } + + /** + * Removes specific class from list of label elements + * @param {string} className + * @param {Array} labelNames + */ + removeClassFromLabels(className, labelNames) { + for (const name of labelNames) { + const entity = this._scene.getEntity(name); + const labelEl = entity?.get('div')?.getDiv(); + + labelEl?.classList.remove(className); + } + } + + /** + * Gets the item at the center of the screen. + * @returns {object} + */ + getItemAtCenter() { + this._centerBoundingRect.x = (window.innerWidth / 2 - this._centerBoundingRect.width / 2); + this._centerBoundingRect.y = (window.innerHeight / 2 - this._centerBoundingRect.height / 2); + + const candidates = this._quadTree.retrieve(this._centerBoundingRect); + // Loop through candidates + for (let i = 0; i < candidates.length; i++) { + const candidate = candidates[i]; + + candidate.y += candidate.height / 2; + candidate.width = this._centerBoundingRect.width; + candidate.height = this._centerBoundingRect.height; + + if (this._checkCollision(candidate, this._centerBoundingRect)) { + return candidate; + } + } + return null; + } + + /** + * Builds a quadtree and update all labels. + */ + _buildQuadtree() { + this._quadTree.clear(); + for (const [key, label] of Object.entries(this._labels)) { + if (this._isPaused) { + return; + } + const div = label.el; + const rect = div.getBoundingClientRect(); + + // Skip if div is not displayed + if (div.style.opacity === '0') { + label.check = false; + continue; + } + // Skip if div is out of window + if (this._isOutOfWindow(rect)) { + label.check = false; + continue; + } + + // Set label info + label.x = rect.x; + label.y = rect.y; + label.width = rect.width; + label.height = rect.height; + label.check = true; + label.collisions = []; + label.isHidden = false; + const camera = this._scene.get('camera', 'camera'); + const entity = this._scene.get(label.name); + label.z = entity?.getCameraSpacePosition(camera).magnitude() || 0; + // Insert into quad tree + this._quadTree.insert(label); + } + } + + /** + * Checks collisions with Quadtree method. + */ + _checkWithQuadtree() { + // Check collision for each label + for (const key of Object.keys(this._labels)) { + if (this._isPaused) { + return; + } + const label = this._labels[key]; + if (!label.check) { + continue; + } + const candidates = this._quadTree.retrieve(label); + + // Loop through candidates + for (let i = 0; i < candidates.length; i++) { + const candidate = candidates[i]; + if (candidate.check && this._checkCollision(candidate, label) && label.name !== candidate.name) { + if (this._overlap(candidate, label) >= this._overlapThreshold) { + this._addCollision(candidate.name, label.name); + } + } + } + } + } + + // Debug function + // _drawQuadtree(node) { + // let bounds = node.bounds; + // let ctx = document.getElementById('canvas').getContext('2d'); + // if (node.nodes.length === 0) { + // ctx.strokeStyle = 'rgba(255,0,0,0.5)'; + // ctx.strokeRect(bounds.x, bounds.y, bounds.width, bounds.height); + // } + // else { + // for (let i = 0; i < node.nodes.length; i = i + 1) { + // this._drawQuadtree(node.nodes[i]); + // } + // } + // } + + /** + * Adds a collision to the temporary array. + * @param {string} label1 + * @param {string} label2 + */ + _addCollision(label1, label2) { + if (this._collidingLabels.indexOf(label1) < 0) { + this._collidingLabels.push(label1); + } + if (this._collidingLabels.indexOf(label2) < 0) { + this._collidingLabels.push(label2); + } + this._labels[label1]?.collisions.push(label2); + } + + /** + * Helper function to check if there is a collision between two rects. + * @param {object} rect1 + * @param {object} rect2 + * @returns {boolean} + */ + _checkCollision(rect1, rect2) { + if (rect1.x < rect2.x + rect2.width + && rect1.x + rect1.width > rect2.x + && rect1.y < rect2.y + rect2.height + && rect1.y + rect1.height > rect2.y) { + return true; + } + else { + return false; + } + } + + /** + * Solves collisions. + */ + _fixCollisions() { + // Sort colliding labels + this._sort(); + + // For each label ordered by weight and z order + // determine if we need to show it or not + for (let i = 0; i < this._collidingLabels.length; i++) { + if (this._isPaused) { + return; + } + const label = this._collidingLabels[i]; + if (!this.isExisting(label)) { + continue; + } + + // Skip already hidden labels + // to avoid waterfall effect + if (this._labels[label].isHidden) { + continue; + } + else { + // Show label + this._showLabel(label); + } + // Hide its collisions + for (let j = 0; j < this._labels[label].collisions.length; j++) { + const collision = this._labels[label].collisions[j]; + this._hideLabel(collision); + } + } + + // Restore labels that are not conflicting + this._restoreLabels(); + } + + /** + * Sorts colliding labels. + */ + _sort() { + // Order labels by weight or z order + this._collidingLabels.sort((a, b) => { + if (this.getWeight(b) - this.getWeight(a) !== 0) { + return this.getWeight(b) - this.getWeight(a); + } + else { + return this.getZ(a) - this.getZ(b); + } + }); + } + + /** + * Calculates overlap percentage on two rects. + * @param {object} rect1 + * @param {object} rect2 + * @returns {number} + */ + _overlap(rect1, rect2) { + const overlap = (Math.min(rect1.x + rect1.width, rect2.x + rect2.width) - Math.max(rect1.x, rect2.x)) + * (Math.min(rect1.y + rect1.height, rect2.y + rect2.height) - Math.max(rect1.y, rect2.y)); + const a1 = rect1.width * rect1.height; + const a2 = rect2.width * rect2.height; + const percentage = overlap / (a1 + a2 - overlap); + return percentage; + } + + /** + * Helper function to check if rect is outside of window. + * @param {object} rect + * @returns {boolean} + */ + _isOutOfWindow(rect) { + if (rect.x > window.innerWidth || rect.x + rect.width < 0 || rect.y > window.innerHeight || rect.y + rect.height < 0) { + return true; + } + else { + return false; + } + } + + /** + * Restores label visibility. + */ + _restoreLabels() { + if (this._allLabelsHidden === true) { + return; + } + for (const key of Object.keys(this._labels)) { + const label = this._labels[key]; + if (!label.isHidden) { + this._showLabel(label.name); + } + if (label.collisions.length === 0) { + this._showLabel(label.name); + } + } + } + + /** + * Shows a label. + * @param {string} label + */ + _showLabel(label) { + const object = this.pioneer.get('main', label); + const div = object?.getComponentByType('div').getDiv(); + div?.classList.add(this._activeClass); + div?.classList.remove(this._hiddenClass); + this._labels[label].isHidden = false; + } + + /** + * Hides a label. + * @param {string} label + */ + _hideLabel(label) { + if (this._exceptions.has(label)) { + return; + } + const object = this.pioneer.get('main', label); + if (object === null) { + return; + } + const div = object.getComponentByType('div').getDiv(); + div.classList.add(this._hiddenClass); + div.classList.remove(this._activeClass); + this._labels[label].isHidden = true; + } + + /** + * Gets Z position in camera space. + * @param {string} name + * @returns {number} + */ + getZ(name) { + if (this.isExisting(name)) { + return this._labels[name].z; + } + } + + /** + * Stops the update loop. + */ + stop() { + this._isPaused = true; + } + + /** + * Starts the update loop. + */ + start() { + this._isPaused = false; + } + + /** + * Called every frame to update the labels. + */ + update() { + if (this._isPaused) { + return; + } + + // Spread operations accross multiple frames + if (this._frameCount === 0) { + this._collidingLabels = []; + this._buildQuadtree(); + } + else if (this._frameCount === this._frameCycle / 3) { + this._checkWithQuadtree(); + } + else if (this._frameCount === 2 * this._frameCycle / 3) { + this._fixCollisions(); + } + + this._frameCount++; + this._frameCount %= this._frameCycle; + } +} + +// Label manager algorithm modes +// TODO Seems to be used by setAlgorithm, which has unused this._algorithm +LabelManager.Quadtree = 1; +LabelManager.BruteForce = 0; + + +/***/ }), + +/***/ "../eyes/src/managers/layer_manager.js": +/*!*********************************************!*\ + !*** ../eyes/src/managers/layer_manager.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LayerManager": function() { return /* binding */ LayerManager; } +/* harmony export */ }); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + + +/** + * @typedef ToggleParams + * @property {string} [layerId] + * @property {string} [parentId] + * @property {string} [group] + */ + +/** + * @typedef {(visible: boolean, params: ToggleParams) => void} ToggleCallback + */ + +/** + * @typedef Layer + * @property {string} name + * @property {string} group + * @property {boolean} defaultVisibility + * @property {boolean} visible + * @property {string[]} categories + * @property {string[]} sublayers + * @property {string} [parent] + * @property {Array} toggleCallback + */ + +/** + * Layer manager class. + */ +class LayerManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + */ + constructor(app) { + super(app); + + /** + * The scene manager. + * @type {SceneManager} + * @private + */ + this._sceneManager = /** @type {SceneManager} */(app.getManager('scene')); + + /** + * The content manager + * @type {ContentManager} + * @private + */ + this._contentManager = /** @type {ContentManager} */(app.getManager('content')); + + /** + * @type {Object} + * @private + */ + this._layers = {}; + + /** + * List of possible contextual layers to check when parent entity changes. + * @type {string[]} + */ + this._contextualLayersList = ['majorMoons', 'minorMoons', 'landers', 'orbiters', 'satelliteGroup', 'heliosphere']; + + this._targetId = ''; + this._previousTarget = /** @type {string[]} */([]); + this._dependencies = new Set(); + this._previousDependencies = new Set(); + + this.bindFunctions([ + 'resetContextualVisibility', + 'toggleLayer', + 'changeSpheroidMap', + 'resetContextualLayers' + ]); + + // Add toggle layer + this._eventNames.push('toggleLayer'); + this._initCallbacks(); + } + + /** + * Adds a layer to the layer manager. + * @param {string} id + * @param {object} options - the options used to setup the layer + * @param {string} [options.name = ''] - layer name + * @param {string} [options.group = ''] - pioneer scripts group + * @param {string | string[]} [options.categories = []] - entity info categories + * @param {boolean} [options.defaultVisibility = true] - default visibility + * @param {ToggleCallback | Array} [options.toggleCallback = []] - callback list + * @param {string[]} [options.sublayers = []] - layers that will be overriden by this one + */ + addLayer(id, { name = '', group = '', categories = [], defaultVisibility = true, toggleCallback = [], sublayers = [] }) { + if (this._layers[id] === undefined) { + this._layers[id] = /** @type {Layer} */({}); + } + this._layers[id].name = name; + this._layers[id].group = group; + this._layers[id].defaultVisibility = defaultVisibility; + this._layers[id].visible = defaultVisibility; + + // Categories + if (!Array.isArray(categories)) { + categories = [categories]; + } + this._layers[id].categories = categories; + + // Sublayers + if (!Array.isArray(sublayers)) { + sublayers = [sublayers]; + } + this._layers[id].sublayers = sublayers; + for (let i = 0; i < sublayers.length; i++) { + const sublayer = sublayers[i]; + if (this._layers[sublayer] === undefined) { + this._layers[sublayer] = /** @type {Layer} */({}); + } + this._layers[sublayer].parent = id; + } + + // Callbacks + if (!Array.isArray(toggleCallback)) { + toggleCallback = [toggleCallback]; + } + this._layers[id].toggleCallback = toggleCallback; + } + + /** + * Adds a toggle callback to a layer. + * @param {string} id + * @param {ToggleCallback} toggleCallback + */ + addCallback(id, toggleCallback) { + const layer = this.getLayer(id); + if (layer === null) { + return; + } + layer.toggleCallback.push(toggleCallback); + } + + /** + * Removes a toggle callback from a layer. + * @param {string} id + * @param {ToggleCallback} toggleCallback + * @override + */ + removeCallback(id, toggleCallback) { + const layer = this.getLayer(id); + if (layer === null) { + return; + } + const index = layer.toggleCallback.indexOf(toggleCallback); + layer.toggleCallback.splice(index, 1); + } + + /** + * Gets a layer. + * @param {string} id + * @returns {Layer} + */ + getLayer(id) { + if (this._layers[id] === undefined) { + return null; + } + return this._layers[id]; + } + + /** + * Change the spheroid texture to new map + * @param {string} id + * @param {any} textureDescription + */ + async changeSpheroidMap(id, textureDescription) { + if (textureDescription.type === 'cmts') { + console.error('This function does not yet handle CMTS texture'); + return; + } + const sceneManager = /** @type {SceneManager} */(this.app.getManager('scene')); + const spheroidLOD = /** @type {SpheroidLODComponent} */ (sceneManager.get('main').getEntity(id)?.getComponentByType('spheroidLOD')); + const atmosphere = /** @type {AtmosphereComponent} */ (sceneManager.get('main').getEntity(id)?.getComponentByType('atmosphere')); + const wmts = /** @type {WMTSComponent} */ (sceneManager.get('main').getEntity(id)?.getComponentByType('wmts')); + + if (spheroidLOD && textureDescription.type === 'texture') { + spheroidLOD.setEnabled(true); + sceneManager.addLoading(id, 'spheroidLOD'); + Object.keys(textureDescription.textures).forEach(key => { + const url = '$STATIC_ASSETS_URL/maps/' + textureDescription.textures[key].url; + spheroidLOD.setTexture(key, url, textureDescription.textures[key].sizes); + }); + await sceneManager.pioneer.waitUntilNextFrame(); + await spheroidLOD.getLoadedPromise(); + if (wmts !== null) { + wmts.setEnabled(false); + } + sceneManager.removeLoading(id, 'spheroidLOD'); + } + else if (textureDescription.type === 'wmts') { + // Add WMTS components + if (wmts === null) { + await sceneManager.addWMTSComponent(id, textureDescription); + } + else if (wmts.isEnabled() === false) { + await sceneManager.enableWMTSComponent(id, wmts); + } + } + if (atmosphere !== null && atmosphere !== undefined) { + atmosphere.setEnabled(textureDescription.features.includes('atmosphere')); + } + /** @type {ContentPanel} */(this.app.getComponent('contentPanel'))?.updateHDButton(); + + // Flip Titan surface map 180 deg until we can fix it officially in Pioneer (TODO) + if (id === 'titan') { + this.app.pioneer.get('main', 'titan', 'spheroidLOD').setLongitudeRotation(pioneer__WEBPACK_IMPORTED_MODULE_1__.MathUtils.degToRad(180)); + } + } + + /** + * Toggles a layer on and off. + * @param {string} id + * @param {ToggleParams} [params={}] + * @param {boolean} [forceVisibility] + */ + async toggleLayer(id, params = {}, forceVisibility) { + const { spout, spoutFontSize } = this.app.getManager('router').configs; + + if (this._layers[id] === undefined) { + return; + } + params.layerId = id; + if (forceVisibility !== undefined && this._layers[id].visible === forceVisibility) { + return; + } + this._layers[id].visible = !this._layers[id].visible; + for (let i = 0; i < this._layers[id].toggleCallback.length; i++) { + const callback = this._layers[id].toggleCallback[i]; + callback(this._layers[id].visible, params); + } + + for (let i = 0; i < this._layers[id].sublayers.length; i++) { + const sublayer = this.getLayer(this._layers[id].sublayers[i]); + sublayer.visible = this._layers[id].visible; + this.triggerCallbacks('toggleLayer', [this._layers[id].sublayers[i], this._layers[id].visible, params]); + } + + this.triggerCallbacks('toggleLayer', [id, this._layers[id].visible, params]); + + const sceneManager = /** @type {SceneManager} */(this.app.getManager('scene')); + + // Make sure the scene is showing the right layers. + if (params.parentId !== null && params.parentId !== undefined) { + sceneManager.updateEntityLayerVisibilityForChildren(params.parentId, params.satelliteGroup); + } + else { + sceneManager.updateEntityLayerVisibility(params.satelliteGroup); + } + + // Add Spout labels to layers + if (spout === true && this._layers[id].visible) { + const relevantEntities = []; + await this.pioneer.waitUntilNextFrame(); + + if (id.toLowerCase().includes('constellations')) { + const constellations = this.app.pioneer.get('main', 'sun').getComponentByType('constellations'); + constellations.getNames().forEach(name => { + relevantEntities.push(this.app.pioneer.get('main').getEntity(`constellation_label_${name}`)); + }); + } + + await this.app.getManager('spout').setUpSpoutLabels(spoutFontSize, relevantEntities?.[0]?.id); + } + } + + /** + * Sets target entity id. + * @param {string} entityId + */ + setTarget(entityId) { + // Store previous targets and dependencies + this._previousTarget.push(this._targetId); + this._previousDependencies = new Set([...this._previousDependencies, ...this._dependencies]); + // Update target id + this._targetId = entityId; + this._dependencies.clear(); + + if (this._targetId !== '') { + // Check for dependencies and activate them if needed + const dependencies = this._sceneManager.getDependencies(this._targetId); + this._dependencies = new Set(dependencies); + } + } + + /** + * Clean previous targets and dependencies visibility status. + */ + resetTarget() { + // Dont clean if the camera is using one of the previous target + // Cleanup will happen in a later call to resetTarget + for (let i = 0; i < this._previousTarget.length; i++) { + const previousTarget = this._previousTarget[i]; + const cameraEntity = /** @type {CameraManager} */(this.app.getManager('camera')).cameraEntity; + if (cameraEntity === null || cameraEntity.getParent() === null) { + return; + } + if (cameraEntity.getParent().getName() === previousTarget) { + return; + } + } + + // Clean all the previous targets + for (let i = 0; i < this._previousTarget.length; i++) { + const previousTarget = this._previousTarget[i]; + + // Reset contextual layers of the previous target to their original value + this.resetContextualVisibility(previousTarget); + } + this._previousTarget = []; + + this._previousDependencies.clear(); + } + + /** + * Resets visibility defaults for contextual toggles + * @param {string} previousTarget + */ + resetContextualVisibility(previousTarget) { + // Get the first ancestor of the previous target with contextual layers. + const time = this._sceneManager.main.getEngine().getTime(); + let contextualLayers = this.getContextualLayers(previousTarget); + while (previousTarget !== '' && contextualLayers.length === 0) { + previousTarget = pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.Parenting.getParentOfEntity(previousTarget, time); + contextualLayers = this.getContextualLayers(previousTarget); + } + // Get the first ancestor of the current target with contextual layers. + let currentTarget = this._targetId; + contextualLayers = this.getContextualLayers(currentTarget); + while (currentTarget !== '' && contextualLayers.length === 0) { + currentTarget = pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.Parenting.getParentOfEntity(currentTarget, time); + contextualLayers = this.getContextualLayers(currentTarget); + } + if (currentTarget === previousTarget) { + return; + } + this._contextId = previousTarget; + for (let i = 0; i < contextualLayers.length; i++) { + const layerName = contextualLayers[i]; + const layer = this.getLayer(layerName); + + // Parent visibility overrides default values + if (layer.parent !== undefined) { + const parentLayer = this.getLayer(layer.parent); + if (parentLayer.visible !== layer.visible) { + this.toggleLayer(layerName, { parentId: previousTarget, group: layer.group }); + } + } + else if (layer.visible !== layer.defaultVisibility) { + // Otherwise restore to default value + this.toggleLayer(layerName, { parentId: previousTarget, group: layer.group }); + } + } + } + + /** + * Gets the target entity id. + * @returns {string} + */ + getTarget() { + return this._targetId; + } + + /** + * Gets an entity layer. + * @param {*} id + * @returns {Layer|null} + */ + getEntityLayer(id) { + const entityInfo = this._contentManager.getEntityInfo(id); + if (entityInfo === null) { + return null; + } + const category = entityInfo.category; + const subcategory = entityInfo.subcategory; + const layer = this.getLayerFromCategory(subcategory) || this.getLayerFromCategory(category); + return layer; + } + + /** + * Gets a layer tied to a category. + * @param {string} category + * @returns {Layer|null} + */ + getLayerFromCategory(category) { + if (!category) { + return null; + } + for (const [key, value] of Object.entries(this._layers)) { + if (value.categories.includes(category)) { + return this._layers[key]; + } + } + return null; + } + + /** + * Gets a layer tied to a satellite group. + * @param {string} group + * @returns {Layer|null} + */ + getLayerFromSatelliteGroup(group) { + if (!group) { + return null; + } + for (const [key, value] of Object.entries(this._layers)) { + if (value.categories.includes(group)) { + return this._layers[key]; + } + } + return null; + } + + /** + * Get a list of contextual layers available for a planet. (Major Moons, Minor Moons, Landers, Orbiters, Rovers, Heliosphere) + * @param {string} parent + * @returns {Array} layerList + */ + getContextualLayers(parent) { + const availableLayers = /** @type {string[]} */([]); + if (parent === '') { + return availableLayers; + } + + const contentManager = /** @type {ContentManager} */(this.app.getManager('content')); + const entityInfo = contentManager.getEntityInfo(parent); + const moons = entityInfo?.hasMoons ? pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.Entity.getEntityNamesInGroup(parent + ', moons') : new Set(); + const spacecraft = pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.Entity.getEntityNamesInGroup(parent + ', spacecraft'); + // Include heliosphere for Sun + if (parent === 'sun') { + if (availableLayers.includes('heliosphere') === false) { + availableLayers.push('heliosphere'); + } + } + // Include major and minor moons if have + moons.forEach(moon => { + const moonEntityInfo = contentManager.getEntityInfo(moon); + if (moonEntityInfo !== null) { + const category = moonEntityInfo.subcategory || moonEntityInfo.category; + switch (category) { + case 'Major Moon': + if (availableLayers.includes('majorMoons') === false) { + availableLayers.push('majorMoons'); + } + break; + case 'Minor Moon': + if (availableLayers.includes('minorMoons') === false) { + availableLayers.push('minorMoons'); + } + break; + default: + break; + } + } + }); + // Include orbiters and landers if has spacecrafts + const time = this._app.pioneer.getTime(); + spacecraft.forEach(sc => { + const entityInfo = contentManager.getEntityInfo(sc); + if (entityInfo !== null) { + const category = entityInfo.subcategory || entityInfo.category; + switch (category) { + case 'Orbiter': + if (availableLayers.includes('orbiters') === false) { + if (pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.Parenting.getParentOfEntity(sc, time) === parent) { + availableLayers.push('orbiters'); + } + } + break; + case 'Landing Site': + case 'Lander': + case 'Rover': + if (availableLayers.includes('landers') === false) { + if (pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.Parenting.getParentOfEntity(sc, time) === parent) { + availableLayers.push('landers'); + } + } + break; + default: + break; + } + } + }); + + // Include satellite group if have + if (entityInfo?.constellation) { + availableLayers.push('satelliteGroup'); + } + + availableLayers.sort((a, b) => { + const layers = Object.keys(this._layers); + return layers.indexOf(a) - layers.indexOf(b); + }); + + return availableLayers; + } + + /** + * Resets all contextual layers of the old parent to their default state. + * Used in the case of an entity changing parents (Object View). + * @param {string} newParent + * @param {string} oldParent + */ + resetContextualLayers(newParent, oldParent) { + const newLayers = this.getContextualLayers(newParent); + this._contextualLayersList.forEach(layer => { + if (newLayers.includes(layer) === false) { + if (layer === 'heliosphere') { + this.toggleLayer(layer, { parentId: undefined }, false); + } + else { + this.toggleLayer(layer, { parentId: oldParent }, this.getLayer(layer).defaultVisibility || false); + } + } + }); + } + + /** + * Returns true if the entity should be visible with the currently visible layers. If there's no valid layer, it returns true. + * @param {string} entityName + * @param {string} satelliteGroup - The satellite group to check against entities + * @returns {boolean} + */ + isEntityVisibleWithCurrentLayers(entityName, satelliteGroup) { + const entityInfo = this._contentManager.getEntityInfo(entityName); + if (entityInfo !== null) { + const layer = this.getLayerFromCategory(entityInfo.category); + const sublayer = this.getLayerFromCategory(entityInfo.subcategory); + const satelliteGroupLayer = this.getLayerFromSatelliteGroup(entityInfo.constellation); + + // Check status of spacecraft constellation first if in it + if (satelliteGroupLayer !== null && entityInfo.constellation === satelliteGroup) { + return satelliteGroupLayer.visible; + } + // Check status of sublayer first + if (sublayer !== null) { + return sublayer.visible; + } + // Check status of layer + if (layer !== null) { + return layer.visible; + } + // If no layer then it is visible + if (layer === null && sublayer === null) { + return true; + } + + return false; + } + // If it doesn't have an entity info, then it has no layer, so it's always visible. + else { + return true; + } + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/route_manager.js": +/*!*********************************************!*\ + !*** ../eyes/src/managers/route_manager.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "RouteManager": function() { return /* binding */ RouteManager; } +/* harmony export */ }); +/* harmony import */ var navigo__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! navigo */ "../eyes/node_modules/navigo/lib/navigo.min.js"); +/* harmony import */ var navigo__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(navigo__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + +/** + * Route Manager class. + * @extends BaseManager + */ +class RouteManager extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + */ + constructor(app) { + super(app); + + /** + * Router instance that handles all routing. + * @type {Navigo} + * @private + * @default + */ + this._router = new (navigo__WEBPACK_IMPORTED_MODULE_0___default())(null, true); + + /** + * Information of previous route. + * @type {null|object} + * @private + * @default + */ + this._previousRoute = null; + + /** + * Information of current route. + * @type {object} + * @private + * @default + */ + this._currentRoute = {}; + + /** + * Flag indicating first app load or not. + * @type {boolean} + * @private + * @default + */ + this._firstLoad = true; + + /** + * Stored queries. + * @type {object} + * @private + * @default + */ + this._query = {}; + + /** + * Persistent queries. Can only be removed by function. + * @type {object} + * @private + * @default + */ + this._configs = {}; + + /** + * List of valid query keys. + * @type {Array} + * @private + * @default + */ + this._validQueries = []; + + /** + * Route for home. + * @type {string} + * @private + * @default + */ + this._homeRoute = '/home'; + + /** + * A way to subscribe to query changes in all views + */ + this._queryCallbacks = {}; + + /** + * Previous view. + * @type {string} + */ + this._previousView = null; + + /** + * Current view. + * @type {string} + */ + this._currentView = null; + /** + * Components that are always hidden on first load, even on view change + * @type {Array} + */ + this._alwaysHiddenComponents = []; + + + this.bindFunctions([ + 'navigate', + 'onRootRoute', + 'onNotFound', + 'leave' + ]); + } + + /** + * Get the route for home. + * @returns {string} + */ + get homeRoute() { + return this._homeRoute; + } + + /** + * Getter for previous route. + * @returns {object} + */ + get previousRoute() { + return this._previousRoute; + } + + /** + * Getter for current route. + * @returns {object} + */ + get currentRoute() { + return this._currentRoute; + } + + /** + * Getter for current query. + * @returns {object} + */ + get query() { + return this._query; + } + + /** + * Getter for current configs. + * @returns {object} + */ + get configs() { + return this._configs; + } + + /** + * Gets the current view. + * @returns {string} + */ + get currentView() { + return this._currentView; + } + + /** + * Sets the current view. + * @param {string} view + */ + set currentView(view) { + this._currentView = view; + } + + /** + * Gets the previous view. + * @returns {string} + */ + get previousView() { + return this._previousView; + } + + /** + * Initialize the router. + * @param {Function} onBefore + * @param {Function} onAfter + */ + init(onBefore, onAfter) { + this._router.hooks({ + before: async done => { + this._previousRoute = { ...this._currentRoute }; + this._currentRoute = this._router.lastRouteResolved() || {}; + + // Remove extra slash + if (this._currentRoute.url) { + this._currentRoute.url = this._currentRoute.url.replace(/(\/)+/, '/'); + } + + // Update query + this.addQuery(this.parseQuery(this.currentRoute.query)); + + if (typeof onBefore === 'function') { + await onBefore(this._currentRoute, this._previousRoute); + } + + done(); + }, + after: async () => { + if (typeof onAfter === 'function') { + await onAfter(this._currentRoute, this._previousRoute); + } + + this._firstLoad = false; + } + }); + + this._router + .on(this.onRootRoute) + .notFound(this.onNotFound) + .on('milky_way', this.onNotFound) + .on('observable_universe', this.onNotFound); + } + + /** + * Execute on leaving a route. + * @param {object} params - Parameters from url + */ + leave(params) { + // Cancel token + params.cancelToken.cancel(); + } + + /** + * Handle root route. + * @param {string} query + */ + onRootRoute(query) { + this.reroute(this._homeRoute, query); + } + + /** + * Handle not found routes. + * @param {string} query + */ + onNotFound(query) { + // Called when there is path specified but + // there is no route matching + let newRoute = this._homeRoute; + // Try to pass the query stored in the params + // to the new route + if (query) { + newRoute += '?' + query; + } + this._router.navigate(newRoute); + } + + /** + * A way to replace a history state which essentially makes the back button skip the current route + * @param {string} replaceStr + */ + replaceState(replaceStr) { + history.replaceState({}, '', replaceStr); + } + + /** + * Reroute to a new path without adding a new step in the history. + * @param {string} path + * @param {string|object} [query=''] + */ + reroute(path, query = '') { + let queryString; + if (typeof query === 'string') { + query = this.parseQuery(query); + } + const configs = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.filterObject(this._configs, val => val !== undefined); + queryString = this.buildQuery({ ...query, ...configs }); + const pathname = window.location.pathname; + history.replaceState(queryString, '', `${pathname}#${path}${queryString}`); + this._router.resolve(); + } + + /** + * Add cancel token to params. Create params for route without one. + * @param {object} params + * @returns {object} + */ + addCancelToken(params) { + const output = params || {}; + output.cancelToken = new _internal__WEBPACK_IMPORTED_MODULE_1__.CancelToken(); + return output; + } + + /** + * Get the last resolved route. + * @returns {object} + */ + lastRouteResolved() { + return this._router.lastRouteResolved(); + } + + /** + * Get the last resolved path. + * @returns {string} + */ + lastPathResolved() { + const lastRoute = this._router.lastRouteResolved(); + return lastRoute.query ? lastRoute.url + '?' + lastRoute.query : lastRoute.url; + } + + /** + * Get only the path part, or first hash part if path is hash. + * @param {string} url + * @returns {string} + */ + getOnlyURL(url) { + let onlyURL = url; + const split = url.split('#'); + onlyURL = split.length > 1 ? this._cleanGETParam(split[1]) : this._cleanGETParam(split[0]); + return onlyURL; + } + + /** + * Get the first part of a url, also remove query. + * @private + * @param {string} url + * @returns {string} + */ + _cleanGETParam(url) { + return url.split(/\?(.*)?$/)[0]; + } + + /** + * Get the list of valid query keys. + * @returns {Array} + */ + getValidQueries() { + return this._validQueries; + } + + /** + * Set the list of valid query keys. + * @param {Array} list + */ + setValidQueries(list) { + this._validQueries = list; + } + + /** + * Parse a string and return a query object. + * @param {string} queryString + * @returns {object} + */ + parseQuery(queryString) { + if (!queryString) { + return {}; + } + queryString.replace('?', ''); + + const query = queryString.split('&').reduce((obj, str) => { + const parts = str.split('='); + if (parts.length > 1) { + let val = decodeURIComponent(parts[1].trim()); + switch (val.toLowerCase()) { + case 'true': + val = true; + break; + case 'false': + val = false; + break; + case 'undefined': + val = undefined; + break; + case 'null': + val = null; + break; + case '': + val = undefined; + break; + default: { + const num = Number(val); + if (!Number.isNaN(num)) { + val = num; + } + break; + } + } + // Only update query, not configs + const key = decodeURIComponent(parts[0].trim()); + if (key in this._configs) { + if (this._configs[key] === undefined) { + this._configs[key] = val; + } + } + else { + obj[key] = val; + } + } + return obj; + }, {}); + + return query; + } + + /** + * Build a query string from a query object. + * @param {object} query + * @returns {string} + */ + buildQuery(query) { + let queryString = ''; + + for (const [key, value] of Object.entries(query)) { + queryString += '&' + key + '=' + value; + } + + // Replace the first `&` with `?` + queryString = queryString.replace('&', '?'); + + return queryString; + } + + /** + * Add query to the stored query. + * @param {object} query + * @returns {object} Updated query + */ + addQuery(query) { + this._query = { ...this._query, ...query }; + return this._query; + } + + /** + * Remove query from the stored query. + * @param {Array} [keys=[]] - Query keys to remove + * @returns {object} Updated query + */ + removeQuery(keys = []) { + keys.forEach(key => delete this._query[key]); + return this._query; + } + + /** + * Add configs to the stored configs. + * @param {object} configs + * @returns {object} Updated configs + */ + addConfigs(configs) { + this._configs = { ...this._configs, ...configs }; + return this._configs; + } + + /** + * Set specific config value + * @param {string} key + * @param {any} value + */ + setConfig(key, value) { + this.configs[key] = value; + } + + /** + * Remove config from the stored configs. + * @param {Array} [keys=[]] - Config keys to remove + * @returns {object} Updated configs + */ + removeConfigs(keys = []) { + keys.forEach(key => delete this._configs[key]); + return this._configs; + } + + /** + * Update, add to, or remove from the stored query. + * { __remove: 'all' } will empty query before adding new query. + * { __remove: string[] } will remove only queries in the list. + * @param {object} query + * @returns {object} Updated query + */ + updateQuery(query) { + if (query.__remove) { + if (query.__remove === 'all') { + this._query = {}; + } + else { + this.removeQuery(query.__remove); + } + delete query.__remove; + } + + const configs = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.filterObject(this._configs, val => val !== undefined); + return { ...this.addQuery(query), ...configs }; + } + + /** + * Update, add to, or remove from path query. + * @param {object} query + * @param {string} [pathname=''] - Base path + * @returns {string} Updated path + */ + updateQueryPath(query, pathname = '') { + const output = pathname || this._router.lastRouteResolved().url; + + return output.replace(/(\/)(?=\/*\1)/, '') + this.buildQuery(this.updateQuery(query)); + } + + /** + * Reset to new view. + * @param {string} currentView - Current view + * @param {object} params + */ + async resetView(currentView, params) { + this._previousView = this._currentView; + this._currentView = currentView; + + // Update only when view change + if (this._currentView !== this._previousView) { + // Leave the previous view + if (this._previousView !== null) { + await this._app.getView(this._previousView).onLeave(params); + } + + // Enter the current view + await this._app.getView(this._currentView).onEnter(params); + + const views = this._app.getViews(); + for (let i = views.length - 1; i >= 0; i--) { + const view = views[i]; + this._app.getView(view).setEnabled(view === currentView); + } + } + } + + /** + * Execute actions in a route. + * @param {string} view - Which view the route corresponds to + * @param {object} params - Parameters from url + * @param {string} query - Query from url + */ + async handleRoute(view, params, query) { + if (!params) { + params = this.addCancelToken(params); + this._currentRoute.params = params; + } + + let objectQuery = {}; + if (query) { + objectQuery = this.parseQuery(query); + } + await this.resetView(view, { ...params, ...objectQuery, ...this._configs }); + await this.goToView(view, params, { ...objectQuery, ...this._configs }); + } + + /** + * Check if app is still on route. + * Useful for route with async actions in before hook to check if user leaves route abruptly. + * @param {string} url - Url to check against current route + * @returns {boolean} + */ + stillOnRoute(url) { + const regex = /^\/([^!/]*)/; + const match = this._currentRoute.url.match(regex); + if (match === null || match[1] === undefined) { + return false; + } + + return match[1] === url; + } + + /** + * Check if url has changed or not. + * Compare only the first part of 2 urls, nested route or query are not considered. + * @param {string} a - First url + * @param {string} b - Second url + * @returns {boolean} + */ + urlChanged(a, b) { + return this.getOnlyURL(a) !== this.getOnlyURL(b); + } + + /** + * Check if a route has changed. + * @param {object} current + * @param {object} previous + * @returns {boolean} + */ + routeChanged(current, previous) { + if (current === '' && !previous) { + return true; + } + if (!previous || _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.isEmptyObject(previous)) { + return true; + } + + // Route check + if (current.url) { + return current.url !== previous.url; + } + + // Object check + const currentRoute = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.deepCopy(current); + const previousRoute = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.deepCopy(previous); + return !_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.deepEqual(currentRoute, previousRoute); + } + + /** + * Check if a query has changed. + * @param {object} current - Like {time: '2020-03-10T20:52:10.904-07:00', rate: 1} + * @param {string} previous - Like 'time=2020-02-10T07:14:45.000-08:00&rate=1' + * @returns {boolean} + */ + queryChanged(current, previous) { + if (!previous) { + return true; + } + + const currentQuery = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.deepCopy(current); + const previousQuery = {}; + for (const p in currentQuery) { + if (typeof currentQuery[p].toString === 'function') { + currentQuery[p] = currentQuery[p].toString(); + } + } + previous.split('&').forEach(param => { + const paramSplit = param.split('='); + previousQuery[paramSplit[0]] = paramSplit[1]; + }); + + // Object check + return !_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.deepEqual(currentQuery, previousQuery); + } + + /** + * Go to a view. + * @param {string} view - View's name + * @param {object} params + * @param {object} query + */ + async goToView(view, params, query) { + // Check if it's a new route + if (this.routeChanged(this.currentRoute, this.previousRoute)) { + await this._app.getView(view).onRouteChange({ ...params, ...query }); + } + else if (this.queryChanged(query, this.previousRoute.query)) { + await this._app.getView(view).onQueryChange({ ...params, ...query }); + } + } + + /** + * Add routes to router. + * @param {object[]} routes + * @param {string} routes[].route - The route to add. + * @param {string} routes[].view - The view corresponding to the route. + */ + addRoutes(routes) { + for (let i = 0; i < routes.length; i++) { + const { route, view } = routes[i]; + this._router.on( + route, + async (params, query) => { + await this.handleRoute(view, params, query); + }, + { + before: async (done, params) => { + await this.before(done, params, view); + }, + leave: this.leave + } + ); + } + } + + /** + * Execute before every route. + * @param {Function} done - Callback on done + * @param {object} params - Parameters from url + * @param {string} view - Which view the route corresponds to + */ + before(done, params, view) { + let objectQuery = {}; + if (this._currentRoute.query) { + objectQuery = this.parseQuery(this._currentRoute.query); + } + + params = this.addCancelToken(params); + + const isValid = this._app.getView(view)?.validateQuery({ ...params, ...objectQuery }); + if (!isValid) { + params.cancelToken.cancel(); + if (typeof done === 'function') { + // Don't resolve route + done(false); + } + } + + if (typeof done === 'function') { + done(); + } + } + + /** + * Method to subscribe to specific query key + * See processQuery method in base_view.js to see when these callbacks are called + * @param {string} key + * @param {Function} callback + * @returns {Function} unsubscribe function + */ + subscribeToQuery(key, callback) { + // Check callback is a function + if (typeof callback !== 'function') return; + + // Create array for key if necessary. + if (!this._queryCallbacks[key]) { + this._queryCallbacks[key] = []; + } + // Push callback into array if it's not already there + if (!this._queryCallbacks[key].includes(callback)) { + this._queryCallbacks[key].push(callback); + } + + // Return the unsubscribe function. + return () => { + const i = this._queryCallbacks[key].indexOf(callback); + this._queryCallbacks[key].splice(i, 1); + }; + } + + /** + * Start the routing + */ + start() { + this._router.resolve(); + + this.handleEmbedQueries(); + } + + /** + * Handle embed queries from URL that should only be handled once + */ + handleEmbedQueries() { + const { hideFullScreenToggle, lighting, noKeyboard, search } = this._configs; + const hideSearch = noKeyboard === true || search === false; + const searchComponent = this.app.getComponent('search'); + const settingsComponent = this.app.getComponent('settings'); + + // Custom tutorial slides if certain embed queries are true + let updatedTutorials = []; + let tutorialsWithVariables = null; + const tutorialOverlay = this.app.getComponent('tutorialOverlay'); + + if (hideFullScreenToggle === true) { + // Called on update of components in case a component updates the settings itself, like Compare View + settingsComponent?.hideFullScreenOption?.(); + } + if (lighting === 'flood' || lighting === 'natural') { + settingsComponent?.toggleLightOptions?.(lighting); + } + + // Hide search component and relevant tutorials + if (hideSearch) { + this._alwaysHiddenComponents.push('search'); + searchComponent?.hide(); + updatedTutorials = tutorialOverlay?.hideTutorialSlide?.('search'); + } + if (this._configs.hideFullScreenToggle === true) { + const settingsTutorial = this.app.tutorials?.find(slide => slide.id === 'settings'); + // Remove mention of full screen in settings tutorial + if (settingsTutorial) { + settingsTutorial.description = settingsTutorial.description.replace(settingsTutorial.description, settingsTutorial.alternateDescription); + } + } + + + tutorialsWithVariables = this.app.setTutorialVariables?.(updatedTutorials.length ? updatedTutorials : this.app.tutorials); + // Hydrate tutorials with replaced function patterns, then set them in the tutorial overlay component. + tutorialOverlay?.setTutorials?.(tutorialsWithVariables); + } + + /** + * Navigate to a path if it is not the current path. Path is adjusted to current base. + * @param {string|object} route - Full path to navigate or query object. To remove query, use { __remove: 'all' } for every query, or { __remove: string[] } for queries in the list. + * @param {string} [base=''] - Base path if navigate with query. If not provided, will only update query. + * @param {object} [options={}] + * @param {boolean} [options.keepTime = false] - If keepTime == true, populates the time again for the url + * @returns {boolean} Navigated or not + */ + navigate(route, base = '', options = {}) { + if (!_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.isEmptyObject(options)) { + if (typeof route === 'string') { + base = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.cleanPathDuplicate(`${base}/${route}`); + route = {}; + } + } + + if (options.__remove) { + route.__remove = options.__remove; + } + + if (options.keepTime) { + const timeManager = this._app.getManager('time'); + if (this.query.time && timeManager) { + if (!base.includes('time=')) { + route.time = route.time || timeManager.getTimeUrl(); + } + if (!base.includes('rate=')) { + route.rate = route.rate || timeManager.getTimeRate(); + } + } + } + + return this._navigate(route, base); + } + + /** + * Navigate to a path if it is not the current path. + * @param {string|object} route - Full path to navigate or query object. To remove query, use { __remove: 'all' } for every query, or { __remove: string[] } for queries in the list. + * @param {string} [base=''] - Base path if navigate with query. If not provided, will only update query. + * @returns {boolean} Navigated or not + */ + _navigate(route, base = '') { + if (typeof route === 'string') { + const current = this.lastPathResolved(); + let outputRoute = route; + if (!route.startsWith('/')) { + outputRoute = '/' + route; + } + if (!route.includes(base)) { + outputRoute = base + route; + } + if (current !== outputRoute) { + const parts = outputRoute.split('?'); + if (parts.length > 1) { + this._query = this.parseQuery(parts[1]); + } + else { + this._query = {}; + const configs = _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.filterObject(this._configs, val => val !== undefined); + outputRoute += this.buildQuery(configs); + } + + this._router.navigate(outputRoute); + return true; + } + return false; + } + else { + return this.navigate(this.updateQueryPath(route, base), base); + } + } + + /** + * Return to home, optionally keeping query + * @param {boolean} keepCurrentQuery + */ + returnHome(keepCurrentQuery = true) { + const currentQuery = keepCurrentQuery ? this.buildQuery(this.query) : ''; + this.navigate(currentQuery); + } + + /** + * Reload current route. + * @param {boolean} [onQueryChange=true] - Call onQueryChange by default, otherwise call onRouteChange + * @param {boolean} [clearQuery=false] - Clear all queries when reload + */ + async reload(onQueryChange = true, clearQuery = false) { + const view = await this._app.getView(this._currentView); + const { params, query } = this._router.lastRouteResolved(); + let objectQuery = {}; + if (!clearQuery && query) { + objectQuery = this.parseQuery(query); + } + + if (onQueryChange) { + view.onQueryChange({ ...params, ...objectQuery }); + } + else { + view.onRouteChange({ ...params, ...objectQuery }); + } + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/scene_manager.js": +/*!*********************************************!*\ + !*** ../eyes/src/managers/scene_manager.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SceneManager": function() { return /* binding */ SceneManager; } +/* harmony export */ }); +/* harmony import */ var moment_timezone__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! moment-timezone */ "../eyes/node_modules/moment-timezone/index.js"); +/* harmony import */ var moment_timezone__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(moment_timezone__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + + + +/** + * @typedef {import('../../../pioneer-scripts/src/entity').ExtraOptions} ExtraOptions + */ + +/** + * Nomenclature: + * Added* means that an entity name is in the entity statuses, but not necessarily loaded into the scene. + * Loaded* means that an entity is in the entity statuses and is also loaded into the scene. + * Visible* means that an entity's components are visible (or would be if the entity were loaded). + */ + +/** + * Every app has a _sceneInfo object and it is passed in to populate the scene. + * @typedef SceneInfo + * @property {string[]} [dynamicEntityGroups] - Entity groups that are loaded depending on layers and distance. + * @property {string[]} [dynamicEntities] - Individual entities that are loaded depending on layers and distance. + * @property {string[]} [staticEntityGroups] - Entity groups that are loaded depending only on layers. + * @property {string[]} [staticEntities] - Individual entities that are lodaed depending only on layers. + * @property {ExtraOptions} [entityOptions] - Extra options that are passed to PioneerScripts.Entity.createEntity(). + * @property {number} [zoomMax] + * @property {object} [meta] + * @property {string} meta.titlePrefix + * @property {string} meta.titleSuffix + * @property {string} meta.url + * @property {string} meta.description + */ + +/** + * A record of the current load status flags of the entities in the scene. + * @typedef EntityStatus + * @property {boolean} forceVisible - If true, it will always be loaded and visible no matter what. + * @property {boolean} dynamic - If true, it will only be loaded when its parent has a large enough pixel-space system radius. + * @property {boolean} layerVisibility - Whether or not the entity is in a visible layer. + * @property {string[]} dependentEntities - The list of entities that are dependent on this. Only populated when loaded. + * @property {Set} entitiesForcingThisVisible - The list of entities that when visible should also show this entity. + * @property {boolean} visible - Whether or not the entity is actually visible (components enabled), taking into account layers, camera, and forceVisible of other entities. + * @property {Set} componentTypesNotVisible - These components are forced invisible even when the entity is visible. + */ + +/** + * Scene Manager class. + * @extends BaseManager + */ +class SceneManager extends _internal__WEBPACK_IMPORTED_MODULE_3__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + */ + constructor(app) { + super(app); + + /** + * List of scenes. + * @type {object} + */ + this._scenes = {}; + + /** + * Main scene. + * @type {Pioneer.Scene} + */ + this._scene = this.add('main'); + + /** + * Stores HD status. + * @type {boolean} + */ + this._isHD = false; + + /** + * Maps entity ids to HD WMTS components. + * @type {object} + */ + this._hdWMTSMap = {}; + + /** + * List of loading items. + * @type {string[]} + */ + this._loadingItems = []; + + /** + * List of forced loaded components. + * @type {Pioneer.BaseComponent[]} + */ + this._loadedComponents = []; + + /** + * Below or equal to this size, it's low resolution. + * Above it's high resolution. + * @type {number} + */ + this._hdBreakpointSize = 512; + + /** + * Maximum texture size. + * @type {number} + */ + this._maxTextureSize = 4096; + + /** + * Array of possible event names. + * @type {string[]} + * @default + */ + this._eventNames.push('loading', 'loaded'); + this._initCallbacks(); + + /** + * Indicator that there is a component(s) loading. + * @type {boolean} + */ + this._isLoading = false; + + /** + * A list of entities that are possible in the scene, loaded depending on their load style and visibilities. + * @type {Pioneer.FastMap} + */ + this._entityStatuses = new pioneer__WEBPACK_IMPORTED_MODULE_1__.FastMap(); + + /** + * The extra options to use when adding new Entities from PioneerScripts. + * @type {ExtraOptions} + * @private + */ + this._entityExtraOptions = undefined; + + /** + * A list of entity added callbacks. + * @type {((entity: Pioneer.Entity) => void)[]} + * @private + */ + this._entityLoadedCallbacks = []; + + /** + * A list of entity will be removed callbacks. + * @type {((entity: Pioneer.Entity) => void)[]} + * @private + */ + this._entityWillBeUnloadedCallbacks = []; + + /** + * These components are not visible even when the entities are visible. + * @type {Set} + * @private + */ + this._componentTypesNotVisible = new Set(); + + /** + * Mobile Texture Size + * TODO: Set this value to less than the max texture size to improve performance of HD textures on mobile. + * @type {number} + * @private + */ + this._mobileTextureSize = 1024; + + this.bindFunctions([ + 'addLoading', + 'removeLoading', + 'update', + 'toggleStarfield', + 'toggleHeliosphere', + 'toggleConstellations', + 'addWMTSComponent', + 'tileIsReady', + 'enableWMTSComponent', + 'forceTextureSizeForEntity', + 'toggleHDTextureForEntity', + 'isEntityHD' + ]); + + /** + * List of temporary entities. + * @type {Pioneer.Entity[]} + */ + this._tempEntities = []; + } + + // FUNCTIONS THAT DEAL WITH ADDING AND REMOVING. + + /** + * Adds a new scene. + * @param {string} name + * @returns {Pioneer.Scene} + */ + add(name) { + if (name === 'main' && this._scene) { + return this._scene; + } + + this._scenes[name] = this.pioneer.addScene(name); + this._scenes[name].setAmbientLightColor(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(0.005, 0.005, 0.005)); + return this._scenes[name]; + } + + /** + * Adds an entity to the scene manager. + * @param {string} entityName - The name of the entity. + * @param {boolean} dynamic - If true, it will only be loaded when its parent has a large enough pixel-space system radius. + */ + addEntity(entityName, dynamic) { + if (this._entityStatuses.has(entityName)) { + throw new Error(`Error adding entity: The entity ${entityName} has already been added.`); + } + this._entityStatuses.set(entityName, { + forceVisible: false, + layerVisibility: /** @type {LayerManager} */(this.app.getManager('layer')).isEntityVisibleWithCurrentLayers(entityName), + dynamic, + dependentEntities: [], + entitiesForcingThisVisible: new Set(), + visible: true, + componentTypesNotVisible: new Set() + }); + } + + /** + * Removes an entity from the scene manger. + * @param {string} entityName + */ + removeEntity(entityName) { + if (!this._entityStatuses.delete(entityName)) { + throw new Error(`Error removing entity: The entity ${entityName} was not in the scene manager.`); + } + // If it's in the scene, remove it, calling the callbacks beforehand. + const entity = this._scene.getEntity(entityName); + if (entity !== null) { + for (let i = 0, k = this._entityWillBeUnloadedCallbacks.length; i < k; i++) { + this._entityWillBeUnloadedCallbacks[i](entity); + } + this._scene.removeEntity(entityName); + } + } + + + /** + * Gets an entity's status object. + * @param {string} entityName + * @returns {EntityStatus} + */ + getEntityStatus(entityName) { + return this._entityStatuses.get(entityName); + } + + /** + * Sets the entities from the scene info. + * @param {SceneInfo} sceneInfo + */ + addEntitiesFromSceneInfo(sceneInfo) { + // Get a big list of entity names from the static and dynamic entity names and groups. + const entityNames = /** @type {Map} */(new Map()); // name => is dynamic + + // Do it for static entities. + if (sceneInfo.staticEntities !== undefined) { + if (sceneInfo.staticEntities.length === 1 && sceneInfo.staticEntities[0] === 'all') { + // It was ['all'] so get every entity in PioneerScripts. + pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityNamesInGroup('').forEach(entityName => entityNames.set(entityName, false)); + } + else { + sceneInfo.staticEntities.forEach(entityName => entityNames.set(entityName, false)); + } + } + if (sceneInfo.staticEntityGroups !== undefined) { + sceneInfo.staticEntityGroups.forEach(entityGroupName => { + pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityNamesInGroup(entityGroupName).forEach(entityName => entityNames.set(entityName, false)); + }); + } + + // Do it for dynamic entities. If an entity was already in the static list, don't add it here. + if (sceneInfo.dynamicEntities !== undefined) { + if (sceneInfo.dynamicEntities.length === 1 && sceneInfo.dynamicEntities[0] === 'all') { + // It was ['all'] so get every entity in PioneerScripts. + pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityNamesInGroup('').forEach(entityName => { + if (!entityNames.has(entityName)) { + entityNames.set(entityName, true); + } + }); + } + else { + sceneInfo.dynamicEntities.forEach(entityName => { + if (!entityNames.has(entityName)) { + entityNames.set(entityName, true); + } + }); + } + } + if (sceneInfo.dynamicEntityGroups !== undefined) { + sceneInfo.dynamicEntityGroups.forEach(entityGroupName => { + pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityNamesInGroup(entityGroupName).forEach(entityName => { + if (!entityNames.has(entityName)) { + entityNames.set(entityName, true); + } + }); + }); + } + + // Remove anything that doesn't have an entity info in the content manager. + const contentManager = /** @type {ContentManager} */(this.app.getManager('content')); + for (const entityName of entityNames.keys()) { + if (contentManager.getEntityInfo(entityName) === null) { + entityNames.delete(entityName); + } + } + + // Add all of the entity names to the scene manager. + entityNames.forEach((dynamic, entityName) => this.addEntity(entityName, dynamic)); + + // Add the entity options. + this.setExtraEntityOptions(sceneInfo.entityOptions); + + // Update the visibility of the layers. + this.updateEntityLayerVisibility(); + } + + // FUNCTIONS THAT DEAL WITH LOADING AND UNLOADING. + + /** + * Adds an entity loaded callback. + * @param {(entity: Pioneer.Entity) => void} callback + */ + addEntityLoadedCallback(callback) { + this._entityLoadedCallbacks.push(callback); + } + + /** + * Removes an entity loaded callback. + * @param {(entity: Pioneer.Entity) => void} callback + */ + removeEntityLoadedCallback(callback) { + for (let i = 0, l = this._entityLoadedCallbacks.length; i < l; i++) { + if (this._entityLoadedCallbacks[i] === callback) { + this._entityLoadedCallbacks.splice(i, 1); + return; + } + } + } + + /** + * Adds an entity will be unloaded callback. + * @param {(entity: Pioneer.Entity) => void} callback + */ + addEntityWillBeUnloadedCallback(callback) { + this._entityWillBeUnloadedCallbacks.push(callback); + } + + /** + * Removes an entity will be unloaded callback. + * @param {(entity: Pioneer.Entity) => void} callback + */ + removeEntityWillBeUnloadedCallback(callback) { + for (let i = 0, l = this._entityWillBeUnloadedCallbacks.length; i < l; i++) { + if (this._entityWillBeUnloadedCallbacks[i] === callback) { + this._entityWillBeUnloadedCallbacks.splice(i, 1); + return; + } + } + } + + /** + * Sets a list of entities to be force loaded, regardless of layer or distance. + * Previously force-loaded entities can be removed if desired. + * @param {string[]} entityNames - The list of entities to be force loaded. + * @param {boolean} removeExisting - If true, remove previous force loaded flags. + */ + setEntitiesForceVisible(entityNames, removeExisting) { + if (removeExisting) { + for (let i = 0, l = this._entityStatuses.size; i < l; i++) { + const entityStatus = this._entityStatuses.getAt(i).value; + entityStatus.forceVisible = false; + } + } + for (let i = 0, l = entityNames.length; i < l; i++) { + const entityName = entityNames[i]; + const entityStatus = this._entityStatuses.get(entityName); + if (entityStatus === undefined) { + throw new Error(`Entity ${entityName} was set to force load, but isn't in the scene manager. Use addEntity().`); + } + entityStatus.forceVisible = true; + } + // Do an update to get the entities created. + this.update(); + } + + /** + * Sets the extra options to use when loading new Entities from PioneerScripts. + * @param {ExtraOptions} extraOptions + */ + setExtraEntityOptions(extraOptions) { + this._entityExtraOptions = { ...extraOptions }; + } + + // FUNCTIONS THAT DEAL LAYER VISIBILITY. + + /** + * Update the layer visibility for only the children of parentId + * @param {string} parentId + * @param {string} satelliteGroup - The satellite group to check against entities + */ + updateEntityLayerVisibilityForChildren(parentId, satelliteGroup) { + const layerManager = /** @type {LayerManager} */(this.app.getManager('layer')); + const now = this._scene.getEngine().getTime(); + for (let i = 0, l = this._entityStatuses.size; i < l; i++) { + const entry = this._entityStatuses.getAt(i); + if (pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Parenting.getAllAncestorsOfEntity(entry.key, now).has(parentId)) { + entry.value.layerVisibility = layerManager.isEntityVisibleWithCurrentLayers(entry.key, satelliteGroup); + } + } + } + + /** + * Updates the entity-layer visibility mapping, which is used in the loading of entities. + * Called when a layer is toggled. + * @param {string} satelliteGroup - The satellite group to check against entities + */ + updateEntityLayerVisibility(satelliteGroup) { + const layerManager = /** @type {LayerManager} */(this.app.getManager('layer')); + for (let i = 0, l = this._entityStatuses.size; i < l; i++) { + const entry = this._entityStatuses.getAt(i); + entry.value.layerVisibility = layerManager.isEntityVisibleWithCurrentLayers(entry.key, satelliteGroup); + } + } + + // THE MAIN UPDATE FUNCTION AND ITS HELPERS. + + /** + * Updates the loaded entities, both static and dynamic, keeping into account layers. + * Makes loaded entities visible or invisible, depending on layers and other factors. + * Runs every frame. + */ + update() { + // Get the camera entity. + const cameraEntity = /** @type {CameraManager} */(this.app.getManager('camera')).cameraEntity; + const contentManager = /** @type {ContentManager} */(this.app.getManager('content')); + + // Go through each of the entities. + for (let i = 0, l = this._entityStatuses.size; i < l; i++) { + const entry = this._entityStatuses.getAt(i); + const entityName = entry.key; + const entityStatus = entry.value; + + // Figure out if it should be loaded or not. + const shouldBeLoaded = entityStatus.forceVisible // force loaded (always loaded) + || (!entityStatus.dynamic // static loaded (checks layer) + && entityStatus.layerVisibility) + || (entityStatus.dynamic // dynamic loaded (checks layer and distance) + && entityStatus.layerVisibility + && this._isEntityVisibleWithinParent(entityName)) + || cameraEntity?.getParent()?.getName() === entityName; + + // Load or unload the entity if needed, calling the appropriate callbacks. + let entity = this._scene.getEntity(entityName); + if (shouldBeLoaded && entity === null) { + this._createEntity(entityName); + // Also do all of its dependencies. + const dependentEntityNames = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.SceneHelpers.getDependentEntities(entityName); + for (const dependentEntityName of dependentEntityNames) { + if (this._scene.getEntity(dependentEntityName) === null) { + this._createEntity(dependentEntityName); + } + } + } + else if (!shouldBeLoaded && entity !== null) { + // First check if it isn't depended on by anything else that is in the scene. + const focusedEntityName = cameraEntity.getParent()?.getName(); + const ignoreDependents = contentManager.getEntityInfo(entityName).ignoreDependentWhenUnloading; + let hasLoadedDependents = false; + for (let j = 0, m = entityStatus.dependentEntities.length; j < m; j++) { + const dependentEntityName = this._scene.get(entityStatus.dependentEntities[j])?.getName(); + if (dependentEntityName) { + if (dependentEntityName === focusedEntityName && ignoreDependents?.includes(focusedEntityName)) { + hasLoadedDependents = false; + break; + } + hasLoadedDependents = true; + } + } + if (!hasLoadedDependents) { + for (let j = 0, m = this._entityWillBeUnloadedCallbacks.length; j < m; j++) { + this._entityWillBeUnloadedCallbacks[j](entity); + entity = null; + } + entityStatus.dependentEntities = []; + this._scene.removeEntity(entityName); + } + } + + // If it's visible but should be invisible, make sure the components are hidden. + const visible = entityStatus.forceVisible || entityStatus.layerVisibility || this._isAncestorOfCamera(cameraEntity, entityName) || entityStatus.entitiesForcingThisVisible.size > 0; + if (entity !== null && entityStatus.visible !== visible) { + // Keep the entity loaded, but hide the components. + this.setVisibility(visible, entityName); + } + } + } + + /** + * Create an entity. + * @param {string} entityName + * @returns {Pioneer.Entity} + * @private + */ + _createEntity(entityName) { + // Create the entity and set its components on/off, depending on its visibility. + const entity = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create(entityName, this._scene, this._entityExtraOptions); + if (!this._entityStatuses.get(entityName).visible) { + this.setVisibility(false, entityName); + } + // Populate its dependencies. + const dependentEntityNames = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.SceneHelpers.getDependentEntities(entityName); + for (const dependentEntityName of dependentEntityNames) { + let entityStatus = this._entityStatuses.get(dependentEntityName); + if (entityStatus === undefined) { + this.addEntity(dependentEntityName, this._entityStatuses.get(entityName).dynamic); + entityStatus = this._entityStatuses.get(dependentEntityName); + } + entityStatus.dependentEntities.push(entityName); + } + // Call the callbacks. + for (let j = 0, m = this._entityLoadedCallbacks.length; j < m; j++) { + this._entityLoadedCallbacks[j](entity); + } + return entity; + } + + /** + * Returns true if the entityName is an ancestor of the camera for any time. + * @param {Pioneer.Entity} cameraEntity + * @param {string} entityName + * @returns {boolean} + * @private + */ + _isAncestorOfCamera(cameraEntity, entityName) { + let cameraAncestor = cameraEntity; + while (cameraAncestor !== null) { + if (cameraAncestor.getName() === entityName) { + return true; + } + // Check the all possible parents of the ancestor as well. + for (let i = 0, l = cameraAncestor.getNumParentingTableEntries(); i < l; i++) { + if (cameraAncestor.getParentingTableEntry(i)[1] === entityName) { + return true; + } + } + cameraAncestor = cameraAncestor.getParent(); + } + return false; + } + + /** + * Sets the visibility of an entity. + * @param {boolean} visible + * @param {string} entityName + * @private + */ + setVisibility(visible, entityName) { + // Update the visibility in the entity statuses. + const entityStatus = this._entityStatuses.get(entityName); + if (entityStatus !== undefined) { + entityStatus.visible = visible; + } + + // Get the entity in the scene. If not loaded, we've got nothing to do. + const entity = this._scene.getEntity(entityName); + if (entity === null) { + return; + } + + // Enable or disable the components. Trails and labels are treated as a separate case. + const layerManager = /** @type {LayerManager} */(this.app.getManager('layer')); + const trailsVisible = layerManager.getLayer('trails').visible; + const divsVisible = layerManager.getLayer('labels').visible; + for (let i = 0; i < entity.getNumComponents(); i++) { + const component = entity.getComponent(i); + const type = component.getType(); + if (entity.getName() === 'sun') { + continue; + } + if (visible && type === 'trail') { + component.setEnabled(visible && trailsVisible && !entityStatus.componentTypesNotVisible.has('trail')); + } + else if (visible && type === 'div') { + component.setEnabled(visible && divsVisible && !entityStatus.componentTypesNotVisible.has('div')); + } + else { + component.setEnabled(visible && !entityStatus.componentTypesNotVisible.has(component.getType())); + } + } + + // If this forces other entities to be visible, mark them as forced visible. + const contentManager = /** @type {ContentManager} */(this.app.getManager('content')); + const entityInfo = contentManager.getEntityInfo(entityName); + if (entityInfo.forceVisibleEntities !== undefined) { + for (let i = 0, l = entityInfo.forceVisibleEntities.length; i < l; i++) { + const entityStatus = this._entityStatuses.get(entityInfo.forceVisibleEntities[i]); + if (entityStatus === undefined) { + throw new Error(`Entity ${entityName} was set to force load, but isn't in the scene manager. Use addEntity().`); + } + if (visible) { + entityStatus.entitiesForcingThisVisible.add(entityName); + } + else { + entityStatus.entitiesForcingThisVisible.delete(entityName); + } + } + } + } + + /** + * Checks if the entity is visible from the point of view of its parent. + * @param {string} entityName + * @returns {boolean} + * @private + */ + _isEntityVisibleWithinParent(entityName) { + const parentName = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Parenting.getParentOfEntity(entityName, this._scene.getEngine().getTime()); + const parent = this._scene.getEntity(parentName); + + // If the parent isn't already in the scene, we can't test the entity. + if (parent === null) { + return false; + } + + const parentOptions = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityOptions(parentName); + const systemRadius = parentOptions.systemRadius + || parentOptions.radius * 25 + || parentOptions.extentsRadius * 25; + const pixelSpaceSystemRadius = systemRadius / parent.getExtentsRadius() * parent.getGreatestPixelSpaceExtentsRadius(); + return pixelSpaceSystemRadius >= 20; + } + + // OTHER HELPING FUNCTIONS. + + /** + * Gets a scene. + * @param {*} name + * @returns {Pioneer.Scene|null} + */ + get(name) { + if (this._scenes[name] !== undefined) { + return this._scenes[name]; + } + return null; + } + + /** + * Get names of entities in current scene. + * @returns {string[]} + */ + getEntitiesNames() { + const entityNames = []; + // Looping through all entities + for (let i = 0; i < this._scene.getNumEntities(); i++) { + const entity = this._scene.getEntity(i); + entityNames.push(entity.getName()); + } + return entityNames; + } + + /** + * Gets the parent of an object. + * @param {string} id - object of which to return parent. + * @returns {string|null} + */ + getParent(id) { + const entity = this._scene.getEntity(id); + if (entity !== null) { + const parent = entity.getParent(); + if (parent !== null) { + return parent.getName(); + } + } + return null; + } + + /** + * Returns a list of parents. + * @param {string} entityName + * @returns {string[]} + */ + getParentList(entityName) { + let parent = this.getParent(entityName); + const parentList = []; + while (parent !== null && parent !== '') { + parentList.push(parent); + parent = this.getParent(parent); + } + return parentList; + } + + /** + * Gets entity dependencies of entity. + * @param {string} entityName + * @returns {string[]} + */ + getDependencies(entityName) { + const entity = this._scene.getEntity(entityName); + const dependencies = new Set(); + // Parents from parenting table are dependencies + if (entity !== null) { + for (let i = 0; i < entity.getNumParentingTableEntries(); i++) { + const parentName = entity.getParentingTableEntry(i)[1]; + if (parentName !== '') { + dependencies.add(parentName); + } + } + } + + // Look through options to get additional dependencies + const options = pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityOptions(entityName); + if (options !== undefined) { + for (const optionName of Object.keys(options)) { + // @ts-ignore + const option = options[optionName]; + + // Check parents from parenting table + if (optionName === 'parents') { + for (let i = 0; i < option.length; i++) { + const parentName = option[i][1]; + if (parentName !== '') { + dependencies.add(parentName); + } + } + } + + // Check align targets + if (optionName === 'align') { + if (option.primary && option.primary.target && option.primary.target !== entityName) { + dependencies.add(option.primary.target); + } + if (option.secondary && option.secondary.target && option.secondary.target !== entityName) { + dependencies.add(option.secondary.target); + } + } + } + } + + return Array.from(dependencies); + } + + /** + * Returns a promise to check when an object is ready for a certain time. + * @param {string} id - Id of the object + * @param {moment} time - Moment time + */ + async isReady(id, time) { + if (time === undefined) { + time = this.pioneer.getTime(); + } + else { + time = this.app.getManager('time').momentToET(time); + } + + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.SceneHelpers.waitTillEntitiesInPlace(this._scene, [id], time); + } + + /** + * Checks multiple ids over multiple times given. + * @param {string[]} objectIds + * @param {moment[]} times + */ + async isListReady(objectIds, times) { + const promises = []; + if (times === undefined) { + times = [undefined]; + } + for (let i = 0; i < objectIds.length; i++) { + for (let j = 0; j < times.length; j++) { + promises.push(this.isReady(objectIds[i], times[j])); + } + } + + await Promise.all(promises); + } + + /** + * Checks if the WMTS tile component is ready. + * @param {WMTSComponent} wmtsComponent + * @returns {Promise} + */ + async tileIsReady(wmtsComponent) { + let loadedPromise = /** @type {Promise} */(null); + const promise = new Promise((resolve, reject) => { + const check = setInterval(() => { + // Reject if component is disabled + if (!wmtsComponent.isEnabled() || !wmtsComponent.getEntity().isEnabled()) { + clearInterval(check); + reject(new Error('disabled')); + } + if (loadedPromise === null && wmtsComponent.getTilesLoadedPromise() !== null) { + loadedPromise = wmtsComponent.getTilesLoadedPromise().then(() => { + clearInterval(check); + resolve(true); + }); + } + }, 30); + }); + + return promise; + } + + /** + * Checks if the CMTS terrain tile component is ready. + * @param {Pioneer.CMTSComponent} cmtsComponent + * @returns {Promise} + */ + async terrainIsReady(cmtsComponent) { + let loadedPromise = null; + const promise = new Promise(resolve => { + const check = setInterval(() => { + // Stop checking if component is disabled during check + if (!cmtsComponent.isEnabled() || !cmtsComponent.getEntity().isEnabled()) { + clearInterval(check); + resolve(true); + } + if (loadedPromise === null && cmtsComponent._loadedPromise !== null) { + loadedPromise = cmtsComponent.getTilesLoadedPromise().then(() => { + clearInterval(check); + resolve(true); + }); + } + }, 30); + }); + + return promise; + } + + /** + * Checks if the component is ready. + * @param {Pioneer.BaseComponent} component + * @returns {Promise} + */ + async componentIsReady(component) { + if (component.isEnabled() && component.getLoadState() === 'loaded') { + return; + } + const promise = new Promise(resolve => { + const check = setInterval(() => { + // Stop checking if component is disabled during check + if (!component.isEnabled() || !component.getEntity().isEnabled()) { + clearInterval(check); + resolve(true); + } + // Return true if component is loaded + if (component.getLoadState() === 'loaded') { + clearInterval(check); + resolve(true); + } + }, 30); + }); + + return promise; + } + + /** + * Toggles Starfields + * @param {boolean} visible + */ + toggleStarfield(visible) { + for (let i = 0; i < 7; i++) { + this._scene.get('sun', 'starfield', i).setEnabled(visible); + } + } + + /** + * Toggle's heliosphere for the sun + * @param {boolean} visible + */ + toggleHeliosphere(visible) { + this._scene.get('sun', 'model').setEnabled(visible); + } + + /** + * Toggles Constellations + * @param {boolean} visible + */ + async toggleConstellations(visible) { + const sun = /** @type {Pioneer.Entity} */(this._scene.get('sun')); + if (sun === null) { + return; + } + let constellations = /** @type {ConstellationsComponent} */(sun.getComponentByType('constellations')); + if (visible && constellations === null) { + // Create + constellations = /** @type {ConstellationsComponent} */(sun.addComponent('constellations')); + if (constellations instanceof pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.ConstellationsComponent) { + constellations.setUrl('$STATIC_ASSETS_URL/stars/constellations.bin'); + constellations.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(0.35, 0.7, 1, 0.5)); + } + await this.pioneer.waitUntilNextFrame(); + await constellations.getLoadedPromise(); + + // Add to label manager + const labelManager = /** @type {LabelManager} */ (this.app.getManager('label')); + const contentManager = /** @type {ContentManager} */ (this.app.getManager('content')); + labelManager.stop(); + const highlightColor = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(0.35, 0.7, 1, 1); + const cameraComponent = /** @type {Pioneer.CameraComponent} */ (this.get('main').getEntity('camera').getComponentByType('camera')); + constellations.getNames().forEach(name => { + const entityName = `constellation_label_${name}`; + const entity = this._scene.getEntity(entityName); + labelManager.addEntity(entity); + labelManager.setLabelProps({ + getLabelClass: entityName => `no-select ${contentManager.getClassName(entityName, 'constellation') ?? 'constellation'}`, + handleTouch: null, + handleMouseEnter: event => { + // Handles constellation line highlight for hover on desktop and touch on mobile. + constellations.setHighlight(constellations.getNearestConstellationIndex(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector2(event.x, event.y), cameraComponent), highlightColor, 2.5); + }, + handleMouseLeave: () => { + // Handles constellation line un-highlight for hover exit on desktop and (second) touch outside of constellation label on mobile. + constellations.setHighlight(undefined, highlightColor, 2.5); + }, + handleClick: null + }, [entityName]); + }); + labelManager.start(); + } + else if (!visible && constellations !== null) { + // Remove from label manager + const labelManager = /** @type {LabelManager} */ (this.app.getManager('label')); + labelManager.stop(); + constellations.getNames().forEach(name => { + const entityName = `constellation_label_${name}`; + const entity = this._scene.getEntity(entityName); + labelManager.removeEntity(entity); + }); + labelManager.start(); + + // Delete + sun.removeComponent(constellations); + } + } + + /** + * Returns true if HD is enabled. + * @returns {boolean} + */ + isHD() { + return this._isHD; + } + + /** + * Checks if an entity has HD available. + * @param {string} id - The Entity id + * @returns {boolean} + */ + hasHD(id) { + const entity = this._scene.get(id); + if (entity === null) { + return false; + } + // Check WMTS + if (Object.prototype.hasOwnProperty.call(this._hdWMTSMap, id)) { + return true; + } + // Check WMTS for parent too + if (entity.getParent() !== null && Object.prototype.hasOwnProperty.call(this._hdWMTSMap, entity.getParent().getName())) { + return true; + } + // Check for high resolution textures + if (entity.get('spheroidLOD') !== null) { + const spheroidLOD = entity.get('spheroidLOD'); + const sizes = spheroidLOD.getTextureSizes('color'); + for (let i = 0; i < sizes.length; i++) { + if (sizes[i] > this._hdBreakpointSize) { + return true; + } + } + } + return false; + } + + /** + * Sets the HD breakpoint sizes. + * Below is Low resolution, above will be considered HD. + * @param {number} breakPointSize - Size (default 512) + * @param {number} maxTextureSize - Size (default 4096) + */ + setHDBreakpoints(breakPointSize, maxTextureSize) { + this._hdBreakpointSize = breakPointSize; + this._maxTextureSize = maxTextureSize; + } + + /** + * Toggles HD features. + */ + async toggleHD() { + this._isHD = !this._isHD; + + // Toggle low resolution textures + if (!this._isHD) { + this.pioneer.getConfig().setValue('maxTextureSize', this._hdBreakpointSize); + } + + // Toggle WMTS + for (const name in this._hdWMTSMap) { + const wmts = this._hdWMTSMap[name]; + const entity = this._scene.get(name); + const spheroidLOD = entity.getComponentByType('spheroidLOD'); + const wmtsComponent = entity.getComponent(wmts); + if (_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.isMobileMode()) { + // Mobile limit + wmtsComponent.setMaxLevel(5); + } + wmtsComponent.setEnabled(this._isHD); + if (this._isHD) { + // Add it to the loading list + this.addLoading(name, 'wmts'); + // Wait for first level to be loaded + await this.pioneer.waitUntilNextFrame(); + const ready = await this.tileIsReady(wmtsComponent).catch(() => { + this.removeLoading(name, 'wmts'); + }); + if (ready === true) { + spheroidLOD.setEnabled(false); + this.removeLoading(name, 'wmts'); + } + } + else { + spheroidLOD.setEnabled(true); + } + + // Toggle 4K textures + if (this._isHD) { + this.pioneer.getConfig().setValue('maxTextureSize', this._maxTextureSize); + } + } + } + + /** + * Set the texture size for a specific entity + * @param {string} entityId + * @param {number} size + * @param {string} textureName + */ + async forceTextureSizeForEntity(entityId, size, textureName = 'color') { + const spheroidLOD = /** @type {Pioneer.SpheroidLODComponent} */ (this.app.pioneer.get('main', entityId, 'spheroidLOD')); + if (spheroidLOD === null || spheroidLOD === undefined) { + return; + } + spheroidLOD.forceTextureSize(textureName, size); + } + + /** + * Returns true if the entity's textures are larger than the HD break size point + * @param {string} entityId + * @returns {Promise} + */ + async isEntityHD(entityId) { + const spheroidLOD = /** @type {Pioneer.SpheroidLODComponent} */ (this.app.pioneer.get('main', entityId, 'spheroidLOD')); + if (spheroidLOD === null || spheroidLOD === undefined) { + return false; + } + await spheroidLOD.getLoadedPromise(); + return spheroidLOD.getTextureCurrentSize('color', 0) > this._hdBreakpointSize; + } + + /** + * Toggle the textures for an an entity between the min and max texture sizes available. + * @param {string} entityId + * @returns {Promise} + */ + async toggleHDTextureForEntity(entityId) { + const spheroidLOD = /** @type {Pioneer.SpheroidLODComponent} */ (this.app.pioneer.get('main', entityId, 'spheroidLOD')); + if (await this.isEntityHD(entityId) === false) { + let hdTextureSize = this._maxTextureSize; + if (_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.isiPhone()) { + hdTextureSize = this._mobileTextureSize; + } + this.addLoading(entityId, 'spheroidLOD'); + spheroidLOD.getTextureNames().forEach(element => { + this.forceTextureSizeForEntity(entityId, hdTextureSize, element); + }); + await this.pioneer.waitUntilNextFrame(); + await spheroidLOD.getLoadedPromise(); + this.removeLoading(entityId, 'spheroidLOD'); + return true; + } + else { + this.addLoading(entityId, 'spheroidLOD'); + spheroidLOD.getTextureNames().forEach(element => { + this.forceTextureSizeForEntity(entityId, this._hdBreakpointSize, element); + }); + await this.pioneer.waitUntilNextFrame(); + await spheroidLOD.getLoadedPromise(); + this.removeLoading(entityId, 'spheroidLOD'); + return false; + } + } + + /** + * Create a ring or disc grid around an entity. + * @param {string} name - Ring entity's name + * @param {number} radius + * @param {string} entityName + * @param {object} [options={}] + * @param {string} [options.orbitPlaneEntityName] - Entity to align ring along its orbit plane + * @param {Pioneer.Color} [options.color] + * @param {number} [options.numCircles=1] + * @param {number} [options.numSpokes=0] + * @param {Pioneer.Vector3} [options.labelPosition=new Pioneer.Vector3(-radius, 0, 0)] + * @param {string} [options.labelText=''] + * @param {boolean} [options.isEnable=true] - Entity is enabled or not by default + */ + createRing(name, radius, entityName, { orbitPlaneEntityName, color, numCircles = 1, numSpokes = 0, labelPosition = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-radius, 0, 0), labelText = '', isEnable = true } = {}) { + // Create ring entity + const ringEntity = this._scene.addEntity(name); + ringEntity.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero); + + // Attach to a parent entity + const entity = this._scene.getEntity(entityName); + ringEntity.setParent(entity); + + // Create ring + const ring = /** @type {DiscGridComponent} */(ringEntity.addComponent('discGrid')); + ring.setLineWidth(6); + ring.setSize(radius); + ring.setNumCircles(numCircles); + ring.setNumSpokes(numSpokes); + ring.setIgnoreDistance(true); + + // Set orientation + if (orbitPlaneEntityName) { + this.setAlignPlane(ringEntity, orbitPlaneEntityName); + } + + // Set color + if (color instanceof pioneer__WEBPACK_IMPORTED_MODULE_1__.Color) { + ring.setColor(color); + } + + // Create label entity + const labelEntity = this._scene.addEntity(`${name}Label`); + labelEntity.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero); + labelEntity.setParent(entity); + const fixed = /** @type {Pioneer.FixedController} */(labelEntity.addController('fixed')); + fixed.setPosition(labelPosition); + const divComponent = /** @type {Pioneer.DivComponent} */(labelEntity.addComponent('div')); + divComponent.setFadeWhenCloseToCamera(false); + const div = divComponent.getDiv(); + div.classList.add('ring-label'); + divComponent.getDiv().innerHTML = labelText; + + ringEntity.setEnabled(isEnable); + labelEntity.setEnabled(isEnable); + } + + /** + * Create a torus around an entity. + * @param {string} name - Torus entity's name + * @param {number} innerRadius + * @param {number} outerRadius + * @param {string} entityName + * @param {object} [options={}] + * @param {string} [options.orbitPlaneEntityName] - Entity to align ring along its orbit plane + * @param {Pioneer.Color} [options.color] + * @param {[number, number]} [options.visibleDistance=[Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY]] + * @param {Pioneer.Vector3} [options.labelPosition=new Pioneer.Vector3(-radius, 0, 0)] + * @param {string} [options.labelText=''] + * @param {boolean} [options.isEnable=true] - Entity is enabled or not by default + */ + createTorus(name, innerRadius, outerRadius, entityName, { orbitPlaneEntityName, color, visibleDistance = [Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY], labelPosition = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-outerRadius, 0, 0), labelText = '', isEnable = true } = {}) { + // Create torus entity + const torusEntity = this._scene.addEntity(name); + torusEntity.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero); + + // Attach to a parent entity + const parent = this._scene.getEntity(entityName); + torusEntity.setParent(parent); + + // Create torus + const torus = /** @type {TorusComponent} */(torusEntity.addComponent('torus')); + torus.setInnerRadius(innerRadius); + torus.setOuterRadius(outerRadius); + torus.setVisibleDistanceInterval(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(...visibleDistance)); + + // Set orientation + if (orbitPlaneEntityName) { + this.setAlignPlane(torusEntity, orbitPlaneEntityName); + } + + // Set color + if (color instanceof pioneer__WEBPACK_IMPORTED_MODULE_1__.Color) { + torus.setColor(color); + } + + // Create label entity + const labelEntity = this._scene.addEntity(`${name}Label`); + labelEntity.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero); + labelEntity.setParent(parent); + const fixed = /** @type {Pioneer.FixedController} */(labelEntity.addController('fixed')); + fixed.setPosition(labelPosition); + const divComponent = /** @type {Pioneer.DivComponent} */(labelEntity.addComponent('div')); + divComponent.setFadeWhenCloseToCamera(false); + const div = divComponent.getDiv(); + div.classList.add('ring-label'); + divComponent.getDiv().innerHTML = labelText; + + torusEntity.setEnabled(isEnable); + labelEntity.setEnabled(isEnable); + } + + /** + * Sets the HD WMTS component for an entity. + * @param {string} id - Target entity id + * @param {string} wmts - Name of the WMTS component + */ + setEntityHDWMTS(id, wmts) { + this._hdWMTSMap[id] = wmts; + } + + /** + * Checks that the tiles are ready and sets the wmtsComponent to enabled. + * @param {string} entityId + * @param {WMTSComponent} wmtsComponent + */ + async enableWMTSComponent(entityId, wmtsComponent) { + if (_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.isMobileMode()) { + wmtsComponent.setMaxLevel(5); + } + const spheroidLOD = this.get('main').getEntity(entityId).getComponentByType('spheroidLOD'); + + this.addLoading(entityId, 'wmts'); + // Wait for first level to be loaded + wmtsComponent.setEnabled(true); + await this.pioneer.waitUntilNextFrame(); + const ready = await this.tileIsReady(wmtsComponent).catch(() => { + this.removeLoading(entityId, 'wmts'); + }); + if (ready) { + spheroidLOD.setEnabled(false); + this.removeLoading(entityId, 'wmts'); + } + else { + spheroidLOD.setEnabled(true); + } + } + + /** + * Add the WMTS component to the entity + * @param {string} entityId + * @param {any} wmtsData + */ + async addWMTSComponent(entityId, wmtsData) { + const entity = /** @type {Pioneer.Entity} */ (this.app.pioneer.get('main', entityId)); + + // Create component if it doesn't already exist. + let wmts = /** @type {WMTSComponent} */ (entity.getComponentByType('wmts')); + if (wmts === null) { + wmts = /** @type {WMTSComponent} */ (entity.addComponent('wmts', wmtsData.id)); + } + wmts.setEnabled(false); + + // Set the end point, layer, and tile matrix set. + wmts.setEndPoint(wmtsData.endPoint); + wmts.setLayer(wmtsData.layer); + + if (wmtsData.tile) { + wmts.setTileMatrixSet(wmtsData.tile); + } + + // Set time + const now = new Date(); + if (wmtsData.time === 'yesterday') { + // Set the date to one day before today. + now.setDate(now.getDate() - 1); + wmts.setDimensionValue('Time', now.getFullYear() + '-' + (String(now.getMonth() + 1)).padStart(2, '0') + '-' + (String(now.getDate())).padStart(2, '0')); + } + else if (wmtsData.time === 'now') { + wmts.setDimensionValue('Time', now.getFullYear() + '-' + (String(now.getMonth() + 1)).padStart(2, '0') + '-' + (String(now.getDate())).padStart(2, '0')); + } + + // Set Max Level + if (wmtsData.level) { + wmts.setMaxLevel(wmtsData.level); + } + else { + wmts.setMaxLevel(Infinity); + } + // Set Min level + wmts.setMinLevel(2); + + await this.enableWMTSComponent(entityId, wmts); + } + + /** + * Parses JSON file and loads WMTS components accordingly. + * @param {JSON} wmtsList + */ + loadWMTSFromJSON(wmtsList) { + // Loop for each entity id + for (const entityId in wmtsList) { + let hdId = ''; + // Loop for each wmts item + for (const key in wmtsList[entityId]) { + if (key === 'hd' || hdId === '') { + // Set HD WMTS id + hdId = wmtsList[entityId][key]; + this._hdWMTSMap[entityId] = hdId; + } + else { + // Parse WMTS data + const wmtsData = wmtsList[entityId][key]; + const entity = this._scene.get(entityId); + // Create component + const wmts = entity.addComponent('wmts', key); + wmts.setEnabled(false); + // Set the end point, layer, and tile matrix set. + wmts.setEndPoint(wmtsData.endPoint); + wmts.setLayer(wmtsData.layer); + if (wmtsData.tile) { + wmts.setTileMatrixSet(wmtsData.tile); + } + // Set time + const now = new Date(); + if (wmtsData.time === 'yesterday') { + // Set the date to one day before today. + now.setDate(now.getDate() - 1); + wmts.setDimensionValue('Time', now.getFullYear() + '-' + (String(now.getMonth() + 1)).padStart(2, '0') + '-' + (String(now.getDate())).padStart(2, '0')); + } + else if (wmtsData.time === 'now') { + wmts.setDimensionValue('Time', now.getFullYear() + '-' + (String(now.getMonth() + 1)).padStart(2, '0') + '-' + (String(now.getDate())).padStart(2, '0')); + } + // Set Max Level + if (wmtsData.level) { + wmts.setMaxLevel(wmtsData.level); + } + else { + wmts.setMaxLevel(Infinity); + } + } + } + } + } + + /** + * Set orientation of an entity to another entity's plane. + * @param {Pioneer.Entity} entity + * @param {string} orbitPlaneEntityName + */ + setAlignPlane(entity, orbitPlaneEntityName) { + const orbitPlaneEntity = this._scene.getEntity(orbitPlaneEntityName); + const ori = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(); + const dynamoController = /** @type {Pioneer.DynamoController} */(orbitPlaneEntity.getControllerByType('dynamo')); + dynamoController.getOrbitOrientation(ori, this.app.pioneer.getTime()); + entity.setOrientation(ori); + } + + /** + * Clears all temporary entities. + */ + clearTempEntities() { + const cameraManager = /** @type {CameraManager} */(this.app.getManager('camera')); + const cameraEntity = cameraManager.cameraEntity; + if (cameraEntity === null || cameraEntity.getParent() === null) { + return; + } + + const camParent = cameraEntity.getParent().getName(); + + this._tempEntities = this._tempEntities.filter(tempEntity => { + // Dont clear the temp entities if the camera is using one + if (camParent === tempEntity.getName()) { + return true; // it stays in the temp entity array + } + + // Remove from label, scene and this array + const labelManager = /** @type {LabelManager} */(this.app.getManager('label')); + labelManager.removeEntity(tempEntity); + this._scene.removeEntity(tempEntity?.getName()); + return false; + }); + } + + /** + * Adds a temporary entity. + * @param {Pioneer.Entity} entity + */ + addTempEntity(entity) { + this._tempEntities.push(entity); + } + + /** + * Adds loading of an object. + * @param {string} id - Entity id + * @param {string} type - Could be camera or wmts + */ + addLoading(id, type) { + const itemId = id + '_' + type; + if (this._loadingItems.indexOf(itemId) < 0) { + this._loadingItems.push(itemId); + } + if (this._loadingItems.length > 0) { + this._isLoading = true; + this.triggerCallbacks('loading'); + } + } + + /** + * Removes loading of an object. + * @param {string} id - Entity id + * @param {string} type - Could be camera or wmts + */ + removeLoading(id, type) { + const itemId = id + '_' + type; + const index = this._loadingItems.indexOf(itemId); + if (index >= 0) { + this._loadingItems.splice(index, 1); + } + if (this._loadingItems.length === 0) { + this._isLoading = false; + this.triggerCallbacks('loaded', [id]); + } + } + + /** + * Forces a component to be loaded. + * @param {Pioneer.BaseComponent} component + */ + forceLoad(component) { + component.setForceLoaded(true); + this._loadedComponents.push(component); + } + + /** + * Removes force load for a component. + * @param {Pioneer.BaseComponent} component + */ + removeForceLoad(component) { + this._loadedComponents = this._loadedComponents.filter(value => { + if (value === component) { + component.setForceLoaded(false); + return false; + } + return true; + }); + } + + /** + * Clear all forced components. + */ + clearForceLoad() { + for (let i = 0; i < this._loadedComponents.length; i++) { + const component = this._loadedComponents[i]; + component.setForceLoaded(false); + } + + this._loadedComponents = []; + } + + /** + * Gets the distance between two objects. + * @param {string} objectA - Id of scene object A + * @param {string} objectB - Id of scene object B + * @param {object} options - the options + * @param {moment} [options.time = undefined] - specific time as moment object + * @param {boolean} [options.subtractRadius = false] - if calculation should subtract radiuses + * @param {boolean} [options.precision = 0] - Rounding error up to precision number + * @returns {number} + */ + getDistance(objectA, objectB, { time = undefined, subtractRadius = false, precision = 0 } = {}) { + const positionRel = pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.get(); + const entityA = this._scene.get(objectA); + const entityB = this._scene.get(objectB); + + let distance = 0; + + if (time !== undefined) { + const pioneerTime = pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.unixToEt(time.valueOf() / 1000); + entityA.getPositionRelativeToEntity(positionRel, pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, entityB, pioneerTime); + } + else { + entityA.getPositionRelativeToEntity(positionRel, pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, entityB); + } + distance = positionRel.magnitude(); + + if (subtractRadius) { + const radiusA = entityA.getExtentsRadius(); + const radiusB = entityB.getExtentsRadius(); + distance -= (radiusA + radiusB); + } + + if (precision > 0) { + const f = Math.pow(10, Math.floor(Math.log10(distance)) - precision); + distance = Math.round(distance / f) * f; + } + + pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.release(positionRel); + return distance; + } + + /** + * Gets the speed of an object. + * @param {string} objectA - Id of scene object A + * @param {string} objectB - Speed of A relative to B + * @param {object} options - the options + * @param {moment} [options.time = undefined] - specific time as moment object + * @returns {number} + */ + getSpeed(objectA, objectB, { time = undefined } = {}) { + const speed = pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.get(); + const entityA = this._scene.get(objectA); + let entityB = null; + if (objectB === undefined) { + entityB = entityA.getParent(); + } + else { + entityB = this._scene.get(objectB); + } + + if (time !== undefined) { + const pioneerTime = this.app.getManager('time').momentToET(time); + entityA.getVelocityRelativeToEntity(speed, pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, entityB, pioneerTime); + } + else { + entityA.getVelocityRelativeToEntity(speed, pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, entityB); + } + + pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.release(speed); + + return speed.magnitude(); + } + + /** + * Gets min and max coverage of am object. + * @param {string} entityId + * @param {boolean} checkOrientation + * @returns {object} + */ + getCoverage(entityId, checkOrientation = true) { + const coverage = { + min: _internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.constants.maxDate, + max: _internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.constants.minDate + }; + // Get coverage for entity + const entity = this.pioneer.get('main', entityId); + const margin = 0.001; // Adds a margin in seconds to the min/max coverage to prevent dynamo issues + + let posOriMin = entity.getPositionCoverage().min; + let posOriMax = entity.getPositionCoverage().max; + if (checkOrientation) { + // Check interval for both position and orientation + posOriMin = Math.max(entity.getPositionCoverage().min, entity.getOrientationCoverage().min); + posOriMax = Math.min(entity.getPositionCoverage().max, entity.getOrientationCoverage().max); + } + + coverage.min = entity ? Math.min(posOriMin, coverage.min) : coverage.min; + coverage.max = entity ? Math.max(posOriMax - margin, coverage.max) : coverage.max; + + // Convert to moment + if (coverage.min === -Infinity || coverage.min < _internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.minDate) { + coverage.min = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.constants.minDate); + } + else { + coverage.min = Math.ceil(coverage.min * 1000) / 1000; + let unix = pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.etToUnix(coverage.min) * 1000; + unix = Math.ceil(unix * 1000) / 1000; + coverage.min = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().tz(unix, 'ETC/Utc'); + } + if (coverage.max === Infinity || coverage.max > _internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.maxDate) { + coverage.max = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.constants.maxDate); + } + else { + coverage.max = Math.floor(coverage.max * 1000) / 1000; + let unix = pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.etToUnix(coverage.max) * 1000; + unix = Math.floor(unix * 1000) / 1000; + coverage.max = moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().tz(unix, 'ETC/Utc'); + } + + return coverage; + } + + /** + * TODO: Toggle on/off ring of target. + * @param {string} target + * @returns {Promise} + */ + async toggleRing(target) { + console.log('toggleRing', target); + } + + /** + * Gets main scene. + * @returns {Pioneer.Scene|null} + */ + get main() { + return this._scene; + } + + /** + * Get loading status. + * @returns {boolean} + */ + get isLoading() { + return this._isLoading; + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/search_manager.js": +/*!**********************************************!*\ + !*** ../eyes/src/managers/search_manager.js ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SearchManager": function() { return /* binding */ SearchManager; } +/* harmony export */ }); +/* harmony import */ var fuse_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fuse.js */ "../eyes/node_modules/fuse.js/dist/fuse.esm.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + +/** + * Search Manager class. + * @extends BaseManager + * @class + */ +class SearchManager extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + * @param {object} [options={}] + */ + constructor(app, options = {}) { + super(app); + + /** + * Maximum results returned. + * @type {number} + */ + this._maxEntries = 10; + + /** + * Fuse instance. + * @type {Fuse} + */ + this._fuse = null; + + /** + * Database to search. + * @type {object[]} + */ + this._database = null; + + /** + * Fuse options. + * @type {object} + */ + this._options = { + threshold: 0.4, + keys: [ + { + name: 'id', + weight: 0.99 + }, + { + name: 'name', + weight: 0.98 + } + ], + includeScore: true, + includeMatches: true, + ignoreLocation: true, + ...options + }; + } + + /** + * Set Fuse options for search. + * @param {object} options + */ + setOptions(options) { + Object.assign(this._options, options); + this._fuse = new fuse_js__WEBPACK_IMPORTED_MODULE_1__["default"](this._database, this._options); + } + + /** + * Set database for search. + * @param {object} database - Data that will be used to search + * @param {object} [options={}] - Fuse options + */ + setDatabase(database, options = {}) { + if (!database) { + console.error('[SearchManager.setDatabase] Missing database.'); + return; + } + + Object.assign(this._options, options); + + this._database = Object.keys(database).filter(key => database[key].searchable !== false).map(key => { + const keywords = database[key].keywords || []; + keywords.map(keyword => ({ + value: keyword + })); + database[key].keywords = keywords; + return database[key]; + }); + + if (!Array.isArray(this._database)) { + console.error('[SearchManager.setDatabase] Database is not an array.'); + return; + } + + this._fuse = new fuse_js__WEBPACK_IMPORTED_MODULE_1__["default"](this._database, this._options); + } + + /** + * Get entry using id. + * @param {string} id + * @returns {object} + */ + getEntry(id) { + return this._database.find(entry => entry.id === id); + } + + /** + * Finds a string and return searh results. + * @param {string} text - string that is searched + * @param {number} maxEntries + * @returns {Fuse.FuseResult|null} + */ + find(text, maxEntries = this._maxEntries) { + if (text === '' || text === null || text === undefined || !this._fuse) { + return null; + } + + // Filtering based on negative keywords if any + let results = this._fuse.search(text); + + // Limiting by the max entries value + results = results.slice(0, maxEntries); + + return results; + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/selection_manager.js": +/*!*************************************************!*\ + !*** ../eyes/src/managers/selection_manager.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SelectionManager": function() { return /* binding */ SelectionManager; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + +/** + * Selection Manager class. + * @extends BaseManager + */ +class SelectionManager extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + * @param {Pioneer.Scene} scene + */ + constructor(app, scene) { + super(app); + + /** + * Main Pioneer scene. + * @type {Pioneer.Scene} + */ + this._scene = scene; + + /** + * Current selected id. + * @type {string} + */ + this._id = null; + + /** + * All 3D objects are clickable or not. + * @type {boolean} + */ + this._isClickable = true; + + /** + * State of suppressing 3D selection handler. + * @type {boolean} + */ + this._isSuppressed = false; + + this._eventNames.push('3dselection'); + this._initCallbacks(); + + this.bindFunctions([ + 'setSuppress', + 'handle3DSelection' + ]); + } + + /** + * Sets the scene. + * @param {Pioneer.Scene} scene + */ + setScene(scene) { + this._scene = scene; + } + + /** + * Selects an entity. + * @param {string} id + */ + selectEntity(id) { + const oldId = this._id; + if (id !== oldId) { + const event = new CustomEvent('selectionupdate', { detail: { new: id, old: this._id } }); + window.dispatchEvent(event); + this._id = id; + this._switchSelectionClass(this._id, oldId); + } + } + + /** + * Unselects what was selected before. + */ + unselect() { + const oldId = this._id; + if (oldId !== null) { + const event = new CustomEvent('unselect', { old: this._id }); + window.dispatchEvent(event); + } + this._id = null; + this._switchSelectionClass(this._id, oldId); + } + + /** + * Returns the ID of the currently selected object. + * @returns {string} + */ + getCurrentId() { + return this._id; + } + + /** + * Enable/disable all 3D objects click. + * @param {boolean} isClickable + */ + setClickable(isClickable) { + this._isClickable = isClickable; + } + + /** + * Initializes the 3D click callback. + * @param {CameraManager} cameraManager + */ + init3Dcallback(cameraManager) { + cameraManager.setSelectionCallback(this.handle3DSelection); + } + + /** + * Gets link from entity's name. + * @param {string} entityName + * @returns {string} + */ + _getLink(entityName) { + return `/${entityName}`; + } + + /** + * Set state of suppressing 3D selection handler once. + * @param {boolean} suppress + */ + setSuppress(suppress) { + this._isSuppressed = suppress; + } + + /** + * A selection callback when a 3D object is clicked. + * @param {Pioneer.Entity} entity + */ + handle3DSelection(entity) { + if (!this._isClickable) { + return; + } + if (!this._isSuppressed && entity !== null) { + const router = this._app.getManager('router'); + const entityName = entity.getName(); + const parsedLink = this._getLink(entityName); + + const linkPath = typeof parsedLink === 'string' ? parsedLink : (parsedLink.path ?? ''); + + const { + options = { keepTime: true }, + query = {} + } = typeof parsedLink === 'object' && parsedLink; + + // Go to the object, maintaining time query if it exists. + const navigated = router.navigate(query, linkPath, options); + + this.triggerCallbacks('3dselection', [navigated, entity]); + } + // Reset suppress state + this._isSuppressed = false; + } + + /** + * Updates selection class on entity div component. + * @param {string|null} newId + * @param {string|null} oldId + */ + _switchSelectionClass(newId, oldId) { + // Remove old selection class + if (oldId !== null) { + const entity = this._scene.get(oldId); + if (entity !== null) { + const label = entity.getComponentByType('div').getDiv(); + if (label) { + label.classList.remove('selection'); + } + } + } + // Add new selection class + if (newId !== null) { + const entity = this._scene.get(newId); + if (entity !== null) { + const label = entity.getComponentByType('div').getDiv(); + if (label) { + label.classList.add('selection'); + } + } + } + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/spout_manager.js": +/*!*********************************************!*\ + !*** ../eyes/src/managers/spout_manager.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SpoutManager": function() { return /* binding */ SpoutManager; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + + +/** + * Spout manager class. + */ +class SpoutManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + */ + constructor(app) { + super(app); + + this._scene = this.app.pioneer.get('main'); + this._defaultTarget = this.getSpoutCameraTargetEntity(this.app.getManager('router').currentRoute.params); + this._defaultTargetRadius = this._defaultTarget ? this._scene.getEntity(this._defaultTarget)?.getExtentsRadius() : this._scene.getEntity('earth').getExtentsRadius(); + } + + /** + * Enable Spout + * @param {boolean} globe + * @param {number} renderWidth + * @param {number} globeDistance + * @param {any} target + * @param {number} fontSize + * @param {number} lonAngleOffset + * @param {boolean} alignToNorthPole + */ + async enableSpout(globe = false, renderWidth = 2048, globeDistance = this._defaultTargetRadius * 2, target = this._defaultTarget, fontSize = 25, lonAngleOffset = 0, alignToNorthPole = false) { + // Set up viewport as invisible + const spoutViewport = this.app.pioneer.getViewport('spoutViewport') || this.app.pioneer.addViewport('spoutViewport'); + spoutViewport.getDiv().style.display = 'none'; + spoutViewport.getDiv().style.width = '100%'; + spoutViewport.getDiv().style.height = '100%'; + + // Get the entity that will be the center for the globe spout + const targetEntity = this._scene.getEntity(target) || this._scene.getEntity('earth'); + + // Set up the Spout camera entity + const spoutCamera = this.setUpSpoutCamera(globe, targetEntity, alignToNorthPole, lonAngleOffset); + + // Add Spout component. + const spoutComponent = spoutCamera.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpoutComponent) || spoutCamera.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpoutComponent); + spoutViewport.setCamera(spoutComponent); // This causes 2 computeBoundingSphere errors. + spoutComponent.setRenderWidth(renderWidth); + this._scene.setAmbientLightColor(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1)); + + if (globe === true) { + spoutComponent.setForGlobe(true, globeDistance || targetEntity.getExtentsRadius() * 2); + spoutComponent.setNearDistance(targetEntity.getExtentsRadius() * 0.5); + targetEntity.get('atmosphere')?.setExcludedFromCamera(spoutComponent, true); + } + + // Turn divs into labels to work with Spout + await this.setUpSpoutLabels(fontSize, targetEntity); + } + + /** + * Set up spout camera. If it's a globe, put a new entity at the target. Otherwise, just use the existing camera entity. + * @param {boolean} globe + * @param {any} targetEntity + * @param {boolean} alignToNorthPole + * @param {number} lonAngleOffset + * @returns {Pioneer.CameraComponent} spoutCamera + */ + setUpSpoutCamera(globe, targetEntity = this._defaultTarget, alignToNorthPole = false, lonAngleOffset = 0) { + let spoutCamera; + if (globe === true) { + spoutCamera = this._scene.getEntity('spoutCamera') || this._scene.addEntity('spoutCamera'); + spoutCamera.clearControllers(); + spoutCamera.setParent(targetEntity); + spoutCamera.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero); + spoutCamera.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + + const align = spoutCamera.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.AlignController); + align.setPrimaryAlignType('align'); + align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis); + align.setPrimaryTargetAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis); + if (alignToNorthPole) { + align.setPrimaryTargetEntity(targetEntity.getName()); + } + else { + align.setPrimaryTargetEntity('camera'); + } + + const xAxis = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Geometry.getXYZFromLLAOnSphere(xAxis, new pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt(0, pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(180 + lonAngleOffset), 1), 1); + align.setSecondaryAlignType('align'); + align.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis); + align.setSecondaryTargetEntity('camera'); + align.setSecondaryTargetAxis(xAxis); + } + else { + spoutCamera = this._scene.getEntity('camera'); + } + + return spoutCamera; + } + + /** + * Set up spout labels + * @param {number} fontSize + * @param {any} targetEntity + */ + async setUpSpoutLabels(fontSize = 25, targetEntity = null) { + let target = targetEntity; + // If no target given, grab target from URL + if (!target) { + target = await this.getSpoutCameraTargetEntity(this.app.getManager('router').currentRoute.params) || 'sun'; + } + + pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(this._scene, [target], this.app.pioneer.getTime(), 10.0, 3.0).then(() => { + for (let i = 0; i < this._scene.getNumEntities(); i++) { + const entity = this._scene.getEntity(i); + + const divComponent = entity.get('div'); + if (divComponent instanceof pioneer__WEBPACK_IMPORTED_MODULE_0__.DivComponent) { + const label = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.LabelComponent) ?? entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.LabelComponent); + label.setText((divComponent.getDiv().querySelector('.text')?.innerHTML || divComponent.getDiv()?.textContent) || ''); + label.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1)); + label.setFontSize(fontSize); + label.setAlignment(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(0, 0.5)); + label.setPixelOffset(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(-fontSize / 4, -1)); + divComponent.setEnabled(false); + } + } + return true; + }).catch(error => { + console.log(error); + }); + } + + /** + * Logic for getting Spout camera parent + * @param {object} params + */ + async getSpoutCameraTargetEntity(params) { + let spaceObject = null; + const contentManager = this.app.getManager('content'); + if (params) { + const onMoon = 'feature' in params && params['feature'] === 'moons'; + const currentObjectId = onMoon ? params.child : params.spaceObject; + const currentObjectEntity = this.pioneer.get('main', currentObjectId) || this.pioneer.get('main', 'earth'); + const entityInfo = contentManager.getEntityInfo(currentObjectId) || {}; + const entityDesc = await contentManager.getEntityDesc(currentObjectId); + const spaceObjParentId = currentObjectId && this.pioneer.get('main', currentObjectId)?.getParent()?.getName(); + + switch (entityInfo.category) { + case 'Spacecraft': + spaceObject = _internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isFutureMission(entityDesc?.dates?.start) ? 'earth' : currentObjectEntity?.getParent()?.getName(); + + // If lander, use parent of landing site aka celestial body + if (entityInfo.keywords.includes('lander') && currentObjectEntity.getParent().getName().includes('landing_site')) { + spaceObject = this.pioneer.get('main', currentObjectId)?.getParent()?.getParent()?.getName(); + } + break; + case 'Landing site': + spaceObject = spaceObjParentId; + break; + default: + spaceObject = currentObjectId; + break; + } + } + + return spaceObject; + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/time_manager.js": +/*!********************************************!*\ + !*** ../eyes/src/managers/time_manager.js ***! + \********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TimeManager": function() { return /* binding */ TimeManager; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var moment_timezone__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! moment-timezone */ "../eyes/node_modules/moment-timezone/index.js"); +/* harmony import */ var moment_timezone__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(moment_timezone__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + + + +/** + * Time manager class. + */ +class TimeManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + */ + constructor(app) { + super(app); + + /** + * Date formats object. + * @default + */ + this._dateFormats = { + utc: { + full: 'YYYY-MM-D HH[:]mm[:]ss', + datetime: 'YYYY-MM-D HH[:]mm', + date: 'YYYY MMMM D', + time: 'HH[:]mm[:]ss', + url: 'YYYY-MM-DDTHH:mm:ss.SSSZ' + }, + local: { + full: 'M/D/YY hh[:]mm[:]ss', + datetime: 'M/D/YY hh[:]mm', + date: 'MMMM D, YYYY', + time: 'hh[:]mm[:]ss', + meridiem: 'a' + } + }; + + /** + * Time limits. + * @default + */ + this._timeLimits = { + min: null, + max: null + }; + + /** + * Default time limits. + * @default + */ + this._defaultLimits = { + min: null, + max: null + }; + + /** + * Start time. + * @type {moment} + * @default + */ + this._startTime = null; + + /** + * Time is forced pause. + * @type {boolean} + * @default + */ + this._forcedPause = false; + + /** + * Display UTC variable. + * @type {boolean} + * @default + */ + this._isUTC = true; + + /** + * ERT manager. + * @type {ERTManager} + */ + this._ertMgr = null; + + /** + * Time rate. + * @type {number} + * @default + */ + this._rate = 0; + + /** + * Default time rate. + * @type {number} + * @default + */ + this._defaultRate = 1.0; + + /** + * Stores the UTC timezone string. + * @type {string} + * @default + */ + this._utcTimezone = 'Etc/UTC'; + + /** + * Stores the local timezone string. + * @type {string} + * @default + */ + this._localTimezone = moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz.guess(); + + /** + * Stores previous time rate. + * @type {number} + * @default + */ + this._previousTimeRate = this.pioneer.getTimeRate(); + + /** + * Stores current timezone string. + * @type {string} + * @default + */ + this._timezone = this._utcTimezone; + + /** + * Array of possible event names. + * @type {string[]} + * @default + */ + this._eventNames.push('update', 'change', 'timezone', 'ratechange', 'forcedpause', 'forcedpauseresume', 'getnow'); + this._initCallbacks(); + + // Set the time to 'now' + this.setToNow(); + + // Add Pioneer callback every frame + this.pioneer.addCallback(() => { + const time = this.pioneer.getTime(); + const rate = this.pioneer.getTimeRate(); + this._time = moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(time) * 1000, this._timezone); + let nextTime = moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(time + rate / this.pioneer.getFPS()) * 1000, this._timezone); + if (isNaN(nextTime)) { + nextTime = this._time; + } + // Check for min/max boundaries + // Use millisecond comparison instead of isBefore isAfter due to rounding to second + if (this._timeLimits.max && nextTime.valueOf() > this._timeLimits.max.valueOf()) { + console.warn('[Time Manager]: Clock has reached maximum limit.'); + this._onLimitReach('max'); + } + else if (this._timeLimits.min && nextTime.valueOf() < this._timeLimits.min.valueOf()) { + console.warn('[Time Manager]: Clock has reached minimum limit.'); + this._onLimitReach('min'); + } + else if ((this._timeLimits.max && nextTime.valueOf() < this._timeLimits.max.valueOf()) && (this._timeLimits.min && nextTime.valueOf() > this._timeLimits.min.valueOf())) { + // Resume time from previous limit reached + if (this._forcedPause) { + this._forcedPause = false; + if (this.getTimeRate() === 0) { + this.play(); + + // Callbacks + this.triggerCallbacks('forcedpauseresume', [this._time]); + } + } + } + + // Callbacks + this.triggerCallbacks('update', [this._time]); + }, true); + } + + /** + * Limit reach handler. + * @param {string} limit - 'min' or 'max' + */ + _onLimitReach(limit) { + if (this.getTimeRate() !== 0) { + this._forcedPause = true; + this.pause(); + this._previousTimeRate = 0; + + // Callbacks + this.triggerCallbacks('forcedpause', [this._time, limit]); + } + this.setTime(this._timeLimits[limit]); + } + + /** + * Set ERT manager. + * @param {ERTManager} ertMgr + */ + setERTManager(ertMgr) { + this._ertMgr = ertMgr; + } + + /** + * Check if time is now. + * @returns {boolean} + */ + isNow() { + return this._rate === 1 && Math.abs(this._time.valueOf() - this.getNow().valueOf()) < 1000; + } + + /** + * Gets current real time as moment object. + * @returns {moment} + */ + getNow() { + let time = moment_timezone__WEBPACK_IMPORTED_MODULE_1___default()().tz(this._timezone); + for (let i = this._callbacks.getnow.length - 1; i >= 0; i--) { + const callback = this._callbacks.getnow[i]; + time = callback(time); + } + return time; + } + + /** + * Sets the engine time to real time. + */ + setToNow() { + this.setTime(this.getNow()); + } + + /** + * Sets start time. + * @param {moment} time + */ + setStartTime(time) { + this._startTime = time; + } + + /** + * Sets the engine time start time. + */ + setToStart() { + if (this._startTime !== null) { + this.setTime(this._startTime); + } + } + + /** + * Gets engine time as moment object. + * @returns {moment} + */ + getTime() { + return this._time; + } + + /** + * Sets current engine time. + * @param {moment|number|string} time - Value that can be parsed by moment + */ + setTime(time) { + time = this.parseTime(time); + const etTime = this.momentToET(time); + this.pioneer.setTime(etTime); + this._time = moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(this.pioneer.getTime()) * 1000, this._timezone); + + // Callbacks + this.triggerCallbacks('change', [this._time]); + } + + /** + * Parses time and returns a moment object. + * @param {moment|number|string} time - Any input time] + * @param {string} dateFormat + * @returns {moment} + */ + parseTime(time, dateFormat = 'url') { + let isUTC = this._isUTC; + let format = (moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().ISO_8601); // ISO string with no fractional seconds + + if (typeof time === 'string' && time !== '') { // Check for UTC string + const reg = /^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d(?:|:[0-5]\d)(?:\.\d{1,6})?(?:|Z|[+-][01]\d:[0-5]\d)$/; + isUTC = time.match(reg) !== null; + const isUTCFormat = isUTC ? 'utc' : 'local'; + const urlFormat = this.getDateFormat(dateFormat, isUTCFormat); + if (urlFormat) { + format = urlFormat; + } + } + else if (typeof time === 'number') { + isUTC = true; + } + + return isUTC + ? moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().utc(time) // This only means UTC format, time can be in any time zone, not just GMT + : moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(time, format, true, this._localTimezone); + } + + /** + * Convert ET time to moment. + * @param {number} time + * @returns {moment} + */ + etToMoment(time) { + return moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(time) * 1000, 'Etc/UTC'); + } + + /** + * Convert moment to ET time in second. + * @param {moment} time + * @returns {number} + */ + momentToET(time) { + const unix = time.valueOf() / 1000; + const etTime = pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.unixToEt(unix); + return Math.round(etTime * 1000) / 1000; + } + + /** + * Gets current timezone. + * @returns {moment.MomentTimezone} + */ + getTimezone() { + return this._timezone; + } + + /** + * Gets UTC timezone. + * @returns {moment.MomentTimezone} + */ + getUTCTimezone() { + return this._utcTimezone; + } + + /** + * Gets local timezone. + * @returns {moment.MomentTimezone} + */ + getLocalTimezone() { + return this._localTimezone; + } + + /** + * Checks if time is displayed in UTC. + * @returns {boolean} + */ + isUTC() { + return this._isUTC; + } + + /** + * Sets UTC mode on/off for time display. + * Updates timezone as UTC or local. + * @param {boolean} val - on/off + */ + setDisplayUTC(val) { + // TODO: Should support different timezone + this._isUTC = val; + this._timezone = this._isUTC ? this._utcTimezone : this._localTimezone; + + // Callbacks + this.triggerCallbacks('timezone', [val]); + } + + /** + * Gets all date formats. + * @returns {object} + */ + getDateFormats() { + return this._dateFormats; + } + + /** + * Replace all date formats. + * @param {object} formats + */ + setDateFormats(formats) { + for (const [key, value] of Object.entries(formats)) { + if (this._dateFormats[key] !== undefined) { + Object.assign(this._dateFormats[key], value); + } + else { + this._dateFormats[key] = value; + } + } + } + + /** + * Gets a specific date format. + * @param {string} format - Format + * @param {string} utcLocal - Either utc or local + * @returns {string} + */ + getDateFormat(format, utcLocal) { + if (!utcLocal) { + utcLocal = this._isUTC ? 'utc' : 'local'; + } + + return this._dateFormats[utcLocal][format]; + } + + /** + * Add/update a specific date format. + * @param {string} name - Format name + * @param {object} format + */ + setDateFormat(name, format) { + this._dateFormats[name] = format; + } + + /** + * Get time limits + * @returns {object} + */ + getLimits() { + return this._timeLimits; + } + + /** + * Set time limits. + * @param {object} limits + */ + setLimits(limits) { + this._timeLimits.min = limits.min.clone(); + this._timeLimits.max = limits.max.clone(); + } + + /** + * Get default time limits. + * @returns {object} + */ + getDefaultLimits() { + return this._defaultLimits; + } + + /** + * Set default time limits. + * @param {object} limits - min and max moments + */ + setDefaultLimits(limits) { + this._defaultLimits.min = limits.min.clone(); + this._defaultLimits.max = limits.max.clone(); + } + + /** + * Reset time limits to default. + */ + resetLimits() { + this._timeLimits.min = this._defaultLimits.min.clone(); + this._timeLimits.max = this._defaultLimits.max.clone(); + } + + /** + * Set the lower limit for time. + * @param {*} time - Any value that can be parsed by moment + */ + setMin(time) { + this._timeLimits.min = moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(time, this._timezone); + } + + /** + * Reset the lower time limit to default. + */ + resetMin() { + this._timeLimits.min = this._defaultLimits.min.clone(); + } + + /** + * Set the upper limit for time. + * @param {*} time - Any value that can be parsed by moment + */ + setMax(time) { + this._timeLimits.max = moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(time, this._timezone); + } + + /** + * Reset the upper time limit to default. + */ + resetMax() { + this._timeLimits.max = this._defaultLimits.max.clone(); + } + + /** + * Gets a url formatted string in UTC. + * @param {moment} [time] - Moment time + * @returns {string} + */ + getTimeUrl(time) { + let utcTime; + if (!time) { + utcTime = moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().utc(this._time); + } + else { + utcTime = moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().utc(moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(time, this._timezone)); + } + // Returns UTC formatted string + return utcTime.utc().format(this._dateFormats.utc.url); + } + + /** + * Get the default time rate. + * @returns {number} + */ + getDefaultTimeRate() { + return this._defaultRate; + } + + /** + * Set the default time rate. + * @param {number} rate + */ + setDefaultTimeRate(rate) { + this._defaultRate = rate; + } + + /** + * Reset time rate to default. + */ + resetTimeRate() { + this.setTimeRate(this._defaultRate); + } + + /** + * Gets current time rate. + * @returns {number} + */ + getTimeRate() { + return this.pioneer.getTimeRate(); + } + + /** + * Sets current time rate. + * @param {number} rate + */ + setTimeRate(rate) { + this._rate = rate; + this.pioneer.setTimeRate(rate); + + // Callbacks + this.triggerCallbacks('ratechange', [this._rate]); + } + + /** + * Plays previous time rate or 1 sec/sec if previous time rate is 0. + */ + play() { + const rate = this._previousTimeRate === 0 ? this._defaultRate : this._previousTimeRate; + this.setTimeRate(rate); + } + + /** + * Pauses time. + */ + pause() { + this._previousTimeRate = this.getTimeRate(); + this.setTimeRate(0); + } + + /** + * Gets time between two moments. + * @param {moment} a - First moment time + * @param {moment} b - Second moment time + * @returns {moment} + */ + getMidTime(a, b) { + const midTime = (a.unix() + b.unix()) / 2; + const m = moment_timezone__WEBPACK_IMPORTED_MODULE_1___default()(midTime, 'X'); + return m; + } + + /** + * Returns a list of event names. + * @returns {Array} + */ + getEventNames() { + return this._eventNames; + } + + /** + * Checks if time is within app time limits. + * @param {moment} time + * @returns {number} - negative for before, positive for after and zero for in bounds + */ + isWithinLimits(time) { + if (this._timeLimits.min && time.isBefore(this._timeLimits.min)) { + return -1; + } + if (this._timeLimits.max && time.isAfter(this._timeLimits.max)) { + return 1; + } + return 0; + } + + /** + * Gets time limits. + * @returns {object} + */ + get timeLimits() { + return this._timeLimits; + } + + /** + * Gets the forced pause status. + * @returns {boolean} + */ + get forcedPause() { + return this._forcedPause; + } + + /** + * Gets the previous time rate. + * @returns {number} + */ + get previousTimeRate() { + return this._previousTimeRate; + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/title_manager.js": +/*!*********************************************!*\ + !*** ../eyes/src/managers/title_manager.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TitleManager": function() { return /* binding */ TitleManager; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + +/** + * Every app has a _sceneInfo object and it is passed in to populate the scene. + * @typedef TitleOptions + * @property {string} prefix + * @property {string} suffix + * @property {Function} parseFn + */ + +/** + * Title Manager class. + * + * When initializing this class, pass in the prefex, suffix, and parse function into the options object. Eg: + * + * { + * prefix: 'Eyes on <>', + * suffix: 'NASA/JPL', + * parseFn: (currentRoute) => currentRoute.url + * } + * @extends BaseManager + */ +class TitleManager extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + * @param {TitleOptions} options + */ + constructor(app, options) { + super(app); + + /** + * @type {TitleOptions} + * @private + */ + this._options = options; + + /** + * @type {string} + * @private + */ + this._currentTitle = null; + + /** + * @type {string} + * @private + */ + this._fullTitle = null; + + /** + * @type {Function} + * @private + */ + this._parseFn = this._options.parseFn ?? null; + } + + /** + * Builds the title strings and sets it. + * @param {object} currentRoute + */ + updateTitle(currentRoute) { + const { prefix, suffix } = this._options || {}; + + this._currentTitle = this._parseRoute(currentRoute); + this._fullTitle = `${prefix} - ${this._currentTitle} - ${suffix}`; + + // In the future, we may need a customizable title format. + document.title = this._fullTitle; + } + + /** + * Parses the route string. Applies parseFn if it's set + * @param {string} routeStr + * @returns {string} + */ + _parseRoute(routeStr) { + if (this._parseFn) { + return this._parseFn(routeStr); + } + + return 'Home'; + } + + /** + * Set the parse function. + * @param {Function} parseFn + */ + setParseFunction(parseFn) { + if (typeof parseFn === 'function') { + this._parseFn = parseFn; + } + } + + /** + * Get the current title. + * @returns {string} + */ + get currentTitle() { + return this._currentTitle; + } + + /** + * Get the current title. + * @returns {string} + */ + get fullTitle() { + return this._fullTitle; + } +} + + +/***/ }), + +/***/ "../eyes/src/managers/trail_manager.js": +/*!*********************************************!*\ + !*** ../eyes/src/managers/trail_manager.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TrailManager": function() { return /* binding */ TrailManager; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer-scripts */ "../pioneer/scripts/src/index.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../internal */ "../eyes/src/internal.js"); + + +// Import locals + + +/** + * The Trail Manager class. + */ +class TrailManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager { + /** + * Constructor. + * @param {BaseApp} app + * @param {Pioneer.Scene} scene + */ + constructor(app, scene) { + super(app); + + /** + * The scene that the trails are in. + * @type {Pioneer.Scene} + */ + this._scene = scene; + + /** + * List of entities that has trail. + * @type {Array} + * @private + */ + this._ids = []; + + /** + * List of entities that hide trail. + * @type {Array} + * @private + */ + this._hiddenIds = []; + + /** + * Trail opacities. + * @type {object} + * @private + * @default + */ + this._opacity = { + primary: 0.75, + secondary: 0.35, + hover: 1.0 + }; + + /** + * Trail width boundaries. + * @type {object} + * @private + * @default + */ + this._width = { + default: [0, 2], + hover: [2, 4] + }; + + this._orbitLinesOpts = { + lineWidth: { + default: 1.2, + hover: 2 + }, + glowWidth: { + default: 0, + hover: 0 + }, + alphaFade: [22, 8] + }; + + /** + * Array of entity names that need orbit lines. + * @type {Set} + * @private + * @default + */ + this._orbitLineEntityNames = pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.getEntityNamesInGroup('planets').add('moon'); + + /** + * Trail colors. + * @type {object} + * @private + * @default + */ + this._colors = { + default: new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, this._opacity.secondary), + mercury: new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(151 / 255, 104 / 255, 172 / 255, this._opacity.primary), + venus: new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(176 / 255, 121 / 255, 25 / 255, this._opacity.primary), + earth: new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(0 / 255, 153 / 255, 204 / 255, this._opacity.primary), + mars: new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(154 / 255, 78 / 255, 25 / 255, this._opacity.primary), + jupiter: new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(218 / 255, 139 / 255, 114 / 255, this._opacity.primary), + saturn: new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(213 / 255, 193 / 255, 135 / 255, this._opacity.primary), + uranus: new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(104 / 255, 204 / 255, 218 / 255, this._opacity.primary), + neptune: new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(112 / 255, 140 / 255, 227 / 255, this._opacity.primary) + }; + + // Binds + this.bindFunctions([ + 'onHoverChange', + 'setUpTrail', + 'toggleTrails', + 'toggleOrbits' + ]); + } + + /** + * Sets the scene. + * @param {Pioneer.Scene} scene + */ + setScene(scene) { + this._scene = scene; + } + + /** + * Create a trail for entity. + * @param {string} id + * @returns {Pioneer.TrailComponent} + */ + create(id) { + const trail = this._scene.get(id, 'trail'); + if (trail) { + console.warn('Trail already exists for', id); + return; + } + + const entity = this._scene.get(id); + const result = entity.addComponent('trail'); + this._ids.push(id); + return result; + } + + /** + * Set start time of the trails. + * @param {string | string[]} ids - Id or array of ids of the entities. + * @param {number} start - Start time. + */ + setStartTime(ids, start) { + if (!Array.isArray(ids)) { + ids = [ids]; + } + + for (let i = 0; i < ids.length; i++) { + const trail = this._scene.get(ids[i], 'trail'); + + if (trail) { + trail.setStartTime(start); + } + } + } + + /** + * Set end time of the trails. + * @param {string | string[]} ids - Id or array of ids of the entities. + * @param {number} end - End time. + */ + setEndTime(ids, end) { + if (!Array.isArray(ids)) { + ids = [ids]; + } + + for (let i = 0; i < ids.length; i++) { + const trail = this._scene.get(ids[i], 'trail'); + + if (trail) { + trail.setEndTime(end); + } + } + } + + /** + * Update trail when entity has or loses hover. + * @param {string} id + * @param {boolean} isHovered + * @param {boolean} setEndOpacity + */ + onHoverChange(id, isHovered, setEndOpacity = false) { + const entity = this._scene.get(id); + const trail = this._scene.get(id, 'trail'); + const orbitLine = entity?.get('orbitLine'); + + if (!entity || (!trail && !orbitLine)) { + return; + } + + const color = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(); + const colorComponent = trail ?? orbitLine; + const optsKey = isHovered ? 'hover' : 'default'; + + // Set properties for orbit line or trail. + if (orbitLine) { + // Set the line and glow width. + const { lineWidth, glowWidth } = this._orbitLinesOpts; + orbitLine.setLineWidth(lineWidth[optsKey]); + orbitLine.setGlowWidth(glowWidth[optsKey]); + } + else if (trail) { + // Set the widths. + const width = entity.trailHover?.width?.[optsKey] ?? this._width[optsKey]; + trail.setWidths(...width); + } + + // Set alpha. + const { primary, secondary, hover } = this._opacity; + const alpha = isHovered ? hover : (this._colors[id] ? primary : secondary); + + color.copy(colorComponent.getColor()); + color.a = alpha; + colorComponent.setColor(color); + + setEndOpacity && trail.setAlphaFade(color.a); + } + + /** + * Set alpha fade of the trails. + * @param {string | string[]} ids - Id or array of ids of the entities. + * @param {number} fade - Fade amount of the trails between 0 and 1. + */ + setFade(ids, fade) { + if (!Array.isArray(ids)) { + ids = [ids]; + } + + for (let i = 0; i < ids.length; i++) { + const trail = this._scene.get(ids[i], 'trail'); + + if (trail) { + trail.setAlphaFade(fade); + } + } + } + + /** + * Set the trails color. + * @param {string | string[]} ids - Id or array of ids of the entities. + * @param {number} widthMin - Min width of the trails. + * @param {number} widthMax - Max width of the trails. + */ + setWidths(ids, widthMin, widthMax) { + if (!Array.isArray(ids)) { + ids = [ids]; + } + + for (let i = 0; i < ids.length; i++) { + const trail = this._scene.get(ids[i], 'trail'); + + if (trail) { + trail.setWidths(widthMin, widthMax); + } + } + } + + /** + * Set the widths of multiple trail ids + * @param {Array} ids + * @param {number} minWidth + * @param {number} maxWidth + */ + setMultipleWidths(ids, minWidth, maxWidth) { + for (const id of ids) { + const trail = this._scene.get(id, 'trail'); + if (!trail) { + continue; + } + + trail.setWidths(minWidth, maxWidth); + } + } + + /** + * Get the trails color. + * @param {string} id - Id of the entity. + * @returns {Pioneer.Color} + */ + getColor(id) { + const trail = this._scene.get(id, 'trail'); + + if (trail) { + return trail.getColor(); + } + + return null; + } + + /** + * Set the trails color. + * @param {string | string[]} ids - id or array of ids of the entities + * @param {Pioneer.Color} [color=null] - color of the trails + */ + setColor(ids, color = null) { + if (!Array.isArray(ids)) { + ids = [ids]; + } + + for (let i = 0; i < ids.length; i++) { + const id = ids[i]; + const trail = this._scene.get(id, 'trail'); + + if (trail) { + const trailColor = color instanceof pioneer__WEBPACK_IMPORTED_MODULE_0__.Color + ? color + : this._colors[id] || this._colors.default; + trail.setColor(trailColor); + } + } + } + + /** + * Callback to execute custom code for trails after entity is created. + * @param {Pioneer.Entity} entity + * @private + */ + setUpTrail(entity) { + // Check status of trails with the layer manager + // Whatever custom code for trails we need to call after entity is created. + const layerManager = /** @type {LayerManager} */ (this._app.getManager('layer')); + const sceneManager = /** @type {SceneManager} */ (this._app.getManager('scene')); + const targetId = entity.getName(); + const trailsLayer = layerManager.getLayer('trails'); + + // Should the entity have orbit lines + const createOrbitLine = this._orbitLineEntityNames.has(targetId); + + if (createOrbitLine) { + this.createOrbitLine(entity); + } + + // Reset visibility of trails + if ((trailsLayer !== null && !trailsLayer.visible) || createOrbitLine) { + sceneManager.setVisibility(false, targetId); + } + } + + /** + * Show trails. + * @param {string | string[] | null} [ids=null] - Id or array of ids of the entities. If none, show previously hidden or all trails. + */ + show(ids = null) { + if (ids === null) { + ids = this._hiddenIds.length > 0 ? this._hiddenIds : this._ids; + } + else if (!Array.isArray(ids)) { + ids = [ids]; + } + + for (let i = 0; i < ids.length; i++) { + const id = ids[i]; + const trail = this._scene.get(id, 'trail'); + + if (trail) { + // Remove from list of hidden trails + const hiddenIndex = this._hiddenIds.indexOf(id); + if (hiddenIndex !== -1) { + this._hiddenIds.splice(hiddenIndex, 1); + } + trail.setEnabled(true); + } + else { + console.warn('TrailManager.show: Trail does not exist - ', id); + } + } + } + + /** + * Hide trails. + * @param {string | string[]} [ids=null] - Id or array of ids of the entities. If none, hide all trails. + */ + hide(ids = null) { + if (ids === null) { + ids = this._ids; + } + else if (!Array.isArray(ids)) { + ids = [ids]; + } + this._hiddenIds = ids; + + for (let i = 0; i < ids.length; i++) { + const trail = this._scene.get(ids[i], 'trail'); + + if (trail) { + trail.setEnabled(false); + } + } + } + + /** + * Toggles all the trails in the scene. + * @param {boolean} active + * @param {object} options + * @param {Pioneer.Scene} [options.scene = undefined] + */ + toggleTrails(active, { scene = undefined } = {}) { + if (scene === undefined) { + scene = this._scene; + } + for (let i = 0; i < scene.getNumEntities(); i++) { + const entity = scene.getEntity(i); + const trail = entity.get('trail'); + if (trail !== null) { + const entityInfo = this._app.getManager('content').getEntityInfo(entity.getName()); + if (entityInfo) { + const category = entityInfo.category; + const subcategory = entityInfo.subcategory; + + // Check if layer for this category is disabled + // We dont want to turn on trails of entities disabled + // An exception should be made for forceVisibled entities. + const layer = this._app.getManager('layer').getLayerFromCategory(subcategory) || this._app.getManager('layer').getLayerFromCategory(category); + const { forceVisible = false } = this.app.getManager('scene').getEntityStatus(entity.getName()) || {}; + + if (layer !== null && !layer.visible && !forceVisible) { + trail.setEnabled(false); + } + else { + trail.setEnabled(active); + } + } + else { + trail.setEnabled(active); + } + } + } + } + + /** + * Creates orbit lines + * @param {Pioneer.Entity} entity + */ + createOrbitLine(entity) { + // First check if we have a trail and remove it. + const trail = entity.get('trail'); + trail && entity.removeComponent(trail); + + // Add orbit line component. + const orbitLine = entity.addComponent('orbitLine'); + + // Set color, fade and line properties. + const { lineWidth, glowWidth, alphaFade } = this._orbitLinesOpts; + const color = this._colors[entity.getName()] ?? this._colors.default; + + orbitLine.setColor(color); + orbitLine.setPixelSpaceRadiiAlphaFade(...alphaFade); + orbitLine.setLineWidth(lineWidth.default); + orbitLine.setGlowWidth(glowWidth.default); + + // Set enbaled depending on whether 'orbits' is checked in the layers manager + const enabled = this._app.getManager('layer').getLayer('orbits').visible; + orbitLine.setEnabled(enabled); + } + + /** + * Callback for orbit line toggle + * @param {boolean} active + */ + toggleOrbits(active) { + this._orbitLineEntityNames.forEach(entityName => { + const orbitLine = this._scene.get(entityName, 'orbitLine'); + orbitLine?.setEnabled(active); + }); + } + + /** + * Get all entity ids with trail. + * @returns {string[]} + */ + get ids() { + return this._ids; + } + + /** + * Set entity ids with trail. + * @param {string[]} ids + */ + set ids(ids) { + if (!Array.isArray(ids)) { + ids = [ids]; + } + for (let i = 0; i < ids.length; i++) { + const id = ids[i]; + if (this._ids.includes(id)) { + continue; + } + const trail = this._scene.get(id, 'trail'); + + if (trail) { + this._ids.push(id); + } + } + } +} + + +/***/ }), + +/***/ "../eyes/src/types.js": +/*!****************************!*\ + !*** ../eyes/src/types.js ***! + \****************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Types": function() { return /* binding */ Types; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal */ "../eyes/src/internal.js"); + + +/** + * The class that holds the mappings from component names to their corresponding constructors. + * @type {Map} + */ +const Types = new Map(); + +Types.set('TimeManager', _internal__WEBPACK_IMPORTED_MODULE_0__.TimeManager); +Types.set('SelectionManager', _internal__WEBPACK_IMPORTED_MODULE_0__.SelectionManager); +Types.set('LabelManager', _internal__WEBPACK_IMPORTED_MODULE_0__.LabelManager); +Types.set('TitleManager', _internal__WEBPACK_IMPORTED_MODULE_0__.TitleManager); +Types.set('TrailManager', _internal__WEBPACK_IMPORTED_MODULE_0__.TrailManager); +Types.set('CameraFollowManager', _internal__WEBPACK_IMPORTED_MODULE_0__.CameraFollowManager); + +Types.set('LoadIcon', _internal__WEBPACK_IMPORTED_MODULE_0__.LoadIcon); +Types.set('Overlay', _internal__WEBPACK_IMPORTED_MODULE_0__.Overlay); +Types.set('Settings', _internal__WEBPACK_IMPORTED_MODULE_0__.Settings); +Types.set('Breadcrumb', _internal__WEBPACK_IMPORTED_MODULE_0__.Breadcrumb); +Types.set('Clock', _internal__WEBPACK_IMPORTED_MODULE_0__.Clock); +Types.set('ClockShortcut', _internal__WEBPACK_IMPORTED_MODULE_0__.ClockShortcut); +Types.set('Story', _internal__WEBPACK_IMPORTED_MODULE_0__.Story); +Types.set('LayerPanel', _internal__WEBPACK_IMPORTED_MODULE_0__.LayerPanel); +Types.set('Search', _internal__WEBPACK_IMPORTED_MODULE_0__.Search); +Types.set('Carousel', _internal__WEBPACK_IMPORTED_MODULE_0__.Carousel); +Types.set('TutorialOverlay', _internal__WEBPACK_IMPORTED_MODULE_0__.TutorialOverlay); + +Types.set('CarouselPanel', _internal__WEBPACK_IMPORTED_MODULE_0__.CarouselPanel); +Types.set('ShareModal', _internal__WEBPACK_IMPORTED_MODULE_0__.ShareModal); +Types.set('TimeController', _internal__WEBPACK_IMPORTED_MODULE_0__.TimeController); +Types.set('KioskBase', _internal__WEBPACK_IMPORTED_MODULE_0__.KioskBase); +Types.set('Toast', _internal__WEBPACK_IMPORTED_MODULE_0__.Toast); + + + + +/***/ }), + +/***/ "../eyes/src/utils/animation_utils.js": +/*!********************************************!*\ + !*** ../eyes/src/utils/animation_utils.js ***! + \********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AnimationUtils": function() { return /* binding */ AnimationUtils; } +/* harmony export */ }); +/** + * The animation utils class. + */ +class AnimationUtils { +} + +/** + * Uses the Web Animations API to create, pause and return an animation + * @param {HTMLElement} element + * @param {object|Array} keyframes + * @param {object|number} timings + * @returns {Animation} + */ +AnimationUtils.createAnimation = (element, keyframes, timings) => { + const kEffect = new KeyframeEffect(element, keyframes, timings); + return new Animation(kEffect, element.ownerDocument.timeline); +}; + +AnimationUtils.directionalFade = (element, { direction = 'up', fade = 'in', yOffset = 0, xOffset = 0, timings = AnimationUtils.defaultTimings }) => { + // Storing values + const v = { + x: { ori: 0, dest: 0 }, + y: { ori: 0, dest: 0 }, + opacity: { ori: 1.0, dest: 0.0 } + }; + + // Fade in/out horizontal + // x0 > x100 / x100 > x0 + // Fade in/out vertical + // y0 > y100 / y100 > y0 + if (direction === 'up' || direction === 'down') { + v.y.ori = (fade === 'in') ? 100 : 0; + v.y.dest = 100 - v.y.ori; + if (direction === 'up') { + v.y.ori *= -1; + v.y.dest *= -1; + } + } + else { + v.x.ori = (fade === 'in') ? 100 : 0; + v.x.dest = 100 - v.x.ori; + if (direction === 'left') { + v.x.ori *= -1; + v.x.dest *= -1; + } + } + + // If fade in switch opacity values + if (fade === 'in') { + v.opacity.ori = 0.0; + v.opacity.dest = 1.0; + } + + // Apply offsets + v.x.ori += xOffset; + v.x.dest += xOffset; + v.y.ori += yOffset; + v.y.dest += yOffset; + + const keyframes = [ + { transform: 'translate(' + v.x.ori + '%, ' + v.y.ori + '%)', opacity: v.opacity.ori }, + { transform: 'translate(' + v.x.dest + '%, ' + v.y.dest + '%)', opacity: v.opacity.dest } + ]; + + return AnimationUtils.createAnimation(element, keyframes, timings); +}; + +AnimationUtils.defaultTimings = { + duration: 1000, + iteration: 1, + fill: 'forwards', + easing: 'ease' +}; + + +/***/ }), + +/***/ "../eyes/src/utils/app_utils.js": +/*!**************************************!*\ + !*** ../eyes/src/utils/app_utils.js ***! + \**************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AppUtils": function() { return /* binding */ AppUtils; } +/* harmony export */ }); +/* harmony import */ var deepmerge__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! deepmerge */ "../eyes/node_modules/deepmerge/dist/cjs.js"); +/* harmony import */ var deepmerge__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(deepmerge__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lodash.debounce */ "../eyes/node_modules/lodash.debounce/index.js"); +/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lodash.throttle */ "../eyes/node_modules/lodash.throttle/index.js"); +/* harmony import */ var lodash_throttle__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var overlayscrollbars__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! overlayscrollbars */ "../eyes/node_modules/overlayscrollbars/js/OverlayScrollbars.js"); +/* harmony import */ var overlayscrollbars__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(overlayscrollbars__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var overlayscrollbars_css_OverlayScrollbars_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! overlayscrollbars/css/OverlayScrollbars.css */ "../eyes/node_modules/overlayscrollbars/css/OverlayScrollbars.css"); +/* harmony import */ var _tweenjs_tween_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @tweenjs/tween.js */ "../eyes/node_modules/@tweenjs/tween.js/dist/tween.esm.js"); + + + + + + + +/** + * The utils class. + */ +class AppUtils { + static conversionTable = { + kmToMi: 0.621371, // 1 km in miles + kmToFt: 3280.84, // 1 km in feet + miToFt: 5280, // 1 mile in feet + kmToM: 1000, // 1 km in meters + auToKm: 149597871, // 1 astromonical unit in km + ldToKm: 384398 // 1 lunar distance in km + }; + + static constants = { + speedOfLight: 299792.458, // km/sec, + minDate: -8e+15, // per https://262.ecma-international.org/5.1/#sec-15.9.1.1 + maxDate: 8e+15 // per https://262.ecma-international.org/5.1/#sec-15.9.1.1 + }; + + /** + * Check if an object is empty or not. + * @param {object} obj + * @returns {boolean} + */ + static isEmptyObject(obj) { + return obj.constructor === Object && Object.keys(obj).length === 0; + } + + /** + * Add starting part to path if path hasn't already started with it. + * @param {string} pathName + * @param {string} [start='/'] - Starting slash or symbol + * @returns {string} + */ + static addStartToPath(pathName, start = '/') { + if (!pathName.startsWith(start)) { + return start + pathName; + } + return pathName; + } + + /** + * Remove duplicate symbol from path. + * @param {string} pathName + * @param {string} [duplicate='/'] + * @param {string} [replacement='/'] + * @returns {string} + */ + static cleanPathDuplicate(pathName, duplicate = '/', replacement = '/') { + const re = new RegExp(`${duplicate}+`, 'g'); + return pathName.replace(re, replacement); + } + + /** + * Add ending part to path if path hasn't already ended with it. + * @param {string} pathName + * @param {string} [end='/'] - Ending slash or extension + * @returns {string} + */ + static addEndToPath(pathName, end = '/') { + if (!pathName.endsWith(end)) { + return pathName + end; + } + return pathName; + } + + /** + * Check if an object is HTML Element. + * @param {object} obj + * @returns {boolean} + */ + static isElement(obj) { + return obj instanceof Element || obj instanceof Document; + } + + /** + * Check if a string is HTML. + * @param {string} str + * @returns {boolean} + */ + static isHTML(str) { + if (typeof str !== 'string') { + return false; + } + return str.match(/<[^/>]+>/gm) !== null && str.match(/<\/[^>]+>/gm) !== null; + } + + /** + * Check if a string has HTML tag inside. + * @param {string} str + * @returns {boolean} + */ + static hasHTML(str) { + if (typeof str !== 'string') { + return false; + } + const doc = new DOMParser().parseFromString(str, 'text/html'); + return Array.from(doc.body.childNodes).some(node => node.nodeType === 1); + } + + /** + * Load JSON file. + * @param {string} fileName + * @returns {Promise} + * @throws {Error} Throw error if status is not 200 + */ + static async loadJSON(fileName) { + fileName = AppUtils.addEndToPath(fileName, '.json'); + const response = await fetch(fileName); + if (response.status === 200) { + return response.json(); + } + else { + // Throw error + const err = new Error(response.status + ' (' + response.statusText + ') when trying to fetch "' + fileName + '"'); + err.name = 'NotFound'; + throw err; + } + } + + /** + * Convert milliseconds to time. + * @param {number} [ms=0] + * @returns {{hour: number, minute: number, second: number, millisecond: number}} Converted time + */ + static msToTime(ms = 0) { + const millisecond = ms % 1000; + ms = (ms - millisecond) / 1000; + const second = ms % 60; + ms = (ms - second) / 60; + const minute = ms % 60; + const hour = (ms - minute) / 60; + + return { + hour, + minute, + second, + millisecond + }; + } + + /** + * Format time into hh:mm:ss for session timer + * @param {number} maxSessionTime - in ms + * @param {number} incomingTime - in ms + * @returns {string} + */ + static formatCountdownTime(maxSessionTime, incomingTime) { + // One hour in milliseconds + const oneHour = 60 * 60 * 1000; + const time = this.msToTime(incomingTime); + + // Pad the front with '0' until it hits 2 digits + time.hour = time.hour.toString().padStart(2, '0'); + time.minute = time.minute.toString().padStart(2, '0'); + time.second = time.second.toString().padStart(2, '0'); + + return `${maxSessionTime >= oneHour ? time.hour + ':' : ''}${time.minute || '00'}:${time.second}`; + } + + /** + * Convert to sec + * @param {number} minutes + * @returns {number} + */ + static minToSec(minutes) { + return minutes * 60; + } + + /** + * Convert to ms + * @param {number} minutes + * @returns {number} + */ + static minToMS(minutes) { + return minutes * 60000; + } + + /** + * Return if the mission start date is in the future + * @param {string} startDate + * @returns {boolean} + */ + static isFutureMission(startDate) { + const today = new Date(); + const missionStartDate = new Date(startDate); + + return missionStartDate > today; + } + + /** + * Copies an object and its sublevels. + * For objects that can be stringified and parsed. + * @param {object} object1 + * @returns {object} + */ + static deepCopy(object1) { + return JSON.parse(JSON.stringify(object1)); + } + + /** + * Clones an object and its sublevels. + * For object that cannot be stringified and parsed. + * @see https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/10916838#10916838 + * @param {any} obj + * @returns {any} + */ + static deepClone(obj) { + const out = /** @type {any} */(Array.isArray(obj) ? [] : {}); + for (const key in obj) { + const value = /** @type {any} */(obj[key]); + out[key] = (typeof value === 'object' && value !== null) ? AppUtils.deepClone(value) : value; + } + return out; + } + + /** + * Uses the deepmerge library from https://github.com/TehShrike/deepmerge + * with custom options to prevent merging of Moment objects + * @param {object} object1 + * @param {object} object2 + * @returns {object} + */ + static deepMerge(object1, object2) { + const options = { + isMergeableObject: (/** @type {any} */value) => (value && value._isAMomentObject ? false : Boolean(value) && typeof value === 'object') + }; + + return deepmerge__WEBPACK_IMPORTED_MODULE_0___default()(object1, object2, options); + } + + + /** + * Checks for object deep equality. + * @param {any} object1 + * @param {any} object2 + * @returns {boolean} + */ + static deepEqual(object1, object2) { + if (!object1 || !object2) { + return false; + } + const keys1 = Object.keys(object1); + const keys2 = Object.keys(object2); + + if (keys1.length !== keys2.length) { + return false; + } + + for (const key of keys1) { + const val1 = object1[key]; + const val2 = object2[key]; + const areObjects = AppUtils.isObject(val1) && AppUtils.isObject(val2); + if (areObjects && !AppUtils.deepEqual(val1, val2)) { + return false; + } + else if (!areObjects && val1 !== val2) { + return false; + } + } + + return true; + } + + /** + * Checks if element is an object. + * @param {any} object + * @returns {boolean} + */ + static isObject(object) { + return object !== null && typeof object === 'object'; + } + + /** + * Filter an object. + * @param {object} obj - Original object + * @param {Function} callback - Condition + * @returns {object} + */ + static filterObject(obj, callback) { + return Object.fromEntries(Object.entries(obj).filter(([key, val]) => callback(val, key))); + } + + /** + * Returns lodash's debounce method + * @returns {Function} + */ + static debounce() { + return lodash_debounce__WEBPACK_IMPORTED_MODULE_1___default()(...arguments); + } + + /** + * Returns lodash's throttle method + * @returns {Function} + */ + static throttle() { + return lodash_throttle__WEBPACK_IMPORTED_MODULE_2___default()(...arguments); + } + + /** + * Waits for n millisecons. + * @param {number} n + * @returns {Promise} + */ + static waitFor(n) { + return new Promise(resolve => { + setTimeout(() => { + resolve(); + }, n); + }); + } + + /** + * Check if the media query is portrait. + * @returns {boolean} + */ + static isPortrait() { + return window.matchMedia('(orientation: portrait)').matches; + } + + /** + * Check if the media query is landscape. + * @returns {boolean} + */ + static isLandscape() { + return window.matchMedia('(orientation: landscape)').matches; + } + + /** + * Check if the media query is landscape. + * @returns {boolean} + */ + static isMobileLandscape() { + return window.matchMedia('(min-width: 320px) and (max-width: 915px) and (orientation: landscape)').matches; + } + + /** + * Check if the media query is portrait. + * @returns {boolean} + */ + static isMobilePortrait() { + return window.matchMedia('(min-width: 320px) and (max-width: 640px) and (orientation: portrait)').matches; + } + + /** + * Check if the media query is mobile. + * @returns {boolean} + */ + static isMobile() { + return AppUtils.isMobileLandscape() || AppUtils.isMobilePortrait(); + } + + /** + * Check if the OS is iOS on an iPhone. + * @returns {boolean} + */ + static isiPhone() { + const platform = window.navigator?.userAgentData?.platform || window.navigator?.platform || 'unknown'; + return platform === 'iPhone'; + } + + /** + * Check if the OS is iOS on an iPad. + * @returns {boolean} + */ + static isiPad() { + // TODO: Update this with a better check if we ever get an intel mac with a touchscreen. + const platform = window.navigator?.userAgentData?.platform || window.navigator?.platform || 'unknown'; + const touchPoints = window.navigator.maxTouchPoints > 1; + return (platform === 'MacIntel' && touchPoints); + } + + /** + * Check if the media query is tablet portrait. + * @returns {boolean} + */ + static isTabletPortrait() { + return window.matchMedia('(min-width: 641px) and (max-width: 1024px) and (orientation: portrait)').matches; + } + + /** + * Check if the media query is tablet landscape. + * @returns {boolean} + */ + static isTabletLandscape() { + return window.matchMedia('(min-width: 916px) and (max-width: 1024px) and (orientation: landscape)').matches; + } + + /** + * Check if the media query is in tablet mode. + * @returns {boolean} + */ + static isTablet() { + return AppUtils.isTabletLandscape() || AppUtils.isTabletPortrait(); + } + + /** + * Check if the media query is in mobile mode: mobile, tablet, or landscape. + * @returns {boolean} + */ + static isMobileMode() { + return AppUtils.isMobilePortrait() || AppUtils.isMobileLandscape() || AppUtils.isTabletLandscape() || AppUtils.isTabletPortrait() || AppUtils.isPanorama(); + } + + /** + * Check if the media query is desktop. + * @returns {boolean} + */ + static isDesktop() { + return window.matchMedia('(min-width: 1025px) and (min-height: 600px)').matches; + } + + /** + * Check if the media query is panorama. + * @returns {boolean} + */ + static isPanorama() { + return window.matchMedia('(min-width: 1025px) and (max-height: 599px) and (orientation: landscape)').matches; + } + + /** + * Check if the media query is 2K. + * @returns {boolean} + */ + static is2K() { + return window.matchMedia('(min-width: 2880px) and (min-height: 1620px)').matches; + } + + /** + * Check if the media query is 2K. + * @returns {boolean} + */ + static is4K() { + return window.matchMedia('(min-width: 3200px) and (min-height: 1800px)').matches; + } + + /** + * Check if the device is using touch. + * @returns {boolean} + */ + static isTouch() { + return ('ontouchstart' in window) || window.navigator.maxTouchPoints > 0; + } + + /** + * Check if the device is primary touch. + * @returns {boolean} + */ + static isPrimaryTouch() { + return window.matchMedia('(pointer: coarse)').matches; + } + + /** + * Check if the device supports hovering. + * @returns {boolean} + */ + static canHover() { + return !(matchMedia('(hover: none)').matches); + } + + /** + * Create an element from HTML string. + * @param {string} html + * @returns {Element} + */ + static htmlToElement(html) { + const template = document.createElement('template'); + template.innerHTML = html.replace(/[\t\n]+/g, '').trim(); // Never return a text node of whitespace as the result + return template.content.firstElementChild; + } + + /** + * Create sibling elements from HTML string. + * @param {string} html + * @returns {NodeList} + */ + static htmlToElements(html) { + const template = document.createElement('template'); + template.innerHTML = html.replace(/[\t\n]+/g, '').trim(); // Never return a text node of whitespace as the result + return template.content.cloneNode(true).childNodes; + } + + /** + * Replace variables in HTML string with params' values. + * @param {string} html + * @param {Object} [params={}] - Parameters to replace in HTML string + * @returns {string} + */ + static insertParamsToHTML(html, params = {}) { + html = html.replace(/[\t\n]+/g, '').trim(); + const keys = Object.keys(params); + + for (let i = keys.length - 1; i >= 0; i--) { + const key = keys[i]; + const param = `{$${key}}`; + html = html.replaceAll(param, params[key]); + } + // Replace all unspecified params with empty string + html = html.replaceAll(/{\$([A-Z])\w+}/gi, ''); + + return html; + } + + /** + * Replace variables in HTML string with params' values then create an element. + * Format of HTML variable: {$var}. + * @example + * // Replace
      {$title}
      with
      Hello
      + * htmlWithParamsToElement(html, { title: 'Hello' }); + * @param {string} html + * @param {Object} [params={}] - Parameters to replace in HTML string + * @returns {Element} + */ + static htmlWithParamsToElement(html, params = {}) { + html = AppUtils.insertParamsToHTML(html, params); + return AppUtils.htmlToElement(html); + } + + /** + * Periodically check if an element is attached to DOM. + * Execute a callback if element is attached, or output error on timeout. + * @param {string|HTMLElement} elementQuery - Query string passed to document.querySelector or HTML element + * @param {Function} callback - Callback to be called on verified attachment + * @param {object} options + * @param {number} [options.interval=100] - Interval to check in ms + * @param {number} [options.timeout=5000] - Timeout to stop in ms + */ + static onAttachElement(elementQuery, callback, { interval = 100, timeout = 5000 } = {}) { + const myInterval = setInterval(() => { + const attached = typeof elementQuery === 'string' + ? document.querySelector(elementQuery) !== null + : document.body.contains(elementQuery); + if (attached) { + clearInterval(myInterval); + clearTimeout(myTimeout); + callback(); + } + }, interval); + const myTimeout = setTimeout(() => { + clearInterval(myInterval); + console.error(`[AppUtils.onAttachElement] Timeout exceeded for "${elementQuery}".`); + }, timeout); + } + + /** + * A callback that is fired once the DOM has detected a node has been added to a specific element. + * Similar to the above util, but without the timeouts. + * https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists + * @param {HTMLElement} parent + * @param {HTMLElement} element + * @param {string} selector + * @param {() => void} callback + */ + static appendWithCallback(parent, element, selector, callback) { + const promise = new Promise(resolve => { + if (document.querySelector(selector)) { + return resolve(document.querySelector(selector)); + } + + const observer = new MutationObserver(() => { + if (document.querySelector(selector)) { + resolve(document.querySelector(selector)); + observer.disconnect(); + } + }); + + observer.observe(document.body, { + childList: true, + subtree: true + }); + }); + + promise.then(callback); + + parent.appendChild(element); + } + + /** + * Uses the mutation observer to wait for an element to be queryable in the DOM. Rejects after timeout. + * @param {string} selector + * @param {number} timeout + * @returns {Promise} + */ + static elementReady(selector, timeout = 1000) { + return new Promise((resolve, reject) => { + const element = document.querySelector(selector); + if (element) { + resolve(element); + return; + } + + const observer = new MutationObserver(() => { + // Query for elements matching the specified selector + const element = document.querySelector(selector); + if (element) { + observer.disconnect(); + clearTimeout(timer); + resolve(element); + } + }); + + + observer.observe(document.body, { + childList: true, + subtree: true + }); + + const timer = setTimeout(() => { + observer.disconnect(); + reject(console.warn(`${selector} not found in DOM`)); + }, timeout); + }); + } + + /** + * Add a default scrollbar to an element. + * @param {HTMLElement} element + * @param {OverlayScrollbars.Options} [options={}] - Options for OverlayScrollbars + * @returns {OverlayScrollbars} + */ + static addScrollbar(element, options = {}) { + const opts = /** @type {OverlayScrollbars.Options} */({ + className: 'os-theme-dark', // default + resize: 'none', // default + clipAlways: false, + normalizeRTL: false, + paddingAbsolute: true, + autoUpdate: false, + sizeAutoCapable: false, + overflowBehavior: { + x: 'hidden', + y: 'scroll' // default + }, + scrollbars: { + clickScrolling: true, + autoHide: 'move' + }, + ...options + }); + return overlayscrollbars__WEBPACK_IMPORTED_MODULE_3___default()(element, opts); + } + + /** + * Makes sure we can add commas and a maximum number of decimal places without float inaccuracies + * @param {number} number + * @param {number} maxDps - number of decimal places + * @param {number} minDps - minimum number of decimal places (ie. can include 10.0) + * @returns {string} + */ + static formatNumber(number, maxDps = 3, minDps = undefined) { + return number.toLocaleString(undefined, { maximumFractionDigits: maxDps, minimumFractionDigits: minDps }); + } + + /** + * Formats a date to local style with options + * @param {Date} date + * @param {object} options + * @returns {string} + */ + static formatDate(date, options = {}) { + return date.toLocaleString(undefined, { year: 'numeric', month: 'long', day: 'numeric', ...options }); + } + + /** + * Tween from one set of values to another in some duration + * @param {object} from - Starting values + * @param {object} to - Ending values + * @param {object} options + * @param {(obj: object) => void} [options.onUpdate] - Action on each update + * @param {() => void} [options.onComplete] - Action on complete + * @param {number} [options.duration=2000] - Duration of animation in milliseconds + * @returns {Tween} + */ + static tween(from, to, { onUpdate, onComplete, duration = 2000 } = {}) { + let request = /** @type {number} */(0); + const tween = new _tweenjs_tween_js__WEBPACK_IMPORTED_MODULE_5__.Tween(from) + .to(to, duration) + .onUpdate(obj => { + if (onUpdate !== undefined) { + onUpdate(obj); + } + }) + .onComplete(() => { + if (typeof onComplete === 'function') { + onComplete(); + } + // Cancel request so it won't call function indefinitely + cancelAnimationFrame(request); + }) + .start(); + + const tweenAnimationFrame = (/** @type {number} */time) => { + request = requestAnimationFrame(tweenAnimationFrame); + (0,_tweenjs_tween_js__WEBPACK_IMPORTED_MODULE_5__.update)(time); + }; + tweenAnimationFrame(); + + return tween; + } + + /** + * Convert values from string to corresponding types in an object. + * @param {Object} obj + * @returns {Object} + */ + static convertObjType(obj) { + Object.entries(obj).forEach(([key, value]) => { + let outValue; + switch (value.trim()) { + case 'undefined': + outValue = undefined; break; + case 'null': + outValue = null; break; + case 'true': + outValue = true; break; + case 'false': + outValue = false; break; + case 'NaN': + outValue = NaN; break; + case '': + break; + default: + outValue = isNaN(value) ? value : parseFloat(value); break; + } + obj[key] = outValue; + }); + return obj; + } +} + + +/***/ }), + +/***/ "../eyes/src/utils/cancel_token.js": +/*!*****************************************!*\ + !*** ../eyes/src/utils/cancel_token.js ***! + \*****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CancelToken": function() { return /* binding */ CancelToken; } +/* harmony export */ }); +/** + * Cancel token class. + */ +class CancelToken { + /** + * Constructor. + */ + constructor() { + this._isCanceled = false; + } + + /** + * Sets the state to canceled. + */ + cancel() { + this._isCanceled = true; + } + + /** + * Gets canceled state. + * @returns {boolean} + */ + get isCanceled() { + return this._isCanceled; + } +} + + +/***/ }), + +/***/ "../eyes/src/version.js": +/*!******************************!*\ + !*** ../eyes/src/version.js ***! + \******************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "version": function() { return /* binding */ version; } +/* harmony export */ }); +// Generated by genversion. +const version = '2.4.0'; + + +/***/ }), + +/***/ "../pioneer/engine/src/capabilities.js": +/*!*********************************************!*\ + !*** ../pioneer/engine/src/capabilities.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Capabilities": function() { return /* binding */ Capabilities; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * A class that can be used to find out the capabilities of the current device. + * @hideconstructor + */ +class Capabilities { + /** + * Returns true if the context is WebGL 2.0. + * @returns {boolean} + */ + static isWebGL2() { + return typeof WebGL2RenderingContext !== 'undefined' && _context instanceof WebGL2RenderingContext; + } + + /** + * Returns true if the context has the gl_fragDepth output variable. + * @returns {boolean} + */ + static hasFragDepth() { + return this.isWebGL2() || this.hasGLExtension('EXT_frag_depth'); + } + + /** + * Returns true if the device has the GL extension enabled. + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Using_Extensions} + * @param {string} extensionName - The extension name. + * @returns {boolean} + */ + static hasGLExtension(extensionName) { + if (_context === null) { + return false; + } + let value = _cache.get(extensionName); + if (value === undefined) { + value = _context.getExtension(extensionName) !== null; + _cache.set(extensionName, value); + } + return value; + } + + /** + * Gets the supported compressed texture extension. + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Compressed_texture_formats} + * @returns {string} + * @internal + */ + static __getCompressedTextureExtension() { + return _compressedTextureExtension; + } + + /** + * Sets the rendering context for use in other functions. Called by Engine. + * @param {WebGLRenderingContext} context - The WebGL context. + * @internal + */ + static __setContext(context) { + _context = context; + + // Check for support of compressed texture formats. + _compressedTextureFormats.forEach((value, key) => { + if (this.hasGLExtension('WEBGL_compressed_texture_' + key) === true + || this.hasGLExtension('WEBKIT_WEBGL_compressed_texture_' + key) === true) { + if (_compressedTextureExtension === '') { + _compressedTextureExtension = value; + } + } + }); + } +} + +/** + * A cache of capabilities for performance. + * @type {Map} + */ +const _cache = new Map(); + +/** + * The rendering context for use in other functions. + * @type {WebGLRenderingContext | null} + */ +let _context = null; + +/** + * The supported compressed texture extension. + * @type {string} + */ +let _compressedTextureExtension = ''; + +/** + * A mapping from compressed texture formats to their corresponding extensions. + * @type {Map} + */ +const _compressedTextureFormats = new Map([ + ['astc', 'astc'], + ['s3tc', 'dxt'], + ['pvrtc', 'pvrtc'], + ['etc', 'etc2'], + ['etc1', 'etc1']]); + + +/***/ }), + +/***/ "../pioneer/engine/src/config.js": +/*!***************************************!*\ + !*** ../pioneer/engine/src/config.js ***! + \***************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Config": function() { return /* binding */ Config; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * The global configuration. It has event triggering when values change. + * It has the built-in default keys: + *
        + *

        maxTextureSize = 512

        + *

        useTextureCompression = true

        + *

        fontFamily = 'Arial'

        + *

        fontSize = 16

        + *

        gammaCorrection = 1.0

        + *
      + */ +class Config { + /** + * Constructor. Called by Engine. + */ + constructor() { + /** + * The map of keys to values. + * @type {Map} + * @private + */ + this._valueMap = new Map(); + + /** + * The map of keys to callbacks. + * @type {Map any)[]>} + * @private + */ + this._callbacksMap = new Map(); + + // Setup some defaults. + this.setValue('maxTextureSize', 512); + this.setValue('useTextureCompression', true); + this.setValue('fontFamily', 'Arial'); + this.setValue('fontSize', 16); + this.setValue('gammaCorrection', 1.0); + } + + /** + * Gets the value for a given key, or undefined if the key is not found. + * @param {string} key - the key of the value to get + * @returns {string | number | boolean | undefined} + */ + getValue(key) { + return this._valueMap.get(key); + } + + /** + * Sets a value for the given key. Calls any added event listeners. + * @param {string} key - the key to set + * @param {string | number | boolean} value - the value to set + */ + setValue(key, value) { + const changed = this._valueMap.get(key) !== value; + if (changed) { + this._valueMap.set(key, value); + const callbacks = this._callbacksMap.get(key); + if (callbacks) { + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](key, value); + } + } + } + } + + /** + * Adds a callback to be called when the value of the key changes. + * @param {string} key - the key for the callback + * @param {(key: string, value: string | number | boolean) => any} callback - the callback + */ + addEventListener(key, callback) { + let callbacks = this._callbacksMap.get(key); + if (callbacks === undefined) { + callbacks = []; + this._callbacksMap.set(key, callbacks); + } + callbacks.push(callback); + } + + /** + * Removes the callback of the key. + * @param {string} key - the key for the callback + * @param {(key: string, value: string | number | boolean) => any} callback - the callback + */ + removeEventListener(key, callback) { + const callbacks = this._callbacksMap.get(key); + if (callbacks) { + for (let i = 0; i < callbacks.length; i++) { + if (callbacks[i] === callback) { + callbacks.splice(i, 1); + break; + } + } + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/downloader.js": +/*!*******************************************!*\ + !*** ../pioneer/engine/src/downloader.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Download": function() { return /* binding */ Download; }, +/* harmony export */ "Downloader": function() { return /* binding */ Downloader; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + + +/** + * A download object for every download that is returned to the user. + */ +class Download { + /** + * The constructor. + * @param {string} url + * @param {string} actualUrl + * @param {boolean} binary + */ + constructor(url, actualUrl, binary) { + /** + * The unprocessed url given by the user. + * @type {string} + */ + this.url = url; + + /** + * The processed url actually sent to the browser. + * @type {string} + */ + this.actualUrl = actualUrl; + + /** + * The progress from 0 to 1. + * @type {number} + */ + this.progress = 0; + + /** + * The total content size in bytes. + * @type {number} + */ + this.totalBytes = 0; + + /** + * The content of the completed download. + * @type {string | ArrayBuffer | undefined} + */ + this.content = undefined; + + /** + * Whether or not the content is binary. + * @type {boolean} + */ + this.binary = binary; + + /** + * The status of the download. It can be 'downloading', 'completed', 'cancelled', or 'failed' + * @type {'downloading' | 'completed' | 'cancelled' | 'failed'} + */ + this.status = 'downloading'; + + /** + * The error message, if there is one. + * @type {string} + */ + this.errorMessage = ''; + } +} + +/** + * A download object for every download that is used by the Downloader. + * @private + */ +class DownloadData { + /** + * The constructor. + * @param {string} url + * @param {string} actualUrl + * @param {boolean} binary + */ + constructor(url, actualUrl, binary) { + /** + * The download object to be returned to the user. + * @type {Download} + */ + this.download = new Download(url, actualUrl, binary); + + /** + * The promise that is returned when completed or cancelled. + * @type {Promise | null} + */ + this.promise = null; + + /** + * The resolve function of the promise. + * @type {(download: Download) => void} + */ + this.resolve = null; + + /** + * The list of callbacks to call when the progress changes. + * @type {((download: Download) => any)[]} + */ + this.progressCallbacks = []; + + /** + * The XMLHttpRequest object. + * @type {XMLHttpRequest | null} + */ + this.request = null; + } +} + +/** + * A class that downloads assets. It can preprocess URLs via replacement keywords. + */ +class Downloader { + /** + * Constructor. Called by Engine. + */ + constructor() { + /** + * The mapping of strings to replacements when downloading urls. + * @type {Map} + * @private + */ + this._replacements = new Map(); + + /** + * The current set of downloads, mapped from url to Download object. + * @type {Map} + * @private + */ + this._currentDownloads = new Map(); + + /** + * The download queue, sorted by priority. + * @type {[number, DownloadData][]} + * @private + */ + this._downloadQueue = []; + + /** + * The maximum number of current downloads. + * @type {number} + */ + this._maxCurrentDownloads = 20; + } + + /** + * Gets the replacement for a given name, or undefined if no replacement was found. + * @param {string} name - The name to be replaced. + * @returns {string | undefined} + */ + getReplacement(name) { + return this._replacements.get(name); + } + + /** + * Sets a replacement so that when a URL contains $name, it will be replaced with the replacement. + * @param {string} name - The name (without the $) to be replaced. + * @param {string} replacement - The replacement string. + */ + setReplacement(name, replacement) { + this._replacements.set(name, replacement); + } + + /** + * Cancels a download for the given url. If there are multiple downloads of the same url, they are all cancelled. + * @param {string} url - The url of the download to cancel. + */ + cancel(url) { + const actualUrl = this.processUrl(url); + + // If we're currently downloading, call the abort function. + if (this._currentDownloads.has(actualUrl)) { + const downloadData = this._currentDownloads.get(actualUrl); + if (downloadData !== undefined && downloadData.request !== null) { + downloadData.request.abort(); + } + } + else { + + // If we're in the queue still, there's no request, so artificially end the download as if there was. + const queueIndex = this._downloadQueue.findIndex(([_, downloadData]) => downloadData.download.actualUrl === actualUrl); + if (queueIndex !== -1) { + + const downloadData = this._downloadQueue[queueIndex][1]; + downloadData.download.content = undefined; + downloadData.download.status = 'cancelled'; + this._downloadQueue.splice(queueIndex, 1); + downloadData.resolve(downloadData.download); + } + } + } + + /** + * Process url parameters, replacing the $name variables with their corresponding replacements. + * @param {string} url - The url to process. + * @returns {string} + */ + processUrl(url) { + let processedUrl = url; + for (const [name, replacement] of this._replacements) { + processedUrl = processedUrl.replace('$' + name, replacement); + } + return processedUrl; + } + + /** + * Downloads a file and returns a promise that resolves with a Download object. + * If the download is cancelled, the status will be 'cancelled'. + * If the download has failed, the status will be 'failed' and the errorMessage will be the error. + * If the download has completed, the status will be 'completed'. + * It replaces $name variables with their replacements. + * @param {string} url - The url to download. + * @param {boolean} binary - If true, the Download.content is an ArrayBuffer and is otherwise a string. + * @param {(download: Download) => any} [progressCallback] - The callback to be called periodically to report the progress of the download. + * @returns {Promise} + */ + download(url, binary, progressCallback) { + // Process the urls, doing the replacements. + const actualUrl = this.processUrl(url); + + // If the download already currently running, just return its promise. + let downloadData = this._currentDownloads.get(actualUrl); + if (downloadData !== undefined && downloadData.promise !== null) { + if (progressCallback) { + downloadData.progressCallbacks.push(progressCallback); + } + return downloadData.promise; + } + + // If the download is in the queue, return its promise. + const queueIndex = this._downloadQueue.findIndex(([_, downloadData]) => downloadData.download.actualUrl === actualUrl); + if (queueIndex !== -1) { + downloadData = this._downloadQueue[queueIndex][1]; + if (progressCallback) { + downloadData.progressCallbacks.push(progressCallback); + } + return downloadData.promise; + } + + // Create the download object. + downloadData = new DownloadData(url, actualUrl, binary); + + // Set the promise. + downloadData.promise = new Promise((resolve) => { + + // Save the resolve function for later calling. + downloadData.resolve = resolve; + + // Add to the download queue and sort it. + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add([0, downloadData], this._downloadQueue, (a, b) => a[0] < b[0], (a, b) => a[0] === b[0]); + + // Check the download queue to see if we can start this request right away. + this.checkDownloadQueue(); + }); + + return downloadData.promise; + } + + /** + * Does an actual request. + * @param {DownloadData} downloadData + * @private + */ + doRequest(downloadData) { + + // Create the XMLHttpRequest. + const request = new XMLHttpRequest(); + + // Load listener. + request.addEventListener('load', () => { + if (200 <= request.status && request.status <= 299) { + downloadData.download.content = request.response; + downloadData.download.status = 'completed'; + } + else { + downloadData.download.content = undefined; + downloadData.download.status = 'failed'; + } + this._currentDownloads.delete(downloadData.download.actualUrl); + this.checkDownloadQueue(); + downloadData.resolve(downloadData.download); + }); + + // Progress listener. + request.addEventListener('progress', (event) => { + downloadData.download.progress = event.lengthComputable ? (event.loaded / event.total) : 0; + downloadData.download.totalBytes = event.lengthComputable ? event.total : 0; + for (const progressCallback of downloadData.progressCallbacks) { + progressCallback(downloadData.download); + } + }); + + // Abort listener. + request.addEventListener('abort', () => { + downloadData.download.content = undefined; + downloadData.download.status = 'cancelled'; + this._currentDownloads.delete(downloadData.download.actualUrl); + this.checkDownloadQueue(); + downloadData.resolve(downloadData.download); + }); + + // Error listener. + request.addEventListener('error', () => { + downloadData.download.content = undefined; + downloadData.download.status = 'failed'; + downloadData.download.errorMessage = request.statusText; + this._currentDownloads.delete(downloadData.download.actualUrl); + this.checkDownloadQueue(); + downloadData.resolve(downloadData.download); + }); + + if (downloadData.download.binary) { + request.responseType = 'arraybuffer'; + } + else { + request.responseType = 'text'; + } + + downloadData.request = request; + request.open('GET', downloadData.download.actualUrl); + request.send(); + } + + /** + * Checks the download queue for another download and starts it, if needed. + * @private + */ + checkDownloadQueue() { + if (this._currentDownloads.size < this._maxCurrentDownloads && this._downloadQueue.length > 0) { + const [_, downloadData] = this._downloadQueue.shift(); + this._currentDownloads.set(downloadData.download.actualUrl, downloadData); + this.doRequest(downloadData); + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/engine.js": +/*!***************************************!*\ + !*** ../pioneer/engine/src/engine.js ***! + \***************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Engine": function() { return /* binding */ Engine; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * @callback ComponentConstructor + * @param {string} type - The type of the component. + * @param {string} name + * @param {Entity} parent + * @returns {BaseComponent} + */ + +/** + * @callback ControllerConstructor + * @param {string} type + * @param {string} name + * @param {Entity} parent + * @returns {BaseController} + */ + +/** + * The main driver of the Pioneer engine. + */ +class Engine { + /** + * Constructs the Pioneer engine. + * @param {HTMLDivElement} rootDiv - A <div> element. The canvas and Pioneer UI will go inside of it. + */ + constructor(rootDiv) { + // Make sure the root div is an actual div element. + if (!(rootDiv instanceof HTMLDivElement)) { + throw new Error('The root div param is not an actual div element.'); + } + + /** + * The root <div> element. + * @type {HTMLDivElement} + * @private + */ + this._rootDiv = rootDiv; + + /** + * The canvas created by the engine inside the root div. + * @type {HTMLCanvasElement} + * @private + */ + this._canvas = null; + + /** + * The current size of the render area as a Vector2. + * @type {Vector2} + * @private + */ + this._renderSize = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + this._renderSize.freeze(); + + /** + * The input object. + * @type {Input} + * @private + */ + this._input = new _internal__WEBPACK_IMPORTED_MODULE_0__.Input(this); + + /** + * The config. + * @type {Config} + * @private + */ + this._config = new _internal__WEBPACK_IMPORTED_MODULE_0__.Config(); + + /** + * The downloader object. + * @type {Downloader} + * @private + */ + this._downloader = new _internal__WEBPACK_IMPORTED_MODULE_0__.Downloader(); + + /** + * The texture loader used by all components for the loading of textures. + * @type {TextureLoader} + * @private + */ + this._textureLoader = null; + + /** + * The compressed texture loader used by all components for the loading of textures. + * @type {TextureLoaderCompressed} + * @private + */ + this._textureLoaderCompressed = null; + + /** + * The shader manager. + * @type {MaterialManager} + * @private + */ + this._materialManager = null; + + /** + * The collection of scenes. + * @type {Collection} + * @private + */ + this._scenes = new _internal__WEBPACK_IMPORTED_MODULE_0__.Collection(this, new Map([['scene', _internal__WEBPACK_IMPORTED_MODULE_0__.Scene]])); + + /** + * The collection of viewports. + * @type {Collection} + * @private + */ + this._viewports = new _internal__WEBPACK_IMPORTED_MODULE_0__.Collection(this, new Map([['viewport', _internal__WEBPACK_IMPORTED_MODULE_0__.Viewport]])); + + /** + * The real-world time last frame. Used to determine the in-app time. + * @type {number} + * @private + */ + this._lastAppTime = Date.now(); + + /** + * The time in seconds it took to complete the last frame. + * @type {number} + * @private + */ + this._realDeltaTime = 0; + + /** + * An FPS calculator. + * @type {FPS} + * @private + */ + this._fps = new _internal__WEBPACK_IMPORTED_MODULE_0__.FPS(); + + /** + * A limit for the FPS. + * @type {number} + * @private + */ + this._fpsLimit = Number.POSITIVE_INFINITY; + + /** + * The in-app time in ET seconds. + * @type {number} + * @private + */ + this._time = 0; + + /** + * The in-app time rate in seconds per second. + * @type {number} + * @private + */ + this._timeRate = 0; + + /** + * The list of callbacks to be called at the end of the next frame. + * If they are not recurring, they will be removed after they are processed. + * @type {{ callback: () => any, recurring: boolean }[]} + * @private + */ + this._callbacks = []; + + /** + * A list of callbacks to remove in the next frame. + * @type {(() => any)[]} + * @private + */ + this._callbacksToRemove = []; + + /** + * This is used in requestAnimationFrame because bind (or ()=>{}) creates garbage. + * @type {(this: Engine) => any} + * @private + */ + this._thisLoop = this._loop.bind(this); + + /** + * The ThreeJS renderer. + * @type {THREE.WebGLRenderer} + * @private + */ + this._threeJsRenderer = null; + + /** + * The div element where the viewports will go. + * @type {HTMLDivElement} + * @private + */ + this._viewportDiv = null; + + // Add styling to the root div to make sure it will work with Pioneer. + if (this._rootDiv.style.position !== 'relative' && this._rootDiv.style.position !== 'absolute') { + this._rootDiv.style.position = 'relative'; + } + this._rootDiv.style.userSelect = 'none'; + this._rootDiv.style.webkitUserSelect = 'none'; + this._rootDiv.style.touchAction = 'none'; + + // Create the canvas and attach it to the root div. + this._canvas = document.createElement('canvas'); + this._canvas.style.position = 'absolute'; + this._canvas.style.left = '0px'; + this._canvas.style.top = '0px'; + this._canvas.style.width = '100%'; + this._canvas.style.height = '100%'; + this._rootDiv.appendChild(this._canvas); + + // Create the viewport div for the viewports and attach it to the root div. + this._viewportDiv = document.createElement('div'); + this._viewportDiv.style.position = 'absolute'; + this._viewportDiv.style.left = '0px'; + this._viewportDiv.style.top = '0px'; + this._viewportDiv.style.width = '100%'; + this._viewportDiv.style.height = '100%'; + this._viewportDiv.style.overflow = 'hidden'; + this._rootDiv.appendChild(this._viewportDiv); + + try { + // Create ThreeJS renderer, using the canvas as a reference. + this._threeJsRenderer = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderer({ + canvas: this._canvas, + antialias: true + }); + this._threeJsRenderer.setScissorTest(true); + + // Make sure the renderer is using the device pixel ratio for extra sharpness. + this._threeJsRenderer.setPixelRatio(window.devicePixelRatio); + + // Create the texture loaders. + this._textureLoader = new _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLoader(this._downloader, this._threeJsRenderer); + this._textureLoaderCompressed = new _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLoaderCompressed(this._downloader, this._config, this._threeJsRenderer); + + // Disable the cache so that things don't get loaded indefinitely. + _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Cache.enabled = false; + + // REMOVE LATER: Fix for GLSL warning about GL_ARB_gpu_shader5 (ThreeJS bug: https://github.com/mrdoob/three.js/issues/9716). + const origGetShaderInfoLog = this._threeJsRenderer.getContext().getShaderInfoLog.bind(this._threeJsRenderer.getContext()); + this._threeJsRenderer.getContext().getShaderInfoLog = (shader) => { + const t = origGetShaderInfoLog(shader); + if (t.includes('GL_ARB_gpu_shader5')) { + return ''; + } + else { + return t; + } + }; + + // Add the WebGL context to the capabilities. + _internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.__setContext(this._threeJsRenderer.getContext()); + + // Create the material manager. + this._materialManager = new _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialManager(this._downloader); + } + catch (error) { + // eslint-disable-next-line no-console + console.log(error); + throw error; + } + + // Start looping. + requestAnimationFrame(this._thisLoop); + } + + // VERSION + + /** + * Gets the Pioneer version. + * @returns {string} + */ + getVersion() { + return _internal__WEBPACK_IMPORTED_MODULE_0__.Version; + } + + // CANVAS AND CONTAINER DIVS + + /** + * Returns the root div that was passed in the constructor. + * @returns {HTMLDivElement} + */ + getRootDiv() { + return this._rootDiv; + } + + /** + * Gets the size of the rendering area. + * @returns {Vector2} + */ + getRenderSize() { + return this._renderSize; + } + + /** + * Returns the canvas used for the engine. + * @returns {HTMLCanvasElement} + */ + getCanvas() { + return this._canvas; + } + + /** + * Returns the div used for the UI. + * @returns {HTMLDivElement} + */ + getViewportDiv() { + return this._viewportDiv; + } + + // SUB-SYSTEMS + + /** + * Returns the config. + * @returns {Config} + */ + getConfig() { + return this._config; + } + + /** + * Returns the input manager. + * @returns {Input} + */ + getInput() { + return this._input; + } + + /** + * Returns the downloader. + * @returns {Downloader} + */ + getDownloader() { + return this._downloader; + } + + /** + * Gets the texture loader. + * @returns {TextureLoader} + */ + getTextureLoader() { + return this._textureLoader; + } + + /** + * Gets the texture loader. + * @returns {TextureLoaderCompressed} + */ + getTextureLoaderCompressed() { + return this._textureLoaderCompressed; + } + + /** + * Get the material manager. + * @returns {MaterialManager} + */ + getMaterialManager() { + return this._materialManager; + } + + // SCENES + + /** + * Gets a scene by name. + * @param {string|number} nameOrIndex - The name or zero-based index of the scene. + * @returns {Scene} + */ + getScene(nameOrIndex) { + return this._scenes.get(nameOrIndex); + } + + /** + * Gets the number of scenes. + * @returns {number} + */ + getNumScenes() { + return this._scenes.size; + } + + /** + * Adds a scene. + * @param {string} name - The name of the scene to be added. + * @returns {Scene} + */ + addScene(name) { + return this._scenes.add('scene', name); + } + + /** + * Removes a scene. + * @param {Scene|string|number} sceneOrNameOrIndex - The scene, name, or index to be removed. + */ + removeScene(sceneOrNameOrIndex) { + this._scenes.remove(sceneOrNameOrIndex); + } + + /** + * Gets the scene, entity, component, or controller described in the parameters. + * @param {string} sceneNameOrIndex - The name of the scene. + * @param {string} [entityNameOrIndex] - The name of the entity. + * @param {string} [componentOrControllerType] - The type of the component or controller. + * @param {number} [componentOrControllerTypeIndex = 0] - The zero-based index of the component or controller of the specified type, in case there are more than one of the same type. + * @returns {Scene|Entity|BaseComponent|BaseController} + */ + get(sceneNameOrIndex, entityNameOrIndex = undefined, componentOrControllerType = undefined, componentOrControllerTypeIndex = 0) { + const scene = this._scenes.get(sceneNameOrIndex); + if (entityNameOrIndex === undefined || scene === null) { + return scene; + } + return scene.get(entityNameOrIndex, componentOrControllerType, componentOrControllerTypeIndex); + } + + // VIEWPORTS + + /** + * Returns the viewport at the index. + * @param {string|number} nameOrIndex - The name or zero-based index of the viewport to get. + * @returns {Viewport} + */ + getViewport(nameOrIndex) { + return this._viewports.get(nameOrIndex); + } + + /** + * Returns the number of viewports. + * @returns {number} + */ + getNumViewports() { + return this._viewports.size; + } + + /** + * Adds a viewport. + * @param {string} [name=''] - A optional name to give the viewport. + * @returns {Viewport} + */ + addViewport(name = '') { + return this._viewports.add('viewport', name); + } + + /** + * Removes a viewport. + * @param {Viewport|string|number} viewportOrNameOrIndex + */ + removeViewport(viewportOrNameOrIndex) { + this._viewports.remove(viewportOrNameOrIndex); + } + + // TIME + + /** + * Gets the in-app time in seconds since the J2000 epoch, which is at 2000-01-01T11:58:55.816 UTC. See {@link https://en.wikipedia.org/wiki/Epoch_(astronomy)#Julian_years_and_J2000}. + * @returns {number} + */ + getTime() { + return this._time; + } + + /** + * Sets the in-app time. + * @param {number} time - The time in seconds since the J2000 epoch. + */ + setTime(time) { + this._time = time; + } + + /** + * Gets the in-app time rate in seconds per real-time second. + * @returns {number} + */ + getTimeRate() { + return this._timeRate; + } + + /** + * Sets the in-app time rate. + * @param {number} timeRate - The time rate in seconds per real-time second. + */ + setTimeRate(timeRate) { + this._timeRate = timeRate; + } + + /** + * Gets the average FPS over the last number of frames. + * @returns {number} + */ + getFPS() { + return this._fps.getFPS(); + } + + /** + * Gets a limit for the FPS. + * @returns {number} + */ + getFPSLimit() { + return this._fpsLimit; + } + + /** + * Sets a limit for the FPS. + * @param {number} limit + */ + setFPSLimit(limit) { + this._fpsLimit = limit; + } + + /** + * Gets the time in seconds it took to complete the last frame. + * @returns {number} + */ + getDeltaTime() { + return this._realDeltaTime; + } + + // COMPONENT REGISTRATION + + /** + * Returns true if a component of the type is already registered. + * @param {string} type + */ + isComponentTypeRegistered(type) { + return _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Components.has(type); + } + + /** + * Registers a component type. + * @param {string} type - The name of the component that will be used with the addComponent function. + * @param {typeof BaseComponent} typeConstructor - The component class to register. + */ + registerComponentType(type, typeConstructor) { + if (_internal__WEBPACK_IMPORTED_MODULE_0__.Types.Components.has(type)) { + throw new Error('Already registered component type \'' + type + '\'.'); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Components.set(type, typeConstructor); + } + + /** + * Unregisters a component type. + * @param {string} type - The name of the component to unregister. + */ + unregisterComponentType(type) { + _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Components["delete"](type); + } + + /** + * Returns true if a controller of the type is already registered. + * @param {string} type + */ + isControllerTypeRegistered(type) { + return _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Controllers.has(type); + } + + /** + * Registers a controller type. + * @param {string} type - The name of the controller that will be used with the addController function. + * @param {typeof BaseController} typeConstructor - The controller class to register. + */ + registerControllerType(type, typeConstructor) { + if (_internal__WEBPACK_IMPORTED_MODULE_0__.Types.Controllers.has(type)) { + throw new Error('Already registered controller type \'' + type + '\'.'); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Controllers.set(type, typeConstructor); + } + + /** + * Unregisters a controller type. + * @param {string} type - The name of the controller to unregister. + */ + unregisterControllerType(type) { + _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Controllers["delete"](type); + } + + // CALLBACKS AND PROMISES + + /** + * Returns a promise that resolves at the end of the current frame. + * It is useful for letting controllers and components do a single update. + * @returns {Promise} + */ + waitUntilNextFrame() { + return new Promise((resolve) => { + this.addCallback(() => { + resolve(); + }, false); + }); + } + + /** + * Adds a callback to be called at the end of the next frame. + * @param {() => any} callback - The callback to be called. + * @param {boolean} recurring - If true it will run at the end of every frame. If not, it will only run once at the end of the next frame. + */ + addCallback(callback, recurring) { + this._callbacks.push({ + callback: callback, + recurring: recurring + }); + } + + /** + * Removes a callback added via `addCallback()`. If there were multiple, only the first found will be removed. + * @param {() => any} callback - The callback to be removed. + */ + removeCallback(callback) { + this._callbacksToRemove.push(callback); + } + + // INTERNALS + + /** + * Returns the ThreeJS renderer for use by viewports and components. + * @returns {THREE.WebGLRenderer} + * @internal + */ + __getThreeJsRenderer() { + return this._threeJsRenderer; + } + + /** + * The main loop. The requestAnimationFrame call calls this at the start of every frame. + * @private + */ + _loop() { + try { + // Update the time according to the time rate and the real-world elapsed time. + const thisAppTime = Date.now(); + this._realDeltaTime = (thisAppTime - this._lastAppTime) / 1000.0; + + // If not enough time has elapsed, don't run the loop. + if (this._realDeltaTime < 1.0 / this._fpsLimit) { + requestAnimationFrame(this._thisLoop); + return; + } + + this._lastAppTime = thisAppTime; + this._fps.update(this._realDeltaTime); + this._time += this._timeRate * this._realDeltaTime; + + // Update the size of the divs to fill the box when the root div has changed. + if (this._renderSize.x !== this._rootDiv.clientWidth || this._renderSize.y !== this._rootDiv.clientHeight) { + this._renderSize.thaw(); + this._renderSize.set(this._rootDiv.clientWidth, this._rootDiv.clientHeight); + this._renderSize.freeze(); + this._threeJsRenderer.setSize(this._renderSize.x, this._renderSize.y, false); + } + + // Update the scene. + for (let i = 0; i < this._scenes.size; i++) { + this._scenes.get(i).__update(); + } + + // Update the viewport-dependent variables. + for (let i = 0; i < this._viewports.size; i++) { + this._viewports.get(i).__updateViewportVariables(); + } + + // Update the camera-non-specific visual parts of the entities in each scene. + for (let i = 0; i < this._scenes.size; i++) { + this._scenes.get(i).__updateVisuals(); + } + + // Fill the screen with black. + this._threeJsRenderer.setViewport(0, 0, this._renderSize.x, this._renderSize.y); + this._threeJsRenderer.setScissor(0, 0, this._renderSize.x, this._renderSize.y); + this._threeJsRenderer.clear(); + + // Draw the viewports. + for (let i = 0; i < this._viewports.size; i++) { + this._viewports.get(i).__render(); + } + + // Remove any callbacks requested. + for (let i = 0, l = this._callbacksToRemove.length; i < l; i++) { + for (let j = 0, m = this._callbacks.length; j < m; j++) { + if (this._callbacks[j].callback === this._callbacksToRemove[i]) { + this._callbacks.splice(j, 1); + break; + } + } + } + this._callbacksToRemove = []; + + // Call the callbacks. + for (let i = 0; i < this._callbacks.length; i++) { + this._callbacks[i].callback(); + if (!this._callbacks[i].recurring) { + this._callbacksToRemove.push(this._callbacks[i].callback); + } + } + + // Make sure the input is ready for the next frame. + this._input.__resetStatesForNextFrame(); + } + catch (error) { + // eslint-disable-next-line no-console + console.log(error); + throw error; + } + + // Tell the browser to give us another frame. + requestAnimationFrame(this._thisLoop); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/index.js": +/*!**************************************!*\ + !*** ../pioneer/engine/src/index.js ***! + \**************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AER": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.AER; }, +/* harmony export */ "AlignController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.AlignController; }, +/* harmony export */ "AnimdataController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.AnimdataController; }, +/* harmony export */ "AtmosphereComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.AtmosphereComponent; }, +/* harmony export */ "BaseComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent; }, +/* harmony export */ "BaseController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController; }, +/* harmony export */ "BaseRef": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.BaseRef; }, +/* harmony export */ "CMTSComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CMTSComponent; }, +/* harmony export */ "Cache": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Cache; }, +/* harmony export */ "CameraComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CameraComponent; }, +/* harmony export */ "Capabilities": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities; }, +/* harmony export */ "Collection": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Collection; }, +/* harmony export */ "CollectionItem": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CollectionItem; }, +/* harmony export */ "Color": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Color; }, +/* harmony export */ "CometTailComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CometTailComponent; }, +/* harmony export */ "ComponentRef": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef; }, +/* harmony export */ "Config": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Config; }, +/* harmony export */ "ConnectedSpriteComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ConnectedSpriteComponent; }, +/* harmony export */ "ControllerRef": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ControllerRef; }, +/* harmony export */ "CoverageController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CoverageController; }, +/* harmony export */ "CubeMap": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.CubeMap; }, +/* harmony export */ "DependencyGraph": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.DependencyGraph; }, +/* harmony export */ "DivComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.DivComponent; }, +/* harmony export */ "Download": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Download; }, +/* harmony export */ "Downloader": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Downloader; }, +/* harmony export */ "DynamicEnvironmentMapComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.DynamicEnvironmentMapComponent; }, +/* harmony export */ "DynamoController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.DynamoController; }, +/* harmony export */ "Engine": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Engine; }, +/* harmony export */ "Entity": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Entity; }, +/* harmony export */ "EntityItem": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.EntityItem; }, +/* harmony export */ "EntityRef": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef; }, +/* harmony export */ "FPS": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.FPS; }, +/* harmony export */ "FastIterable": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.FastIterable; }, +/* harmony export */ "FastMap": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap; }, +/* harmony export */ "FastMapEntry": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.FastMapEntry; }, +/* harmony export */ "FastSet": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.FastSet; }, +/* harmony export */ "FixedController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.FixedController; }, +/* harmony export */ "FixedToParentController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.FixedToParentController; }, +/* harmony export */ "FreeFlyController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.FreeFlyController; }, +/* harmony export */ "Freezable": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable; }, +/* harmony export */ "Geometry": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry; }, +/* harmony export */ "GizmoComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.GizmoComponent; }, +/* harmony export */ "GroundClampController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.GroundClampController; }, +/* harmony export */ "Input": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Input; }, +/* harmony export */ "Interval": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Interval; }, +/* harmony export */ "KeyframeController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.KeyframeController; }, +/* harmony export */ "LabelComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.LabelComponent; }, +/* harmony export */ "LatLonAlt": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt; }, +/* harmony export */ "LightSourceComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.LightSourceComponent; }, +/* harmony export */ "LineMesh": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.LineMesh; }, +/* harmony export */ "LookController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.LookController; }, +/* harmony export */ "MaterialManager": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialManager; }, +/* harmony export */ "MaterialUtils": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils; }, +/* harmony export */ "MaterialUtilsPhong": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtilsPhong; }, +/* harmony export */ "MaterialUtilsStandard": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtilsStandard; }, +/* harmony export */ "MathUtils": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils; }, +/* harmony export */ "ModelAnimateController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ModelAnimateController; }, +/* harmony export */ "ModelComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ModelComponent; }, +/* harmony export */ "OrbitController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitController; }, +/* harmony export */ "OrbitKeyframeController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitKeyframeController; }, +/* harmony export */ "OrbitalElements": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements; }, +/* harmony export */ "OrbitalElementsController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalElementsController; }, +/* harmony export */ "OrbitalElementsKeyFrame": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalElementsKeyFrame; }, +/* harmony export */ "OrbitalParticlesComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalParticlesComponent; }, +/* harmony export */ "ParticleSprayComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ParticleSprayComponent; }, +/* harmony export */ "PickController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.PickController; }, +/* harmony export */ "Pool": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Pool; }, +/* harmony export */ "Quaternion": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion; }, +/* harmony export */ "Reader": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Reader; }, +/* harmony export */ "Rect": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Rect; }, +/* harmony export */ "RingsComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.RingsComponent; }, +/* harmony export */ "RollController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.RollController; }, +/* harmony export */ "RotateByEntityOrientationController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.RotateByEntityOrientationController; }, +/* harmony export */ "RotateController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.RotateController; }, +/* harmony export */ "ScaleController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ScaleController; }, +/* harmony export */ "Scene": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Scene; }, +/* harmony export */ "SelectController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SelectController; }, +/* harmony export */ "SetParentController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SetParentController; }, +/* harmony export */ "ShaderChunkLogDepth": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth; }, +/* harmony export */ "ShaderFix": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ShaderFix; }, +/* harmony export */ "SkyboxComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SkyboxComponent; }, +/* harmony export */ "Sort": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Sort; }, +/* harmony export */ "SpheroidComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent; }, +/* harmony export */ "SpheroidLODComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SpheroidLODComponent; }, +/* harmony export */ "SpinController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SpinController; }, +/* harmony export */ "SpoutComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SpoutComponent; }, +/* harmony export */ "SpriteComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SpriteComponent; }, +/* harmony export */ "SpriteParticles": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.SpriteParticles; }, +/* harmony export */ "StarfieldComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.StarfieldComponent; }, +/* harmony export */ "THREE": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.THREE; }, +/* harmony export */ "TapController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TapController; }, +/* harmony export */ "TextureLOD": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLOD; }, +/* harmony export */ "TextureLoader": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLoader; }, +/* harmony export */ "TextureLoaderCompressed": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLoaderCompressed; }, +/* harmony export */ "ThreeJsEffectComposer": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsEffectComposer; }, +/* harmony export */ "ThreeJsGLTFLoader": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsGLTFLoader; }, +/* harmony export */ "ThreeJsHelper": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper; }, +/* harmony export */ "ThreeJsKTXLoader": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsKTXLoader; }, +/* harmony export */ "ThreeJsOutlinePass": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsOutlinePass; }, +/* harmony export */ "ThreeJsRenderPass": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsRenderPass; }, +/* harmony export */ "ThreeJsUnrealBloomPass": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsUnrealBloomPass; }, +/* harmony export */ "Tile": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Tile; }, +/* harmony export */ "TimeUtils": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TimeUtils; }, +/* harmony export */ "TrailComponent": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TrailComponent; }, +/* harmony export */ "TransitionController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TransitionController; }, +/* harmony export */ "TranslateController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.TranslateController; }, +/* harmony export */ "Types": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Types; }, +/* harmony export */ "Vector2": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2; }, +/* harmony export */ "Vector3": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3; }, +/* harmony export */ "Version": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Version; }, +/* harmony export */ "Viewport": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.Viewport; }, +/* harmony export */ "ZoomController": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.ZoomController; }, +/* harmony export */ "waitUntil": function() { return /* reexport safe */ _internal__WEBPACK_IMPORTED_MODULE_0__.waitUntil; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal */ "../pioneer/engine/src/internal.js"); + + + +/***/ }), + +/***/ "../pioneer/engine/src/input.js": +/*!**************************************!*\ + !*** ../pioneer/engine/src/input.js ***! + \**************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Input": function() { return /* binding */ Input; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A single touch on the device by the user. + */ +class Touch { + /** + * The constructor. + */ + constructor() { + /** + * The browser-given identifier of the touch. Each identifier is unique. 0 is always the mouse left-click. + * @type {number} + */ + this.identifier = 0; + + /** + * The position relative to the root div where the touch initially occurred. + * @type {Vector2} + */ + this.pressedPosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + + /** + * The duration so-far of the touch. + * @type {number} + */ + this.pressedTime = 0; + + /** + * The position relative to the root div where the touch was moved to last frame. + * @type {Vector2} + */ + this.lastFramePosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + + /** + * The current position relative to the root div of the touch. + * @type {Vector2} + */ + this.thisFramePosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + } +} + +/** + * The input system. Handles all the dragging, rotating, zooming, keyboard, touch, etc. + * @hideconstructor + */ +class Input { + /** + * Constructs the input manager. + * @param {Engine} engine - The Pioneer engine. + */ + constructor(engine) { + /** + * The engine. + * @type {Engine} + * @private + */ + this._engine = engine; + + /** + * The active viewport. The viewport is activated when a left-click or touch happens. + * @type {Viewport} + * @private + */ + this._activeViewport = null; + + /** + * The amount that the cursor was tragged in the last frame. + * @type {Vector2} + * @private + */ + this._draggedOffset = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + this._draggedOffset.freeze(); + + /** + * The amount that was zoomed in the last frame. + * @type {number} + * @private + */ + this._zoomedOffset = 0; + + /** + * The amount that was rotated in the last frame. + * @type {number} + * @private + */ + this._rotatedOffset = 0; + + /** + * Is shift pressed? + * @type {boolean} + * @private + */ + this._shiftPressed = false; + + /** + * The keys that are pressed. + * @type {Set} + * @private + */ + this._keysPressed = new Set(); + + /** + * The modifiers keys that are pressed. + * @type {Set} + * @private + */ + this._modifierKeysPressed = new Set(); + + /** + * The maximum time in seconds before it is considered a drag. + * @type {number} + * @private + */ + this._maxSelectTime = 0.5; + + /** + * Minimum distance to move the press before it is considered a drag. + * @type {number} + * @private + */ + this._maxSelectDistance = 5; + + /** + * The position of the cursor. + * @type {Vector2} + * @private + */ + this._cursorPosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + + /** + * Did the user select something last frame? + * @type {boolean} + * @private + */ + this._selected = false; + + /** + * If selected, this is the position of the selection. + * @type {Vector2} + * @private + */ + this._selectedPosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + this._selectedPosition.freeze(); + + /** + * The current touches. + * @type {Touch[]} + * @private + */ + this._touches = []; + + // Setup the event listeners. + window.addEventListener('blur', () => { + this._touches = []; + this._keysPressed.clear(); + this._modifierKeysPressed.clear(); + this._shiftPressed = false; + }); + window.addEventListener('keydown', event => { + // Don't process key down events if the user is focused on writing text. + if (event.target instanceof HTMLElement && ['INPUT', 'SELECT', 'TEXTAREA'].includes(event.target.tagName)) { + return; + } + if (event.key === 'Shift') { + this._shiftPressed = true; + } + // If a modifier key is hit that isn't shift, clear all pressed keys. + else if (modifierKeys.has(event.key)) { + this._modifierKeysPressed.add(event.key.toLowerCase()); + this._keysPressed.clear(); + this._shiftPressed = false; + } + else if (this._modifierKeysPressed.size === 0) { + this._keysPressed.add(event.key.toLowerCase()); + } + }); + window.addEventListener('keyup', event => { + if (event.key === 'Shift') { + this._shiftPressed = false; + } + else if (modifierKeys.has(event.key)) { + this._modifierKeysPressed.delete(event.key.toLowerCase()); + } + else { + this._keysPressed.delete(event.key.toLowerCase()); + } + }); + this._engine.getRootDiv().addEventListener('mousedown', event => { + if (event.button === 0) { + // Unfocus any other elements on the page. + if (document.activeElement instanceof HTMLElement) { + document.activeElement.blur(); + } + + // If this is the first touch. + if (this._touches.length === 0) { + const rootDivBounds = this._engine.getRootDiv().getBoundingClientRect(); + + // Check for an existing touch with the same identifier. + let touch = null; + for (let j = 0; j < this._touches.length; j++) { + if (this._touches[j].identifier === 0) { + touch = this._touches[j]; + } + } + if (touch === null) { + touch = new Touch(); + } + + // Create the new touch. + touch.identifier = 0; + touch.pressedPosition.set(event.clientX - rootDivBounds.left, event.clientY - rootDivBounds.top); + touch.pressedTime = Date.now(); + touch.lastFramePosition.copy(touch.pressedPosition); + touch.thisFramePosition.copy(touch.pressedPosition); + this._touches.push(touch); + + // Updates active viewport to the one clicked + this._updateActiveViewport(); + } + } + }); + window.addEventListener('mousemove', event => { + const rootDivBounds = this._engine.getRootDiv().getBoundingClientRect(); + if (this._touches.length === 1 && this._touches[0].identifier === 0) { + const touch = this._touches[0]; + touch.thisFramePosition.set(event.clientX - rootDivBounds.left, event.clientY - rootDivBounds.top); + + // Update the dragged offset and the latest touch position. + this._draggedOffset.thaw(); + this._draggedOffset.sub(touch.thisFramePosition, touch.lastFramePosition); + + // If the cursor hasn't moved enough, there is no drag. + const pressedPositionDistance = Math.max(Math.abs(touch.thisFramePosition.x - touch.pressedPosition.x), Math.abs(touch.thisFramePosition.y - touch.pressedPosition.y)); + if ((Date.now() - touch.pressedTime) / 1000 <= this._maxSelectTime && pressedPositionDistance <= this._maxSelectDistance) { + this._draggedOffset.set(0, 0); + } + this._draggedOffset.freeze(); + } + if (this._touches.length <= 1) { + this._cursorPosition.set(event.clientX - rootDivBounds.left, event.clientY - rootDivBounds.top); + } + }); + window.addEventListener('mouseup', event => { + if (event.button === 0) { + if (this._touches.length === 1 && this._touches[0].identifier === 0) { + const rootDivBounds = this._engine.getRootDiv().getBoundingClientRect(); + const touch = this._touches[0]; + touch.thisFramePosition.set(event.clientX - rootDivBounds.left, event.clientY - rootDivBounds.top); + const pressedPositionDistance = Math.max(Math.abs(touch.thisFramePosition.x - touch.pressedPosition.x), Math.abs(touch.thisFramePosition.y - touch.pressedPosition.y)); + if ((Date.now() - touch.pressedTime) / 1000 <= this._maxSelectTime && pressedPositionDistance <= this._maxSelectDistance) { + this._selected = true; + this._selectedPosition.thaw(); + this._selectedPosition.copy(touch.thisFramePosition); + this._selectedPosition.freeze(); + } + this._touches.splice(0, 1); + } + } + }); + this._engine.getRootDiv().addEventListener('wheel', event => { + if (event.deltaY) { + this._zoomedOffset += event.deltaY * 0.1; + } + event.preventDefault(); + }, { passive: false }); + this._engine.getRootDiv().addEventListener('touchstart', event => { + const rootDivBounds = this._engine.getRootDiv().getBoundingClientRect(); + for (let i = 0; i < event.changedTouches.length; i++) { + const touchEvent = event.changedTouches[i]; + + // Check for an existing touch with the same identifier. + let touch = null; + for (let j = 0; j < this._touches.length; j++) { + if (this._touches[j].identifier === touchEvent.identifier) { + touch = this._touches[j]; + } + } + if (touch === null) { + touch = new Touch(); + } + + // Create the new touch. + touch.identifier = touchEvent.identifier; + touch.pressedPosition.thaw(); + touch.pressedPosition.set(touchEvent.pageX - window.pageXOffset - rootDivBounds.left, touchEvent.pageY - window.pageYOffset - rootDivBounds.top); + touch.pressedPosition.freeze(); + touch.pressedTime = Date.now(); + touch.lastFramePosition.copy(touch.pressedPosition); + touch.thisFramePosition.copy(touch.pressedPosition); + this._touches.push(touch); + if (this._touches.length === 1) { + this._cursorPosition.copy(touch.thisFramePosition); + } + + // Updates active viewport to the one touched + this._updateActiveViewport(); + } + }, { passive: false }); + window.addEventListener('touchmove', event => { + const rootDivBounds = this._engine.getRootDiv().getBoundingClientRect(); + for (let i = 0; i < event.changedTouches.length; i++) { + const touchEvent = event.changedTouches[i]; + + for (let j = 0; j < this._touches.length; j++) { + const touch = this._touches[j]; + if (touch.identifier === touchEvent.identifier) { + touch.thisFramePosition.set(touchEvent.pageX - window.pageXOffset - rootDivBounds.left, touchEvent.pageY - window.pageYOffset - rootDivBounds.top); + if (this._touches.length === 1) { + this._draggedOffset.thaw(); + this._draggedOffset.sub(touch.thisFramePosition, touch.lastFramePosition); + // If the cursor hasn't moved enough, there is no drag. + const pressedPositionDistance = Math.max(Math.abs(touch.thisFramePosition.x - touch.pressedPosition.x), Math.abs(touch.thisFramePosition.y - touch.pressedPosition.y)); + if ((Date.now() - touch.pressedTime) / 1000 <= this._maxSelectTime && pressedPositionDistance <= this._maxSelectDistance) { + this._draggedOffset.set(0, 0); + } + this._draggedOffset.freeze(); + this._cursorPosition.copy(touch.thisFramePosition); + } + else if (this._touches.length === 2) { + const touchDiff = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + touchDiff.sub(this._touches[i].thisFramePosition, this._touches[1 - i].thisFramePosition); + const touchOffset = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + touchOffset.sub(this._touches[i].thisFramePosition, this._touches[i].lastFramePosition); + const dot = touchOffset.dot(touchDiff) / touchDiff.magnitude() / touchOffset.magnitude(); + const cross = touchOffset.cross(touchDiff) / touchDiff.magnitude() / touchOffset.magnitude(); + if (dot < -0.7) { + this._zoomedOffset += -(dot + 0.7) * touchOffset.magnitude(); + } + else if (dot > 0.7) { + this._zoomedOffset += -(dot - 0.7) * touchOffset.magnitude(); + } + else if (Math.abs(cross) > 0.3) { + this._rotatedOffset += cross * touchOffset.magnitude(); + } + + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(touchOffset); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(touchDiff); + + // If the touch hasn't moved enough, there is no zoom. + const pressedPositionDistance = Math.max(Math.abs(touch.thisFramePosition.x - touch.pressedPosition.x), Math.abs(touch.thisFramePosition.y - touch.pressedPosition.y)); + if ((Date.now() - touch.pressedTime) / 1000 <= this._maxSelectTime && pressedPositionDistance <= this._maxSelectDistance) { + this._zoomedOffset = 0; + this._rotatedOffset = 0; + } + } + } + } + } + }); + window.addEventListener('touchend', event => { + const rootDivBounds = this._engine.getRootDiv().getBoundingClientRect(); + for (let i = 0; i < event.changedTouches.length; i++) { + const touchEvent = event.changedTouches[i]; + for (let j = 0; j < this._touches.length; j++) { + const touch = this._touches[j]; + if (touch.identifier === touchEvent.identifier) { + touch.thisFramePosition.set(touchEvent.pageX - window.pageXOffset - rootDivBounds.left, touchEvent.pageY - window.pageYOffset - rootDivBounds.top); + if (this._touches.length === 1) { + const pressedPositionDistance = Math.max(Math.abs(touch.thisFramePosition.x - touch.pressedPosition.x), Math.abs(touch.thisFramePosition.y - touch.pressedPosition.y)); + if ((Date.now() - touch.pressedTime) / 1000 <= this._maxSelectTime && pressedPositionDistance <= this._maxSelectDistance) { + this._selected = true; + this._selectedPosition.thaw(); + this._selectedPosition.copy(touch.thisFramePosition); + this._selectedPosition.freeze(); + } + } + this._touches.splice(j, 1); + } + } + } + }); + window.addEventListener('touchcancel', () => { + }); + } + + /** + * Return the current active viewport. + * @returns {Viewport} + */ + getActiveViewport() { + return this._activeViewport; + } + + /** + * Gets how much the user dragged this frame. + * @returns {Vector2} + */ + getDraggedOffset() { + return this._draggedOffset; + } + + /** + * Returns how much the user zoomed this frame. + * @returns {number} + */ + getZoomedOffset() { + return this._zoomedOffset; + } + + /** + * Returns how much the user rotated this frame. + * @returns {number} + */ + getRotatedOffset() { + return this._rotatedOffset; + } + + /** + * Returns true if the shift key is down this frame. + * @returns {boolean} + */ + isShiftPressed() { + return this._shiftPressed; + } + + /** + * Returns true if the key is pressed. + * @param {string} key - The key (in lower-case) to query. + * @returns {boolean} + */ + isKeyPressed(key) { + return this._keysPressed.has(key); + } + + /** + * Did the user click (or tap) last frame? + * @returns {boolean} + */ + isSelected() { + return this._selected; + } + + /** + * Gets the position when the user last selected, relative to the root div. + * @returns {Vector2} + */ + getSelectedPosition() { + return this._selectedPosition; + } + + /** + * Gets the position of the cursor or the last touch. + * @returns {Vector2} + */ + getCursorPosition() { + return this._cursorPosition; + } + + /** + * Manually set the active viewport. Called by a viewport on construction if there is no active viewport. + * @param {Viewport} viewport - The viewport to set. + * @internal + */ + __setActiveViewport(viewport) { + this._activeViewport = viewport; + } + + /** + * Resets all of the values for the next frame. Called by Engine only. + * @internal + */ + __resetStatesForNextFrame() { + for (let i = 0; i < this._touches.length; i++) { + this._touches[i].lastFramePosition.copy(this._touches[i].thisFramePosition); + } + + this._selected = false; + this._altSelected = false; + this._draggedOffset.thaw(); + this._draggedOffset.set(0, 0); + this._draggedOffset.freeze(); + this._zoomedOffset = 0; + this._rotatedOffset = 0; + } + + /** + * Automatically updates the active viewport. Called by a mouse down or touch start event. + * @private + */ + _updateActiveViewport() { + this._activeViewport = null; + for (let i = this._engine.getNumViewports() - 1; i >= 0; i--) { + const pixelBounds = this._engine.getViewport(i).getBounds(); + if (this._engine.getViewport(i).isEnabled() && pixelBounds.contains(this._touches[0].pressedPosition)) { + this._activeViewport = this._engine.getViewport(i); + break; + } + } + } +} + +/** + * All modifier keys in Javascript, from https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values. + */ +const modifierKeys = new Set(['Alt', 'AltGraph', 'CapsLock', 'Control', 'Fn', 'FnLock', 'Hyper', 'Meta', 'NumLock', 'ScrollLock', 'Shift', 'Super', 'Symbol', 'SymbolLock']); + + +/***/ }), + +/***/ "../pioneer/engine/src/internal.js": +/*!*****************************************!*\ + !*** ../pioneer/engine/src/internal.js ***! + \*****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "THREE": function() { return /* reexport module object */ three__WEBPACK_IMPORTED_MODULE_0__; }, +/* harmony export */ "ThreeJsEffectComposer": function() { return /* reexport safe */ three_examples_jsm_postprocessing_EffectComposer_js__WEBPACK_IMPORTED_MODULE_1__.EffectComposer; }, +/* harmony export */ "ThreeJsGLTFLoader": function() { return /* reexport safe */ three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_2__.GLTFLoader; }, +/* harmony export */ "ThreeJsKTXLoader": function() { return /* reexport safe */ three_examples_jsm_loaders_KTXLoader__WEBPACK_IMPORTED_MODULE_3__.KTXLoader; }, +/* harmony export */ "ThreeJsOutlinePass": function() { return /* reexport safe */ three_examples_jsm_postprocessing_OutlinePass_js__WEBPACK_IMPORTED_MODULE_4__.OutlinePass; }, +/* harmony export */ "ThreeJsRenderPass": function() { return /* reexport safe */ three_examples_jsm_postprocessing_RenderPass_js__WEBPACK_IMPORTED_MODULE_5__.RenderPass; }, +/* harmony export */ "ThreeJsUnrealBloomPass": function() { return /* reexport safe */ three_examples_jsm_postprocessing_UnrealBloomPass_js__WEBPACK_IMPORTED_MODULE_6__.UnrealBloomPass; }, +/* harmony export */ "ShaderChunkLogDepth": function() { return /* reexport safe */ _shaders_log_depth__WEBPACK_IMPORTED_MODULE_7__.ShaderChunkLogDepth; }, +/* harmony export */ "BaseRef": function() { return /* reexport safe */ _utils_base_ref__WEBPACK_IMPORTED_MODULE_8__.BaseRef; }, +/* harmony export */ "Collection": function() { return /* reexport safe */ _utils_collection__WEBPACK_IMPORTED_MODULE_9__.Collection; }, +/* harmony export */ "CollectionItem": function() { return /* reexport safe */ _utils_collection__WEBPACK_IMPORTED_MODULE_9__.CollectionItem; }, +/* harmony export */ "DependencyGraph": function() { return /* reexport safe */ _utils_dependency_graph__WEBPACK_IMPORTED_MODULE_10__.DependencyGraph; }, +/* harmony export */ "FastIterable": function() { return /* reexport safe */ _utils_fast_iterable__WEBPACK_IMPORTED_MODULE_11__.FastIterable; }, +/* harmony export */ "FPS": function() { return /* reexport safe */ _utils_fps__WEBPACK_IMPORTED_MODULE_12__.FPS; }, +/* harmony export */ "Freezable": function() { return /* reexport safe */ _utils_freezable__WEBPACK_IMPORTED_MODULE_13__.Freezable; }, +/* harmony export */ "MathUtils": function() { return /* reexport safe */ _utils_math_utils__WEBPACK_IMPORTED_MODULE_14__.MathUtils; }, +/* harmony export */ "Pool": function() { return /* reexport safe */ _utils_pool__WEBPACK_IMPORTED_MODULE_15__.Pool; }, +/* harmony export */ "Reader": function() { return /* reexport safe */ _utils_reader__WEBPACK_IMPORTED_MODULE_16__.Reader; }, +/* harmony export */ "Sort": function() { return /* reexport safe */ _utils_sort__WEBPACK_IMPORTED_MODULE_17__.Sort; }, +/* harmony export */ "Tile": function() { return /* reexport safe */ _utils_tile__WEBPACK_IMPORTED_MODULE_18__.Tile; }, +/* harmony export */ "TimeUtils": function() { return /* reexport safe */ _utils_time_utils__WEBPACK_IMPORTED_MODULE_19__.TimeUtils; }, +/* harmony export */ "waitUntil": function() { return /* reexport safe */ _utils_wait_until__WEBPACK_IMPORTED_MODULE_20__.waitUntil; }, +/* harmony export */ "AER": function() { return /* reexport safe */ _utils_aer__WEBPACK_IMPORTED_MODULE_21__.AER; }, +/* harmony export */ "Color": function() { return /* reexport safe */ _utils_color__WEBPACK_IMPORTED_MODULE_22__.Color; }, +/* harmony export */ "FastMap": function() { return /* reexport safe */ _utils_fast_map__WEBPACK_IMPORTED_MODULE_23__.FastMap; }, +/* harmony export */ "FastMapEntry": function() { return /* reexport safe */ _utils_fast_map__WEBPACK_IMPORTED_MODULE_23__.FastMapEntry; }, +/* harmony export */ "FastSet": function() { return /* reexport safe */ _utils_fast_set__WEBPACK_IMPORTED_MODULE_24__.FastSet; }, +/* harmony export */ "Geometry": function() { return /* reexport safe */ _utils_geometry__WEBPACK_IMPORTED_MODULE_25__.Geometry; }, +/* harmony export */ "Interval": function() { return /* reexport safe */ _utils_interval__WEBPACK_IMPORTED_MODULE_26__.Interval; }, +/* harmony export */ "OrbitalElements": function() { return /* reexport safe */ _utils_orbital_elements__WEBPACK_IMPORTED_MODULE_27__.OrbitalElements; }, +/* harmony export */ "Rect": function() { return /* reexport safe */ _utils_rect__WEBPACK_IMPORTED_MODULE_28__.Rect; }, +/* harmony export */ "Quaternion": function() { return /* reexport safe */ _utils_quaternion__WEBPACK_IMPORTED_MODULE_29__.Quaternion; }, +/* harmony export */ "Vector2": function() { return /* reexport safe */ _utils_vector2__WEBPACK_IMPORTED_MODULE_30__.Vector2; }, +/* harmony export */ "Vector3": function() { return /* reexport safe */ _utils_vector3__WEBPACK_IMPORTED_MODULE_31__.Vector3; }, +/* harmony export */ "Cache": function() { return /* reexport safe */ _utils_cache__WEBPACK_IMPORTED_MODULE_32__.Cache; }, +/* harmony export */ "ComponentRef": function() { return /* reexport safe */ _utils_component_ref__WEBPACK_IMPORTED_MODULE_33__.ComponentRef; }, +/* harmony export */ "ControllerRef": function() { return /* reexport safe */ _utils_controller_ref__WEBPACK_IMPORTED_MODULE_34__.ControllerRef; }, +/* harmony export */ "CubeMap": function() { return /* reexport safe */ _utils_cube_map__WEBPACK_IMPORTED_MODULE_35__.CubeMap; }, +/* harmony export */ "EntityRef": function() { return /* reexport safe */ _utils_entity_ref__WEBPACK_IMPORTED_MODULE_36__.EntityRef; }, +/* harmony export */ "LatLonAlt": function() { return /* reexport safe */ _utils_lat_lon_alt__WEBPACK_IMPORTED_MODULE_37__.LatLonAlt; }, +/* harmony export */ "LineMesh": function() { return /* reexport safe */ _utils_line_mesh__WEBPACK_IMPORTED_MODULE_38__.LineMesh; }, +/* harmony export */ "MaterialUtilsPhong": function() { return /* reexport safe */ _utils_material_utils_phong__WEBPACK_IMPORTED_MODULE_39__.MaterialUtilsPhong; }, +/* harmony export */ "MaterialUtilsStandard": function() { return /* reexport safe */ _utils_material_utils_standard__WEBPACK_IMPORTED_MODULE_40__.MaterialUtilsStandard; }, +/* harmony export */ "MaterialUtils": function() { return /* reexport safe */ _utils_material_utils__WEBPACK_IMPORTED_MODULE_41__.MaterialUtils; }, +/* harmony export */ "ShaderFix": function() { return /* reexport safe */ _utils_shader_fix__WEBPACK_IMPORTED_MODULE_42__.ShaderFix; }, +/* harmony export */ "SpriteParticles": function() { return /* reexport safe */ _utils_sprite_particles__WEBPACK_IMPORTED_MODULE_43__.SpriteParticles; }, +/* harmony export */ "TextureLOD": function() { return /* reexport safe */ _utils_texture_lod__WEBPACK_IMPORTED_MODULE_44__.TextureLOD; }, +/* harmony export */ "ThreeJsHelper": function() { return /* reexport safe */ _utils_three_js_helper__WEBPACK_IMPORTED_MODULE_45__.ThreeJsHelper; }, +/* harmony export */ "Capabilities": function() { return /* reexport safe */ _capabilities__WEBPACK_IMPORTED_MODULE_46__.Capabilities; }, +/* harmony export */ "Config": function() { return /* reexport safe */ _config__WEBPACK_IMPORTED_MODULE_47__.Config; }, +/* harmony export */ "Download": function() { return /* reexport safe */ _downloader__WEBPACK_IMPORTED_MODULE_48__.Download; }, +/* harmony export */ "Downloader": function() { return /* reexport safe */ _downloader__WEBPACK_IMPORTED_MODULE_48__.Downloader; }, +/* harmony export */ "Engine": function() { return /* reexport safe */ _engine__WEBPACK_IMPORTED_MODULE_49__.Engine; }, +/* harmony export */ "Entity": function() { return /* reexport safe */ _scene_entity__WEBPACK_IMPORTED_MODULE_50__.Entity; }, +/* harmony export */ "EntityItem": function() { return /* reexport safe */ _scene_entity_item__WEBPACK_IMPORTED_MODULE_51__.EntityItem; }, +/* harmony export */ "Input": function() { return /* reexport safe */ _input__WEBPACK_IMPORTED_MODULE_52__.Input; }, +/* harmony export */ "MaterialManager": function() { return /* reexport safe */ _material_manager__WEBPACK_IMPORTED_MODULE_53__.MaterialManager; }, +/* harmony export */ "Scene": function() { return /* reexport safe */ _scene_scene__WEBPACK_IMPORTED_MODULE_54__.Scene; }, +/* harmony export */ "TextureLoader": function() { return /* reexport safe */ _texture_loader__WEBPACK_IMPORTED_MODULE_55__.TextureLoader; }, +/* harmony export */ "TextureLoaderCompressed": function() { return /* reexport safe */ _texture_loader_compressed__WEBPACK_IMPORTED_MODULE_56__.TextureLoaderCompressed; }, +/* harmony export */ "Version": function() { return /* reexport safe */ _version__WEBPACK_IMPORTED_MODULE_57__.Version; }, +/* harmony export */ "Viewport": function() { return /* reexport safe */ _viewport__WEBPACK_IMPORTED_MODULE_58__.Viewport; }, +/* harmony export */ "BaseComponent": function() { return /* reexport safe */ _scene_components_base_component__WEBPACK_IMPORTED_MODULE_59__.BaseComponent; }, +/* harmony export */ "AtmosphereComponent": function() { return /* reexport safe */ _scene_components_atmosphere_component__WEBPACK_IMPORTED_MODULE_60__.AtmosphereComponent; }, +/* harmony export */ "CameraComponent": function() { return /* reexport safe */ _scene_components_camera_component__WEBPACK_IMPORTED_MODULE_61__.CameraComponent; }, +/* harmony export */ "CMTSComponent": function() { return /* reexport safe */ _scene_components_cmts_component__WEBPACK_IMPORTED_MODULE_62__.CMTSComponent; }, +/* harmony export */ "CometTailComponent": function() { return /* reexport safe */ _scene_components_comet_tail_component__WEBPACK_IMPORTED_MODULE_63__.CometTailComponent; }, +/* harmony export */ "ConnectedSpriteComponent": function() { return /* reexport safe */ _scene_components_connected_sprite_component__WEBPACK_IMPORTED_MODULE_64__.ConnectedSpriteComponent; }, +/* harmony export */ "DivComponent": function() { return /* reexport safe */ _scene_components_div_component__WEBPACK_IMPORTED_MODULE_65__.DivComponent; }, +/* harmony export */ "DynamicEnvironmentMapComponent": function() { return /* reexport safe */ _scene_components_dynamic_environment_map_component__WEBPACK_IMPORTED_MODULE_66__.DynamicEnvironmentMapComponent; }, +/* harmony export */ "GizmoComponent": function() { return /* reexport safe */ _scene_components_gizmo_component__WEBPACK_IMPORTED_MODULE_67__.GizmoComponent; }, +/* harmony export */ "LabelComponent": function() { return /* reexport safe */ _scene_components_label_component__WEBPACK_IMPORTED_MODULE_68__.LabelComponent; }, +/* harmony export */ "LightSourceComponent": function() { return /* reexport safe */ _scene_components_light_source_component__WEBPACK_IMPORTED_MODULE_69__.LightSourceComponent; }, +/* harmony export */ "ModelComponent": function() { return /* reexport safe */ _scene_components_model_component__WEBPACK_IMPORTED_MODULE_70__.ModelComponent; }, +/* harmony export */ "OrbitalParticlesComponent": function() { return /* reexport safe */ _scene_components_orbital_particles_component__WEBPACK_IMPORTED_MODULE_71__.OrbitalParticlesComponent; }, +/* harmony export */ "ParticleSprayComponent": function() { return /* reexport safe */ _scene_components_particle_spray_component__WEBPACK_IMPORTED_MODULE_72__.ParticleSprayComponent; }, +/* harmony export */ "RingsComponent": function() { return /* reexport safe */ _scene_components_rings_component__WEBPACK_IMPORTED_MODULE_73__.RingsComponent; }, +/* harmony export */ "SkyboxComponent": function() { return /* reexport safe */ _scene_components_skybox_component__WEBPACK_IMPORTED_MODULE_74__.SkyboxComponent; }, +/* harmony export */ "SpheroidComponent": function() { return /* reexport safe */ _scene_components_spheroid_component__WEBPACK_IMPORTED_MODULE_75__.SpheroidComponent; }, +/* harmony export */ "SpheroidLODComponent": function() { return /* reexport safe */ _scene_components_spheroid_lod_component__WEBPACK_IMPORTED_MODULE_76__.SpheroidLODComponent; }, +/* harmony export */ "SpoutComponent": function() { return /* reexport safe */ _scene_components_spout_component__WEBPACK_IMPORTED_MODULE_77__.SpoutComponent; }, +/* harmony export */ "SpriteComponent": function() { return /* reexport safe */ _scene_components_sprite_component__WEBPACK_IMPORTED_MODULE_78__.SpriteComponent; }, +/* harmony export */ "StarfieldComponent": function() { return /* reexport safe */ _scene_components_starfield_component__WEBPACK_IMPORTED_MODULE_79__.StarfieldComponent; }, +/* harmony export */ "TrailComponent": function() { return /* reexport safe */ _scene_components_trail_component__WEBPACK_IMPORTED_MODULE_80__.TrailComponent; }, +/* harmony export */ "BaseController": function() { return /* reexport safe */ _scene_controllers_base_controller__WEBPACK_IMPORTED_MODULE_81__.BaseController; }, +/* harmony export */ "AlignController": function() { return /* reexport safe */ _scene_controllers_align_controller__WEBPACK_IMPORTED_MODULE_82__.AlignController; }, +/* harmony export */ "AnimdataController": function() { return /* reexport safe */ _scene_controllers_animdata_controller__WEBPACK_IMPORTED_MODULE_83__.AnimdataController; }, +/* harmony export */ "CoverageController": function() { return /* reexport safe */ _scene_controllers_coverage_controller__WEBPACK_IMPORTED_MODULE_84__.CoverageController; }, +/* harmony export */ "DynamoController": function() { return /* reexport safe */ _scene_controllers_dynamo_controller__WEBPACK_IMPORTED_MODULE_85__.DynamoController; }, +/* harmony export */ "FixedController": function() { return /* reexport safe */ _scene_controllers_fixed_controller__WEBPACK_IMPORTED_MODULE_86__.FixedController; }, +/* harmony export */ "FixedToParentController": function() { return /* reexport safe */ _scene_controllers_fixed_to_parent_controller__WEBPACK_IMPORTED_MODULE_87__.FixedToParentController; }, +/* harmony export */ "FreeFlyController": function() { return /* reexport safe */ _scene_controllers_free_fly_controller__WEBPACK_IMPORTED_MODULE_88__.FreeFlyController; }, +/* harmony export */ "GroundClampController": function() { return /* reexport safe */ _scene_controllers_ground_clamp_controller__WEBPACK_IMPORTED_MODULE_89__.GroundClampController; }, +/* harmony export */ "KeyframeController": function() { return /* reexport safe */ _scene_controllers_keyframe_controller__WEBPACK_IMPORTED_MODULE_90__.KeyframeController; }, +/* harmony export */ "LookController": function() { return /* reexport safe */ _scene_controllers_look_controller__WEBPACK_IMPORTED_MODULE_91__.LookController; }, +/* harmony export */ "ModelAnimateController": function() { return /* reexport safe */ _scene_controllers_model_animate_controller__WEBPACK_IMPORTED_MODULE_92__.ModelAnimateController; }, +/* harmony export */ "OrbitController": function() { return /* reexport safe */ _scene_controllers_orbit_controller__WEBPACK_IMPORTED_MODULE_93__.OrbitController; }, +/* harmony export */ "OrbitKeyframeController": function() { return /* reexport safe */ _scene_controllers_orbit_keyframe_controller__WEBPACK_IMPORTED_MODULE_94__.OrbitKeyframeController; }, +/* harmony export */ "OrbitalElementsController": function() { return /* reexport safe */ _scene_controllers_orbital_elements_controller__WEBPACK_IMPORTED_MODULE_95__.OrbitalElementsController; }, +/* harmony export */ "OrbitalElementsKeyFrame": function() { return /* reexport safe */ _scene_controllers_orbital_elements_controller__WEBPACK_IMPORTED_MODULE_95__.OrbitalElementsKeyFrame; }, +/* harmony export */ "PickController": function() { return /* reexport safe */ _scene_controllers_pick_controller__WEBPACK_IMPORTED_MODULE_96__.PickController; }, +/* harmony export */ "RollController": function() { return /* reexport safe */ _scene_controllers_roll_controller__WEBPACK_IMPORTED_MODULE_97__.RollController; }, +/* harmony export */ "RotateController": function() { return /* reexport safe */ _scene_controllers_rotate_controller__WEBPACK_IMPORTED_MODULE_98__.RotateController; }, +/* harmony export */ "RotateByEntityOrientationController": function() { return /* reexport safe */ _scene_controllers_rotate_by_entity_orientation_controller__WEBPACK_IMPORTED_MODULE_99__.RotateByEntityOrientationController; }, +/* harmony export */ "ScaleController": function() { return /* reexport safe */ _scene_controllers_scale_controller__WEBPACK_IMPORTED_MODULE_100__.ScaleController; }, +/* harmony export */ "SelectController": function() { return /* reexport safe */ _scene_controllers_select_controller__WEBPACK_IMPORTED_MODULE_101__.SelectController; }, +/* harmony export */ "SetParentController": function() { return /* reexport safe */ _scene_controllers_set_parent_controller__WEBPACK_IMPORTED_MODULE_102__.SetParentController; }, +/* harmony export */ "SpinController": function() { return /* reexport safe */ _scene_controllers_spin_controller__WEBPACK_IMPORTED_MODULE_103__.SpinController; }, +/* harmony export */ "TapController": function() { return /* reexport safe */ _scene_controllers_tap_controller__WEBPACK_IMPORTED_MODULE_104__.TapController; }, +/* harmony export */ "TransitionController": function() { return /* reexport safe */ _scene_controllers_transition_controller__WEBPACK_IMPORTED_MODULE_105__.TransitionController; }, +/* harmony export */ "TranslateController": function() { return /* reexport safe */ _scene_controllers_translate_controller__WEBPACK_IMPORTED_MODULE_106__.TranslateController; }, +/* harmony export */ "ZoomController": function() { return /* reexport safe */ _scene_controllers_zoom_controller__WEBPACK_IMPORTED_MODULE_107__.ZoomController; }, +/* harmony export */ "Types": function() { return /* reexport safe */ _scene_types__WEBPACK_IMPORTED_MODULE_108__.Types; } +/* harmony export */ }); +/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ "../pioneer/engine/node_modules/three/build/three.module.js"); +/* harmony import */ var three_examples_jsm_postprocessing_EffectComposer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three/examples/jsm/postprocessing/EffectComposer.js */ "../pioneer/engine/node_modules/three/examples/jsm/postprocessing/EffectComposer.js"); +/* harmony import */ var three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three/examples/jsm/loaders/GLTFLoader */ "../pioneer/engine/node_modules/three/examples/jsm/loaders/GLTFLoader.js"); +/* harmony import */ var three_examples_jsm_loaders_KTXLoader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! three/examples/jsm/loaders/KTXLoader */ "../pioneer/engine/node_modules/three/examples/jsm/loaders/KTXLoader.js"); +/* harmony import */ var three_examples_jsm_postprocessing_OutlinePass_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! three/examples/jsm/postprocessing/OutlinePass.js */ "../pioneer/engine/node_modules/three/examples/jsm/postprocessing/OutlinePass.js"); +/* harmony import */ var three_examples_jsm_postprocessing_RenderPass_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! three/examples/jsm/postprocessing/RenderPass.js */ "../pioneer/engine/node_modules/three/examples/jsm/postprocessing/RenderPass.js"); +/* harmony import */ var three_examples_jsm_postprocessing_UnrealBloomPass_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! three/examples/jsm/postprocessing/UnrealBloomPass.js */ "../pioneer/engine/node_modules/three/examples/jsm/postprocessing/UnrealBloomPass.js"); +/* harmony import */ var _shaders_log_depth__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./shaders/log_depth */ "../pioneer/engine/src/shaders/log_depth.js"); +/* harmony import */ var _utils_base_ref__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./utils/base_ref */ "../pioneer/engine/src/utils/base_ref.js"); +/* harmony import */ var _utils_collection__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./utils/collection */ "../pioneer/engine/src/utils/collection.js"); +/* harmony import */ var _utils_dependency_graph__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./utils/dependency_graph */ "../pioneer/engine/src/utils/dependency_graph.js"); +/* harmony import */ var _utils_fast_iterable__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./utils/fast_iterable */ "../pioneer/engine/src/utils/fast_iterable.js"); +/* harmony import */ var _utils_fps__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./utils/fps */ "../pioneer/engine/src/utils/fps.js"); +/* harmony import */ var _utils_freezable__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./utils/freezable */ "../pioneer/engine/src/utils/freezable.js"); +/* harmony import */ var _utils_math_utils__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./utils/math_utils */ "../pioneer/engine/src/utils/math_utils.js"); +/* harmony import */ var _utils_pool__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./utils/pool */ "../pioneer/engine/src/utils/pool.js"); +/* harmony import */ var _utils_reader__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./utils/reader */ "../pioneer/engine/src/utils/reader.js"); +/* harmony import */ var _utils_sort__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./utils/sort */ "../pioneer/engine/src/utils/sort.js"); +/* harmony import */ var _utils_tile__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./utils/tile */ "../pioneer/engine/src/utils/tile.js"); +/* harmony import */ var _utils_time_utils__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./utils/time_utils */ "../pioneer/engine/src/utils/time_utils.js"); +/* harmony import */ var _utils_wait_until__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./utils/wait_until */ "../pioneer/engine/src/utils/wait_until.js"); +/* harmony import */ var _utils_aer__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./utils/aer */ "../pioneer/engine/src/utils/aer.js"); +/* harmony import */ var _utils_color__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./utils/color */ "../pioneer/engine/src/utils/color.js"); +/* harmony import */ var _utils_fast_map__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./utils/fast_map */ "../pioneer/engine/src/utils/fast_map.js"); +/* harmony import */ var _utils_fast_set__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./utils/fast_set */ "../pioneer/engine/src/utils/fast_set.js"); +/* harmony import */ var _utils_geometry__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./utils/geometry */ "../pioneer/engine/src/utils/geometry.js"); +/* harmony import */ var _utils_interval__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./utils/interval */ "../pioneer/engine/src/utils/interval.js"); +/* harmony import */ var _utils_orbital_elements__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./utils/orbital_elements */ "../pioneer/engine/src/utils/orbital_elements.js"); +/* harmony import */ var _utils_rect__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./utils/rect */ "../pioneer/engine/src/utils/rect.js"); +/* harmony import */ var _utils_quaternion__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./utils/quaternion */ "../pioneer/engine/src/utils/quaternion.js"); +/* harmony import */ var _utils_vector2__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./utils/vector2 */ "../pioneer/engine/src/utils/vector2.js"); +/* harmony import */ var _utils_vector3__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./utils/vector3 */ "../pioneer/engine/src/utils/vector3.js"); +/* harmony import */ var _utils_cache__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./utils/cache */ "../pioneer/engine/src/utils/cache.js"); +/* harmony import */ var _utils_component_ref__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./utils/component_ref */ "../pioneer/engine/src/utils/component_ref.js"); +/* harmony import */ var _utils_controller_ref__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./utils/controller_ref */ "../pioneer/engine/src/utils/controller_ref.js"); +/* harmony import */ var _utils_cube_map__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./utils/cube_map */ "../pioneer/engine/src/utils/cube_map.js"); +/* harmony import */ var _utils_entity_ref__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./utils/entity_ref */ "../pioneer/engine/src/utils/entity_ref.js"); +/* harmony import */ var _utils_lat_lon_alt__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./utils/lat_lon_alt */ "../pioneer/engine/src/utils/lat_lon_alt.js"); +/* harmony import */ var _utils_line_mesh__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./utils/line_mesh */ "../pioneer/engine/src/utils/line_mesh.js"); +/* harmony import */ var _utils_material_utils_phong__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ./utils/material_utils_phong */ "../pioneer/engine/src/utils/material_utils_phong.js"); +/* harmony import */ var _utils_material_utils_standard__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ./utils/material_utils_standard */ "../pioneer/engine/src/utils/material_utils_standard.js"); +/* harmony import */ var _utils_material_utils__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ./utils/material_utils */ "../pioneer/engine/src/utils/material_utils.js"); +/* harmony import */ var _utils_shader_fix__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! ./utils/shader_fix */ "../pioneer/engine/src/utils/shader_fix.js"); +/* harmony import */ var _utils_sprite_particles__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! ./utils/sprite_particles */ "../pioneer/engine/src/utils/sprite_particles.js"); +/* harmony import */ var _utils_texture_lod__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! ./utils/texture_lod */ "../pioneer/engine/src/utils/texture_lod.js"); +/* harmony import */ var _utils_three_js_helper__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! ./utils/three_js_helper */ "../pioneer/engine/src/utils/three_js_helper.js"); +/* harmony import */ var _capabilities__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! ./capabilities */ "../pioneer/engine/src/capabilities.js"); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! ./config */ "../pioneer/engine/src/config.js"); +/* harmony import */ var _downloader__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(/*! ./downloader */ "../pioneer/engine/src/downloader.js"); +/* harmony import */ var _engine__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(/*! ./engine */ "../pioneer/engine/src/engine.js"); +/* harmony import */ var _scene_entity__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(/*! ./scene/entity */ "../pioneer/engine/src/scene/entity.js"); +/* harmony import */ var _scene_entity_item__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(/*! ./scene/entity_item */ "../pioneer/engine/src/scene/entity_item.js"); +/* harmony import */ var _input__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(/*! ./input */ "../pioneer/engine/src/input.js"); +/* harmony import */ var _material_manager__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(/*! ./material_manager */ "../pioneer/engine/src/material_manager.js"); +/* harmony import */ var _scene_scene__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(/*! ./scene/scene */ "../pioneer/engine/src/scene/scene.js"); +/* harmony import */ var _texture_loader__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(/*! ./texture_loader */ "../pioneer/engine/src/texture_loader.js"); +/* harmony import */ var _texture_loader_compressed__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(/*! ./texture_loader_compressed */ "../pioneer/engine/src/texture_loader_compressed.js"); +/* harmony import */ var _version__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(/*! ./version */ "../pioneer/engine/src/version.js"); +/* harmony import */ var _viewport__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(/*! ./viewport */ "../pioneer/engine/src/viewport.js"); +/* harmony import */ var _scene_components_base_component__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(/*! ./scene/components/base_component */ "../pioneer/engine/src/scene/components/base_component.js"); +/* harmony import */ var _scene_components_atmosphere_component__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(/*! ./scene/components/atmosphere_component */ "../pioneer/engine/src/scene/components/atmosphere_component.js"); +/* harmony import */ var _scene_components_camera_component__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(/*! ./scene/components/camera_component */ "../pioneer/engine/src/scene/components/camera_component.js"); +/* harmony import */ var _scene_components_cmts_component__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(/*! ./scene/components/cmts_component */ "../pioneer/engine/src/scene/components/cmts_component.js"); +/* harmony import */ var _scene_components_comet_tail_component__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(/*! ./scene/components/comet_tail_component */ "../pioneer/engine/src/scene/components/comet_tail_component.js"); +/* harmony import */ var _scene_components_connected_sprite_component__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(/*! ./scene/components/connected_sprite_component */ "../pioneer/engine/src/scene/components/connected_sprite_component.js"); +/* harmony import */ var _scene_components_div_component__WEBPACK_IMPORTED_MODULE_65__ = __webpack_require__(/*! ./scene/components/div_component */ "../pioneer/engine/src/scene/components/div_component.js"); +/* harmony import */ var _scene_components_dynamic_environment_map_component__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(/*! ./scene/components/dynamic_environment_map_component */ "../pioneer/engine/src/scene/components/dynamic_environment_map_component.js"); +/* harmony import */ var _scene_components_gizmo_component__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(/*! ./scene/components/gizmo_component */ "../pioneer/engine/src/scene/components/gizmo_component.js"); +/* harmony import */ var _scene_components_label_component__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(/*! ./scene/components/label_component */ "../pioneer/engine/src/scene/components/label_component.js"); +/* harmony import */ var _scene_components_light_source_component__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(/*! ./scene/components/light_source_component */ "../pioneer/engine/src/scene/components/light_source_component.js"); +/* harmony import */ var _scene_components_model_component__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(/*! ./scene/components/model_component */ "../pioneer/engine/src/scene/components/model_component.js"); +/* harmony import */ var _scene_components_orbital_particles_component__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(/*! ./scene/components/orbital_particles_component */ "../pioneer/engine/src/scene/components/orbital_particles_component.js"); +/* harmony import */ var _scene_components_particle_spray_component__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(/*! ./scene/components/particle_spray_component */ "../pioneer/engine/src/scene/components/particle_spray_component.js"); +/* harmony import */ var _scene_components_rings_component__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(/*! ./scene/components/rings_component */ "../pioneer/engine/src/scene/components/rings_component.js"); +/* harmony import */ var _scene_components_skybox_component__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(/*! ./scene/components/skybox_component */ "../pioneer/engine/src/scene/components/skybox_component.js"); +/* harmony import */ var _scene_components_spheroid_component__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(/*! ./scene/components/spheroid_component */ "../pioneer/engine/src/scene/components/spheroid_component.js"); +/* harmony import */ var _scene_components_spheroid_lod_component__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(/*! ./scene/components/spheroid_lod_component */ "../pioneer/engine/src/scene/components/spheroid_lod_component.js"); +/* harmony import */ var _scene_components_spout_component__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(/*! ./scene/components/spout_component */ "../pioneer/engine/src/scene/components/spout_component.js"); +/* harmony import */ var _scene_components_sprite_component__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(/*! ./scene/components/sprite_component */ "../pioneer/engine/src/scene/components/sprite_component.js"); +/* harmony import */ var _scene_components_starfield_component__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(/*! ./scene/components/starfield_component */ "../pioneer/engine/src/scene/components/starfield_component.js"); +/* harmony import */ var _scene_components_trail_component__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(/*! ./scene/components/trail_component */ "../pioneer/engine/src/scene/components/trail_component.js"); +/* harmony import */ var _scene_controllers_base_controller__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(/*! ./scene/controllers/base_controller */ "../pioneer/engine/src/scene/controllers/base_controller.js"); +/* harmony import */ var _scene_controllers_align_controller__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(/*! ./scene/controllers/align_controller */ "../pioneer/engine/src/scene/controllers/align_controller.js"); +/* harmony import */ var _scene_controllers_animdata_controller__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(/*! ./scene/controllers/animdata_controller */ "../pioneer/engine/src/scene/controllers/animdata_controller.js"); +/* harmony import */ var _scene_controllers_coverage_controller__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(/*! ./scene/controllers/coverage_controller */ "../pioneer/engine/src/scene/controllers/coverage_controller.js"); +/* harmony import */ var _scene_controllers_dynamo_controller__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(/*! ./scene/controllers/dynamo_controller */ "../pioneer/engine/src/scene/controllers/dynamo_controller.js"); +/* harmony import */ var _scene_controllers_fixed_controller__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(/*! ./scene/controllers/fixed_controller */ "../pioneer/engine/src/scene/controllers/fixed_controller.js"); +/* harmony import */ var _scene_controllers_fixed_to_parent_controller__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(/*! ./scene/controllers/fixed_to_parent_controller */ "../pioneer/engine/src/scene/controllers/fixed_to_parent_controller.js"); +/* harmony import */ var _scene_controllers_free_fly_controller__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(/*! ./scene/controllers/free_fly_controller */ "../pioneer/engine/src/scene/controllers/free_fly_controller.js"); +/* harmony import */ var _scene_controllers_ground_clamp_controller__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(/*! ./scene/controllers/ground_clamp_controller */ "../pioneer/engine/src/scene/controllers/ground_clamp_controller.js"); +/* harmony import */ var _scene_controllers_keyframe_controller__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(/*! ./scene/controllers/keyframe_controller */ "../pioneer/engine/src/scene/controllers/keyframe_controller.js"); +/* harmony import */ var _scene_controllers_look_controller__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(/*! ./scene/controllers/look_controller */ "../pioneer/engine/src/scene/controllers/look_controller.js"); +/* harmony import */ var _scene_controllers_model_animate_controller__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(/*! ./scene/controllers/model_animate_controller */ "../pioneer/engine/src/scene/controllers/model_animate_controller.js"); +/* harmony import */ var _scene_controllers_orbit_controller__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(/*! ./scene/controllers/orbit_controller */ "../pioneer/engine/src/scene/controllers/orbit_controller.js"); +/* harmony import */ var _scene_controllers_orbit_keyframe_controller__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(/*! ./scene/controllers/orbit_keyframe_controller */ "../pioneer/engine/src/scene/controllers/orbit_keyframe_controller.js"); +/* harmony import */ var _scene_controllers_orbital_elements_controller__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(/*! ./scene/controllers/orbital_elements_controller */ "../pioneer/engine/src/scene/controllers/orbital_elements_controller.js"); +/* harmony import */ var _scene_controllers_pick_controller__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(/*! ./scene/controllers/pick_controller */ "../pioneer/engine/src/scene/controllers/pick_controller.js"); +/* harmony import */ var _scene_controllers_roll_controller__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(/*! ./scene/controllers/roll_controller */ "../pioneer/engine/src/scene/controllers/roll_controller.js"); +/* harmony import */ var _scene_controllers_rotate_controller__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(/*! ./scene/controllers/rotate_controller */ "../pioneer/engine/src/scene/controllers/rotate_controller.js"); +/* harmony import */ var _scene_controllers_rotate_by_entity_orientation_controller__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(/*! ./scene/controllers/rotate_by_entity_orientation_controller */ "../pioneer/engine/src/scene/controllers/rotate_by_entity_orientation_controller.js"); +/* harmony import */ var _scene_controllers_scale_controller__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(/*! ./scene/controllers/scale_controller */ "../pioneer/engine/src/scene/controllers/scale_controller.js"); +/* harmony import */ var _scene_controllers_select_controller__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(/*! ./scene/controllers/select_controller */ "../pioneer/engine/src/scene/controllers/select_controller.js"); +/* harmony import */ var _scene_controllers_set_parent_controller__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(/*! ./scene/controllers/set_parent_controller */ "../pioneer/engine/src/scene/controllers/set_parent_controller.js"); +/* harmony import */ var _scene_controllers_spin_controller__WEBPACK_IMPORTED_MODULE_103__ = __webpack_require__(/*! ./scene/controllers/spin_controller */ "../pioneer/engine/src/scene/controllers/spin_controller.js"); +/* harmony import */ var _scene_controllers_tap_controller__WEBPACK_IMPORTED_MODULE_104__ = __webpack_require__(/*! ./scene/controllers/tap_controller */ "../pioneer/engine/src/scene/controllers/tap_controller.js"); +/* harmony import */ var _scene_controllers_transition_controller__WEBPACK_IMPORTED_MODULE_105__ = __webpack_require__(/*! ./scene/controllers/transition_controller */ "../pioneer/engine/src/scene/controllers/transition_controller.js"); +/* harmony import */ var _scene_controllers_translate_controller__WEBPACK_IMPORTED_MODULE_106__ = __webpack_require__(/*! ./scene/controllers/translate_controller */ "../pioneer/engine/src/scene/controllers/translate_controller.js"); +/* harmony import */ var _scene_controllers_zoom_controller__WEBPACK_IMPORTED_MODULE_107__ = __webpack_require__(/*! ./scene/controllers/zoom_controller */ "../pioneer/engine/src/scene/controllers/zoom_controller.js"); +/* harmony import */ var _scene_types__WEBPACK_IMPORTED_MODULE_108__ = __webpack_require__(/*! ./scene/types */ "../pioneer/engine/src/scene/types.js"); +// Three.js + + + + + + + + +// Shader Chunks + + +// Utils with 0 dependencies + + + + + + + + + + + + + + +// Utils with only one of the above dependencies. + + + + + + + + + + + + +// Utils with only one of the above dependencies. + + + + + + + + + + + + + + + +// Core + + + + + + + + + + + + + + +// Components + + + + + + + + + + + + + + + + + + + + + + + +// Controllers + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// The types that imports all of the above components and controllers. + + + +/***/ }), + +/***/ "../pioneer/engine/src/material_manager.js": +/*!*************************************************!*\ + !*** ../pioneer/engine/src/material_manager.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "MaterialManager": function() { return /* binding */ MaterialManager; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal */ "../pioneer/engine/src/internal.js"); +/* harmony import */ var _shaders_basic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./shaders/basic */ "../pioneer/engine/src/shaders/basic.js"); +/* harmony import */ var _shaders_basic_alpha__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./shaders/basic_alpha */ "../pioneer/engine/src/shaders/basic_alpha.js"); +/* harmony import */ var _shaders_connected_sprite__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./shaders/connected_sprite */ "../pioneer/engine/src/shaders/connected_sprite.js"); +/* harmony import */ var _shaders_line__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./shaders/line */ "../pioneer/engine/src/shaders/line.js"); +/* harmony import */ var _shaders_plumes__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./shaders/plumes */ "../pioneer/engine/src/shaders/plumes.js"); +/* harmony import */ var _shaders_sprite__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./shaders/sprite */ "../pioneer/engine/src/shaders/sprite.js"); +/* harmony import */ var _shaders_sprite_particles__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./shaders/sprite_particles */ "../pioneer/engine/src/shaders/sprite_particles.js"); +/* harmony import */ var _shaders_trail__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./shaders/trail */ "../pioneer/engine/src/shaders/trail.js"); +/** @module pioneer */ + + +// Preloaded shaders. + + + + + + + + + +/** + * A generic resource. + * @template Type + */ +class Resource { + /** + * Constructs the class. + * @param {Type} value + */ + constructor(value) { + /** + * The value of the resource. + * @type {Type} + */ + this.value = value; + + /** + * How many of this resource are currently being used. + * @type {number} + */ + this.useCount = 0; + } +} + +/** + * Material manager. Constructs materials from nodes. + */ +class MaterialManager { + /** + * @param {Downloader} downloader + */ + constructor(downloader) { + /** + * The downloader. + * @type {Downloader} + * @private + */ + this._downloader = downloader; + + /** + * A mapping from urls to materials. + * @type {Map>} + * @private + */ + this._cache = new Map(); + + /** + * A mapping from cloned materials to the urls. + * @type {Map} + * @private + */ + this._clonedMaterials = new Map(); + + /** + * A mapping from urls to promises that resolve to materials. + * @type {Map>>} + * @private + */ + this._promises = new Map(); + + // Preload node types that are required for the built-in components. + this._preload(); + } + + /** + * Gets a material. + * @param {string} url + * @returns {Promise} + */ + async get(url) { + // If it is already loaded, return a resolved promise. + let resource = this._cache.get(url); + + // If it is loading right now, return the existing promise. + if (resource === undefined) { + const promise = this._promises.get(url); + if (promise !== undefined) { + resource = await promise; + } + } + + // Load the material. + if (resource === undefined) { + const download = await this._downloader.download(url, false); + if (download.status !== 'completed' || typeof download.content !== 'string') { + throw new Error('Failed to download material "' + url + '".'); + } + const obj = JSON.parse(download.content); + resource = new Resource(await this._load(url, obj)); + this._cache.set(url, resource); + } + + // Increment the use count and return it. + resource.useCount += 1; + return this._clone(resource.value, url); + } + + /** + * Gets a pre-loaded material without using promises. + * @param {string} url + * @returns {THREE.RawShaderMaterial} + */ + getPreloaded(url) { + // If it is already loaded, return a resolved promise. + const resource = this._cache.get(url); + if (resource === undefined) { + throw new Error('Invalid pre-loaded material "' + url + '".'); + } + resource.useCount += 1; + return this._clone(resource.value, url); + } + + /** + * Releases a material, unloading it if necessary. + * @param {THREE.RawShaderMaterial} material + */ + release(material) { + // Get the url from the material. + const url = this._clonedMaterials.get(material); + if (url === undefined) { + return; + } + // Remove the cloned material. + this._clonedMaterials.delete(material); + // Get the resource from the url. + const resource = this._cache.get(url); + if (resource) { + resource.useCount -= 1; + // If it isn't be used by anyone, unload the original material. + if (resource.useCount === 0) { + this._unload(resource.value); + this._cache.delete(url); + } + } + } + + /** + * Unloads a material. + * @param {THREE.RawShaderMaterial} material + * @private + */ + _unload(material) { + const uniforms = material.uniforms; + for (const uniform in uniforms) { + if (Object.prototype.hasOwnProperty.call(uniforms, uniform) && uniforms[uniform].value !== null && uniforms[uniform].value.dispose !== undefined) { + uniforms[uniform].value.dispose(); + } + } + material.dispose(); + } + + /** + * Preloads a given list of shaders for quick access in the engine. + * @private + */ + _preload() { + // Declare the preloaded shaders. + /** @type {Map} */ + const shaders = new Map(); + shaders.set('basic', _shaders_basic__WEBPACK_IMPORTED_MODULE_1__.BasicShader); + shaders.set('basic_alpha', _shaders_basic_alpha__WEBPACK_IMPORTED_MODULE_2__.BasicAlphaShader); + shaders.set('connected_sprite', _shaders_connected_sprite__WEBPACK_IMPORTED_MODULE_3__.ConnectedSpriteShader); + shaders.set('line', _shaders_line__WEBPACK_IMPORTED_MODULE_4__.LineShader); + shaders.set('plumes', _shaders_plumes__WEBPACK_IMPORTED_MODULE_5__.PlumesShader); + shaders.set('sprite', _shaders_sprite__WEBPACK_IMPORTED_MODULE_6__.SpriteShader); + shaders.set('sprite_particles', _shaders_sprite_particles__WEBPACK_IMPORTED_MODULE_7__.SpriteParticlesShader); + shaders.set('trail', _shaders_trail__WEBPACK_IMPORTED_MODULE_8__.TrailShader); + + // Load them. + for (const [name, json] of shaders) { + const material = this._load(name, json); + const resource = new Resource(material); + resource.useCount += 1; + this._cache.set(name, resource); + } + } + + /** + * Loads a shader from JSON. + * @param {string} url + * @param {any} json + * @returns {THREE.RawShaderMaterial} + * @private + */ + _load(url, json) { + try { + // Generate ThreeJS uniform objects + /** @type {Object} */ + const uniforms = {}; + if (json.uniforms) { + for (const [name, type] of Object.entries(json.uniforms)) { + // Don't add the Three.js pre-defined uniforms, because they would overwrite them when rendering. + if (['modelMatrix', 'modelViewMatrix', 'projectionMatrix', 'viewMatrix', 'normalMatrix', 'cameraPosition'].includes(name)) { + continue; + } + uniforms[name] = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._getUniformValueFromType(type)); + } + } + + // Process some properties. + let transparent = false; + let depthWrite = true; + let side = /** @type {THREE.Side} */(_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.FrontSide); + let blending = /** @type {THREE.Blending} */(_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NoBlending); + if (json.properties) { + if (json.properties.transparent === true) { + transparent = true; + } + if (json.properties.depthWrite === false) { + depthWrite = false; + } + switch (json.properties.side) { + case 'front': side = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.FrontSide; break; + case 'back': side = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BackSide; break; + case 'double': side = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide; break; + } + switch (json.properties.blending) { + case 'normal': blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NormalBlending; break; + case 'additive': blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.AdditiveBlending; break; + case 'subtractive': blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.SubtractiveBlending; break; + case 'multiply': blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.MultiplyBlending; break; + case 'custom': blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CustomBlending; break; + } + } + + // Check for required code. + if (typeof json.vertex !== 'object' || typeof json.vertex.code !== 'string') { + throw new Error('Missing vertex stage code.'); + } + if (typeof json.fragment !== 'object' || typeof json.fragment.code !== 'string') { + throw new Error('Missing fragment stage code.'); + } + + // Set the extension code. + if (Array.isArray(json.vertex.extensions)) { + let extensionCode = ''; + for (const extension of json.vertex.extensions) { + if (_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasGLExtension(extension)) { + extensionCode += '#extension GL_' + extension + ': enable\n'; + } + } + for (const extension of json.vertex.extensions) { + if (_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasGLExtension(extension)) { + extensionCode += '#define L_' + extension + ' true\n'; + } + if (_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.isWebGL2() && extension === 'EXT_frag_depth') { + extensionCode += '#define L_' + extension + ' true\n'; + } + } + json.vertex.code = extensionCode + json.vertex.code; + } + if (Array.isArray(json.fragment.extensions)) { + let extensionCode = ''; + for (const extension of json.fragment.extensions) { + if (_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasGLExtension(extension)) { + extensionCode += '#extension GL_' + extension + ': enable\n'; + } + } + for (const extension of json.fragment.extensions) { + if (_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasGLExtension(extension)) { + extensionCode += '#define L_' + extension + ' true\n'; + } + } + json.fragment.code = extensionCode + json.fragment.code; + } + + // Create the material. + const material = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RawShaderMaterial({ + uniforms, + vertexShader: json.vertex.code, + fragmentShader: json.fragment.code, + transparent: transparent, + depthWrite: depthWrite, + side: side, + blending: blending, + glslVersion: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.GLSL3 + }); + _internal__WEBPACK_IMPORTED_MODULE_0__.ShaderFix.fix(material); + material.needsUpdate = true; + + // Return the loaded material. + return material; + } + catch (e) { + if (e instanceof Error) { + e.message = `While processing material "${url}": ${e.message}`; + } + throw e; + } + } + + /** + * Gets a uniform value from the type. + * @param {string} type + * @returns {any} + * @private + */ + _getUniformValueFromType(type) { + type = type.replace(/.* /, ''); + switch (type) { + case 'int': + case 'float': + return 0; + case 'ivec2': + case 'vec2': + return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(0, 0); + case 'ivec3': + case 'vec3': + return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0); + case 'ivec4': + case 'vec4': + return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4(0, 0, 0, 0); + case 'mat3': + return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix3(); + case 'mat4': + return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix4(); + case 'sampler2D': + return null; + case 'samplerCube': + return null; + } + if (type.endsWith(']')) { + const indexOfOpenBracket = type.indexOf('['); + const indexOfCloseBracket = type.indexOf(']'); + const baseType = type.substring(0, indexOfOpenBracket); + const numElements = Number.parseInt(type.substring(indexOfOpenBracket + 1, indexOfCloseBracket)); + const array = []; + for (let i = 0; i < numElements; i++) { + array.push(this._getUniformValueFromType(baseType)); + } + return array; + } + throw new Error('Unrecognized type: ' + type + '.'); + } + + /** + * Clones a material. + * @param {THREE.RawShaderMaterial} material + * @param {string} url + * @returns {THREE.RawShaderMaterial} + * @private + */ + _clone(material, url) { + // Use the built-in Three.js material clone. + const newMaterial = material.clone(); + + // Manually clone array uniforms of Three.js objects, since Three.js doesn't do this (see https://github.com/mrdoob/three.js/issues/16080). + for (const [name, uniform] of Object.entries(material.uniforms)) { + const value = uniform.value; + if (Array.isArray(value)) { + const value0 = value[0]; + if (value0 && (value0.isColor || value0.isMatrix3 || value0.isMatrix4 + || value0.isVector2 || value0.isVector3 || value0.isVector4 + || value0.isTexture)) { + material.uniforms[name].value = []; + for (let i = 0; i < value.length; i++) { + material.uniforms[name].value[i] = value[i].clone(); + } + } + } + } + + // Make sure the new material is updated. + newMaterial.needsUpdate = true; + + // Add to the cloned materials list so that it can be found during the release. + this._clonedMaterials.set(newMaterial, url); + + return newMaterial; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/atmosphere_component.js": +/*!**********************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/atmosphere_component.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AtmosphereComponent": function() { return /* binding */ AtmosphereComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * An atmosphere over a component with a spheroid. + */ +class AtmosphereComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The density of the atmosphere at sea level. + * @type {number} + * @private + */ + this._density = 0.0; + + /** + * The scale height of the atmosphere. + * @type {number} + * @private + */ + this._scaleHeight = 1.0; + + /** + * The emissivity of the atmosphere. 0 means not emissive and 1 means 100% emissive. + * @type {number} + * @private + */ + this._emissivity = 0.0; + + /** + * The base color of the atmosphere. + * @type {Color} + * @private + */ + this._color = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(); + this._color.freeze(); + + /** + * The brightness of the sun in the sky when looking through the atmosphere. + * @type {number} + * @private + */ + this._sunBrightness = 1.0; + + /** + * The sunset color of the atmosphere. + * @type {Color} + * @private + */ + this._sunsetColor = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(); + this._sunsetColor.freeze(); + + /** + * The sunset intensity of the atmosphere. + * @type {number} + * @private + */ + this._sunsetIntensity = 0.0; + + /** + * A reference to the spheroid component. + * @type {ComponentRef} + * @private + */ + this._spheroidComponentRef = new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene()); + this._spheroidComponentRef.setByType(this.getEntity().getName(), 'spheroid'); + this._spheroidComponentRef.setRefChangedCallback(this._spheroidRefChangedCallback.bind(this)); + + // Bind the callbacks to this. + this._spheroidChangedCallback = this._spheroidChangedCallback.bind(this); + + // It aligns with the entity's orientation. + this.__setUsesEntityOrientation(true); + } + + /** + * Gets the spheroid that this uses. + * @returns {SpheroidComponent} + */ + getSpheroid() { + return this._spheroidComponentRef.get(); + } + + /** + * Gets the density of the atmosphere at sea level. + * @returns {number} + */ + getDensity() { + return this._density; + } + + /** + * Sets the density of the atmosphere at sea level. + * @param {number} density + */ + setDensity(density) { + this._density = density; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'density', density); + } + + /** + * Gets the scale height of the atmosphere. + * @returns {number} + */ + getScaleHeight() { + return this._scaleHeight; + } + + /** + * Sets the scale height of the atmosphere. + * @param {number} scaleHeight + */ + setScaleHeight(scaleHeight) { + this._scaleHeight = scaleHeight; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'scaleHeight', scaleHeight); + } + + /** + * Gets the emissivity of the atmosphere. 0 means not emissive and 1 means 100% emissive. Defaults to 0. + * @returns {number} + */ + getEmissivity() { + return this._emissivity; + } + + /** + * Sets the emissivity of the atmosphere. + * @param {number} emissivity + */ + setEmissivity(emissivity) { + this._emissivity = emissivity; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'emissivity', emissivity); + } + + /** + * Gets the base color of the atmosphere. Default is white. + * @returns {Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the base color of the atmosphere. Default is white. + * @param {Color} color + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGB(this.getThreeJsMaterials()[0], 'color', color); + } + + /** + * Gets the brightness of the sun in the sky when looking through the atmosphere. + * @returns {number} + */ + getSunBrightness() { + return this._sunBrightness; + } + + /** + * Sets the brightness of the sun in the sky when looking through the atmosphere. + * @param {number} sunBrightness + */ + setSunBrightness(sunBrightness) { + this._sunBrightness = sunBrightness; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'sunBrightness', sunBrightness); + } + + /** + * Gets the sunset color of the atmosphere. Default is white. + * @returns {Color} + */ + getSunsetColor() { + return this._sunsetColor; + } + + /** + * Sets the sunset color of the atmosphere. Default is white. + * @param {Color} sunsetColor + */ + setSunsetColor(sunsetColor) { + this._sunsetColor.thaw(); + this._sunsetColor.copy(sunsetColor); + this._sunsetColor.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGB(this.getThreeJsMaterials()[0], 'sunsetColor', sunsetColor); + } + + /** + * Gets the sunset intensity of the atmosphere. Default is 0. + * @returns {number} + */ + getSunsetIntensity() { + return this._sunsetIntensity; + } + + /** + * Sets the sunset intensity of the atmosphere. Default is 0. + * @param {number} sunsetIntensity + */ + setSunsetIntensity(sunsetIntensity) { + this._sunsetIntensity = sunsetIntensity; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'sunsetIntensity', sunsetIntensity); + } + + /** + * Sets the reference to use for the spheroid component, by name or the type index. + * @param {string | number} nameOrTypeIndex + */ + setSpheroidReference(nameOrTypeIndex) { + if (typeof nameOrTypeIndex === 'string') { + this._spheroidComponentRef.setByName(this.getEntity().getName(), nameOrTypeIndex); + } + else { + this._spheroidComponentRef.setByType(this.getEntity().getName(), 'spheroid', nameOrTypeIndex); + } + } + + /** + * Cleans up the component. + * @override + * @package + */ + __destroy() { + // Remove the spheroid changed callback. + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent !== null) { + spheroidComponent.removeChangedCallback(this._spheroidChangedCallback); + } + + super.__destroy(); + } + + /** + * Updates the camera-non-specific parts of the component. + * @override + * @internal + */ + __update() { + // Update the spheroid component reference. + this._spheroidComponentRef.update(); + } + + /** + * Prepare the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + // Set the camera position uniform. + const cameraPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + cameraPosition.neg(this.getEntity().getCameraSpacePosition(camera)); + cameraPosition.rotateInverse(this.getEntity().getOrientation(), cameraPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'cameraPosition', cameraPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraPosition); + + // Set the lightPosition and lightColor uniform. + _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setLightSourceUniforms(this.getThreeJsMaterials(), this.getEntity(), camera); + + // Set the entity's orientation to get the lights into the entity-space. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformQuaternion(this.getThreeJsMaterials()[0], 'entityOrientation', this.getEntity().getOrientation()); + + // Set the orientation to the entity's orientation. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0], this.getEntity()); + + // Set the Three.js object position the entity's camera-space position. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + // Create the material. + const material = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RawShaderMaterial({ + uniforms: { + lightPositions: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0)]), + lightColors: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0)]), + lightRadii: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0, 0, 0, 0, 0]), + numLights: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + + density: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._density), + scaleHeight: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._scaleHeight), + emissivity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._emissivity), + equatorialRadius: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1.0), + polarRadius: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1.0), + cameraPosition: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0)), + entityOrientation: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4(1, 0, 0, 0)), + color: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(this._color.r, this._color.g, this._color.b)), + sunBrightness: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._sunBrightness), + sunsetColor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(this._sunsetColor.r, this._sunsetColor.g, this._sunsetColor.b)), + sunsetIntensity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._sunsetIntensity), + + ..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms + }, + vertexShader: vertexShader, + fragmentShader: fragmentShader, + transparent: true, + depthWrite: false, + blending: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NormalBlending + }); + _internal__WEBPACK_IMPORTED_MODULE_0__.ShaderFix.fix(material); + this.getThreeJsMaterials().push(material); + + const object = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this, material, [{ name: 'position', dimensions: 3 }], false); + this.getThreeJsObjects().push(object); + + // Create the mesh itself. + const numLatVerts = 64; + const numLonVerts = 128; + const latStep = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi / (numLatVerts - 1); + const lonStep = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi / numLonVerts; + const numVerts = (numLonVerts + 1) * numLatVerts; + const meshPositions = new Float32Array(numVerts * 3); + const meshIndices = new Uint16Array(numLonVerts * (numLatVerts - 1) * 6); + const xyz = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + for (let latI = 0; latI < numLatVerts; latI++) { + lla.lat = latI * latStep - _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi; + lla.alt = 0; + const cosLat = Math.cos(lla.lat); + const sinLat = Math.sin(lla.lat); + for (let lonI = 0; lonI < numLonVerts + 1; lonI++) { + lla.lon = lonI * lonStep - _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi; + + const vertexI = latI * (numLonVerts + 1) + lonI; + meshPositions[vertexI * 3 + 0] = cosLat * Math.cos(lla.lon); + meshPositions[vertexI * 3 + 1] = cosLat * Math.sin(lla.lon); + meshPositions[vertexI * 3 + 2] = sinLat; + + const triangleI = latI * numLonVerts + lonI; + if (latI < numLatVerts - 1 && lonI < numLonVerts) { + meshIndices[triangleI * 6 + 0] = (numLonVerts + 1) * (latI + 0) + (lonI + 0); + meshIndices[triangleI * 6 + 1] = (numLonVerts + 1) * (latI + 1) + (lonI + 0); + meshIndices[triangleI * 6 + 2] = (numLonVerts + 1) * (latI + 1) + (lonI + 1); + meshIndices[triangleI * 6 + 3] = (numLonVerts + 1) * (latI + 0) + (lonI + 0); + meshIndices[triangleI * 6 + 4] = (numLonVerts + 1) * (latI + 1) + (lonI + 1); + meshIndices[triangleI * 6 + 5] = (numLonVerts + 1) * (latI + 0) + (lonI + 1); + } + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(xyz); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(object.geometry, 'position', meshPositions); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(object.geometry, meshIndices); + + // Make it render before other transparent objects. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setRenderOrder(object, -1); + + // Make it used in the dynamic environment map. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.useInDynEnvMap(object, true); + + // Update from the spheroid properties. + this._spheroidChangedCallback(); + + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + } + + /** + * Callback called when the spheroid reference is found or lost. + * @param {SpheroidComponent} oldRef + * @param {SpheroidComponent} newRef + * @private + */ + _spheroidRefChangedCallback(oldRef, newRef) { + if (oldRef !== null) { + oldRef.removeChangedCallback(this._spheroidChangedCallback); + } + if (newRef !== null) { + newRef.addChangedCallback(this._spheroidChangedCallback); + } + this._spheroidChangedCallback(); + } + + /** + * Callback to be called when the spheroid component changed. + * @private + */ + _spheroidChangedCallback() { + // Set the radii uniforms. + const spheroidComponent = this._spheroidComponentRef.get(); + const material = this.getThreeJsMaterials()[0]; + if (spheroidComponent !== null) { + // Set the radii. + this.__setRadius(Math.max(spheroidComponent.getEquatorialRadius(), spheroidComponent.getPolarRadius())); + // Set the radii uniforms. + if (material !== undefined) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'equatorialRadius', spheroidComponent.getEquatorialRadius()); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'polarRadius', spheroidComponent.getPolarRadius()); + } + } + else { + this.__setRadius(0); + if (material !== undefined) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'equatorialRadius', 0); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'polarRadius', 0); + } + } + } +} + +const vertexShader = ` + attribute vec3 position; + uniform mat4 projectionMatrix; + uniform mat4 modelViewMatrix; + + uniform float scaleHeight; + uniform float equatorialRadius; + uniform float polarRadius; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + varying vec3 localPosition; + + void main() { + float scaleHeightMultiplier = 20.0; + localPosition = vec3(position.x * (equatorialRadius + scaleHeight * scaleHeightMultiplier), position.y * (equatorialRadius + scaleHeight * scaleHeightMultiplier), position.z * (polarRadius + scaleHeight * scaleHeightMultiplier)); + vec4 viewPosition = modelViewMatrix * vec4(localPosition, 1.); + gl_Position = projectionMatrix * viewPosition; + gl_Position.w = viewPosition.y; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`; + +const fragmentShader = ` + precision highp float; + + uniform vec3 lightPositions[5]; + uniform vec3 lightColors[5]; + uniform int numLights; + + uniform float density; + uniform float scaleHeight; + uniform float equatorialRadius; + uniform float polarRadius; + uniform vec3 cameraPosition; + uniform vec4 entityOrientation; + uniform vec3 color; + uniform float emissivity; + uniform float sunBrightness; + uniform vec3 sunsetColor; + uniform float sunsetIntensity; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + varying vec3 localPosition; + + const int numIterations = 5; + + // Inverse rotate a vector by a quaternion. + vec3 quatRotInv(vec4 q, vec3 v) { + float tx = q.w * v.x - q.y * v.z + q.z * v.y; + float ty = q.w * v.y - q.z * v.x + q.x * v.z; + float tz = q.w * v.z - q.x * v.y + q.y * v.x; + float tw = q.x * v.x + q.y * v.y + q.z * v.z; + float x = tx * q.w + tw * q.x + ty * q.z - tz * q.y; + float y = ty * q.w + tw * q.y + tz * q.x - tx * q.z; + float z = tz * q.w + tw * q.z + tx * q.y - ty * q.x; + return vec3(x, y, z); + } + + // Given an origin and direction, computes the sampling start and end as distance from the origin in the direction. + void getStartEndSamples(out float start, out float end, vec3 origin, vec3 direction, float maxDistance, float groundRadius, float atmosphereScaleHeight) { + // Get the along the ray perpendicular to the sphere. + float perpD = -dot(origin, direction); + vec3 perp = origin + direction * perpD; + + // Figure out the sample distance. + float atmosphereRadius = groundRadius + atmosphereScaleHeight * 6.0; + float chordHalfLength = sqrt(max(0.0, atmosphereRadius * atmosphereRadius - dot(perp, perp))); + + // Figure out starting and ending sample points, and step distance. + start = max(0.0, perpD - chordHalfLength); + end = min(maxDistance, perpD + chordHalfLength); + } + + // Gets the density of the atmosphere at a given position. + float getDensity(vec3 position, float radius, float density, float atmosphereScaleHeight) { + return density * exp(min(radius - length(position), 0.0) / atmosphereScaleHeight); + } + + // Returns 0 if the ray does not intersect and 1.0 if the ray very intersects (with a gradient inbetween). + float getDayLevel(vec3 origin, vec3 direction, float radius, float scaleHeight) { + float blendHeight = scaleHeight * radius / 200.0; + float perpD = -dot(origin, direction); + float depth = radius - sqrt(dot(origin, origin) - sign(perpD) * perpD * perpD); + if (depth < 0.0) { // day + return 1.0 - max(0.0, 0.25 * depth / blendHeight + 0.25); + } + else { // night + return 1.0 - min(1.0, 0.75 * depth / blendHeight + 0.25); + } + } + + float easeInOut(float x, float sharpness) { + float b = sharpness; + if (x < 0.5) { + return max(0.0, (pow(b, 2.0 * x) - 1.0) / (2.0 * (b - 1.0))); + } + else { + return min(1.0, 1.0 - (pow(b, 2.0 * (1.0 - x)) - 1.0) / (2.0 * (b - 1.0))); + } + } + + vec3 adjustOverbrightness(vec3 color) { + float maxColor = max(color.r, max(color.g, color.b)); + if (maxColor > 1.0) { + float f = (maxColor - 1.0) / maxColor; + color.r = min(1.0, pow(color.r / maxColor, 1.0 / maxColor)); + color.g = min(1.0, pow(color.g / maxColor, 1.0 / maxColor)); + color.b = min(1.0, pow(color.b / maxColor, 1.0 / maxColor)); + } + return color; + } + + // Calculates a glow around the light direction (the star). + float glow(float spread, float amount, float lightDotCamera) { + return amount * spread / (1.0 + spread - lightDotCamera); + } + + vec4 getEmissiveColor(float totalDensity, vec3 cameraPositionS, vec3 color, float emissivity) { + + // The color that will be added onto gl_FragColor. + vec4 outColor; + + // Apply the total density to the transparency of the atmosphere. + outColor.a = emissivity * clamp(totalDensity, 0.0, 1.0); + + // Multiply it all together with the source light color. + outColor.rgb = emissivity * color * clamp(pow(15.0 * totalDensity / (density * equatorialRadius), 0.2), 0.75, 1.0); + + // Make it more opaque when lower down. + outColor.a = mix(outColor.a, emissivity, getDensity(cameraPositionS, equatorialRadius + scaleHeight, 1.0, 2.0 * scaleHeight)); + + // Clamp it to make it clean for the day/night transition. + outColor.a = clamp(outColor.a, 0.0, 1.0); + + return outColor; + } + + // Gets the color for an atmosphere for a light. + vec4 getColor(float totalDensity, vec3 lightColor, vec3 lightPosition, float spheroidRatio, vec3 positionS, vec3 cameraPositionS, vec3 cameraToPositionUnit) { + + // The color starts out in full brightness (as if emissivity was 1.0). + vec4 outColor = getEmissiveColor(totalDensity, cameraPositionS, lightColor * color, 1.0); + + // Make the alpha dependent on the brightness of the light. + outColor.a *= length(lightColor) / sqrt(3.0); + + // Setup vectors. + highp vec3 lightPositionS = quatRotInv(entityOrientation, lightPosition); + lightPositionS.z *= spheroidRatio; + highp vec3 lightToPosition = positionS - lightPositionS; + highp vec3 lightToPositionUnit = normalize(lightToPosition / 1.0e8); + + // Get the day level, from 0 to 1, and apply it to the alpha. Lots of tricks to get it looking good on earth. + vec3 dayRefUp = normalize(cameraPositionS - min(0.0, dot(cameraPositionS, cameraToPositionUnit)) * cameraToPositionUnit); + float dayLevel = -dot(lightToPositionUnit, dayRefUp); + outColor.rgb *= easeInOut(0.5 + 2.0 * dayLevel, 2.0); + outColor.a *= easeInOut(1.0 + 2.0 * dayLevel, 2.0); + + // Brighten up the atmosphere when looking from space toward the sun. + float lightDotCamera = max(0.0, -dot(lightToPositionUnit, cameraToPositionUnit)); + outColor.a = clamp(outColor.a * (1.0 + glow(0.004, 1.0, lightDotCamera)), 0.0, 1.0); + + // Add narrower sun glare. + outColor.rgb *= lightColor * (1.0 + sunBrightness * outColor.a * glow(0.00004, 1.0, lightDotCamera)); + + // Add broader sun glare. + outColor.rgb *= lightColor * (1.0 + sunBrightness * outColor.a * glow(0.04, 0.125, lightDotCamera)); + + // Apply the sunset. + float lightDotHorizon = pow(clamp(1.0 - dot(lightToPositionUnit, dayRefUp), 0.0, 1.0), 2.0); + float cameraDotHorizon = pow(clamp(1.0 - dot(cameraToPositionUnit, dayRefUp), 0.0, 1.0), 8.0); + float sunsetAmount = sunsetIntensity * lightDotHorizon * cameraDotHorizon * glow(0.04, 0.5, lightDotCamera); + outColor.rgb = mix(outColor.rgb, sunsetColor, clamp(sunsetAmount, 0.0, 1.0)); + + return outColor; + } + + void main(void) { + // Convert everything into a sphere frame. + float spheroidRatio = equatorialRadius / polarRadius; + highp vec3 positionS = localPosition; + highp vec3 cameraPositionS = cameraPosition; + positionS.z *= spheroidRatio; + cameraPositionS.z *= spheroidRatio; + + highp vec3 cameraToPosition = positionS - cameraPositionS; + float cameraToPositionDist = length(cameraToPosition / 1.0e8) * 1.0e8; + highp vec3 cameraToPositionUnit = cameraToPosition / cameraToPositionDist; + + // Get the start and end of the sampling from the camera to the position. + float start; + float end; + getStartEndSamples(start, end, cameraPositionS, cameraToPositionUnit, 1.0e24, equatorialRadius, scaleHeight); + float fracPerStep = 1.0 / float(numIterations - 1); + float stepDist = fracPerStep * (end - start); + + // Do the sampling. + float totalDensity = 0.0; + float segmentStart = start; + for (int j = 0; j < numIterations; j++) { + // Get the distance that this segment covers. + float segDist = stepDist; + if (j == 0 || j == numIterations - 1) { + segDist *= 0.5; + } + + // Get the segment start that we're looking at. + vec3 p = cameraPositionS + segmentStart * cameraToPositionUnit; + + // Get the density at that segment start. It'll be the density for the whole segment. + float densityAtP = getDensity(p, equatorialRadius, density, scaleHeight); + + // Add it to the total density. + totalDensity += densityAtP * segDist; + + // Next step. + segmentStart += stepDist; + } + + // Add emissivity lightness. + gl_FragColor += getEmissiveColor(totalDensity, cameraPositionS, color, emissivity); + + // For each light, + for (int i = 0; i < 5; i++) { + if (i >= numLights) { + break; + } + + // If it's not a camera light, + if (length(lightPositions[i]) > 0.0) { + // Add on the color for the light. + gl_FragColor += getColor(totalDensity, lightColors[i], lightPositions[i], spheroidRatio, positionS, cameraPositionS, cameraToPositionUnit); + } + } + + // Adjust for values that are greater than one. + gl_FragColor.rgb = adjustOverbrightness(gl_FragColor.rgb); + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`; + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/base_component.js": +/*!****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/base_component.js ***! + \****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "BaseComponent": function() { return /* binding */ BaseComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The base class for all components. + * */ +class BaseComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.EntityItem { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The radius of the component. + * @type {number} + * @private + */ + this._radius = 0.5; + + /** + * The pixel-space radius of the component for each camera. + * @type {FastMap} + * @private + */ + this._pixelSpaceRadiusPerCamera = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The greatest pixel-space radius of the component in any camera. + * @type {number} + * @private + */ + this._greatestPixelSpaceRadius = 0.0; + + /** + * The load state of the component. It can be 'unloaded', 'loading', or 'loaded'. + * @type {'unloaded' | 'loading' | 'loaded'} + * @private + */ + this._loadState = 'unloaded'; + + /** + * A flag that determines if the component should always be loaded, except if disabled. + * @type {boolean} + * @private + */ + this._forceLoaded = false; + + /** + * A callback that is called right after the mesh has been created and materials have been loaded. + * @type {() => any} + * @private + */ + this._resourcesLoadedCallback = null; + + /** + * A callback that is called right after the mesh is destroyed. + * @type {() => any} + * @private + */ + this._resourcesUnloadedCallback = null; + + /** + * A promise that resolves when the resources are loaded. + * @type {Promise} + * @private + */ + this._loadedPromise = Promise.resolve(); + + /** + * Camera exclusion list. + * @type {Set} + * @private + */ + this._excludedCameras = new Set(); + + /** + * Whether or not the component is visible. It will still be enabled and run, just not render. + * @type {boolean} + * @private + */ + this._visible = true; + + /** + * The Three.js objects. + * @type {THREE.Object3D[]} + * @private + */ + this._threeJsObjects = []; + + /** + * The Three.js materials. + * @type {THREE.ShaderMaterial[]} + * @private + */ + this._threeJsMaterials = []; + + /** + * The flag that if true sets the root Three.js objects to have the same orientation as the entity. + * @type {boolean} + * @private + */ + this._usesEntityOrientation = false; + } + + /** + * Cleans up the component. + * @override + * @internal + */ + __destroy() { + // Unload any resources used by the component. + if (this._loadState === 'loaded') { + this._unloadResources(); + } + // Call the super. + super.__destroy(); + } + + // ENABLED & DISABLED. + + /** + * Sets whether the component is enabled by the user. If false, __update and __prepareForRender will not run. + * Defaults to true. + * @param {boolean} enabled + * @override + */ + setEnabled(enabled) { + super.setEnabled(enabled); + this.__updateLoadState(); + } + + // RADIUS. + + /** + * Gets the radius of the component. No part of the component should be outside this. + * @returns {number} + */ + getRadius() { + return this._radius; + } + + /** + * Sets the radius of the component. No part of the component should be outside this. Defaults to 0.5; + * @param {number} radius + * @protected + */ + __setRadius(radius) { + this._radius = radius; + } + + /** + * Gets the pixel-space radius in a specific camera. + * @param {CameraComponent} camera + * @returns {number | undefined} + */ + getPixelSpaceRadiusInCamera(camera) { + return this._pixelSpaceRadiusPerCamera.get(camera); + } + + /** + * Gets the greatest pixel-space radius in all cameras. + * @returns {number} + */ + getGreatestPixelSpaceRadius() { + return this._greatestPixelSpaceRadius; + } + + // ACCESSING THREE.JS OBJECTS. + + /** + * Gets the Three.js objects. This includes any child objects. + * @returns {THREE.Object3D[]} + */ + getThreeJsObjects() { + return this._threeJsObjects; + } + + /** + * Gets the Three.js materials. + * @returns {THREE.ShaderMaterial[]} + */ + getThreeJsMaterials() { + return this._threeJsMaterials; + } + + /** + * Gets the first Three.js root or descendent that matches the name, or null if not found. + * @param {string} name + * @returns {THREE.Object3D | null} + */ + getThreeJsObjectByName(name) { + for (let i = 0; i < this._threeJsObjects.length; i++) { + const object = this._threeJsObjects[i]; + if (object.name === name) { + return object; + } + } + return null; + } + + // LOADING AND UNLOADING OF RESOURCES. + + /** + * Returns the load state. It can be 'unloaded', 'loading', or 'loaded'. + * @returns {'unloaded' | 'loading' | 'loaded'} + */ + getLoadState() { + return this._loadState; + } + + /** + * Sets whether or not the component is always loaded, except if disabled. Defaults to false. + * @param {boolean} enabled + */ + setForceLoaded(enabled) { + this._forceLoaded = enabled; + if (this._forceLoaded && this._loadState === 'unloaded') { + this._loadResources(); + } + } + + /** + * Sets whether the component is visible. The __update function will run, but not the __prepareForRender function. + * Only called by Entity and BaseComponent. + * @internal + */ + __updateLoadState() { + const entity = this.getEntity(); + const isEnabled = entity.isEnabled() && this.isEnabled(); + const isInTime = entity.isInPositionCoverage() && (entity.isInOrientationCoverage() || !this._usesEntityOrientation); + + // Create or destroy the rendering object based on the pixel-space radius. + if ((isEnabled && (this._forceLoaded || (isInTime && this._greatestPixelSpaceRadius > 0.5))) && this._loadState === 'unloaded') { + this._loadResources(); + } + else if ((!isEnabled || (!this._forceLoaded && (!isInTime || this._greatestPixelSpaceRadius < 0.25))) && this._loadState === 'loaded') { + this._unloadResources(); + } + } + + /** + * Reloads the resources of the component. They will be loaded, if necessary, on the next __update(). + */ + resetResources() { + // If it was loading, set it to unloaded so any __loadResources function will stop. + if (this._loadState === 'loading') { + this._loadState = 'unloaded'; + } + // Unload any loaded resources. + else if (this._loadState === 'loaded') { + this._unloadResources(); + } + } + + /** + * Sets the callback that is called right after the resources have been loaded. + * @param {() => any} callback + */ + setResourcesLoadedCallback(callback) { + this._resourcesLoadedCallback = callback; + } + + /** + * Sets the callback that is called right after the resources are unloaded. + * @param {() => any} callback + */ + setResourcesUnloadedCallback(callback) { + this._resourcesUnloadedCallback = callback; + } + + /** + * Loads the Three.js objects, materials, and any other resources the component might need. + * @private + */ + _loadResources() { + // Set the load state to loading. + this._loadState = 'loading'; + // Load the resources via the user function and set the loaded promise. + this._loadedPromise = this.__loadResources().then(() => { + // If it has since been unloaded, unload and return. + if (this._loadState !== 'loading') { + this._unloadResources(); + return; + } + // Set the load state to loaded. + this._loadState = 'loaded'; + // Call the callback. + if (this._resourcesLoadedCallback !== null) { + this._resourcesLoadedCallback(); + } + }); + } + + /** + * Unloads any of the resources loaded by the component. + * @private + */ + _unloadResources() { + // Unload the resources via the user function. + this.__unloadResources(); + // Set the load state to unloaded. + this._loadState = 'unloaded'; + // Clear the arrays. + this._threeJsObjects = []; + this._threeJsMaterials = []; + // Call the callback. + if (this._resourcesUnloadedCallback !== null) { + this._resourcesUnloadedCallback(); + } + } + + /** + * Loads the Three.js objects, materials, and any other resources the component might need. + * It should be implemented by subclasses and never called directly. + * It should populate the Three.js objects and materials arrays. + * @returns {Promise} + * @protected + */ + __loadResources() { + return Promise.resolve(); + } + + /** + * Unloads any of the resources loaded by the component. + * It should be implemented by subclasses and never called directly. + * It does not need to clear the Three.js objects and materials arrays. + * @protected + */ + __unloadResources() { + } + + /** + * Gets a promise that resolves when the texture is loaded. + * @override + * @returns {Promise} + */ + getLoadedPromise() { + return this._loadedPromise; + } + + // UPDATING + + /** + * Updates the camera-dependent parts of the component. + * @param {CameraComponent} camera - the camera being used in the render + * @abstract + */ + __updateCameraVariablesBase(camera) { + // Get the viewport using the camera. + const viewport = camera.getViewport(); + + // Get the normal-space extents radius. + const normalSpaceRadius = camera.getNormalSpaceRadiusFromRadius(this._radius, this.getEntity().getCameraSpacePosition(camera).magnitude()); + + // Get the pixel-space extents radius. + const pixelSpaceRadius = viewport.getPixelSpaceRadiusFromNormalSpaceRadius(normalSpaceRadius); + this._pixelSpaceRadiusPerCamera.set(camera, pixelSpaceRadius); + + // Call the component's updateCameraVariables function. + this.__updateCameraVariables(camera); + } + + /** + * Updates the component. + * @internal + */ + __updateBase() { + // Update the greatest pixel-space radius. + this._greatestPixelSpaceRadius = 0.0; + for (let i = 0, l = this._pixelSpaceRadiusPerCamera.size; i < l; i++) { + const pixelSpaceRadius = this._pixelSpaceRadiusPerCamera.getAt(i).value; + if (this._greatestPixelSpaceRadius < pixelSpaceRadius) { + this._greatestPixelSpaceRadius = pixelSpaceRadius; + } + } + + this.__updateLoadState(); + + // Call the component's update function. + this.__update(); + } + + /** + * Updates the camera-dependent parts of the component. Only called by the Entity. + * @param {CameraComponent} camera - the camera being used in the render + * @abstract + */ + __prepareForRenderBase(camera) { + // If the component has been loaded. + if (this._loadState === 'loaded') { + // If the component is not excluding this camera, + if (!this._excludedCameras.has(camera) && this._visible) { + // Make all objects visible. + for (let i = 0; i < this._threeJsObjects.length; i++) { + this._threeJsObjects[i].visible = true; + } + + // Call the component's prepareForRender. + this.__prepareForRender(camera); + + // Set the log-depth buffer uniforms, if they exist. + for (let i = 0; i < this._threeJsMaterials.length; i++) { + const uniforms = this._threeJsMaterials[i].uniforms; + if (uniforms['invertDepth'] !== undefined) { + uniforms['invertDepth'].value = camera.getInvertDepth(); + uniforms['nearDistance'].value = camera.getAutoNearDistance(); + uniforms['midDistance'].value = camera.getAutoMidDistance(); + } + } + + // Update the matrix for the objects, since it isn't done automatically in Three.js (unset by a flag). + for (let i = 0; i < this._threeJsObjects.length; i++) { + this._threeJsObjects[i].updateMatrix(); + } + } + // If the component is excluded in this camera. + else { + // Make all objects invisible. + for (let i = 0; i < this._threeJsObjects.length; i++) { + this._threeJsObjects[i].visible = false; + } + } + } + } + + /** + * Updates the camera-dependent parts of the component. + * @param {CameraComponent} _camera - the camera being used in the render + * @abstract + */ + __updateCameraVariables(_camera) { + } + + /** + * Updates the camera-dependent parts of the component. Implemented by the component. + * @param {CameraComponent} _camera + * @abstract + */ + __prepareForRender(_camera) { + } + + /** + * Gets the flag that if true, the component uses the entity's orientation. + * @returns {boolean} + */ + getUsesEntityOrientation() { + return this._usesEntityOrientation; + } + + /** + * Sets the flag that if true sets the root Three.js objects to have the same orientation as the entity. Defaults to false. + * @param {boolean} enabled + * @protected + */ + __setUsesEntityOrientation(enabled) { + this._usesEntityOrientation = enabled; + this.__updateLoadState(); + } + + // VISIBILITY OF THREE.JS OBJECTS. + + /** + * Returns true if the component is currently excluded from the camera. + * @param {CameraComponent} camera + * @returns {boolean} + */ + isExcludedFromCamera(camera) { + return this._excludedCameras.has(camera); + } + + /** + * Sets whether the component is excluded from the camera. The default is false. + * @param {CameraComponent} camera + * @param {boolean} excluded + */ + setExcludedFromCamera(camera, excluded) { + if (!excluded && this._excludedCameras.has(camera)) { + this._excludedCameras.delete(camera); + } + else if (excluded && !this._excludedCameras.has(camera)) { + this.__removeCameraDependents(camera); + this._excludedCameras.add(camera); + } + } + + /** + * Returns true if the component is visible. It will still be enabled and run, just not render. + * @returns {boolean} + */ + isVisible() { + return this._visible; + } + + /** + * Sets whether or not the component is visible. It will still be enabled and run, just not render. Defaults to true. + * @param {boolean} visible + */ + setVisible(visible) { + this._visible = visible; + } + + /** + * Removes the camera from any camera-dependent variables. Called during camera clean up. + * @param {CameraComponent} camera + */ + __removeCameraDependentsBase(camera) { + // Remove any camera-specific variables. + this._pixelSpaceRadiusPerCamera.delete(camera); + + // Call the user-implemented function. + this.__removeCameraDependents(camera); + } + + /** + * Clears the camera from any camera-dependent variables. Called by entity when clearing its camera references. + * @internal + */ + __clearCameraDependentsBase() { + // Clear any camera-specific variables. + this._pixelSpaceRadiusPerCamera.clear(); + + // Call the user-implemented function. + this.__clearCameraDependents(); + } + + /** + * Removes the camera from any camera-dependent variables. Called during camera clean up. + * @param {CameraComponent} _camera + */ + __removeCameraDependents(_camera) { + } + + /** + * Clears the camera from any camera-dependent variables. Called by entity when clearing its camera references. + * @internal + */ + __clearCameraDependents() { + } + + // MISCELLANEOUS + + /** + * Converts the entity item to a nice string. + * @override + * @returns {string} + */ + toString() { + let typeIndex = 0; + // Search the components for the type. + for (let i = 0, l = this.getEntity().getNumComponents(); i < l; i++) { + const component = this.getEntity().getComponent(i); + if (this === component) { + break; + } + if (this.getType() === component.getType()) { + typeIndex += 1; + } + } + return this.getEntity().getName() + '.' + this.getType() + '.' + typeIndex; + } +} + +/** + * A temporary Three.js Quaternion. + * @type {THREE.Quaternion} + */ +BaseComponent._tempThreeJsQuaternion = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Quaternion(); + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/camera_component.js": +/*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/camera_component.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CameraComponent": function() { return /* binding */ CameraComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * Camera component. This is typically attached to a {@link Viewport}. The +y axis is forward, +x is right, and +z is up. + */ +class CameraComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The Three.js renderer. + * @type {THREE.WebGLRenderer} + * @protected + */ + this._threeJsRenderer = this.getEntity().getScene().getEngine().__getThreeJsRenderer(); + + /** + * The viewport that is using this camera component. + * @type {Viewport} + * @private + */ + this._viewport = null; + + /** + * The three js scene. + * @type {THREE.Scene} + * @private + */ + this._threeJsScene = entity.getScene().getThreeJsScene(); + + /** + * The field of view in radians. + * @type {number} + * @private + */ + this._fieldOfView = 1.0471975512; + + /** + * The near clipping plane distance in km. + * @type {number} + * @private + */ + this._nearDistance = undefined; + + /** + * Whether or not to invert the depth buffer. + * @type {number} + * @private + */ + this._invertDepth = 0; + + /** + * The near clipping plane distance in km. + * @type {number} + * @private + */ + this._autoNearDistance = 0.0; + + /** + * The z-buffer mid-point distance in km. Only used when frag-depth buffering isn't available. + * @type {number} + * @private + */ + this._midDistance = undefined; + + /** + * The automatically calculated z-buffer mid-point distance in km. Only used when frag-depth buffering isn't available and _midDistance is unefined. + * @type {number} + * @private + */ + this._autoMidDistance = 0.0; + + /** + * The aspect ratio given by the viewport. + * @type {number} + * @private + */ + this._aspectRatio = 1.0; + + /** + * The render size of the previous frame, used for comparing with this frame. + * @type {Vector2} + * @private + */ + this._renderSize = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + + /** + * The list of entities which will occlude things like labels. Only things that are big enough on screen will be here. + * @type {Entity[]} + * @private + */ + this._occludingEntities = []; + + /** + * The three js camera. + * @type {THREE.PerspectiveCamera} + * @private + */ + this._threeJsCamera = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.PerspectiveCamera(75, this._aspectRatio, 0.1, 1000); + + /** + * The Three.js render pass composer. + * @type {ThreeJsEffectComposer} + * @private + */ + this._threeJsComposer = null; + + /** + * The Three.js outline pass. + * @type {ThreeJsOutlinePass} + * @private + */ + this._outlinePass = new _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsOutlinePass(undefined, this._threeJsScene, this._threeJsCamera, []); + this._outlinePass.enabled = false; + + /** + * The Three.js unreal bloom pass. + * @type {ThreeJsUnrealBloomPass} + * @private + */ + this._threeJsUnrealBloomPass = new _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsUnrealBloomPass(undefined, 0, 0, 0); + this._threeJsUnrealBloomPass.enabled = false; + + // Setup the pass composer. + this.__setupEffectComposer(); + } + + // FIELDS OF VIEW + + /** + * Gets the viewport that is using this camera component. + * @returns {Viewport} + */ + getViewport() { + return this._viewport; + } + + /** + * Returns the field of view in radians. Defaults to PI / 3. The field of view is applied to the viewport axis (horizontal or vertical) that has the greatest length. + * @returns {number} + */ + getFieldOfView() { + return this._fieldOfView; + } + + /** + * Get the field of view in the horizontal direction. It will be less than or equal to the general field of view. + * @returns {number} + */ + getHorizontalFieldOfView() { + if (this._aspectRatio >= 1) { + return this._fieldOfView; + } + else { + return 2.0 * Math.atan(Math.tan(this._fieldOfView / 2.0) * this._aspectRatio); + } + } + + /** + * Get the field of view in the vertical direction. It will be less than or equal to the general field of view. + * @returns {number} + */ + getVerticalFieldOfView() { + if (this._aspectRatio > 1) { + return 2.0 * Math.atan(Math.tan(this._fieldOfView / 2.0) / this._aspectRatio); + } + else { + return this._fieldOfView; + } + } + + /** + * Sets the field of view in radians. + * @param {number} fieldOfView + */ + setFieldOfView(fieldOfView) { + this._fieldOfView = fieldOfView; + } + + // LOD-DEPTH BUFFERING VARIABLES + + /** + * Returns 1 if the depth is inverted, 0 otherwise. + * @returns {number} + */ + getInvertDepth() { + return this._invertDepth; + } + + /** + * Sets whether or not the depth is inverted. Use 1 to invert the depth, 0 otherwise. + * @param {number} invertDepth + */ + setInvertDepth(invertDepth) { + this._invertDepth = invertDepth; + } + + /** + * Returns the distance in km at which nothing closer gets rendered. + * @returns {number} + */ + getNearDistance() { + return this._nearDistance; + } + + /** + * Sets the distance in km at which nothing closer gets rendered. Set this to be greater for enhanced depth precision. If it is set to undefined, then it is auto set to 1% of the distance to the parent. The default is undefined. + * @param {number} nearDistance + */ + setNearDistance(nearDistance) { + this._nearDistance = nearDistance; + } + + /** + * Returns the auto near distance in km. + * @returns {number} + */ + getAutoNearDistance() { + return this._autoNearDistance; + } + + /** + * Returns the z-buffer mid-point distance in km. Only used when frag-depth buffering isn't available. + * @returns {number} + */ + getMidDistance() { + return this._midDistance; + } + + /** + * Sets the z-buffer mid-point distance in km. Only used when frag-depth buffering isn't available. If it is set to undefined, then it is auto set to the distance to the parent + 2 times the parent's radius. The default is undefined. + * @param {number} midDistance + */ + setMidDistance(midDistance) { + this._midDistance = midDistance; + } + + /** + * Returns the z-buffer mid-point distance in km. Only used when frag-depth buffering isn't available. + * @returns {number} + */ + getAutoMidDistance() { + return this._autoMidDistance; + } + + // CAMERA/NORMAL-SPACE CONVERSIONS + + /** + * Gets the normal-space position from a camera-space position. + * @param {Vector3} outNormalSpacePosition + * @param {Vector3} cameraSpacePosition + */ + getNormalSpacePositionFromCameraSpacePosition(outNormalSpacePosition, cameraSpacePosition) { + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + orientation.copy(this.getEntity().getOrientation()); + orientation.inverse(orientation); + const rotatedCameraSpacePosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + rotatedCameraSpacePosition.rotate(orientation, cameraSpacePosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + + outNormalSpacePosition.x = this._threeJsCamera.projectionMatrix.elements[0] * rotatedCameraSpacePosition.x / rotatedCameraSpacePosition.y; + outNormalSpacePosition.y = this._threeJsCamera.projectionMatrix.elements[9] * rotatedCameraSpacePosition.z / rotatedCameraSpacePosition.y; + outNormalSpacePosition.z = this._threeJsCamera.projectionMatrix.elements[6] + this._threeJsCamera.projectionMatrix.elements[14] / rotatedCameraSpacePosition.y; + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(rotatedCameraSpacePosition); + } + + /** + * Gets the normal-space size (fraction of viewport) from a radius of a sphere and a distance to the camera. + * @param {number} radius - radius of object + * @param {number} distanceInCameraYDir - distance to camera of object along the camera's y axis. + * @returns {number} + */ + getNormalSpaceRadiusFromRadius(radius, distanceInCameraYDir) { + return radius / Math.abs(distanceInCameraYDir) / Math.tan(this._fieldOfView / 2); + } + + /** + * Gets the camera-space position from a normal-space position. + * @param {Vector3} outCameraSpacePosition + * @param {Vector3} normalSpacePosition + */ + getCameraSpacePositionFromNormalSpacePosition(outCameraSpacePosition, normalSpacePosition) { + const rotatedCameraSpacePosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + rotatedCameraSpacePosition.y = this._threeJsCamera.projectionMatrix.elements[14] / (normalSpacePosition.z - this._threeJsCamera.projectionMatrix.elements[6]); + rotatedCameraSpacePosition.x = normalSpacePosition.x * rotatedCameraSpacePosition.y / this._threeJsCamera.projectionMatrix.elements[0]; + rotatedCameraSpacePosition.z = normalSpacePosition.y * rotatedCameraSpacePosition.y / this._threeJsCamera.projectionMatrix.elements[9]; + + outCameraSpacePosition.rotate(this.getEntity().getOrientation(), rotatedCameraSpacePosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(rotatedCameraSpacePosition); + } + + /** + * Gets the camera/world-space size (fraction of viewport) from a radius of a sphere and a distance to the camera. + * @param {number} radius - normal-space radius of object + * @param {number} distanceInCameraYDir - distance to camera of object along the camera's y axis. + * @returns {number} + */ + getRadiusFromNormalSpaceRadius(radius, distanceInCameraYDir) { + return radius * Math.abs(distanceInCameraYDir) * Math.tan(this._fieldOfView / 2); + } + + // OCCLUSION + + /** + * Returns true if the camera-space position is occluded by any of the occluding entities. + * @param {Vector3} cameraSpacePosition + * @returns {boolean} + */ + isPositionOccluded(cameraSpacePosition) { + for (let i = 0; i < this._occludingEntities.length; i++) { + if (this._occludingEntities[i].isOccludingPosition(this, cameraSpacePosition)) { + return true; + } + } + return false; + } + + /** + * Find the nearest entity that intersects the ray form the camera to the camera-space position, or null if there is no such intersection. + * @param {Vector3} cameraSpacePosition + * @returns {Entity} + */ + getNearestIntersectingEntity(cameraSpacePosition) { + let minDistance = Number.POSITIVE_INFINITY; + let minEntity = null; + const interval = _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get(); + for (let i = 0; i < this._occludingEntities.length; i++) { + const entityCameraSpacePosition = this._occludingEntities[i].getCameraSpacePosition(this); + _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLineSphereIntersectionWithLineStartAtOrigin(interval, cameraSpacePosition, entityCameraSpacePosition, this._occludingEntities[i].getOcclusionRadius()); + if (!Number.isNaN(interval.min) && interval.min >= 0) { + const distance = interval.min * entityCameraSpacePosition.magnitude(); + if (distance < minDistance) { + minDistance = distance; + minEntity = this._occludingEntities[i]; + } + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(interval); + return minEntity; + } + + // POST-PROCESSING + + /** + * Sets the bloom value. + * @param {number} strength + */ + setBloom(strength) { + this._threeJsUnrealBloomPass.enabled = (strength > 0); + this._threeJsUnrealBloomPass.strength = strength; + } + + /** + * Sets the outline pass. Works with any component that has implemented getThreeJsObjects(). If component is null, it is disabled. + * @param {Color} color + * @param {BaseComponent} component + * @param {string} [subObjectName=''] + */ + setOutline(color, component, subObjectName) { + this._outlinePass.enabled = (component !== null); + if (component !== null) { + if (subObjectName !== undefined) { + const subObject = component.getThreeJsObjectByName(subObjectName); + if (subObject === null) { + throw new Error(`Could not set outline on component ${component} sub-object ${subObjectName}.`); + } + this._outlinePass.selectedObjects = [subObject]; + } + else { + const objects = component.getThreeJsObjects(); + this._outlinePass.selectedObjects = []; + for (let i = 0, l = objects.length; i < l; i++) { + if (objects[i].parent === this._threeJsScene) { + this._outlinePass.selectedObjects.push(objects[i]); + } + } + } + this._outlinePass.visibleEdgeColor.setRGB(color.r, color.g, color.b); + this._outlinePass.hiddenEdgeColor.setRGB(color.r / 4, color.g / 4, color.b / 4); + } + this.__setupEffectComposer(); + } + + // INTERNALS + + /** + * Add an entity to the list of occluding entities. This is called by the entity during its prepareForRender, and used by occlusion and intersection functions. + * @param {Entity} entity + * @internal + */ + __addToOccludingEntities(entity) { + // Check to see if it already exists. + for (let i = 0; i < this._occludingEntities.length; i++) { + if (this._occludingEntities[i] === entity) { + return; + } + } + // If not, add it. + this._occludingEntities.push(entity); + } + + /** + * Cleans up the component. + * @override + * @internal + */ + __destroy() { + super.__destroy(); + + // Remove any camera-dependent variables in the scene that reference this camera. + this.getEntity().getScene().__removeCameraDependents(this); + + // If it has a viewport, unlink it. + if (this._viewport !== null) { + this._viewport.setCamera(null); + } + } + + /** + * Prepares the camera-dependent variables and those of its connected entities. + * @internal + */ + __updateCameraVariablesForConnectedScene() { + // Update the aspect ratio. + const renderSize = this._viewport.getBounds().size; + if (!renderSize.equals(this._renderSize)) { + const aspectRatio = renderSize.x / renderSize.y; + if (this._aspectRatio !== aspectRatio) { + this._aspectRatio = aspectRatio; + } + + // Set the resolution of the render passes. + this._threeJsComposer.setSize(renderSize.x, renderSize.y); + this._renderSize.copy(renderSize); + } + + // Set the auto mid-point distance, if necessary. + if (this._midDistance === undefined) { + if (this.getEntity().getParent() !== null) { + this._autoMidDistance = this.getEntity().getPosition().magnitude() + this.getEntity().getParent().getExtentsRadius() * 10.0; + } + } + else { + this._autoMidDistance = this._midDistance; + } + + // Set the near-point distance, if necessary. + if (this._nearDistance === undefined) { + if (this.getEntity().getParent() !== null) { + this._autoNearDistance = Math.max(0.00001, (this.getEntity().getPosition().magnitude() - this.getEntity().getParent().getExtentsRadius()) * 0.01); + } + else { + this._autoNearDistance = Math.max(0.00001, this.getEntity().getPosition().magnitude() * 0.01); + } + } + else { + this._autoNearDistance = this._nearDistance; + } + + // Update the projection matrix. + this._updateProjectionMatrix(); + + // Update the camera-dependent variables of entities in the scene that are connected to the camera. + this.getEntity().__updateCameraVariables(this, null, false); + + // Remove any objects that are too small visually from the occluding list. + for (let i = 0; i < this._occludingEntities.length; i++) { + if (this._occludingEntities[i].getPixelSpaceOcclusionRadius(this) < 1 || !this._occludingEntities[i].isEnabled() || !this._occludingEntities[i].canOcclude() || this.getEntity().getScene().get(this._occludingEntities[i].getName()) === null) { + this._occludingEntities.splice(i, 1); + i--; + } + } + } + + /** + * Prepares the camera for rendering. + * @override + */ + __prepareForRender() { + // Prepare each entity in the scene for rendering using this. + const scene = this.getEntity().getScene(); + for (let i = 0; i < scene.getNumEntities(); i++) { + const entity = scene.getEntity(i); + if (entity.isEnabled()) { + entity.__prepareForRender(this); + } + } + + // If there is a dynamic environment map component, render it first. + const dynEnvMapComponent = /** @type {DynamicEnvironmentMapComponent} */(this.getEntity().get('dynEnvMap')); + if (dynEnvMapComponent !== null) { + dynEnvMapComponent.__render(); + } + } + + /** + * Renders the camera. Called by Viewport. + * @internal + */ + __render() { + // Set the camera's orientation. + const orientation = this.getEntity().getOrientation(); + CameraComponent._tempThreeJsQuaternion.set(orientation.x, orientation.y, orientation.z, orientation.w); + this._threeJsCamera.setRotationFromQuaternion(CameraComponent._tempThreeJsQuaternion); + + // Do the render! + this._threeJsComposer.render(); + } + + /** + * Sets the viewport that is using this camera component. Only used by Viewport itself. + * @param {Viewport} viewport + * @internal + */ + __setViewport(viewport) { + // Unlink from any previous other viewport. + if (this._viewport !== null && this._viewport !== viewport) { + this._viewport.setCamera(null); + } + + this._viewport = viewport; + } + + /** + * Updates the render targets and sets up the effect composer. Can be called multiple times when conditions change. + * @private + */ + __setupEffectComposer() { + // Create the render target. + const size = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(); + this._threeJsRenderer.getSize(size); + const renderTargetOptions = { + samples: (_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.isWebGL2() && !this._outlinePass.enabled) ? 4 : 0 + }; + const renderTarget = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderTarget(size.x, size.y, renderTargetOptions); + if (this._threeJsComposer !== null) { + this._threeJsComposer.reset(renderTarget); + } + else { + // Create the Three.js effect composer. + this._threeJsComposer = new _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsEffectComposer(this._threeJsRenderer, renderTarget); + + // Add the render passes. + const renderPass = new _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsRenderPass(this._threeJsScene, this._threeJsCamera); + this._threeJsComposer.addPass(renderPass); + this._threeJsComposer.addPass(this._outlinePass); + this._threeJsComposer.addPass(this._threeJsUnrealBloomPass); + } + } + + /** + * Updates the projection. + * @private + */ + _updateProjectionMatrix() { + if (this._fieldOfView > 0 && this._fieldOfView < 180 && this._aspectRatio > 0) { + const tanHalfFov = Math.tan(this._fieldOfView / 2); + let sx = 0; + let sz = 0; + if (this._aspectRatio >= 1) { + sx = 1 / tanHalfFov; + sz = this._aspectRatio / tanHalfFov; + } + else { + sx = 1 / (tanHalfFov * this._aspectRatio); + sz = 1 / tanHalfFov; + } + const f1 = Number.EPSILON - 1.0; + const f2 = this._autoNearDistance * (2.0 - Number.EPSILON); + const projectionMatrix = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix4(); + projectionMatrix.set( + sx, 0, 0, 0, + 0, 0, sz, 0, + 0, f1, 0, f2, + 0, 1, 0, 0); + this._threeJsCamera.projectionMatrix = projectionMatrix; + const projectionMatrixInverse = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix4(); + projectionMatrixInverse.set( + 1 / sx, 0, 0, 0, + 0, 0, 0, 1, + 0, 1 / sz, 0, 0, + 0, 0, 1 / f2, -f1 / f2); + this._threeJsCamera.projectionMatrixInverse = projectionMatrixInverse; + } + } + + /** + * Required by BaseComponent, does nothing. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + return Promise.resolve(); + } + + /** + * Required by BaseComponent, does nothing. + * @override + * @protected + */ + __unloadResources() { + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/cmts_component.js": +/*!****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/cmts_component.js ***! + \****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CMTSComponent": function() { return /* binding */ CMTSComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The CMTS component. + */ +class CMTSComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The ThreeJS scene. + * @type {THREE.Scene} + * @private + */ + this._threeJsScene = this.getEntity().getScene().getThreeJsScene(); + + /** + * The end points for the texture names. + * @type {FastMap} + * @private + */ + this._endPoints = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The height scale if a height texture is used. + * @type {number} + * @private + */ + this._heightScale = 1; + + /** + * The number of end points still loading. + * @type {number} + * @private + */ + this._numEndPointsLoading = 0; + + /** + * The minimum level to which the tiles must split. + * @type {number} + * @private + */ + this._minLevel = Number.NEGATIVE_INFINITY; + + /** + * The maximum level to which the tiles can split. + * @type {number} + * @private + */ + this._maxLevel = Number.POSITIVE_INFINITY; + + /** + * The tileOffsets in the CMTS. + * @type {Array<{offset: Vector3, face: number, level: number, min: Vector2, max: Vector2}>} + * @private + */ + this._tileOffsets = []; + + /** + * A factor that determines when to split the tiles. Higher means more splits. + * @type {number} + * @private + */ + this._splitJoinThresholdFactor = 512.0; + + /** + * The tile size of the color configuration. + * @type {number} + * @private + */ + this._colorTileSize = 512; + + /** + * The entities used for shadows. Derived from the shadow entity names. + * @type {EntityRef[]} + * @private + */ + this._shadowEntities = []; + + /** + * The downloader for easier future access. + * @private + */ + this._engine = this.getEntity().getScene().getEngine(); + + /** + * The positions of all active cameras. + * @type {Vector3[]} + * @private + */ + this._cameraPositions = []; + + /** + * The fields of view of all active cameras. + * @type {number[]} + * @private + */ + this._cameraFieldsOfView = []; + + /** + * The root tile. + * @type {CMTSTile[]} + * @private + */ + this._rootTiles = [null, null, null, null, null, null]; + + /** + * A promise that resolves when all tiles are no longer transitioning. + * @type {Promise} + * @private + */ + this._tilesLoadedPromise = null; + + /** + * The callback that gets called when all tiles are no longer transitioning. + * @type {() => any} + * @private + */ + this._transitionsCompleteCallback = null; + + /** + * A cache of textures, one for each tile. + * @type {Cache>} + * @private + */ + this._textureCache = new _internal__WEBPACK_IMPORTED_MODULE_0__.Cache((textureUrl) => { + return this.getEntity().getScene().getEngine().getTextureLoader().loadTexture(textureUrl, true); + }, (texturePromise) => { + texturePromise.then((texture) => { + texture.dispose(); + }); + }); + + /** + * A counter that ensures that we don't do too many splits or joins at once. + * @type {number} + * @private + */ + this._numCurrentLoads = 0; + + /** + * Get the maximum number of loads that can happen at one time. + * @type {number} + * @private + */ + this._maxCurrentLoads = 10; + + /** + * A reference to the atmosphere component. + * @type {ComponentRef} + * @private + */ + this._atmosphereComponentRef = new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene()); + this._atmosphereComponentRef.setByType(this.getEntity().getName(), 'atmosphere'); + + /** + * A reference to the spheroid component. + * @type {ComponentRef} + * @private + */ + this._spheroidComponentRef = new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene()); + this._spheroidComponentRef.setByType(this.getEntity().getName(), 'spheroid'); + this._spheroidComponentRef.setRefChangedCallback(this._spheroidRefChangedCallback.bind(this)); + + // Bind the callbacks to this. + this._spheroidChangedCallback = this._spheroidChangedCallback.bind(this); + + // Lets the base component to check for valid orientation when determining whether this is visible. + this.__setUsesEntityOrientation(true); + } + + /** + * Sets a base url for the CMTS protocol for a given texture. + * @param {string} textureName + * @param {string} endPoint + */ + setBaseUrl(textureName, endPoint) { + this.resetResources(); + + // Set the end point. + this._endPoints.set(textureName, { url: endPoint, configuration: null }); + } + + /** + * Gets the height scale if a height texture is used. + * @returns {number} + */ + getHeightScale() { + return this._heightScale; + } + + /** + * Sets the height scale if a height texture is used. + * @param {number} heightScale + */ + setHeightScale(heightScale) { + this._heightScale = heightScale; + this.resetResources(); + } + + /** + * Gets the minimum level to which the tiles must split. + * @returns {number} + */ + getMinLevel() { + return this._minLevel; + } + + /** + * Sets the minimum level to which the tiles must split. Defaults to negative infinity. + * @param {number} minLevel + */ + setMinLevel(minLevel) { + this._minLevel = minLevel; + } + + /** + * Gets the maximum level to which the tiles can split. + * @returns {number} + */ + getMaxLevel() { + return this._maxLevel; + } + + /** + * Sets the maximum level to which the tiles can split. Defaults to positive infinity. + * @param {number} maxLevel + */ + setMaxLevel(maxLevel) { + this._maxLevel = maxLevel; + } + + /** + * Adds a tileOffset to the CMTS. + * @param {Vector3} offset + * @param {number} face + * @param {number} level + * @param {number} minX + * @param {number} minY + * @param {number} maxX + * @param {number} maxY + */ + addTileOffset(offset, face, level, minX, minY, maxX, maxY) { + this._tileOffsets.push({ offset, face, level, min: new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(minX, minY), max: new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(maxX, maxY) }); + this.resetResources(); + } + + /** + * Removes a tileOffset from the CMTS. + * @param {number} face + * @param {number} level + * @param {number} minX + * @param {number} minY + * @param {number} maxX + * @param {number} maxY + */ + removeTileOffset(level, face, minX, minY, maxX, maxY) { + for (let i = 0; i < this._tileOffsets.length; i++) { + const tileOffset = this._tileOffsets[i]; + if (tileOffset.face === face && tileOffset.level === level && tileOffset.min.x === minX && tileOffset.min.y === minY && tileOffset.max.x === maxX && tileOffset.max.y === maxY) { + this._tileOffsets.splice(i, 1); + this.resetResources(); + return; + } + } + } + + /** + * Gets the number of shadow entities. Can be used to enumerate the shadow entities. + * @returns {number} + */ + getNumShadowEntities() { + return this._shadowEntities.length; + } + + /** + * Returns the shadow entity or its name at the index. + * @param {number} index + * @returns {string | undefined} + */ + getShadowEntity(index) { + return this._shadowEntities[index]?.getName(); + } + + /** + * Sets the shadow entities. Each element can be either the name of an entity or an entity itself. + * @param {string[]} shadowEntities + */ + setShadowEntities(shadowEntities) { + this._shadowEntities = []; + for (const shadowEntity of shadowEntities) { + this._shadowEntities.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(), shadowEntity)); + } + const shadowEntitiesEnabled = (shadowEntities.length > 0); + for (let i = 0, l = this.getThreeJsMaterials().length; i < l; i++) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setDefine(this.getThreeJsMaterials()[i], 'shadowEntities', shadowEntitiesEnabled); + } + } + + /** + * Gets the frame-space position and height direction on the surface at the given frame-space position. + * Note that the height direction is not up with planetocentric coordinates. + * @param {Vector3} outPosition + * @param {Vector3} outHeightDir + * @param {Vector3} position + */ + getGroundPosition(outPosition, outHeightDir, position) { + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent === null) { + outPosition.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + // Get the position on the surface of the spheroid. + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + spheroidComponent.llaFromXYZ(lla, position); + lla.alt = 0; + spheroidComponent.xyzFromLLA(outPosition, lla); + // Get the height direction. + if (spheroidComponent.isPlanetographic()) { + spheroidComponent.upFromLLA(outHeightDir, lla); + } + else { + outHeightDir.normalize(position); + } + // If there is height data, add on the height. + const heightEndPoint = this._endPoints.get('height'); + if (heightEndPoint !== undefined) { + // Get the position is in "sphere" space and get the cmts coord uvFace. + const uvFace = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const posOnSphere = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + lla.alt = 1; + _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getXYZFromLLAOnSphere(posOnSphere, lla, 0); + _internal__WEBPACK_IMPORTED_MODULE_0__.CubeMap.xyzToUVFace(uvFace, posOnSphere); + // Get the corresponding root tile. + let tile = this._rootTiles[uvFace.z]; + // Check if it is a valid tile. + if (tile === undefined || tile === null) { + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posOnSphere); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(uvFace); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + return; + } + // Get the lowest level tile that the uv is within and has height data. + while (tile.children.length > 0) { + const levelFactor = 1 << (tile.getLevel() + 1); + const xTile = Math.floor(uvFace.x * levelFactor - tile.getTileCoord().x * 2); + const yTile = Math.floor(uvFace.y * levelFactor - tile.getTileCoord().y * 2); + tile = tile.children[yTile * 2 + xTile]; + } + while (tile.getHeightData() === null && tile.getParent() !== null) { + tile = tile.getParent(); + } + // Get the height within that tile. + const heightData = tile.getHeightData(); + if (heightData !== null) { + const levelFactor = 1 << tile.getLevel(); + const pixelX = (uvFace.x * levelFactor - tile.getTileCoord().x) * (heightData.width - 4) + 2; + const pixelY = (1 - (uvFace.y * levelFactor - tile.getTileCoord().y)) * (heightData.width - 4) + 2; + const height = CMTSTile.getLinearInterpolatedHeightPixel(pixelX, pixelY, heightData.data, heightData.width); + // Get the new height offset and scale. + const configuration = heightEndPoint.configuration; + const heightOffset = configuration['height_range'].min * this._heightScale; + const heightScale = (configuration['height_range'].max - configuration['height_range'].min) * this._heightScale; + // Set the height and convert back to xyz. + lla.alt = heightOffset + height * heightScale; + spheroidComponent.xyzFromLLA(outPosition, lla); + } + // Cleanup. + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posOnSphere); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(uvFace); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + } + + /** + * Returns true if tiles are all loaded. + * @returns {boolean} + */ + areTilesLoaded() { + return this._tilesLoadedPromise === null; + } + + /** + * Returns a promise when no more tiles are loading. + * @returns {Promise} + */ + getTilesLoadedPromise() { + return this._tilesLoadedPromise ?? Promise.resolve(); + } + + /** + * Sets the reference to use for the spheroid component, by name or the type index. + * @param {string | number} nameOrTypeIndex + */ + setSpheroidReference(nameOrTypeIndex) { + if (typeof nameOrTypeIndex === 'string') { + this._spheroidComponentRef.setByName(this.getEntity().getName(), nameOrTypeIndex); + } + else { + this._spheroidComponentRef.setByType(this.getEntity().getName(), 'spheroid', nameOrTypeIndex); + } + } + + /** + * Cleans up the component. + * @override + * @internal + */ + __destroy() { + // Remove the spheroid changed callback. + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent !== null) { + spheroidComponent.removeChangedCallback(this._spheroidChangedCallback); + } + + super.__destroy(); + } + + /** + * Updates the component. + * @override + * @internal + */ + __update() { + // Update the spheroid component reference. + this._spheroidComponentRef.update(); + + // If the end points are not loaded, there's nothing more to do. + if (this.getLoadState() !== 'loaded' || this._spheroidComponentRef.get() === null) { + return; + } + + if (this._rootTiles[0] === null) { + if (this._numEndPointsLoading === 0) { + // Create the root tiles to start. + for (let face = 0; face < 6; face++) { + this._rootTiles[face] = new CMTSTile(this, null, face, 0, new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0, 0)); + this._rootTiles[face].forceLoad(); + } + } + else { + return; + } + } + + // Set to true if any tile or configuration is still loading or unloading. + let transitioning = false; + + // Get the positions of all cameras as lat, lon, alt in the frame of the spheroid. + while (this._cameraPositions.length > this._engine.getNumViewports()) { + this._cameraPositions.pop(); + this._cameraFieldsOfView.pop(); + } + while (this._cameraPositions.length < this._engine.getNumViewports()) { + this._cameraPositions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()); + this._cameraFieldsOfView.push(1); + } + for (let i = 0, l = this._engine.getNumViewports(); i < l; i++) { + const cameraPosition = this._cameraPositions[i]; + const cameraComponent = this._engine.getViewport(i).getCamera(); + cameraComponent.getEntity().getPositionRelativeToEntity(cameraPosition, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, this.getEntity()); + cameraPosition.rotateInverse(this.getEntity().getOrientation(), cameraPosition); + this._cameraFieldsOfView[i] = cameraComponent.getFieldOfView(); + } + + // Do the update on all of the tiles recursively. + // If any tile is still transitioning, set transitioning to true. + for (let face = 0; face < 6; face++) { + transitioning = this._rootTiles[face].update() || transitioning; + } + + // If there is no current promise (there were no tiles or configuration transitioning) and now there are, + // Create the loaded promise and record its resolve callback. + if (this._tilesLoadedPromise === null && transitioning) { + this._tilesLoadedPromise = new Promise((resolve) => { + this._transitionsCompleteCallback = resolve; + }); + } + + // If the loaded promise callback exists and we're no longer transitioning, + // Clear the loaded promise and callback and call the callback (the resolve function of the promise). + if (this._tilesLoadedPromise !== null && !transitioning) { + const callback = this._transitionsCompleteCallback; + this._tilesLoadedPromise = null; + this._transitionsCompleteCallback = null; + callback(); + } + } + + /** + * Prepares the component for render. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + if (this._rootTiles[0] === null) { + return; + } + + // Set the orientation to the entity's orientation. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects(), this.getEntity()); + + // Prepare the root tiles for rendering. + for (let face = 0; face < 6; face++) { + this._rootTiles[face].prepareForRender(camera); + } + + // Get the atmosphere. + const atmosphere = this._atmosphereComponentRef.get(); + + // Setup the regular uniforms. + _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setUniforms(this.getThreeJsMaterials(), camera, this.getEntity(), this._shadowEntities, atmosphere, true); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + /** @type {Array>} */ + const promises = []; + for (let i = 0, l = this._endPoints.size; i < l; i++) { + const entry = this._endPoints.getAt(i); + const endPoint = entry.value.url; + // Load the end point. + this._numEndPointsLoading += 1; + const promise = this.getEntity().getScene().getEngine().getDownloader().download(endPoint + '/configuration.json', false).then((download) => { + if (download.status === 'failed') { + throw new Error('Failed to download ' + endPoint + '/configuration.json'); + } + if (download.status === 'completed' && typeof download.content === 'string') { + const configuration = /** @type {CMTSConfiguration} */(JSON.parse(download.content)); + entry.value.configuration = configuration; + if (entry.key === 'color') { + this._colorTileSize = configuration.tile_size; + } + this._numEndPointsLoading -= 1; + } + }); + promises.push(promise); + } + + // Return promise that resolves when all end points have been loaded. + return Promise.all(promises); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + for (let face = 0; face < 6; face++) { + if (this._rootTiles[face] !== null) { + this._rootTiles[face].destroy(); + } + } + this._rootTiles = [null, null, null, null, null, null]; + } + + /** + * Gets the number of loads currently happening. + * @returns {number} + * @internal + */ + __getNumCurrentLoads() { + return this._numCurrentLoads; + } + + /** + * Increments the number of loads currently happening. Used by CMTSTile. + * @internal + */ + __incNumCurrentLoads() { + this._numCurrentLoads += 1; + } + + /** + * Decrements the number of loads currently happening. Used by CMTSTile. + * @internal + */ + __decNumCurrentLoads() { + this._numCurrentLoads -= 1; + } + + /** + * Gets the maximum number of loads that can happen. Used by CMTSTile. + * @internal + */ + __getMaxCurrentLoads() { + return this._maxCurrentLoads; + } + + /** + * Gets the end points. + * @returns {FastMap} + * @internal + */ + __getEndPoints() { + return this._endPoints; + } + + /** + * Returns true if thare are no end points loading. + * @returns {boolean} + * @internal + */ + __endPointsAreLoaded() { + return this._numEndPointsLoading === 0; + } + + /** + * Gets the tileOffsets. Used by CMTSTile. + * @returns {Array<{offset: Vector3, face: number, level: number, min: Vector2, max: Vector2}>} + * @internal + */ + __getTileOffsets() { + return this._tileOffsets; + } + + /** + * Gets the texture cache. Used by CMTSTile. + * @returns {Cache>} + * @internal + */ + __getTextureCache() { + return this._textureCache; + } + + /** + * Gets the camera positions. Used by CMTSTile. + * @returns {Vector3[]} + * @internal + */ + __getCameraPositions() { + return this._cameraPositions; + } + + /** + * Gets the camera fields of view. Used by CMTSTile. + * @returns {number[]} + * @internal + */ + __getCameraFieldsOfView() { + return this._cameraFieldsOfView; + } + + /** + * Gets the Three.js scene. Used by CMTSTile. + * @returns {THREE.Scene} + * @internal + */ + __getThreeJsScene() { + return this._threeJsScene; + } + + /** + * Gets the split/join threshold factor. + * @returns {number} + * @internal + */ + __getSplitJoinThresholdFactor() { + return this._splitJoinThresholdFactor; + } + + /** + * Gets the tile size of the color configuration. + * @returns {number} + * @internal + */ + __getColorTileSize() { + return this._colorTileSize; + } + + /* + * Gets the spheroid component this is using. Used by Tile. + * @returns {SpheroidComponent} + * @package + */ + __getSpheroidComponent() { + return this._spheroidComponentRef.get(); + } + + /** + * Callback called when the spheroid reference is found or lost. + * @param {SpheroidComponent} oldRef + * @param {SpheroidComponent} newRef + * @private + */ + _spheroidRefChangedCallback(oldRef, newRef) { + if (oldRef !== null) { + oldRef.removeChangedCallback(this._spheroidChangedCallback); + } + if (newRef !== null) { + newRef.addChangedCallback(this._spheroidChangedCallback); + } + this._spheroidChangedCallback(); + } + + /** + * Callback to be called when the spheroid component changed. + * @private + */ + _spheroidChangedCallback() { + // Set the radii uniforms. + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent !== null) { + this.__setRadius(Math.max(spheroidComponent.getEquatorialRadius(), spheroidComponent.getPolarRadius())); + } + else { + this.__setRadius(0); + } + this.resetResources(); + } +} + +/** + * A single tile with mesh, material, and bounds. + * @extends Tile + * @private + */ +class CMTSTile extends _internal__WEBPACK_IMPORTED_MODULE_0__.Tile { + /** + * Constructor. + * @param {CMTSComponent} component + * @param {CMTSTile} parent + * @param {number} face + * @param {number} level + * @param {Vector2} tile + */ + constructor(component, parent, face, level, tile) { + super(parent); + + /** + * The CMTS component. + * @type {CMTSComponent} + * @private + */ + this._component = component; + + /** + * The face. + * @type {number} + * @private + */ + this._face = face; + + /** + * The level. + * @type {number} + * @private + */ + this._level = level; + + /** + * The level exponential factor. + * @type {number} + * @private + */ + this._levelPow = Math.pow(2, -Math.max(0, level)); + + /** + * The tile coordinates. + * @type {Vector2} + * @private + */ + this._tile = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + this._tile.copy(tile); + + /** + * True if this can't be split any more. + * @type {boolean} + * @private + */ + this._isLeaf = true; + + /** + * The center of the tile's surface, for distance checking. + * @type {Vector3} + * @private + */ + this._center = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + /** + * The "radius", the distance from the center to one of the corners, for distance checking. + * @type {number} + * @private + */ + this._radius = 0; + + /** + * The material used by the tile. + * @type {THREE.ShaderMaterial} + * @private + */ + this._threeJsMaterial = null; + + /** + * Gets the level to which the texture belongs for the given texture name. + * @type {FastMap} + * @private + */ + this._textureLevels = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * Gets the texture promises that are aquired from the texture cache. + * @type {FastMap>} + * @private + */ + this._texturePromises = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * A flag that says whether or not one of the non-positive textures is loading. + * @type {boolean} + * @private + */ + this._nonPositiveTextureLoading = false; + + /** + * The Three.js object of the tile. + * @type {THREE.Mesh} + * @private + */ + this._threeJsObject = null; + + /** + * The height data if it exists. + * @type {ImageData} + * @private + */ + this._heightData = null; + + /** + * The tile offset. The vertices will use this as their origin. + * @type {Vector3} + * @private + */ + this._tileOffset = this._getTileOffset(); + + // Check if this tile is a leaf. + for (let y = 0; y < 2; y++) { + for (let x = 0; x < 2; x++) { + for (let i = 0; i < this._component.__getEndPoints().size; i++) { + const configuration = this._component.__getEndPoints().getAt(i).value.configuration; + this._isLeaf = this._isLeaf && !CMTSTile._isInABoundary(configuration, this._face, this._level + 1, new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(this._tile.x * 2 + x, this._tile.y * 2 + y)); + } + } + } + + // Get the spheroid component. + const spheroidComponent = component.__getSpheroidComponent(); + + // Calculate the center. + CMTSTile.cmtsCoordToPosition(this._center, this._face, this._levelPow, this._tile.x + 0.5, this._tile.y + 0.5, spheroidComponent); + + // Calculate the radius by getting the distance between the center and the origin point. + const origin1 = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const origin2 = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const origin3 = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const origin4 = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + CMTSTile.cmtsCoordToPosition(origin1, this._face, this._levelPow, this._tile.x, this._tile.y, spheroidComponent); + CMTSTile.cmtsCoordToPosition(origin2, this._face, this._levelPow, this._tile.x + 1, this._tile.y, spheroidComponent); + CMTSTile.cmtsCoordToPosition(origin3, this._face, this._levelPow, this._tile.x + 1, this._tile.y + 1, spheroidComponent); + CMTSTile.cmtsCoordToPosition(origin4, this._face, this._levelPow, this._tile.x, this._tile.y + 1, spheroidComponent); + origin1.sub(this._center, origin1); + origin2.sub(this._center, origin2); + origin3.sub(this._center, origin3); + origin4.sub(this._center, origin4); + this._radius = Math.max(origin1.magnitude(), origin2.magnitude(), origin3.magnitude(), origin4.magnitude()); + + // Figure out which texture levels this uses. It may use a texture from a higher level if a texture doesn't exist at this level. + const endPoints = this._component.__getEndPoints(); + for (let i = 0; i < endPoints.size; i++) { + const textureName = endPoints.getAt(i).key; + const endPoint = endPoints.getAt(i).value; + + // If we're at level 0, check for non-positive levels. + const nonPositiveLevel = this._level === 0 ? this._getNonPositiveLevel(textureName) : 0; + + if (CMTSTile._isInABoundary(endPoint.configuration, this._face, this._level, this._tile)) { + const textureLevel = this._level === 0 ? nonPositiveLevel : this._level; + // Set the material's level for the texture name to this level. + this._textureLevels.set(textureName, textureLevel); + } + else { + let ancestor = this.getParent(); + while (ancestor !== null && ancestor._level !== ancestor._textureLevels.getAt(i).value) { + ancestor = ancestor.getParent(); + } + if (ancestor !== null) { // It found an ancestor, so use that texture for this tile. + this._textureLevels.set(textureName, ancestor._textureLevels.getAt(i).value); + } + else { // There's no coverage for this tile all the way up to the top, so just set it to 0. + this._textureLevels.set(textureName, 0); + } + } + } + } + + /** + * Gets the level. + * @returns {number} + */ + getLevel() { + return this._level; + } + + /** + * Gets the tile coords. + * @returns {Vector2} + */ + getTileCoord() { + return this._tile; + } + + /** + * Gets the height data, if any. + * @returns {ImageData | null} + */ + getHeightData() { + return this._heightData; + } + + /** + * @param {CMTSTile} parent + * @param {number} row - 0 or 1 + * @param {number} col - 0 or 1 + * @returns {CMTSTile} + * @override + */ + createNewTile(parent, row, col) { + const level = this._level + 1; + const tile = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(parent._tile.x * 2 + col, parent._tile.y * 2 + row); + return new CMTSTile(parent._component, this, this._face, level, tile); + } + + /** + * Returns true if this tile should be split. + * @returns {boolean} + * @override + */ + checkSplit() { + // Don't split if we're a leaf or at the maximum level of detail. + if (this._isLeaf || this._level >= this._component.getMaxLevel()) { + return false; + } + if (this._component.__getNumCurrentLoads() >= this._component.__getMaxCurrentLoads()) { + return false; + } + // Always split if we're below the minimum level of detail. + if (this._level < this._component.getMinLevel()) { + return true; + } + // Get the pixel size, used to determine how much we should split. + const tilePixelSize = this._component.__getColorTileSize(); + // Split if the nearest camera distance is less than the threshold. + return this._getNearestDistance() < this._component.__getSplitJoinThresholdFactor() * this._radius / tilePixelSize; + } + + /** + * Returns true if this tile should join its children. + * @returns {boolean} + * @override + */ + checkJoin() { + // Always join is we're above the maximum level of detail. + if (this._level >= this._component.getMaxLevel()) { + return true; + } + if (this._component.__getNumCurrentLoads() >= this._component.__getMaxCurrentLoads()) { + return false; + } + // Never join if we're at or below the minimum level of detail. + if (this._level < this._component.getMinLevel()) { + return false; + } + // Get the pixel size, used to determine how much we should split. + const tilePixelSize = this._component.__getColorTileSize(); + // Check if the nearest camera distance is greater than the threshold. + return this._getNearestDistance() > this._component.__getSplitJoinThresholdFactor() * this._radius / tilePixelSize * 4; + } + + /** + * Asynchronously loads the tile so that it may be used. + * @returns {Promise} + * @override + */ + async load() { + // Increment the number of loads so we don't have too many concurrent loads. + this._component.__incNumCurrentLoads(); + + if (this._threeJsMaterial !== null) { + this._component.__decNumCurrentLoads(); + throw new Error('Tile already has material.'); + } + + // Get a material from the component's materials cache. + this._threeJsMaterial = _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.get(); + this._component.getThreeJsMaterials().push(this._threeJsMaterial); + this._threeJsMaterial.defines['shadowEntities'] = (this._component.getNumShadowEntities() > 0); + // this._threeJsMaterial.wireframe = true; + // this._threeJsMaterial.defines['baseColor'] = true; + // this._threeJsMaterial.uniforms['color'].value.setRGB(0.25 + 0.75 * Math.random(), 0.25 + 0.75 * Math.random(), 0.25 + 0.75 * Math.random()); + + const endPoints = this._component.__getEndPoints(); + // A list of promises that will be returned by load. + const loadPromises = []; + for (let i = 0; i < endPoints.size; i++) { + const textureName = endPoints.getAt(i).key; + const endPoint = endPoints.getAt(i).value; + let texturePromise = /** @type {Promise} */(null); + const textureLevel = this._textureLevels.get(textureName); + const tileX = this._tile.x >> (this._level - textureLevel); + const tileY = this._tile.y >> (this._level - textureLevel); + // Form the URL from the end point and the tile params. + const textureUrl = endPoint.url + '/' + this._face + '/' + textureLevel + '/' + tileX + '/' + tileY + '.' + endPoint.configuration.extension; + // Do the loading of the texture. + texturePromise = this._component.__getTextureCache().get(textureUrl); + this._texturePromises.set(textureName, texturePromise); + loadPromises.push(texturePromise.then((texture) => { + this._setTexture(textureName, texture); + }).catch(async () => { // There was an error, so just set it to pink. + this._component.__getTextureCache().release(texturePromise); + texturePromise = this._component.__getTextureCache().get('pink'); + const texture = await texturePromise; + this._setTexture(textureName, texture); + })); + } + return Promise.all(loadPromises).finally(() => { + this._component.__decNumCurrentLoads(); + }); + } + + /** + * Asynchronously unloads the tile. + * @returns {Promise} + * @override + */ + async unload() { + if (this._threeJsMaterial === null) { + throw new Error('Tile has no material to unload.'); + } + // Remove up the material from the materials list. + const materials = this._component.getThreeJsMaterials(); + for (let i = 0, l = materials.length; i < l; i++) { + if (materials[i] === this._threeJsMaterial) { + materials.splice(i, 1); + break; + } + } + // Dispose of the material. + this._threeJsMaterial.dispose(); + this._threeJsMaterial = null; + // Clean up the texture. + for (let i = 0; i < this._texturePromises.size; i++) { + this._component.__getTextureCache().release(this._texturePromises.getAt(i).value); + } + } + + /** + * Asynchronously activates the tile. + * @returns {Promise} + * @override + */ + async activate() { + if (this._threeJsObject !== null || this._threeJsMaterial === null) { + throw new Error('NULL'); + } + // Setup the attributes, depending on the types of data and textures available. + const attributes = [ + { name: 'position', dimensions: 3 }, + { name: 'normal', dimensions: 3 }, + { name: 'uv', dimensions: 2 } + ]; + const hasNormalTexture = this._textureLevels.has('normal'); + if (hasNormalTexture) { + attributes.push({ name: 'tangent', dimensions: 3 }); + attributes.push({ name: 'bitangent', dimensions: 3 }); + } + for (let i = 0; i < this._textureLevels.size; i++) { + const textureName = this._textureLevels.getAt(i).key; + if (textureName !== 'color' && textureName !== 'height') { + attributes.push({ name: textureName + 'UV', dimensions: 2 }); + } + } + // Create the Three.js object. + this._threeJsObject = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this._component, this._threeJsMaterial, attributes, false); + this._component.getThreeJsObjects().push(this._threeJsObject); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.useInDynEnvMap(this._threeJsObject, true); + + this._setupMesh(); + } + + /** + * Asynchronously deactivates the tile. + * @returns {Promise} + * @override + */ + async deactivate() { + // Remove the object from the objects list. + const objects = this._component.getThreeJsObjects(); + for (let i = 0, l = objects.length; i < l; i++) { + if (objects[i] === this._threeJsObject) { + objects.splice(i, 1); + break; + } + } + // Destroy the object and its geometry. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyObject(this._threeJsObject); + this._threeJsObject = null; + } + + /** + * Updates the tiles recursively. Returns true if the tile or any descendant is transitioning. + * @returns {boolean} + */ + update() { + if (!this._component.__endPointsAreLoaded()) { + return false; + } + let transitioning = this.check(); + for (let i = 0, l = this.children.length; i < l; i++) { + transitioning = this.children[i].update() || transitioning; + } + + // If we're at the root level and it's loaded, see if we need to change to a negative level texture. + if (!transitioning && !this._nonPositiveTextureLoading && this._level === 0 && this.children.length === 0) { + const endPoints = this._component.__getEndPoints(); + for (let i = 0; i < endPoints.size; i++) { + const textureName = endPoints.getAt(i).key; + const endPoint = endPoints.getAt(i).value; + const textureLevel = this._getNonPositiveLevel(textureName); + if (textureLevel !== this._textureLevels.get(textureName)) { + this._nonPositiveTextureLoading = true; + this._textureLevels.set(textureName, textureLevel); + transitioning = true; + // Form the URL from the end point and the tile params. + const textureUrl = endPoint.url + '/' + this._face + '/' + textureLevel + '/0/0.' + endPoint.configuration.extension; + // Save the previous texture promise. + const prevTexturePromise = this._texturePromises.get(textureName); + // Do the loading of the texture. + let texturePromise = this._component.__getTextureCache().get(textureUrl); + this._texturePromises.set(textureName, texturePromise); + texturePromise.then((texture) => { + this._setTexture(textureName, texture); + this._setupMesh(); + this._nonPositiveTextureLoading = false; + }).catch(async () => { // There was an error, so just set it to pink. + this._component.__getTextureCache().release(texturePromise); + texturePromise = this._component.__getTextureCache().get('pink'); + const texture = await texturePromise; + this._setTexture(textureName, texture); + this._nonPositiveTextureLoading = false; + }).finally(() => { + // Now that the new texture is loaded, release the previous texture. + if (textureName !== 'height') { + this._component.__getTextureCache().release(prevTexturePromise); + } + }); + } + } + } + transitioning = this._nonPositiveTextureLoading || transitioning; + + return transitioning; + } + + _setupMesh() { + // Get the pixel tab, used to make mesh tabs. + const tilePixelSize = this._component.__getColorTileSize(); + + // Since there is one set of UVs per texture name, we have to set them up here. + /** @type {FastMap} */ + const meshUVs = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + /** @type {FastMap} */ + const uvOffsets = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + /** @type {FastMap} */ + const uvScales = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + for (let i = 0; i < this._textureLevels.size; i++) { + const textureName = this._textureLevels.getAt(i).key; + // Calculate the uv bounds, since it may be using a material from a different level. + const levelFactor = 1 << (this._level - Math.max(0, this._textureLevels.get(textureName))); + uvOffsets.set(textureName, new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2( + (this._tile.x - Math.floor(this._tile.x / levelFactor) * levelFactor) / levelFactor, + (this._tile.y - Math.floor(this._tile.y / levelFactor) * levelFactor) / levelFactor)); + uvScales.set(textureName, new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(1 / levelFactor, 1 / levelFactor)); + } + const hasNormalTexture = this._textureLevels.has('normal'); + + // Create the vertices, normals, uvs, and indices arrays. + const numUVerts = this._heightData ? _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(Math.ceil(this._heightData.width * uvScales.get('height').x) - 2, 5, 129) : (5 << _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(2 - this._level / 2, 0, 2)); + const numVVerts = this._heightData ? _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(Math.ceil(this._heightData.height * uvScales.get('height').y) - 2, 5, 129) : (5 << _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(2 - this._level / 2, 0, 2)); + const numVerts = numUVerts * numVVerts; + const meshPositions = new Float32Array(numVerts * 3); + const meshNormals = new Float32Array(numVerts * 3); + let meshTangents = null; + let meshBitangents = null; + if (hasNormalTexture) { + meshTangents = new Float32Array(numVerts * 3); + meshBitangents = new Float32Array(numVerts * 3); + } + const meshIndices = new Uint16Array((numUVerts - 1) * (numVVerts - 1) * 6); + for (let i = 0; i < this._textureLevels.size; i++) { + const textureName = this._textureLevels.getAt(i).key; + // Create the uv array. + meshUVs.set(textureName, new Float32Array(numVerts * 2)); + } + + // Get the height offset and scale, if it has a height map. + let heightOffset = 0; + let heightScale = 0; + if (this._textureLevels.has('height')) { + const configuration = this._component.__getEndPoints().get('height').configuration; + heightOffset = configuration['height_range'].min * this._component.getHeightScale(); + heightScale = (configuration['height_range'].max - configuration['height_range'].min) * this._component.getHeightScale(); + } + + // Set the vertices, normals, uvs, and indices arrays. + const tile = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + const pos = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const heightDir = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const up = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const tangent = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const bitangent = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const lla = new _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt(); + const spheroid = this._component.__getSpheroidComponent(); + for (let y = 0; y < numVVerts; y++) { + for (let x = 0; x < numUVerts; x++) { + const vertexI = y * numUVerts + x; + // Get the tile coordinate of this place within the tile. + tile.set(this._tile.x + (x - 1) / (numUVerts - 3), this._tile.y + (y - 1) / (numVVerts - 3)); + + // Convert it to an XYZ. + CMTSTile.cmtsCoordToPosition(pos, this._face, this._levelPow, tile.x, tile.y, spheroid); + if (hasNormalTexture) { + CMTSTile.cmtsCoordToTangent(tangent, this._face, this._levelPow, tile.x, tile.y, spheroid); + CMTSTile.cmtsCoordToBitangent(bitangent, this._face, this._levelPow, tile.x, tile.y, spheroid); + } + + // Convert it to an LLA and get up. + spheroid.llaFromXYZ(lla, pos); + spheroid.upFromLLA(up, lla); + + // Get the height direction. It is not the same as up if it is planetocentric. + if (spheroid.isPlanetographic()) { + heightDir.copy(up); + } + else { + heightDir.normalize(pos); + } + + if (this._heightData) { // If there's a height map, get the heightmap value and apply it to the position. + const data = this._heightData.data; + const uvOffset = uvOffsets.get('height'); + const uvScale = uvScales.get('height'); + const heightTileSize = this._heightData.width - 4; + + // Get the height position. + CMTSTile.getHeightPos(pos, heightDir, x, y, data, uvOffset, numUVerts, numVVerts, uvScale, heightTileSize, heightOffset, heightScale); + // Calculate the normal if there isn't a normal map. + if (!this._textureLevels.has('normal')) { + const posX1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const posX2 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const posY1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const posY2 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const posX1Y1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const posX2Y2 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const temp1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const temp2 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + CMTSTile.cmtsCoordToPosition(posX1, this._face, this._levelPow, tile.x - 1 / (numUVerts - 3), tile.y, spheroid); + CMTSTile.getHeightPos(posX1, heightDir, x - 1, y, data, uvOffset, numUVerts, numVVerts, uvScale, heightTileSize, heightOffset, heightScale); + CMTSTile.cmtsCoordToPosition(posX2, this._face, this._levelPow, tile.x + 1 / (numUVerts - 3), tile.y, spheroid); + CMTSTile.getHeightPos(posX2, heightDir, x + 1, y, data, uvOffset, numUVerts, numVVerts, uvScale, heightTileSize, heightOffset, heightScale); + CMTSTile.cmtsCoordToPosition(posY1, this._face, this._levelPow, tile.x, tile.y - 1 / (numVVerts - 3), spheroid); + CMTSTile.getHeightPos(posY1, heightDir, x, y - 1, data, uvOffset, numUVerts, numVVerts, uvScale, heightTileSize, heightOffset, heightScale); + CMTSTile.cmtsCoordToPosition(posY2, this._face, this._levelPow, tile.x, tile.y + 1 / (numVVerts - 3), spheroid); + CMTSTile.getHeightPos(posY2, heightDir, x, y + 1, data, uvOffset, numUVerts, numVVerts, uvScale, heightTileSize, heightOffset, heightScale); + CMTSTile.cmtsCoordToPosition(posX1Y1, this._face, this._levelPow, tile.x - 1 / (numUVerts - 3), tile.y - 1 / (numVVerts - 3), spheroid); + CMTSTile.getHeightPos(posX1Y1, heightDir, x - 1, y - 1, data, uvOffset, numUVerts, numVVerts, uvScale, heightTileSize, heightOffset, heightScale); + CMTSTile.cmtsCoordToPosition(posX2Y2, this._face, this._levelPow, tile.x + 1 / (numUVerts - 3), tile.y + 1 / (numVVerts - 3), spheroid); + CMTSTile.getHeightPos(posX2Y2, heightDir, x + 1, y + 1, data, uvOffset, numUVerts, numVVerts, uvScale, heightTileSize, heightOffset, heightScale); + posX1.sub(posX2, posX1); + posY1.sub(posY2, posY1); + heightDir.cross(posX1, posY1); + heightDir.normalize(heightDir); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posX1); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posX2); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posY1); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posY2); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posX1Y1); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posX2Y2); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(temp1); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(temp2); + } + } + if (x === 0 || y === 0 || x === numUVerts - 1 || y === numVVerts - 1) { + if (this._textureLevels.has('height')) { + pos.setMagnitude(pos, pos.magnitude() - 2.0 * heightScale * this._levelPow); + } + else { + pos.mult(pos, 0.9); + } + } + + pos.sub(pos, this._tileOffset); + + meshPositions[vertexI * 3 + 0] = pos.x; + meshPositions[vertexI * 3 + 1] = pos.y; + meshPositions[vertexI * 3 + 2] = pos.z; + + meshNormals[vertexI * 3 + 0] = heightDir.x; + meshNormals[vertexI * 3 + 1] = heightDir.y; + meshNormals[vertexI * 3 + 2] = heightDir.z; + + if (hasNormalTexture) { + meshTangents[vertexI * 3 + 0] = tangent.x; + meshTangents[vertexI * 3 + 1] = tangent.y; + meshTangents[vertexI * 3 + 2] = tangent.z; + + meshBitangents[vertexI * 3 + 0] = bitangent.x; + meshBitangents[vertexI * 3 + 1] = bitangent.y; + meshBitangents[vertexI * 3 + 2] = bitangent.z; + } + + for (let i = 0; i < this._textureLevels.size; i++) { + const textureName = this._textureLevels.getAt(i).key; + const uvOffset = uvOffsets.get(textureName); + const uvScale = uvScales.get(textureName); + const uvs = meshUVs.get(textureName); + uvs[vertexI * 2 + 0] = ((uvOffset.x + (x - 1) / (numUVerts - 3) * uvScale.x)) * tilePixelSize / (tilePixelSize + 4) + 2.0 / (tilePixelSize + 4); + uvs[vertexI * 2 + 1] = 1 - (((uvOffset.y + (y - 1) / (numVVerts - 3) * uvScale.y)) * tilePixelSize / (tilePixelSize + 4) + 2.0 / (tilePixelSize + 4)); + } + + if (x < numUVerts - 1 && y < numVVerts - 1) { + const triangleI = y * (numUVerts - 1) + x; + meshIndices[triangleI * 6 + 0] = numUVerts * (y + 0) + (x + 0); + meshIndices[triangleI * 6 + 1] = numUVerts * (y + 0) + (x + 1); + meshIndices[triangleI * 6 + 2] = numUVerts * (y + 1) + (x + 1); + meshIndices[triangleI * 6 + 3] = numUVerts * (y + 0) + (x + 0); + meshIndices[triangleI * 6 + 4] = numUVerts * (y + 1) + (x + 1); + meshIndices[triangleI * 6 + 5] = numUVerts * (y + 1) + (x + 0); + } + } + } + + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(this._threeJsObject.geometry, 'position', meshPositions); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(this._threeJsObject.geometry, 'normal', meshNormals); + if (hasNormalTexture) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(this._threeJsObject.geometry, 'tangent', meshTangents); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(this._threeJsObject.geometry, 'bitangent', meshBitangents); + } + for (let i = 0; i < this._textureLevels.size; i++) { + const textureName = this._textureLevels.getAt(i).key; + const uvs = meshUVs.get(textureName); + if (textureName === 'height') { + continue; + } + if (textureName === 'color') { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(this._threeJsObject.geometry, 'uv', uvs); + } + else { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(this._threeJsObject.geometry, textureName + 'UV', uvs); + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(this._threeJsObject.geometry, meshIndices); + } + + /** + * Gets the non-positive level for root tiles. + * @param {string} textureName + * @returns {number} + * @private + */ + _getNonPositiveLevel(textureName) { + const nearestDistance = this._getNearestDistance(); + const endPoint = this._component.__getEndPoints().get(textureName); + const tilePixelSize = endPoint.configuration.tile_size; + return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(4 - Math.floor(Math.log2(nearestDistance / this._radius / this._component.__getSplitJoinThresholdFactor() * tilePixelSize * 4)), endPoint.configuration.first_level, 0); + } + + /** + * Gets the nearest distance of all cameras to see if we need to split or join this node. + * @private + */ + _getNearestDistance() { + let nearestDistance = Number.POSITIVE_INFINITY; + const cameraPositions = this._component.__getCameraPositions(); + const cameraFieldsOfView = this._component.__getCameraFieldsOfView(); + for (let i = 0, l = cameraPositions.length; i < l; i++) { + const position = cameraPositions[i]; + const fieldOfView = cameraFieldsOfView[i]; + CMTSTile._pos.sub(position, this._center); + const distance = Math.max(0, CMTSTile._pos.magnitude() - this._radius) * Math.tan(fieldOfView / 2); + if (nearestDistance > distance) { + nearestDistance = distance; + } + } + return nearestDistance; + } + + /** + * Converts this to a string. + * @returns {string} + * @override + */ + toString() { + return this._face + '/' + this._level + '/' + this._tile.x + '/' + this._tile.y; + } + + /** + * Prepares the tile for rendering. + * @param {CameraComponent} camera + */ + prepareForRender(camera) { + // Check if the tile should be hidden. + const entity = this._component.getEntity(); + if (this._threeJsObject !== null) { + const cameraSpacePosition = entity.getCameraSpacePosition(camera); + const centerInJ2000 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + centerInJ2000.rotate(entity.getOrientation(), this._center); + const angleBetweenCenterAndCamera = Math.acos(centerInJ2000.dot(cameraSpacePosition) + / centerInJ2000.magnitude() / cameraSpacePosition.magnitude()); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(centerInJ2000); + if (angleBetweenCenterAndCamera < Math.PI / 2 - (Math.PI / 4) * this._levelPow) { + this._threeJsObject.visible = false; + return; + } + } + + // Set the Three.js object position. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this._threeJsObject, this._component.getEntity(), camera, this._tileOffset, true); + + // Prepare the children for rendering. + for (let i = 0, l = this.children.length; i < l; i++) { + this.children[i].prepareForRender(camera); + } + } + + /** + * Sets the texture. + * @param {string} textureName + * @param {THREE.Texture} texture + * @private + */ + _setTexture(textureName, texture) { + if (this._component.getLoadState() !== 'loaded') { + return; + } + if (textureName === 'height') { + const canvas = document.createElement('canvas'); + canvas.width = texture.image.width; + canvas.height = texture.image.height; + const context = canvas.getContext('2d', { desynchronized: true, alpha: false }); + context.drawImage(texture.image, 0, 0); + texture.dispose(); + this._heightData = context.getImageData(0, 0, texture.image.width, texture.image.height); + // Release the used height texture. + this._component.__getTextureCache().release(this._texturePromises.get('height')); + this._texturePromises.delete('height'); + // Recalculate the center using the height data. + const spheroid = this._component.__getSpheroidComponent(); + CMTSTile.cmtsCoordToPosition(this._center, this._face, this._levelPow, this._tile.x + 0.5, this._tile.y + 0.5, spheroid); + const up = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + spheroid.llaFromXYZ(lla, this._center); + spheroid.upFromLLA(up, lla); + const height = CMTSTile.getLinearInterpolatedHeightPixel(this._heightData.width / 2, this._heightData.height / 2, this._heightData.data, this._heightData.width); + const configuration = this._component.__getEndPoints().get('height').configuration; + const heightOffset = configuration['height_range'].min * this._component.getHeightScale(); + const heightScale = (configuration['height_range'].max - configuration['height_range'].min) * this._component.getHeightScale(); + this._center.addMult(this._center, up, heightOffset + height * heightScale); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(up); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + } + else { + this._threeJsMaterial.uniforms[textureName + 'Texture'].value = texture; + if (textureName === 'normal') { + this._threeJsMaterial.defines['normalMap'] = true; + this._threeJsMaterial.defines['normalUVs'] = true; + this._threeJsMaterial.defines['hasBitangents'] = true; + this._threeJsMaterial.uniforms['normalScale'].value.set(this._component.getHeightScale(), this._component.getHeightScale()); + this._threeJsMaterial.uniforms['specularIntensity'].value = 0; + this._threeJsMaterial.uniforms['specularHardness'].value = 100; + } + else if (textureName === 'specular') { + this._threeJsMaterial.defines['specularMap'] = true; + this._threeJsMaterial.defines['specularUVs'] = true; + } + else if (textureName === 'night') { + this._threeJsMaterial.defines['nightMap'] = true; + this._threeJsMaterial.defines['nightUVs'] = true; + } + else if (textureName === 'decal') { + this._threeJsMaterial.defines['decalMap'] = true; + this._threeJsMaterial.defines['decalUVs'] = true; + } + } + } + + /** + * Gets the greatest level available for the given tile. + * @param {CMTSConfiguration} configuration + * @param {number} face + * @param {number} level + * @param {Vector2} tile + * @returns {number} + */ + static _getGreatestLevel(configuration, face, level, tile) { + let greatestLevel = Number.NEGATIVE_INFINITY; + for (let i = 0, l = configuration.boundaries.length; i < l; i++) { + const boundary = configuration.boundaries[i]; + if (boundary.face !== face) { // Different face. + continue; + } + const levelDifference = boundary['last_level'] - level; + if (boundary.min[0] <= (tile.x >> levelDifference) && (tile.x >> levelDifference) <= boundary.max[0] + && boundary.min[1] <= (tile.y >> levelDifference) && (tile.y >> levelDifference) <= boundary.max[1] + && greatestLevel < boundary['last_level']) { + greatestLevel = boundary['last_level']; + } + } + return greatestLevel; + } + + /** + * Returns true if the tile coordinates are within a boundary. + * @param {CMTSConfiguration} configuration + * @param {number} face + * @param {number} level + * @param {Vector2} tile + * @returns {boolean} + */ + static _isInABoundary(configuration, face, level, tile) { + let foundValidBoundary = false; + for (let i = 0, l = configuration.boundaries.length; i < l; i++) { + const boundary = configuration.boundaries[i]; + if (boundary.face !== face) { // Different face. + continue; + } + if (boundary['last_level'] < level) { // Not a deep enough level to cover the child tile. + continue; + } + const levelFactor = 1 << (boundary['last_level'] - level); + if (tile.x < Math.floor(boundary.min[0] / levelFactor) || Math.floor(boundary.max[0] / levelFactor) < tile.x) { + continue; + } + if (tile.y < Math.floor(boundary.min[1] / levelFactor) || Math.floor(boundary.max[1] / levelFactor) < tile.y) { + continue; + } + foundValidBoundary = true; + } + return foundValidBoundary; + } + + /** + * Updates the position based on the tileOffsets. + * @returns {Vector3} + * @private + */ + _getTileOffset() { + const tileOffsets = this._component.__getTileOffsets(); + for (let i = 0, l = tileOffsets.length; i < l; i++) { + const tileOffset = tileOffsets[i]; + if (tileOffset.face !== this._face || tileOffset.level > this._level) { + continue; + } + const levelMult = 1 << (this._level - tileOffset.level); + if (tileOffset.min.x * levelMult <= this._tile.x && this._tile.x < (tileOffset.max.x + 1) * levelMult && tileOffset.min.y * levelMult <= this._tile.y && this._tile.y < (tileOffset.max.y + 1) * levelMult) { + return tileOffset.offset; + } + } + return _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero; + } + + /** + * Adjust the position given the height on a tile. + * @param {Vector3} pos + * @param {Vector3} heightDir + * @param {number} x + * @param {number} y + * @param {Uint8ClampedArray} data + * @param {Vector2} uvOffset + * @param {number} numUVerts + * @param {number} numVVerts + * @param {Vector2} uvScale + * @param {number} heightTileSize + * @param {number} heightOffset + * @param {number} heightScale + */ + static getHeightPos(pos, heightDir, x, y, data, uvOffset, numUVerts, numVVerts, uvScale, heightTileSize, heightOffset, heightScale) { + const u = ((uvOffset.x + (x - 1) / (numUVerts - 3) * uvScale.x)) * heightTileSize / (heightTileSize + 4) + 2.0 / (heightTileSize + 4); + const v = 1 - (((uvOffset.y + (y - 1) / (numVVerts - 3) * uvScale.y)) * heightTileSize / (heightTileSize + 4) + 2.0 / (heightTileSize + 4)); + const pixelX = u * (heightTileSize + 4); + const pixelY = v * (heightTileSize + 4); + const height = this.getLinearInterpolatedHeightPixel(pixelX, pixelY, data, heightTileSize + 4); + pos.addMult(pos, heightDir, heightOffset + height * heightScale); + } + + /** Gets the linearly interpolated height from a pixel. + * @param {number} pixelX + * @param {number} pixelY + * @param {Uint8ClampedArray} data + * @param {number} size + * @returns {number} */ + static getLinearInterpolatedHeightPixel(pixelX, pixelY, data, size) { + const pixelXInt = Math.floor(pixelX); + const pixelYInt = Math.floor(pixelY); + const pixelXFrac = pixelX - pixelXInt; + const pixelYFrac = pixelY - pixelYInt; + const u = Math.abs(pixelXFrac - 0.5); + const v = Math.abs(pixelYFrac - 0.5); + let height = this.getHeightFromPixel(pixelXInt, pixelYInt, data, size) * ((1 - u) * (1 - v)); + if (pixelXFrac >= 0.5) { + height += this.getHeightFromPixel(pixelXInt + 1, pixelYInt, data, size) * (u * (1 - v)); + if (pixelYFrac < 0.5) { + height += this.getHeightFromPixel(pixelXInt + 1, pixelYInt - 1, data, size) * (u * v); + } + else if (pixelYFrac >= 0.5) { + height += this.getHeightFromPixel(pixelXInt + 1, pixelYInt + 1, data, size) * (u * v); + } + } + else if (pixelXFrac < 0.5) { + height += this.getHeightFromPixel(pixelXInt - 1, pixelYInt, data, size) * (u * (1 - v)); + if (pixelYFrac < 0.5) { + height += this.getHeightFromPixel(pixelXInt - 1, pixelYInt - 1, data, size) * (u * v); + } + else if (pixelYFrac >= 0.5) { + height += this.getHeightFromPixel(pixelXInt - 1, pixelYInt + 1, data, size) * (u * v); + } + } + if (pixelYFrac >= 0.5) { + height += this.getHeightFromPixel(pixelXInt, pixelYInt + 1, data, size) * ((1 - u) * v); + } + else if (pixelYFrac < 0.5) { + height += this.getHeightFromPixel(pixelXInt, pixelYInt - 1, data, size) * ((1 - u) * v); + } + return height; + } + + /** Gets the height from a pixel. + * @param {number} pixelX + * @param {number} pixelY + * @param {Uint8ClampedArray} data + * @param {number} size + * @returns {number} */ + static getHeightFromPixel(pixelX, pixelY, data, size) { + pixelX = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(pixelX, 0, size - 1); + pixelY = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(pixelY, 0, size - 1); + const pixelIndex = (pixelY * size + pixelX) * 4; // 4 for the rgba channels. + // We parse the color, combining it into a single 24-bit value. + // Eventually a proposal will allow more efficient types of height data. https://github.com/WICG/canvas-color-space/blob/master/CanvasColorSpaceProposal.md + return data[pixelIndex + 0] / 256 + data[pixelIndex + 1] / 65536 + data[pixelIndex + 2] / 16777216; + } + + /** + * Converts a CMTS coordinate to an XYZ coordinate in the frame of the spheroid. + * @param {Vector3} out + * @param {number} face + * @param {number} levelPow + * @param {number} x + * @param {number} y + * @param {SpheroidComponent} spheroid + */ + static cmtsCoordToPosition(out, face, levelPow, x, y, spheroid) { + let u = x * levelPow; + let v = y * levelPow; + + // If the uv are out of bounds, get the correct uv and face. + while (u < 0 || u > 1 || v < 0 || v > 1) { + if (0 <= face && face <= 3) { // One of the horizontal faces + if (u > 1) { + u -= 1; + face = (face + 1) % 4; + } + else if (u < 0) { + u += 1; + face = (face + 3) % 4; // same as - 1 + } + else if (face === 0) { + if (v < 0) { + v += 1; + face = 5; + } + else if (v > 1) { + v -= 1; + face = 4; + } + } + else if (face === 1) { + if (v < 0) { + const t = u; + u = v + 1; + v = 1 - t; + face = 5; + } + else if (v > 1) { + const t = u; + u = 2 - v; + v = t; + face = 4; + } + } + else if (face === 2) { + if (v < 0) { + u = 1 - u; + v = 0 - v; + face = 5; + } + else if (v > 1) { + u = 1 - u; + v = 2 - v; + face = 4; + } + } + else if (face === 3) { + if (v < 0) { + const t = u; + u = 0 - v; + v = t; + face = 5; + } + else if (v > 1) { + const t = u; + u = v - 1; + v = 1 - t; + face = 4; + } + } + } + else if (face === 4) { + if (u < 0) { + const t = u; + u = 1 - v; + v = t + 1; + face = 3; + } + else if (u > 1) { + const t = u; + u = v; + v = 2 - t; + face = 1; + } + else if (v < 0) { + v += 1; + face = 0; + } + else if (v > 1) { + u = 1 - u; + v = 2 - v; + face = 2; + } + } + else if (face === 5) { + if (u < 0) { + const t = u; + u = v; + v = 0 - t; + face = 3; + } + else if (u > 1) { + const t = u; + u = 1 - v; + v = t - 1; + face = 1; + } + else if (v < 0) { + u = 1 - u; + v = 0 - v; + face = 2; + } + else if (v > 1) { + v -= 1; + face = 0; + } + } + } + + const uT = 2 * u - 1; + const vT = 2 * v - 1; + + const basis = this._basis[face]; + + // Convert to XYZ vector as if it were a sphere. + out.set( + basis[0].x * uT + basis[1].x * vT + basis[2].x, + basis[0].y * uT + basis[1].y * vT + basis[2].y, + basis[0].z * uT + basis[1].z * vT + basis[2].z); + out.normalize(out); + + // Get it as an LLA. + _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLLAFromXYZOnSphere(this._lla, out, 0); + this._lla.alt = 0; + + // Convert to a proper XYZ. + spheroid.xyzFromLLA(out, this._lla); + }; + + /** + * Converts a CMTS coordinate to a tangent XYZ coordinate in the frame of the spheroid. + * @param {Vector3} out + * @param {number} face + * @param {number} levelPow + * @param {number} x + * @param {number} y + * @param {SpheroidComponent} spheroid + */ + static cmtsCoordToTangent(out, face, levelPow, x, y, spheroid) { + this.cmtsCoordToPosition(out, face, levelPow, x, y, spheroid); + const basis = this._basis[face]; + out.setNormalTo(out, basis[0]); + }; + + /** + * Converts a CMTS coordinate to a bitangent XYZ coordinate in the frame of the spheroid. + * @param {Vector3} out + * @param {number} face + * @param {number} levelPow + * @param {number} x + * @param {number} y + * @param {SpheroidComponent} spheroid + */ + static cmtsCoordToBitangent(out, face, levelPow, x, y, spheroid) { + this.cmtsCoordToPosition(out, face, levelPow, x, y, spheroid); + const basis = this._basis[face]; + out.setNormalTo(out, basis[1]); + }; +} + +/** + * The basis vectors for every face. The first corresponds to the U direction, then the V direction, and then out of the face. + */ +CMTSTile._basis = [ + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis], + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis], + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg], + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg], + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis], + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxisNeg] +]; + +/** + * A temporary lat/lon/alt. + */ +CMTSTile._lla = new _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt(); + +/** + * A temporary vector3 + */ +CMTSTile._pos = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + +/** + * @typedef CMTSBoundary + * @property {number} face + * @property {number} last_level + * @property {{ 0: number, 1: number }} min + * @property {{ 0: number, 1: number }} max + */ + +/** + * @typedef CMTSRange { + * @property {number} min + * @property {number} max + */ + +/** + * @typedef CMTSConfiguration + * @property {CMTSBoundary[]} boundaries + * @property {number} first_level + * @property {number} tile_size + * @property {string} extension + * @property {CMTSRange} height_range + */ + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/comet_tail_component.js": +/*!**********************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/comet_tail_component.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CometTailComponent": function() { return /* binding */ CometTailComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A comet coma and tail. + */ +class CometTailComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The light source. + * @type {EntityRef} + * @private + */ + this._lightSource = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + + /** + * The length of the particle stream. + * @type {number} + * @private + */ + this._timeLength = 6e5; + + /** + * The number of particles. + * @type {number} + * @private + */ + this._numberOfParticles = 200; + + /** + * The color of the particles. + * @type {Color} + * @private + */ + this._color = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(); + this._color.freeze(); + + /** + * The force multiplier of the star. + * @type {number} + * @private + */ + this._starAccelerationMultiplier = 1.0; + + /** + * The time of particle 0. All values in originTimeArray are relative to this. + * @type {number} + * @private + */ + this._timeOfParticle0 = 0; + } + + /** + * Returns the light source's name. + * @return {string} + */ + getLightSource() { + return this._lightSource.getName(); + } + + /** + * Sets the light source's name. + * @param {string} lightSource + */ + setLightSource(lightSource) { + this._lightSource.setName(lightSource); + } + + /** + * Gets the length in seconds of the particle stream. + * @returns {number} + */ + getTimeLength() { + return this._timeLength; + } + + /** + * Sets the length of the particle stream. Defaults to 6e5. + * @param {number} length + */ + setTimeLength(length) { + this._timeLength = length; + this.resetResources(); + } + + /** + * Gets the acceleration multiplier of the star. + * @returns {number} + */ + getStarAccelerationMultiplier() { + return this._starAccelerationMultiplier; + } + + /** + * Sets the acceleration multiplier of the star. Defaults to 1. + * @param {number} starAccelerationMultiplier + */ + setStarAccelerationMultiplier(starAccelerationMultiplier) { + this._starAccelerationMultiplier = starAccelerationMultiplier; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'starAccelerationMultiplier', this._starAccelerationMultiplier); + } + + /** + * Gets the number of particles. + * @returns {number} + */ + getNumberOfParticles() { + return this._numberOfParticles; + } + + /** + * Sets the number of particles. Defaults to 100. + * @param {number} numberOfParticles + */ + setNumberOfParticles(numberOfParticles) { + this._numberOfParticles = numberOfParticles; + this.resetResources(); + } + + /** + * Gets the color of the particles. + * @returns {Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the color of the particles. Defaults to white. + * @param {Color} color + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._color); + } + + /** + * Updates the particles. + * @override + */ + __update() { + // Update the radius given the time length. + this.__setRadius(Math.max(this.getEntity().getExtentsRadius(), this._timeLength * this.getEntity().getVelocity().magnitude())); + + // If not loaded, do nothing. + if (this.getLoadState() !== 'loaded') { + return; + } + + // Check if any particles have gone outside the time bounds and recreate them if so. + const time = this.getEntity().getScene().getEngine().getTime(); + const originTimeAttribute = /** @type THREE.Mesh */(this.getThreeJsObjects()[0]).geometry.attributes['originTime']; + const originTimeArray = /** @type {Float32Array} */(originTimeAttribute.array); + for (let i = 0, l = this._numberOfParticles; i < l; i++) { + const particleTime = originTimeArray[i] + this._timeOfParticle0; + if (particleTime < time - this._timeLength || particleTime > time) { + this._newParticle(i, _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(particleTime, time - this._timeLength, time)); + } + } + + // Update the uniform with the time. If there is a single particle, it's a coma, so don't update the time. + if (this._numberOfParticles > 1) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'time', time - this._timeOfParticle0); + } + else { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'time', 0); + } + + // Get the light source for the updates below. + const lightSource = this._lightSource.get(); + if (lightSource !== null) { + // Update the star absolute magnitude. + const lightSourceComponent = /** @type {LightSourceComponent} */(lightSource.getComponentByType('lightSource')); + if (lightSourceComponent !== null) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'starAbsoluteMagnitude', lightSourceComponent.getAbsoluteMagnitude()); + } + + // Update the position entity uniform. + const position = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.getEntity().getPositionRelativeToEntity(position, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, lightSource); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'positionOfEntity', position); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + } + } + + /** + * Prepares the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + // Set the position of the ThreeJs object. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects(), this.getEntity(), camera); + + // Set the position-in-camera as well. + const cameraSpacePosition = this.getEntity().getCameraSpacePosition(camera); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'positionInCamera', cameraSpacePosition); + + if (cameraSpacePosition.magnitude() < 4e4) { + this.getThreeJsObjects()[0].visible = false; + } + else { + const u = (cameraSpacePosition.magnitude() - 4e4) / 4e5; + this.getThreeJsMaterials()[0].uniforms['color'].value.w = this._color.a * _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(u); + this.getThreeJsObjects()[0].visible = true; + } + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + // Setup the Three.js material. + const threeJsMaterial = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RawShaderMaterial({ + uniforms: { + time: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + timeLength: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + positionInCamera: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()), + starAbsoluteMagnitude: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + starAccelerationMultiplier: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + positionOfEntity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()), + color: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4()), + + ..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms + }, + vertexShader: CometTailComponent.vertexShader, + fragmentShader: CometTailComponent.fragmentShader, + transparent: true, + depthWrite: false, + blending: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.AdditiveBlending, + side: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide + }); + _internal__WEBPACK_IMPORTED_MODULE_0__.ShaderFix.fix(threeJsMaterial); + this.getThreeJsMaterials().push(threeJsMaterial); + + // Setup the attribute arrays. + const positionArray = new Float32Array([-1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0]); + const indexArray = new Uint16Array([0, 1, 2, 2, 3, 0]); + const originTimeArray = new Float32Array(1 * this._numberOfParticles); + const originPositionArray = new Float32Array(3 * this._numberOfParticles); + const accelerationMultiplier = new Float32Array(1 * this._numberOfParticles); + + // Setup the Three.js geometry. + const threeJsGeometry = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferGeometry(); + threeJsGeometry.setAttribute('position', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(positionArray, 3)); + threeJsGeometry.setAttribute('originTime', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(originTimeArray, 1)); + threeJsGeometry.setAttribute('originPosition', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(originPositionArray, 3)); + threeJsGeometry.setAttribute('accelerationMultiplier', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(accelerationMultiplier, 1)); + threeJsGeometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(indexArray, 1)); + threeJsGeometry.instanceCount = this._numberOfParticles; + + // Setup the Three.js object. + const threeJsObject = /** @type {THREE.Mesh} */ (_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObjectGivenGeometry(this, threeJsMaterial, threeJsGeometry)); + this.getThreeJsObjects().push(threeJsObject); + + // Setup the arrays. + const time = this.getEntity().getScene().getEngine().getTime(); + for (let i = 0, l = this._numberOfParticles; i < l; i++) { + this._newParticle(i, time - (i / l) * this._timeLength); + } + + // Set the uniforms. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'timeLength', this._timeLength); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'starAccelerationMultiplier', this._starAccelerationMultiplier); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._color); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + } + + /** + * Sets up a new particle at the comet. + * @param {number} i - the particle number + * @param {number} time - the time to instantiate + * @private + */ + _newParticle(i, time) { + // Set the origin time. + const originTime = time; + const originTimeAttribute = /** @type THREE.Mesh */(this.getThreeJsObjects()[0]).geometry.attributes['originTime']; + const originTimeArray = /** @type {Float32Array} */(originTimeAttribute.array); + if (i > 0) { + originTimeArray[i] = originTime - this._timeOfParticle0; + } + else { + // Adjust the rest of the particle times to be relative to the new particle 0. + for (let j = 1, l = this._numberOfParticles; j < l; j++) { + originTimeArray[j] += this._timeOfParticle0 - originTime; + } + this._timeOfParticle0 = originTime; + originTimeArray[0] = 0; + } + originTimeAttribute.needsUpdate = true; + + // Set the origin position. + const originPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const lightSource = this._lightSource.get(); + if (lightSource !== null) { + this.getEntity().getPositionRelativeToEntity(originPosition, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, lightSource, originTime); + } + const originPositionAttribute = /** @type THREE.Mesh */(this.getThreeJsObjects()[0]).geometry.attributes['originPosition']; + const originPositionArray = /** @type {Float32Array} */(originPositionAttribute.array); + originPositionArray[i * 3 + 0] = originPosition.x; + originPositionArray[i * 3 + 1] = originPosition.y; + originPositionArray[i * 3 + 2] = originPosition.z; + originPositionAttribute.needsUpdate = true; + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(originPosition); + + // Set the acceleration factor. + const accelerationMultiplierAttribute = /** @type THREE.Mesh */(this.getThreeJsObjects()[0]).geometry.attributes['accelerationMultiplier']; + const accelerationMultiplierArray = /** @type {Float32Array} */(accelerationMultiplierAttribute.array); + accelerationMultiplierArray[i] = 0 + 1 * Math.random(); + accelerationMultiplierAttribute.needsUpdate = true; + } +} + +CometTailComponent.vertexShader = ` + attribute vec3 position; + attribute float originTime; + attribute vec3 originPosition; + attribute vec3 originStarPosition; + attribute vec3 originExternalAcceleration; + attribute float accelerationMultiplier; + + uniform float time; + uniform float timeLength; + uniform vec3 positionInCamera; + uniform float starAbsoluteMagnitude; + uniform float starAccelerationMultiplier; + uniform vec3 positionOfEntity; + uniform mat4 viewMatrix; + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + varying vec2 vPosition; + varying float vAlpha; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + // Get the position of the center point of the quad in model space. + float deltaTime = time - originTime; + vec3 externalAcceleration = starAccelerationMultiplier * accelerationMultiplier * normalize(originPosition) * 5.0e7 * pow(2.51188643151, 20.0 - starAbsoluteMagnitude) / dot(originPosition, originPosition); + vec3 modelPosition = externalAcceleration * pow(deltaTime, 1.5); + + // Get a general expansion scale in all directions. + float expansion = 0.2 * max(1.0e5, length(modelPosition)); + + // Get the stretch direction in view space. + vec3 modelStretch = modelPosition; + vec3 cameraDirection = normalize(positionInCamera); + modelStretch = modelStretch - dot(cameraDirection, modelStretch) * cameraDirection; + vec4 viewStretch = viewMatrix * vec4(modelStretch, 1.0); + + // Get the stretch amounts in the x and y directions. + vec2 stretch2d = vec2(max(expansion, 2.0 * length(viewStretch.xz)), expansion); + + // Do the stretch calculation on the vertex position in view space. + // It translates it, rotates it, stretches it, and unrotates it. + vec2 translate = 0.5 * normalize(vec2(viewStretch.xz)); + float angle = length(viewStretch.xz) > 0.0 ? atan(viewStretch.z, viewStretch.x) : 0.0; + float cosAngle = cos(angle); + float sinAngle = sin(angle); + float stretchedX = (stretch2d.x * cosAngle * cosAngle + stretch2d.y * sinAngle * sinAngle) * 0.5 * (position.x + translate.x) + (stretch2d.x - stretch2d.y) * sinAngle * cosAngle * 0.5 * (position.y + translate.y); + float stretchedY = (stretch2d.x - stretch2d.y) * sinAngle * cosAngle * 0.5 * (position.x + translate.x) + (stretch2d.x * sinAngle * sinAngle + stretch2d.y * cosAngle * cosAngle) * 0.5 * (position.y + translate.y); + + // Get the position in view space and then in normalized space. + vec4 viewPosition = vec4(stretchedX, 0.0, stretchedY, 0.0) + modelViewMatrix * vec4(modelPosition, 1.0); + gl_Position = projectionMatrix * viewPosition; + gl_Position.w = viewPosition.y; + + // Set the varying variables for adjusting te + vPosition = vec2(cosAngle * position.x + sinAngle * position.y, -sinAngle * position.x + cosAngle * position.y); + vAlpha = sqrt(1.0 - sqrt(deltaTime / timeLength)); + + // Make the gas fade far from the star. + vAlpha *= min(1.0, 1.0 - length(originPosition) / 7.0e8); + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`; + +CometTailComponent.fragmentShader = ` + precision highp float; + + uniform vec4 color; + + varying vec2 vPosition; + varying float vAlpha; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main(void) { + // Set the color to be a circle tinted by the color. + gl_FragColor = vec4(color.rgb, 0.5 * color.a) * max(0.0, 1.0 - dot(vPosition, vPosition)) * vAlpha; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`; + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/connected_sprite_component.js": +/*!****************************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/connected_sprite_component.js ***! + \****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ConnectedSpriteComponent": function() { return /* binding */ ConnectedSpriteComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A 2D sprite in the X-Y plane relative to an entity. + */ +class ConnectedSpriteComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The entity 1 to connect to. + * @type {EntityRef} + * @private + */ + this._entity1 = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + + /** + * The offset of entity 1 in entity 1's frame. + * @type {Vector3} + * @private + */ + this._entity1Offset = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._entity1Offset.freeze(); + + /** + * The entity 2 to connect to. + * @type {EntityRef} + * @private + */ + this._entity2 = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + + /** + * The offset of entity 2 in entity 2's frame. + * @type {Vector3} + * @private + */ + this._entity2Offset = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._entity2Offset.freeze(); + + /** + * The width of the sprite along the axis perpendicular to the line between the two entities at entity 1. + * @type {number} + * @private + */ + this._width1 = 1.0; + + /** + * The width of the sprite along the axis perpendicular to the line between the two entities at entity 2. + * @type {number} + * @private + */ + this._width2 = 1.0; + + /** + * The units of the width. It can be 'px' or 'km'. + * @type {string} + * @private + */ + this._widthUnits = 'km'; + + /** + * The url for the texture. + * @type {string} + * @private + */ + this._textureUrl = ''; + + /** + * The aspect ratio of the texture. + * @type {number} + * @private + */ + this._textureAspectRatio = 1; + + /** + * The flag for whether to repeat or stretch the texture. + * @type {boolean} + * @private + */ + this._textureRepeat = true; + + /** + * The stretch factor for textures. + * @type {number} + * @private + */ + this._textureStretch = 1; + + /** + * The y offset from 0 to 1 of the texture. + * @type {number} + * @private + */ + this._textureYOffset = 0; + + /** + * The u offset from 0 to 1 of the start of the line. 0 is at Entity1, 1 is at Entity2. + * @type {number} + * @private + */ + this._uOffsetStart = 0; + + /** + * The u offset from 0 to 1 of the end of the line. 0 is at Entity1, 1 is at Entity2. + * @type {number} + * @private + */ + this._uOffsetEnd = 1; + + /** + * Each pixel in the texture is multiplied by this value. + * @type {Color} + * @private + */ + this._colorMultiplier = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1); + this._colorMultiplier.freeze(); + + /** + * A flag that determines if the sprite has blending mode. + * @type {string} + * @private + */ + this._blending = 'normal'; + } + + /** + * Gets the entity 1 to connect to. + * @returns {string} + */ + getEntity1() { + return this._entity1.getName(); + } + + /** + * Sets the entity 1 to connect to. It defaults to null. + * @param {string} entityName + */ + setEntity1(entityName) { + this._entity1.setName(entityName); + } + + /** + * Gets the offset of entity 1 in entity 1's frame. + * @returns {Vector3} + */ + getEntity1Offset() { + return this._entity1Offset; + } + + /** + * Sets the offset of entity 1 in entity 1's frame. It defaults to zero. + * @param {Vector3} offset + */ + setEntity1Offset(offset) { + this._entity1Offset.thaw(); + this._entity1Offset.copy(offset); + this._entity1Offset.freeze(); + } + + /** + * Gets the entity 2 to connect to. + * @returns {string} + */ + getEntity2() { + return this._entity2.getName(); + } + + /** + * Sets the entity 2 to connect to. It defaults to null. + * @param {string} entityName + */ + setEntity2(entityName) { + this._entity2.setName(entityName); + } + + /** + * Gets the offset of entity 2 in entity 2's frame. + * @returns {Vector3} + */ + getEntity2Offset() { + return this._entity2Offset; + } + + /** + * Sets the offset of entity 2 in entity 2's frame. It defaults to zero. + * @param {Vector3} offset + */ + setEntity2Offset(offset) { + this._entity2Offset.thaw(); + this._entity2Offset.copy(offset); + this._entity2Offset.freeze(); + } + + /** + * Gets the width of the sprite along the axis perpendicular to the line between the two entities at entity 1. + * @return {number} + */ + getWidth1() { + return this._width1; + } + + /** + * Gets the width of the sprite along the axis perpendicular to the line between the two entities at entity 2. + * @return {number} + */ + getWidth2() { + return this._width2; + } + + /** + * Sets the widths of the sprite along the axis perpendicular to the line between the two entities. It defaults to 1 for both. + * @param {number} width1 - The width near entity1. + * @param {number} width2 - The width near entity2. + */ + setWidths(width1, width2) { + this._width1 = width1; + this._width2 = width2; + } + + /** + * Gets the units of the width. It can be 'px' or 'km'. + * @returns {string} + */ + getWidthUnits() { + return this._widthUnits; + } + + /** + * Sets the units of the width. It can be 'px' or 'km'. Defaults to 'km'. + * @param {string} widthUnits + */ + setWidthUnits(widthUnits) { + this._widthUnits = widthUnits; + if (this.getLoadState() === 'loaded') { + const material = this.getThreeJsMaterials()[0]; + material.defines['PIXEL_BASED'] = (widthUnits === 'px'); + material.needsUpdate = true; + } + } + + /** + * Gets the url of the texture. + * @returns {string} + */ + getTextureUrl() { + return this._textureUrl; + } + + /** + * Sets the url of the texture. It defaults '', meaning no texture. + * @param {string} url + */ + setTextureUrl(url) { + this._textureUrl = url; + this.resetResources(); + } + + /** + * Gets the flag for whether to repeat or stretch the texture. + * @returns {boolean} + */ + getTextureRepeat() { + return this._textureRepeat; + } + + /** + * Sets the flag for whether to repeat or stretch the texture. Defaults to true. + * @param {boolean} repeat + */ + setTextureRepeat(repeat) { + this._textureRepeat = repeat; + } + + /** + * Gets the stretch factor for textures. + * @returns {number} + */ + getTextureStretch() { + return this._textureStretch; + } + + /** + * Sets the stretch factor for textures. Defaults to 1. + * @param {number} stretch + */ + setTextureStretch(stretch) { + this._textureStretch = stretch; + } + + /** + * Gets the y offset from 0 to 1 of the texture. + * @returns {number} + */ + getTextureYOffset() { + return this._textureYOffset; + } + + /** + * Sets the y offset from 0 to 1 of the texture. Defaults to 0. + * @param {number} offset + */ + setTextureYOffset(offset) { + this._textureYOffset = offset; + } + + /** + * Gets the u offset from 0 to 1 of the start of the line. 0 is at Entity1, 1 is at Entity2. + * @returns {number} + */ + getUOffsetStart() { + return this._uOffsetStart; + } + + /** + * Sets the u offset from 0 to 1 of the start of the line. 0 is at Entity1, 1 is at Entity2. Defaults to 0. + * @param {number} uOffsetStart + */ + setUOffsetStart(uOffsetStart) { + this._uOffsetStart = uOffsetStart; + } + + /** + * Gets the u offset from 0 to 1 of the end of the line. 0 is at Entity1, 1 is at Entity2. + * @returns {number} + */ + getUOffsetEnd() { + return this._uOffsetEnd; + } + + /** + * Sets the u offset from 0 to 1 of the end of the line. 0 is at Entity1, 1 is at Entity2. Defaults to 1. + * @param {number} uOffsetEnd + */ + setUOffsetEnd(uOffsetEnd) { + this._uOffsetEnd = uOffsetEnd; + } + + /** + * Gets the color multiplier of the sprite. Each pixel in the texture is multiplied by this color. + * @returns {Color} + */ + getColorMultiplier() { + return this._colorMultiplier; + } + + /** + * Sets the color multiplier of the sprite. Each pixel in the texture is multiplied by this color. It defaults to (1, 1, 1, 1). + * @param {Color} colorMultiplier + */ + setColorMultiplier(colorMultiplier) { + this._colorMultiplier.thaw(); + this._colorMultiplier.copy(colorMultiplier); + this._colorMultiplier.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._colorMultiplier, 1.0); + } + + /** + * Sets blending mode. It defaults to 'normal'. + * @param {string} blending - one of 'normal', 'additive', 'subtractive', 'multliply', 'custom', or 'none' + */ + setBlending(blending) { + this._blending = blending; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setBlending(this.getThreeJsMaterials()[0], blending); + } + + /** + * Updates the camera-independent parts of the component. + * @override + * @internal + */ + __update() { + const entity1 = this._entity1.get(); + const entity2 = this._entity2.get(); + if (entity1 === null || entity2 === null) { + return; + } + + // Update the radius of the component. + const offset = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + entity1.getPositionRelativeToEntity(offset, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, entity2); + this.__setRadius(offset.magnitude() + entity1.getExtentsRadius() + entity2.getExtentsRadius()); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(offset); + } + + /** + * Prepares the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + // If either entity is not there, don't show the line. + const entity1 = this._entity1.get(); + const entity2 = this._entity2.get(); + if (entity1 === null || entity2 === null) { + this.getThreeJsObjects()[0].visible = false; + return; + } + + // Get the two positions in camera space. + const cameraSpacePosition1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const cameraSpacePosition2 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const cameraSpacePosition1Temp = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + cameraSpacePosition1.rotate(entity1.getOrientation(), this._entity1Offset); + cameraSpacePosition1.add(entity1.getCameraSpacePosition(camera), cameraSpacePosition1); + cameraSpacePosition2.rotate(entity2.getOrientation(), this._entity2Offset); + cameraSpacePosition2.add(entity2.getCameraSpacePosition(camera), cameraSpacePosition2); + cameraSpacePosition1Temp.copy(cameraSpacePosition1); + cameraSpacePosition1.lerp(cameraSpacePosition1, cameraSpacePosition2, this._uOffsetStart); + cameraSpacePosition2.lerp(cameraSpacePosition1Temp, cameraSpacePosition2, this._uOffsetEnd); + + // Make entity1 always the closer of the two. Indicate if they were flipped. + let entity1DistanceToCamera = cameraSpacePosition1.magnitude(); + let entity2DistanceToCamera = cameraSpacePosition2.magnitude(); + let entitiesFlipped = false; + if (entity1DistanceToCamera > entity2DistanceToCamera) { + cameraSpacePosition1Temp.copy(cameraSpacePosition1); + cameraSpacePosition1.copy(cameraSpacePosition2); + cameraSpacePosition2.copy(cameraSpacePosition1Temp); + entity1DistanceToCamera = cameraSpacePosition1.magnitude(); + entity2DistanceToCamera = cameraSpacePosition2.magnitude(); + entitiesFlipped = true; + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraSpacePosition1Temp); + + // If we're in pixel mode, make sure the camera-space positions don't get too far from the normal clipping box or + // visual bugs can appear. This clips their x and y to the normal-space bounds. + const normalSpacePosition1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const normalSpacePosition2 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + camera.getNormalSpacePositionFromCameraSpacePosition(normalSpacePosition1, cameraSpacePosition1); + camera.getNormalSpacePositionFromCameraSpacePosition(normalSpacePosition2, cameraSpacePosition2); + + // Get the vertical and horizontal axes. The vertical is the one connecting the entities. + const vAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const hAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + vAxis.sub(cameraSpacePosition2, cameraSpacePosition1); + hAxis.copy(cameraSpacePosition1); + hAxis.cross(vAxis, hAxis); + hAxis.normalize(hAxis); + + // Make the vAxis shorter so that we don't have such large numbers. + vAxis.setMagnitude(vAxis, Math.min(vAxis.magnitude(), entity1DistanceToCamera * 10)); + cameraSpacePosition2.add(cameraSpacePosition1, vAxis); + camera.getNormalSpacePositionFromCameraSpacePosition(normalSpacePosition2, cameraSpacePosition2); + entity2DistanceToCamera = cameraSpacePosition2.magnitude(); + + // Get the widths at each entity and the 'midpoint' value. + let width1 = entitiesFlipped ? this._width2 : this._width1; + let width2 = entitiesFlipped ? this._width1 : this._width2; + + // If we're in pixel mode, the widths need to be adjusted from pixel-space to camera-space. + if (this._widthUnits === 'px') { + const forward = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + camera.getEntity().getOrientation().getAxis(forward, 1); + width1 = camera.getViewport().getNormalSpaceRadiusFromPixelSpaceRadius(width1); + width2 = camera.getViewport().getNormalSpaceRadiusFromPixelSpaceRadius(width2); + width1 = camera.getRadiusFromNormalSpaceRadius(width1, cameraSpacePosition1.dot(forward)); + width2 = camera.getRadiusFromNormalSpaceRadius(width2, cameraSpacePosition2.dot(forward)); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(forward); + } + + // Get the amount to repeat the texture. + let repeatAmount = 1 / this._textureStretch; + if (this._widthUnits === 'px') { + if (this._textureRepeat) { + const pixelSpacePosition1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + const pixelSpacePosition2 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + camera.getViewport().getPixelSpacePositionFromNormalSpacePosition(pixelSpacePosition1, normalSpacePosition1); + camera.getViewport().getPixelSpacePositionFromNormalSpacePosition(pixelSpacePosition2, normalSpacePosition2); + const pixelDiff = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + pixelDiff.sub(pixelSpacePosition1, pixelSpacePosition2); + if (pixelDiff.isNaN()) { + const bounds = camera.getViewport().getBounds(); + pixelDiff.x = bounds.size.x * (normalSpacePosition2.x - normalSpacePosition1.x) / 2.0; + pixelDiff.y = bounds.size.y * (normalSpacePosition2.y - normalSpacePosition1.y) / 2.0; + } + repeatAmount *= pixelDiff.magnitude() / Math.max(this._width1, this._width2) * this._textureAspectRatio; + + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelDiff); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelSpacePosition1); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelSpacePosition2); + } + } + else { + if (this._textureRepeat) { + repeatAmount *= vAxis.magnitude() / Math.max(this._width1, this._width2) * this._textureAspectRatio; + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(normalSpacePosition1); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(normalSpacePosition2); + + // Set the camera position of the Three.js object. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPosition(this.getThreeJsObjects(), cameraSpacePosition1); + + // Update the uniforms. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'vAxis', vAxis); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'width1', width1); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'width2', width2); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'textureYOffset', this._textureYOffset * (entitiesFlipped ? -1 : 1)); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'repeatAmount', repeatAmount); + + // Release the temporaries. + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraSpacePosition1); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraSpacePosition2); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(vAxis); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(hAxis); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + // Load the texture. + const texture = await _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTexture(this, this._textureUrl, true, false); + texture.wrapT = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RepeatWrapping; + this._textureAspectRatio = texture.image.width / texture.image.height; + + // Check if the component has since stopped loading. + if (this.getLoadState() !== 'loading') { + texture.dispose(); + return; + } + + // Create the material. + const threeJsMaterial = this.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('connected_sprite'); + this.getThreeJsMaterials().push(threeJsMaterial); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setBlending(this.getThreeJsMaterials()[0], this._blending); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setDefine(threeJsMaterial, 'PIXEL_BASED', (this._widthUnits === 'px')); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(threeJsMaterial, 'color', this._colorMultiplier, 1.0); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformTexture(threeJsMaterial, 'colorTexture', texture); + + // Create the object. + const threeJsObject = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this, threeJsMaterial, [ + { name: 'position', dimensions: 2 }], false); + this.getThreeJsObjects().push(threeJsObject); + + // Setup the vertices and indices. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(threeJsObject.geometry, 'position', new Float32Array([-1, 0, 1, 0, -1, 1, 1, 1])); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(threeJsObject.geometry, new Uint16Array([0, 2, 3, 3, 1, 0])); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/div_component.js": +/*!***************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/div_component.js ***! + \***************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "DivComponent": function() { return /* binding */ DivComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * Div component. Creates an HTML div element located at position of the entity, using absolute positioning. +*/ +class DivComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The camera in which the div is active. + * @type {CameraComponent} + * @private + */ + this._activeCamera = null; + + /** + * The flag that determines whether or not the div ignores the distance to the camera when determining visibility. + * @type {boolean} + * @private + */ + this._fadeWhenCloseToCamera = true; + + /** + * The entity that, if defined, when the div gets close to, fades away. If set to '', it defaults to the parent. + * @type {EntityRef} + * @private + */ + this._fadeWhenCloseToEntity = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + + /** + * The HTML div element. It will be contained in the labels container div, which will be after the canvas element. + * @type {HTMLDivElement} + * @private + */ + this._div = document.createElement('div'); + this._div.style.position = 'absolute'; + this._div.style.left = '0'; + this._div.style.top = '0'; + this._div.style.transform = 'translate(0%, 0%);'; + + /** + * The alignment of the text. + * @type {Vector2} + * @private + */ + this._alignment = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0.0, 0.5); + this._alignment.freeze(); + + /** + * The size of the div in px. Used instead of offsetWidth/offsetHeight every frame so as not to trigger reflow. + * @type {Vector2} + * @private + */ + this._sizeInPx = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0, 0); + + /** + * The current html, used to see if the sizeInPx needs to be updated. + * @type {string} + * @private + */ + this._currentHTML = ''; + + // Set the radius to infinity, since it will always be visible. + this.__setRadius(Number.POSITIVE_INFINITY); + } + + /** + * Gets the div. + * @returns {HTMLDivElement} + */ + getDiv() { + return this._div; + } + + /** + * Gets the camera in which the div is active. + * @returns {CameraComponent} + */ + getActiveCamera() { + return this._activeCamera; + } + + /** + * Sets the camea in which the div is active. Defaults to the first viewport when created. + * @param {CameraComponent} activeCamera + */ + setActiveCamera(activeCamera) { + this._activeCamera = activeCamera; + this.resetResources(); + } + + /** + * Gets the flag that determines whether or not the div ignores the distance to the camera when determining visibility. + * @returns {boolean} + */ + getFadeWhenCloseToCamera() { + return this._fadeWhenCloseToCamera; + } + + /** + * Sets the flag that determines whether or not the div ignores the distance to the camera when determining visibility. Defaults to true. + * @param {boolean} enable + */ + setFadeWhenCloseToCamera(enable) { + this._fadeWhenCloseToCamera = enable; + } + + /** + * Gets the entity name that, if defined, when the div gets close to, fades away. + * @returns {string} + */ + getFadeWhenCloseToEntity() { + return this._fadeWhenCloseToEntity.getName(); + } + + /** + * Sets the entity name that, if defined, when the div gets close to, fades away. If set to '', it defaults to the parent. Defaults to ''. + * @param {string} entityName + */ + setFadeWhenCloseToEntity(entityName) { + this._fadeWhenCloseToEntity.setName(entityName); + } + + /** + * Gets the div alignment. Defaults to the left aligned to the entity and vertically centered. + * @returns {Vector2} + */ + getAlignment() { + return this._alignment; + } + + /** + * Sets the alignment. Defaults to Vector2(0.0, 0.5). + * @param {Vector2} alignment - the alignment to set + */ + setAlignment(alignment) { + this._alignment.thaw(); + this._alignment.copy(alignment); + this._alignment.freeze(); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + // Detach the div from its parent. + if (this._div.parentNode !== null) { + this._div.parentNode.removeChild(this._div); + } + } + + /** + * Prepares the component for render. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + // If there's no active camera, set the first viewport as the default one. + if (this._activeCamera === null) { + const firstViewport = this.getEntity().getScene().getEngine().getViewport(0); + if (firstViewport !== null) { + this._activeCamera = firstViewport.getCamera(); + } + } + // Check to see that there's a camera and viewport set up. + if (this._activeCamera !== camera || this._activeCamera === null || this._activeCamera.getViewport() === null) { + return; + } + // Attach the div to the viewport's div, if it isn't already done. + if (this._activeCamera.getViewport().getDiv() !== this._div.parentNode) { + this._activeCamera.getViewport().getDiv().appendChild(this._div); + } + + let alphaMultiplier = 1; + + // Fade the label when too close to the object. + if (alphaMultiplier > 0 && this._fadeWhenCloseToCamera) { + const normalizedSizeOfEntity = this.getEntity().getNormalSpaceExtentsRadius(camera); + alphaMultiplier *= _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((0.02 - normalizedSizeOfEntity) / 0.02); + } + + // Fade the div when the entity div is visually close to the closest parent div. + const cameraSpacePosition = this.getEntity().getCameraSpacePosition(camera); + if (alphaMultiplier > 0) { + let closeToEntity = /** @type {Entity} */(null); + if (this._fadeWhenCloseToEntity.getName() === '') { + closeToEntity = this.getEntity().getParent(); + } + else { + closeToEntity = this._fadeWhenCloseToEntity.get(); + } + if (closeToEntity !== null) { + const normalSpaceDifferenceFromParent = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + normalSpaceDifferenceFromParent.sub(this.getEntity().getNormalSpacePosition(camera), closeToEntity.getNormalSpacePosition(camera)); + const normalizedEntityDistanceFromParent = normalSpaceDifferenceFromParent.magnitude(); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(normalSpaceDifferenceFromParent); + const normalizedParentRadius = closeToEntity.getNormalSpaceExtentsRadius(camera); + if (normalizedParentRadius < 0.02) { + alphaMultiplier *= _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((normalizedEntityDistanceFromParent - 0.02) / 0.02); + } + } + } + + // If it is occluded, hide the div. Check parent always, too. + if (alphaMultiplier > 0) { + if (this.getEntity().getParent() !== null && this.getEntity().getParent().isOccludingPosition(camera, cameraSpacePosition)) { + alphaMultiplier = 0; + } + else if (camera.isPositionOccluded(cameraSpacePosition)) { + alphaMultiplier = 0; + } + } + + // If the div is behind the camera, make it invisible. + if (alphaMultiplier > 0) { + const cameraForward = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + camera.getEntity().getOrientation().getAxis(cameraForward, 1); + if (cameraForward.dot(this.getEntity().getCameraSpacePosition(camera)) <= 0) { + alphaMultiplier = 0; + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraForward); + } + + // Set the opacity and pointerEvents from the above conditions. + if (this._div.style.opacity !== '' + alphaMultiplier) { + this._div.style.opacity = '' + alphaMultiplier; + if (alphaMultiplier === 0) { + this._div.style.pointerEvents = 'none'; + } + else { + this._div.style.pointerEvents = ''; + } + } + + if (alphaMultiplier > 0) { + // Update the pixel size if needed. + if (this._currentHTML !== this._div.innerHTML) { + this._sizeInPx.set(this._div.offsetWidth, this._div.offsetHeight); + this._currentHTML = this._div.innerHTML; + } + + // Set the position of the div. + const renderBounds = camera.getViewport().getBounds(); + const pixelSpacePosition = this.getEntity().getPixelSpacePosition(camera); + const left = pixelSpacePosition.x - this._sizeInPx.x * this._alignment.x - renderBounds.origin.x + (renderBounds.size.x % 2 === 0 ? -0.5 : 0); + const top = pixelSpacePosition.y - this._sizeInPx.y * this._alignment.y - renderBounds.origin.y + (renderBounds.size.y % 2 === 0 ? -0.5 : 0); + this._div.style.transform = `translate(${left}px, ${top}px)`; + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/dynamic_environment_map_component.js": +/*!***********************************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/dynamic_environment_map_component.js ***! + \***********************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "DynamicEnvironmentMapComponent": function() { return /* binding */ DynamicEnvironmentMapComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * Environmental map component. The entity should also have a camera component. + */ +class DynamicEnvironmentMapComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The face width of the highest resolution render. Must be power of two. + * @type {number} + * @private + */ + this._faceSize = 64; + + /** + * The color of the invalid area. Used for finding meshes with bad normals or faces. + * @type {Color} + * @private + */ + this._invalidColor = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0, 0, 0, 1); + this._invalidColor.freeze(); + + // STUFF FOR RENDERING FACES + + /** + * The Three.js renderer. + * @type {THREE.WebGLRenderer} + * @private + */ + this._threeJsRenderer = this.getEntity().getScene().getEngine().__getThreeJsRenderer(); + + /** + * The three js cameras. + * @type {THREE.PerspectiveCamera[]} + * @private + */ + this._threeJsFaceCameras = []; + + /** + * This render targets. + * @type {THREE.WebGLRenderTarget[]} + * @private + */ + this._threeJsFaceRenderTargets = []; + + // STUFF FOR RENDERING FINAL TEXTURE + + /** + * The ThreeJS quad. + * @type {THREE.Mesh} + * @private + */ + this._threeJsQuad = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh(); + + /** + * The ThreeJS scene. + * @type {THREE.Scene} + * @private + */ + this._threeJsScene = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Scene(); + + /** + * The ThreeJS cube camera. + * @type {THREE.OrthographicCamera} + * @private + */ + this._threeJsCubeCamera = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.OrthographicCamera(-1, 1, -1, 1, -1, 1); + + /** + * This render target is the texture that will be used as the environment map. + * @private + */ + this._envMapTexture = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderTarget(this._faceSize * 4, this._faceSize * 4, { minFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter, magFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter, wrapS: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ClampToEdgeWrapping, wrapT: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ClampToEdgeWrapping }); + + // Setup the cameras. + this._setupFaceCameras(); + + // Setup the quad for the final render. + this._setupQuad(); + } + + /** + * Gets the face size. + * @return {number} + */ + getFaceSize() { + return this._faceSize; + } + + /** + * Sets the face size. Defaults to 64. + * @param {number} faceSize + */ + setFaceSize(faceSize) { + this._faceSize = faceSize; + if (this._envMapTexture.width !== this._faceSize * 4) { + this._envMapTexture.setSize(this._faceSize * 4, this._faceSize * 4); + this._threeJsQuad.material.uniforms['faceSize'].value = this._faceSize; + } + for (let face = 0; face < 6; face++) { + this._threeJsFaceRenderTargets[face].setSize(this._faceSize, this._faceSize); + } + } + + /** + * Gets the color of the invalid area. Used for finding meshes with bad normals or faces. + * @returns {Color} + */ + getInvalidColor() { + return this._invalidColor; + } + + /** + * Sets the color of the invalid area. Used for finding meshes with bad normals or faces. + * @param {Color} invalidColor + */ + setInvalidColor(invalidColor) { + this._invalidColor.thaw(); + this._invalidColor.copy(invalidColor); + this._invalidColor.freeze(); + if (this._threeJsQuad !== null) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGB(this._threeJsQuad.material, 'invalidColor', this._invalidColor); + } + } + + /** + * Gets the environment map texture. + * @returns {THREE.Texture} + */ + getTexture() { + return this._envMapTexture.texture; + } + + // INTERNALS + + /** + * Cleans up the component. + * @override + * @internal + */ + __destroy() { + this._threeJsQuad.geometry.dispose(); + this._threeJsQuad.material.dispose(); + this._envMapTexture.dispose(); + for (let i = 0; i < this._threeJsFaceRenderTargets.length; i++) { + this._threeJsFaceRenderTargets[i].dispose(); + } + super.__destroy(); + } + + /** + * Renders the camera. Called by Viewport. + * @internal + */ + __render() { + // Update the projection matrix. + this._updateProjectionMatrix(); + + // Set the camera's orientation for each of the face cameras. + const sqrt2 = 0.7071067811865476; + _tempThreeJsQuaternion.set(0, 0, -sqrt2, sqrt2); + this._threeJsFaceCameras[0].setRotationFromQuaternion(_tempThreeJsQuaternion); + _tempThreeJsQuaternion.set(0, 0, 0, 1); + this._threeJsFaceCameras[1].setRotationFromQuaternion(_tempThreeJsQuaternion); + _tempThreeJsQuaternion.set(0, 0, sqrt2, sqrt2); + this._threeJsFaceCameras[2].setRotationFromQuaternion(_tempThreeJsQuaternion); + _tempThreeJsQuaternion.set(0, 0, 1, 0); + this._threeJsFaceCameras[3].setRotationFromQuaternion(_tempThreeJsQuaternion); + _tempThreeJsQuaternion.set(0.5, -0.5, -0.5, 0.5); + this._threeJsFaceCameras[4].setRotationFromQuaternion(_tempThreeJsQuaternion); + _tempThreeJsQuaternion.set(-0.5, 0.5, -0.5, 0.5); + this._threeJsFaceCameras[5].setRotationFromQuaternion(_tempThreeJsQuaternion); + + // Render each of the face cameras to the render targets. + for (let face = 0; face < 6; face++) { + this._threeJsRenderer.setRenderTarget(this._threeJsFaceRenderTargets[face]); + this._threeJsRenderer.render(this.getEntity().getScene().getThreeJsScene(), this._threeJsFaceCameras[face]); + } + + // Render to the environment map texture using the render targets. + this._threeJsRenderer.setRenderTarget(this._envMapTexture); + // this._threeJsRenderer.setRenderTarget(null); + this._threeJsRenderer.render(this._threeJsScene, this._threeJsCubeCamera); + } + + /** + * Sets up the cameras. + * @private + */ + _setupFaceCameras() { + for (let face = 0; face < 6; face++) { + this._threeJsFaceCameras.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.PerspectiveCamera(90.0, 1.0, 0.1, 1000)); + const projectionMatrix = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix4(); + projectionMatrix.set( + 1, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + 0, 1, 0, 0); + this._threeJsFaceCameras[face].projectionMatrix = projectionMatrix; + const projectionMatrixInverse = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix4(); + projectionMatrixInverse.set( + 1, 0, 0, 0, + 0, 0, 0, 1, + 0, 1, 0, 0, + 0, 0, 1, 0); + this._threeJsFaceCameras[face].projectionMatrixInverse = projectionMatrixInverse; + this._threeJsFaceCameras[face].layers.set(1); + + const renderTarget = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderTarget(this._faceSize, this._faceSize, { minFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter, magFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter }); + this._threeJsFaceRenderTargets.push(renderTarget); + } + } + + /** + * Updates the projection. + * @private + */ + _updateProjectionMatrix() { + const cameraComponent = /** @type {CameraComponent} */(this.getEntity().get('camera')); + if (cameraComponent === null) { + return; + } + const f1 = 1.0 - Number.EPSILON; + const f2 = -cameraComponent.getAutoNearDistance() * (2.0 - Number.EPSILON); + for (let face = 0; face < 6; face++) { + this._threeJsFaceCameras[face].projectionMatrix.elements[6] = f1; + this._threeJsFaceCameras[face].projectionMatrix.elements[14] = f2; + this._threeJsFaceCameras[face].projectionMatrixInverse.elements[11] = 1 / f2; + this._threeJsFaceCameras[face].projectionMatrixInverse.elements[15] = -f1 / f2; + } + } + + /** + * Sets the quad meshes up. + */ + _setupQuad() { + // Setup geometry. + const geometry = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferGeometry(); + const meshPositions = new Float32Array([-1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0]); + const meshIndices = new Uint16Array([0, 1, 2, 0, 2, 3]); + geometry.setAttribute('position', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(meshPositions, 3)); + geometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(meshIndices, 1)); + + // Setup material uniforms. + const uniforms = { + textures: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([]), + faceSize: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._faceSize), + invalidColor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(this._invalidColor.r, this._invalidColor.g, this._invalidColor.b)) + }; + for (let face = 0; face < 6; face++) { + uniforms['textures'].value.push(this._threeJsFaceRenderTargets[face].texture); + } + + // Setup material. + const material = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RawShaderMaterial({ + uniforms: uniforms, + vertexShader: ` + attribute vec3 position; + varying vec2 xy; + void main() { + gl_Position = vec4(position, 1.0); + xy = position.xy; + }`, + fragmentShader: ` + precision highp float; + + uniform sampler2D textures[6]; + uniform float faceSize; + uniform vec3 invalidColor; + + varying vec2 xy; + + void adjustTextureCoordsForBorders(inout int textureIndex, inout vec2 xyInTexture, in float pixelSize) { + // Get the pixells in pixel-space. + vec2 xyInPixels = xyInTexture * pixelSize; + + // Flip the x since this code is for surface cubes, but we're inside out. + xyInPixels.x = pixelSize - xyInPixels.x; + + // If it's a border, adjust the pixel it's reading the next pixel in one face over. + // This allows for nice linear filtering to happen on the material side of things. + if (xyInPixels.x < 0.6 || xyInPixels.x > pixelSize - 0.6 || xyInPixels.y < 0.6 || xyInPixels.y > pixelSize - 0.6) { + if (0 <= textureIndex && textureIndex <= 3) { // One of the horizontal faces + if (xyInPixels.x > pixelSize - 0.6) { + xyInPixels.x = 1.5; + textureIndex = (textureIndex + 1); + if (textureIndex == 4) { + textureIndex = 0; + } + } + else if (xyInPixels.x < 0.6) { + xyInPixels.x = pixelSize - 1.5; + textureIndex = textureIndex - 1; + if (textureIndex == -1) { + textureIndex = 3; + } + } + } + if (textureIndex == 0) { + if (xyInPixels.y < 0.6) { + xyInPixels.y = pixelSize - 1.5; + textureIndex = 5; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.y = 1.5; + textureIndex = 4; + } + } + if (textureIndex == 1) { + if (xyInPixels.y < 0.6) { + xyInPixels.y = pixelSize - xyInPixels.x; + xyInPixels.x = pixelSize - 1.5; + textureIndex = 5; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.y = xyInPixels.x; + xyInPixels.x = pixelSize - 1.5; + textureIndex = 4; + } + } + if (textureIndex == 2) { + if (xyInPixels.y < 0.6) { + xyInPixels.x = pixelSize - xyInPixels.x; + xyInPixels.y = 1.5; + textureIndex = 5; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.x = pixelSize - xyInPixels.x; + xyInPixels.y = pixelSize - 1.5; + textureIndex = 4; + } + } + if (textureIndex == 3) { + if (xyInPixels.y < 0.6) { + xyInPixels.y = xyInPixels.x; + xyInPixels.x = 1.5; + textureIndex = 5; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.y = pixelSize - xyInPixels.x; + xyInPixels.x = 1.5; + textureIndex = 4; + } + } + if (textureIndex == 4) { + if (xyInPixels.x < 0.6) { + xyInPixels.x = pixelSize - xyInPixels.y; + xyInPixels.y = pixelSize - 1.5; + textureIndex = 3; + } + else if (xyInPixels.x > pixelSize - 0.6) { + xyInPixels.x = xyInPixels.y; + xyInPixels.y = pixelSize - 1.5; + textureIndex = 1; + } + if (xyInPixels.y < 0.6) { + xyInPixels.y = pixelSize - 1.5; + textureIndex = 0; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.x = pixelSize - xyInPixels.x; + xyInPixels.y = pixelSize - 1.5; + textureIndex = 2; + } + } + if (textureIndex == 5) { + if (xyInPixels.x < 0.6) { + xyInPixels.x = xyInPixels.y; + xyInPixels.y = 1.5; + textureIndex = 3; + } + else if (xyInPixels.x > pixelSize - 0.6) { + xyInPixels.x = pixelSize - xyInPixels.y; + xyInPixels.y = 1.5; + textureIndex = 1; + } + if (xyInPixels.y < 0.6) { + xyInPixels.x = pixelSize - xyInPixels.x; + xyInPixels.y = 1.5; + textureIndex = 2; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.y = 1.5; + textureIndex = 0; + } + } + } + + // Shrink all pixels so that they fit within the border. + // The border pixels have already been modified so that they work with this equation. + xyInPixels.x = ((pixelSize - 1.0) * xyInPixels.x - pixelSize) / (pixelSize - 3.0); + xyInPixels.y = ((pixelSize - 1.0) * xyInPixels.y - pixelSize) / (pixelSize - 3.0); + + // Flip the x back. + xyInPixels.x = pixelSize - xyInPixels.x; + + // Go back into unit-space. + xyInTexture = xyInPixels / pixelSize; + } + + void main() { + // Make it pink everywhere else for easy debugging. + vec3 color = invalidColor; + // Get the mip level, size, and offset. + float level = floor(1.0 - log2(1.0 - xy.y)); // 0 is base, then 1, etc. + float mipSizeX = pow(2.0, -level); // 1, .5, .25, .125, etc. + float mipOffsetY = 1.0 - pow(2.0, -level); // 0, .5, .75, .875, etc. + // Get the xy within the mip level. Note the x value is * 3 for less computing further on. + vec2 xyInMip; + xyInMip.x = 0.5 * (xy.x + 1.0) / mipSizeX * 4.0; + xyInMip.y = (xy.y + 1.0 - 2.0 * mipOffsetY) / mipSizeX; + if (xyInMip.x <= 3.0) { + int textureIndex = int(floor(xyInMip.y * 2.0) * 3.0 + floor(xyInMip.x)); + // Get the xy within the face/texture. + vec2 xyInTexture; + xyInTexture.x = 1.0 - xyInMip.x + floor(xyInMip.x); + xyInTexture.y = 2.0 * (xyInMip.y - floor(xyInMip.y * 2.0) / 2.0); + // Adjust the coordinates and face to account for borders. + adjustTextureCoordsForBorders(textureIndex, xyInTexture, faceSize * mipSizeX); + // Set the color based on the face (textureIndex) and the coords. + if (textureIndex == 0) { + color = texture2D(textures[0], xyInTexture).rgb; + } + else if (textureIndex == 1) { + color = texture2D(textures[1], xyInTexture).rgb; + } + else if (textureIndex == 2) { + color = texture2D(textures[2], xyInTexture).rgb; + } + else if (textureIndex == 3) { + color = texture2D(textures[3], xyInTexture).rgb; + } + else if (textureIndex == 4) { + color = texture2D(textures[4], xyInTexture).rgb; + } + else if (textureIndex == 5) { + color = texture2D(textures[5], xyInTexture).rgb; + } + } + gl_FragColor = vec4(color, 1.0); + }`, + depthTest: false, + depthWrite: false + }); + + // Setup object. + this._threeJsQuad = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh(geometry, material); + this._threeJsQuad.frustumCulled = false; + this._threeJsScene.add(this._threeJsQuad); + } +} + +/** + * A temporary ThreeJs Quaternion. + * @type {THREE.Quaternion} + * @private + */ +const _tempThreeJsQuaternion = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Quaternion(); + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/gizmo_component.js": +/*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/gizmo_component.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "GizmoComponent": function() { return /* binding */ GizmoComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * Red, green, blue axes to help in understanding the orientation of an object. + */ +class GizmoComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The size of the gizmo lines. If not set, defaults to two times the radius of the entity. + * @type {number | undefined} + * @private + */ + this._size = undefined; + + /** + * Whether or not the gizmo lines are relative to the orientation of the entity. + * @type {boolean} + * @private + */ + this._relativeToEntity = true; + + /** + * The joint for the model to show the gizmo. If empty, the entity itself is used. + * @type {string} + * @private + */ + this._joint = ''; + + /** + * The joint's ThreeJs object. + * @type {THREE.Object3D} + * @private + */ + this._jointObject = null; + + /** + * The model for the joint. + * @type {ModelComponent} + * @private + */ + this._model = null; + + /** + * The line mesh. + * @type {LineMesh} + * @private + */ + this._lineMesh = null; + + // Set the radius to twice the entity's radius. + this.__setRadius(entity.getExtentsRadius() * 2.0); + + // It uses the entity's orientation. + this.__setUsesEntityOrientation(this._relativeToEntity); + } + + /** + * Gets the size of the gizmo lines. If not set, defaults to two times the extents radius of the entity. + * @returns {number} + */ + getSize() { + if (this._size !== undefined) { + return this._size; + } + else { + return Math.max(0.0001, this.getEntity().getExtentsRadius() * 2.0); + } + } + + /** + * Sets the size of the gizmo lines. If not set, defaults to two times the extents radius of the entity. + * @param {number} [size] + */ + setSize(size) { + this._size = size; + this.__setRadius(this.getSize()); + } + + /** + * Gets whether or not the gizmo lines are relative to the orientation of the entity. Defaults to true. + * @returns {boolean} + */ + isRelativeToEntity() { + return this._relativeToEntity; + } + + /** + * Sets whether or not the gizmo lines are relative to the orientation of the entity. + * @param {boolean} relativeToEntity + */ + setRelativeToEntity(relativeToEntity) { + this._relativeToEntity = relativeToEntity; + this.__setUsesEntityOrientation(this._relativeToEntity); + } + + /** + * Sets the gizmo to be at the joint on the specified model. If no model is given, the first model in the entity is used. + * @param {string} joint + * @param {ModelComponent} [model] + */ + setJoint(joint, model) { + this._joint = joint; + if (!model) { + const modelFromEntity = /** @type {ModelComponent} */(this.getEntity().get('model')); + if (modelFromEntity !== null) { + this._model = modelFromEntity; + } + } + else { + this._model = model; + } + } + + /** + * Prepare the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + // If a joint is specified, setup the joint's ThreeJs object. + if (this._joint !== '' && (this._jointObject === null || this._jointObject.name !== this._joint) && this._model !== null) { + this._jointObject = this._model.getThreeJsObjectByName(this._joint); + } + // If the joint object is valid, + if (this._jointObject !== null) { + // Get the position of the joint within the entity by adding up the ancestor positions. + const position = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + let jointAncestor = this._jointObject; + GizmoComponent._tempThreeJsVector3.copy(jointAncestor.position); + GizmoComponent._tempThreeJsQuaternion.copy(jointAncestor.quaternion); + while (jointAncestor.parent !== null && jointAncestor.parent !== this._model.getThreeJsObjects()[0]) { + jointAncestor = jointAncestor.parent; + GizmoComponent._tempThreeJsVector3.add(jointAncestor.position); + GizmoComponent._tempThreeJsQuaternion.multiplyQuaternions(jointAncestor.quaternion, GizmoComponent._tempThreeJsQuaternion); + } + position.copyFromThreeJs(GizmoComponent._tempThreeJsVector3); + position.mult(position, 0.001); // Get it into the proper km scale. + position.rotate(this._model.getRotation(), position); // Rotate it to be in the model component's frame. + + // Set the Three.js object position the entity's camera-space position. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera, position, true); + + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + orientation.copyFromThreeJs(GizmoComponent._tempThreeJsQuaternion); + orientation.mult(this._model.getRotation(), orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0], this.getEntity(), orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + } + else { + if (this._relativeToEntity) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0], this.getEntity()); + } + else { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(this.getThreeJsObjects()[0], _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + + // Set the Three.js object position the entity's camera-space position. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setScale(this.getThreeJsObjects()[0], this.getSize()); + + this._lineMesh.prepareForRender(camera); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + this._lineMesh = new _internal__WEBPACK_IMPORTED_MODULE_0__.LineMesh(this); + const positions = []; + positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 0)); + positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(1, 0, 0)); + positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 0)); + positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 1, 0)); + positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 0)); + positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 1)); + this._lineMesh.setPositions(positions); + const colors = []; + colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1, 0, 0)); + colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1, 0, 0)); + colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0, 1, 0)); + colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0, 1, 0)); + colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0, 0, 1)); + colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0, 0, 1)); + this._lineMesh.setColors(colors); + const widths = []; + widths.push(2); + widths.push(2); + widths.push(2); + widths.push(2); + widths.push(2); + widths.push(2); + this._lineMesh.setWidths(widths); + + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + this._lineMesh = null; + } +} + +/** + * A temporary ThreeJs Vector3. + * @type {THREE.Vector3} + */ +GizmoComponent._tempThreeJsVector3 = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(); + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/label_component.js": +/*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/label_component.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LabelComponent": function() { return /* binding */ LabelComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * Label component. + */ +class LabelComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The text to be displayed. + * @type {string} + * @private + */ + this._text = ''; + + /** + * The font face. + * @type {string} + * @private + */ + this._fontFamily = 'Arial'; + + /** + * The font size in pixels. + * @type {number} + * @private + */ + this._fontSize = 16; + + /** + * The color of the text. + * @type {Color} + * @private + */ + this._color = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(); + this._color.freeze(); + + /** + * A flag the determines whether or not the label ignores the distance when determining visibility. + * @type {boolean} + * @private + */ + this._ignoreDistance = false; + + /** + * The alignment of the text. + * @type {Vector2} + * @private + */ + this._alignment = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0.0, 0.5); + this._alignment.freeze(); + + /** + * The pixel offset of the text. + * @type {Vector2} + * @private + */ + this._pixelOffset = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0, 0); + this._pixelOffset.freeze(); + + /** + * The pixel-space size of the text. + * @type {Vector2} + * @private + */ + this._pixelSize = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + + /** + * The pixel device ratio. Saved here when text is created. + * @type {number} + * @private + */ + this._devicePixelRatio = 1; + + /** + * The canvas to draw text on. + * @type {HTMLCanvasElement} + * @private + */ + this._canvas = null; + + /** + * The normal-space bounds. + * @type {Map} + * @private + */ + this._normalSpaceBounds = new Map(); + + // Set the font family and font size from the config, if it exists. + const fontFamily = entity.getScene().getEngine().getConfig().getValue('fontFamily'); + if (typeof fontFamily === 'string') { + this._fontFamily = fontFamily; + } + const fontSize = entity.getScene().getEngine().getConfig().getValue('fontSize'); + if (typeof fontSize === 'number') { + this._fontSize = fontSize; + } + + // Set the radius to infinity, since it will always show, regardless of distance. + this.__setRadius(Number.POSITIVE_INFINITY); + } + + /** + * Returns the text. + * @returns {string} + */ + getText() { + return this._text; + } + + /** + * Sets the text. Defaults to ''. + * @param {string} text + */ + setText(text) { + this._text = text; + this._updateText(); + } + + /** + * Gets the font face. + * @returns {string} + */ + getFontFamily() { + return this._fontFamily; + } + + /** + * Sets the font face. Defaults to Arial. + * @param {string} fontFamily + */ + setFontFamily(fontFamily) { + this._fontFamily = fontFamily; + this._updateText(); + } + + /** + * Gets the font size in pixels. + * @returns {number} + */ + getFontSize() { + return this._fontSize; + } + + /** + * Sets the font size in pixels. Defaults to 16. + * @param {number} fontSize + */ + setFontSize(fontSize) { + this._fontSize = fontSize; + this._updateText(); + } + + /** + * Gets the text color. + * @returns {Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the text color. Defaults to white. + * @param {Color} color - the color to set + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + } + + /** + * Ignores the distance when determining whether it should show the label or not. Defaults to false. + * @param {boolean} enable + */ + setIgnoreDistance(enable) { + this._ignoreDistance = enable; + } + + /** + * Gets the label alignment. + * @returns {Vector2} + */ + getAlignment() { + return this._alignment; + } + + /** + * Sets the alignment. Defaults to the left aligned to the entity and vertically centered (0, .5). Each component should only be between 0 and 1. + * @param {Vector2} alignment - the alignment to set + */ + setAlignment(alignment) { + this._alignment.thaw(); + this._alignment.copy(alignment); + this._alignment.freeze(); + this._updateText(); + } + + /** + * Gets the pixel offset. + * @returns {Vector2} + */ + getPixelOffset() { + return this._pixelOffset; + } + + /** + * Sets the pixel offset. + * @param {Vector2} pixelOffset + */ + setPixelOffset(pixelOffset) { + this._pixelOffset.thaw(); + this._pixelOffset.copy(pixelOffset); + this._pixelOffset.freeze(); + } + + /** + * Gets the normal-space bounds of the label for the given camera. Used by the selection controller for selecting labels. + * @param {CameraComponent} camera + * @returns {Rect} + */ + getNormalSpaceBounds(camera) { + return this._normalSpaceBounds.get(camera); + } + + /** + * Prepares the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + const cameraSpacePosition = this.getEntity().getCameraSpacePosition(camera); + + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(this.getThreeJsObjects()[0], _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + + // If the camera is a Spout camera, use Spout for the render size. + const renderSize = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + if (camera.getType() === 'spout') { + const spoutComponent = /** @type {SpoutComponent} */(camera); + renderSize.set(spoutComponent.getForGlobe() ? -spoutComponent.getRenderWidth() : spoutComponent.getRenderWidth(), spoutComponent.getRenderWidth()); + renderSize.div(renderSize, 4); + } + // Otherwise use the viewport size. + else { + renderSize.copy(camera.getViewport().getBounds().size); + } + + // Set the uniforms. + const pixelOffset = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + const pixelSize = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + const renderUp = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const renderRight = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + pixelOffset.set( + (this._pixelOffset.x - this._alignment.x * this._canvas.width), + (this._pixelOffset.y - this._alignment.y * this._canvas.height)); + pixelSize.set(this._canvas.width, this._canvas.height); + camera.getEntity().getOrientation().getAxis(renderUp, 2); + camera.getEntity().getOrientation().getAxis(renderRight, 0); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0], 'pixelOffset', pixelOffset); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0], 'pixelSize', pixelSize); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0], 'renderSize', renderSize); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'renderUp', renderUp); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'renderRight', renderRight); + + // Update the normal-space bounds. + if (camera.getType() !== 'spout') { + // Get the normalized bounds. + if (!this._normalSpaceBounds.has(camera)) { + this._normalSpaceBounds.set(camera, new _internal__WEBPACK_IMPORTED_MODULE_0__.Rect()); + } + + const normalSpaceBounds = this._normalSpaceBounds.get(camera); + normalSpaceBounds.thaw(); + const normalSpacePosition = this.getEntity().getNormalSpacePosition(camera); + normalSpaceBounds.origin.x = normalSpacePosition.x + 2.0 * (this._pixelOffset.x - this._alignment.x * this._pixelSize.x) / renderSize.x; + normalSpaceBounds.origin.y = normalSpacePosition.y + 2.0 * (this._pixelOffset.y - this._alignment.y * this._pixelSize.y) / renderSize.y; + normalSpaceBounds.size.x = 2.0 * this._pixelSize.x / renderSize.x; + normalSpaceBounds.size.y = 2.0 * this._pixelSize.y / renderSize.y; + normalSpaceBounds.freeze(); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelSize); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelOffset); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(renderUp); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(renderRight); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(renderSize); + + // Fade the label when the camera is close. + let alphaMultiplier = 1.0; + const normalizedRadiusOfEntity = this.getEntity().getNormalSpaceExtentsRadius(camera); + if (!this._ignoreDistance) { + alphaMultiplier *= _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((0.02 - normalizedRadiusOfEntity) / 0.02); + } + + // Fade the label when the entity is visually close to its parent and its parent also has a label. + if (this.getEntity().getParent() !== null) { + const normalizedEntityDistanceFromParent = camera.getNormalSpaceRadiusFromRadius(this.getEntity().getPosition().magnitude(), cameraSpacePosition.magnitude()); + const normalizedParentRadius = this.getEntity().getParent().getNormalSpaceExtentsRadius(camera); + if (!this._ignoreDistance && normalizedParentRadius < 0.02) { + alphaMultiplier *= _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((normalizedEntityDistanceFromParent - 0.02) / 0.02); + } + } + + // If it is occluded, hide label. Check parent always, too. + if (this.getEntity().getParent() !== null && this.getEntity().getParent().isOccludingPosition(camera, cameraSpacePosition)) { + alphaMultiplier = 0; + } + else if (camera.isPositionOccluded(cameraSpacePosition)) { + alphaMultiplier = 0; + } + + // Set the color of the sprite and include the alpha multiplier. + const color = _internal__WEBPACK_IMPORTED_MODULE_0__.Color.pool.get(); + color.copy(this._color); + color.a *= alphaMultiplier; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'colorMultiplier', color); + _internal__WEBPACK_IMPORTED_MODULE_0__.Color.pool.release(color); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + // Create the Three.js object. + if (LabelComponent._useCount === 0) { + // Create the shared geometry as a square 0, 0 to 1, 1. + LabelComponent._threeJsGeometry = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createGeometry([{ name: 'position', dimensions: 2 }, { name: 'uv', dimensions: 2 }], false); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(LabelComponent._threeJsGeometry, 'position', new Float32Array([0, 0, 1, 0, 1, 1, 0, 1])); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(LabelComponent._threeJsGeometry, 'uv', new Float32Array([0, 1, 1, 1, 1, 0, 0, 0])); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(LabelComponent._threeJsGeometry, new Uint16Array([0, 1, 2, 2, 3, 0])); + + // Create the shared material. + LabelComponent._threeJsMaterial = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ShaderMaterial({ + uniforms: { + colorMultiplier: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4(1.0, 1.0, 1.0, 1.0)), + colorTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + pixelOffset: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(0, 0)), + pixelSize: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(1, 1)), + renderSize: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(1, 1)), + renderUp: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 1, 0)), + renderRight: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0)), + + ..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms + }, + vertexShader: ` + uniform vec2 pixelOffset; + uniform vec2 pixelSize; + uniform vec2 renderSize; + uniform vec3 renderUp; + uniform vec3 renderRight; + varying vec2 fUV; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + // Get a frame for the label to be on the x-y axis. + vec3 forward = (modelMatrix * vec4(0, 0, 0, 1.)).xyz; + float distance = length(forward); + forward = normalize(forward); + vec3 up = normalize(renderUp); + vec3 right = normalize(cross(forward, up)); + + // Setup the up and right vectors. + up *= (position.y * pixelSize.y + pixelOffset.y) / renderSize.y * distance; + right *= (position.x * pixelSize.x + pixelOffset.x) / renderSize.x * distance * projectionMatrix[1][3]; + + // Do the transforms. + vec4 viewPosition = modelViewMatrix * vec4(up + right, 1.); + gl_Position = projectionMatrix * viewPosition; + + fUV = uv; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`, + fragmentShader: ` + precision highp float; + + uniform vec4 colorMultiplier; + uniform sampler2D colorTexture; + varying vec2 fUV; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main(void) { + gl_FragColor = texture2D(colorTexture, fUV); + gl_FragColor *= colorMultiplier; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`, + side: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide + }); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupLogDepthBuffering(LabelComponent._threeJsMaterial); + } + LabelComponent._useCount += 1; + + // Create the material. + const material = LabelComponent._threeJsMaterial.clone(); + this.getThreeJsMaterials().push(material); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setTransparent(material, true); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOverlay(material, true); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(material, 'colorMultiplier', this._color); + + // Create the object. + const object = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObjectGivenGeometry(this, material, LabelComponent._threeJsGeometry); + this.getThreeJsObjects().push(object); + + // Create the canvas. + this._canvas = document.createElement('canvas'); + this._canvas.width = 1; + this._canvas.height = 1; + + // Update the text. + this._updateText(); + } + + /** + * Unloads the resources. + * @override + * @protected + */ + __unloadResources() { + LabelComponent._useCount -= 1; + if (LabelComponent._useCount === 0) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyGeometry(LabelComponent._threeJsGeometry); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyMaterial(LabelComponent._threeJsMaterial); + } + const object = this.getThreeJsObjects()[0]; + if (object.parent !== null) { + object.parent.remove(object); + } + this.getThreeJsMaterials()[0].dispose(); + this._canvas = null; + } + + _updateText() { + if (this._canvas === null) { + return; + } + + const context = this._canvas.getContext('2d'); + this._devicePixelRatio = window.devicePixelRatio; + + // Get the dimensions of the text. + context.font = this._fontSize + 'px ' + this._fontFamily; + const metrics = context.measureText(this._text); + this._pixelSize.set(metrics.width * this._devicePixelRatio, this._fontSize * this._devicePixelRatio); + + // Get the texture size. It needs to be a power of 2. + const textureWidth = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.ceilPow2(this._pixelSize.x); + const textureHeight = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.ceilPow2(this._pixelSize.y); + + if (textureWidth !== this._canvas.width || textureHeight !== this._canvas.height) { + this._canvas.width = textureWidth; + this._canvas.height = textureHeight; + } + + context.clearRect(0, 0, this._canvas.width, this._canvas.height); + this._canvas.style.width = (textureWidth / this._devicePixelRatio) + 'px'; + this._canvas.style.height = (textureHeight / this._devicePixelRatio) + 'px'; + context.font = this._pixelSize.y + 'px ' + this._fontFamily; // need to do this again due to browser bug + context.fillStyle = 'rgba(255, 255, 255, 255)'; + context.fillText(this._text, (this._canvas.width - this._pixelSize.x) * _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(this._alignment.x), (this._canvas.height - this._pixelSize.y * 0.1875) - (this._canvas.height - this._pixelSize.y) * _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(this._alignment.y)); + + const material = this.getThreeJsMaterials()[0]; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformTexture(material, 'colorTexture', _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTextureFromCanvas(this._canvas)); + } +} + +/** + * A global shared material, copied by labels. + * @type {THREE.ShaderMaterial} + */ +LabelComponent._threeJsMaterial = null; + +/** + * A global shared geometry unit square with a corner at (0, 0), copied by labels. + * @type {THREE.BufferGeometry} + */ +LabelComponent._threeJsGeometry = null; + +/** + * The count for the number of labels used. + * @type {number} + */ +LabelComponent._useCount = 0; + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/light_source_component.js": +/*!************************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/light_source_component.js ***! + \************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LightSourceComponent": function() { return /* binding */ LightSourceComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A light source. Does not produce any actual light per se, but is used by other shaders when referenced. Shaders can use the 'lightSourceColor' and 'lightSourcePos' uniforms, and call setUniforms() to use the light source. + */ +class LightSourceComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The color of the light. Alpha is not used. + * @type {Color} + * @private + */ + this._color = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1); + this._color.freeze(); + + /** + * The absolute magnitude of the light. + * @type {number} + * @private + */ + this._absoluteMagnitude = 1; + + // Make the light source work everywhere. + this.__setRadius(Number.POSITIVE_INFINITY); + } + + /** + * Gets the color. Defaults to white. + * @returns {Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the color. + * @param {Color} color - the color to set + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + } + + /** + * Gets the absolute magnitude. Defaults to 1. + * @returns {number} + */ + getAbsoluteMagnitude() { + return this._absoluteMagnitude; + } + + /** + * Sets the absolute magnitude. + * @param {number} absoluteMagnitude + */ + setAbsoluteMagnitude(absoluteMagnitude) { + this._absoluteMagnitude = absoluteMagnitude; + } + + /** + * Loads the light source, adding it to the scene. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + this.getEntity().getScene().__addLightSource(this.getEntity().getName(), this.getTypeIndex()); + return Promise.resolve(); + } + + /** + * Unloads the light source, removing it from the scene. + * @override + * @protected + */ + __unloadResources() { + this.getEntity().getScene().__removeLightSource(this.getEntity().getName(), this.getTypeIndex()); + } + + /** + * Sets the type index. Overriden to ensure that the scene has the correct type index. + * @param {number} typeIndex + * @override + * @internal + */ + __setTypeIndex(typeIndex) { + if (this.getLoadState() === 'loaded') { + this.getEntity().getScene().__removeLightSource(this.getEntity().getName(), this.getTypeIndex()); + } + super.__setTypeIndex(typeIndex); + if (this.getLoadState() === 'loaded') { + this.getEntity().getScene().__addLightSource(this.getEntity().getName(), this.getTypeIndex()); + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/model_component.js": +/*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/model_component.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ModelComponent": function() { return /* binding */ ModelComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A model, usually imported from a GLTF file. + */ +class ModelComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The url of the model. + * @type {string} + * @private + */ + this._url = ''; + + /** + * The entities uses for shadows. Derived from the shadow entity names. + * @type {EntityRef[]} + * @private + */ + this._shadowEntities = []; + + /** + * The translation to apply to the model when rendering it. + * @type {Vector3} + * @private + */ + this._translation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._translation.freeze(); + + /** + * The rotation to apply to the model when rendering it. + * @type {Quaternion} + * @private + */ + this._rotation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + this._rotation.freeze(); + + /** + * The mapping of file names to urls when loading GLTF references. + * @type {Map} + * @private + */ + this._urlReferenceMap = new Map(); + + /** + * The Three.js animation clips, keyed by name. + * @type {Map} + * @private + */ + this._threeJsAnimationClips = new Map(); + + /** + * A mapping of names to objects of objects that should be hidden. + * @type {FastMap} + * @private + */ + this._hiddenObjects = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The scale to apply to the model. + * @type {Vector3} + * @private + */ + this._scale = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0.001, 0.001, 0.001); + this._scale.freeze(); + + /** + * The size of the actual model without any scaling. Defaults to NaN since it doesn't + * know the actual model radius until the model is loaded. + * @type {number} + * @private + */ + this._modelRadius = NaN; + + /** + * The url for the environment cube map. + * @type {string} + * @private + */ + this._environmentCubemapUrl = ''; + + /** + * The url for the cylindrical cube map. + * @type {string} + * @private + */ + this._environmentCylindricalUrl = ''; + + /** + * The environment cube map. + * @type {THREE.Texture} + * @private + */ + this._environmentCubemap = null; + + /** + * The intensity of the environment. + * @type {number} + * @private + */ + this._environmentIntensity = 0.5; + + /** + * The dynamic environment map texture, if used. + * @type {DynamicEnvironmentMapComponent} + * @private + */ + this._dynamicEnvironmentMapComponent = null; + + /** + * The pixel radius interval over which the model is visible. It will fade to nothing for 50% outside of these bounds. + * @type {Interval | undefined} + */ + this._pixelRadiusVisibleInterval = undefined; + + /** + * The flag that if true, uses compressed textures. + * @type {boolean} + * @private + */ + this._useCompressedTextures = false; + + /** + * A bound function for use in callbacks. + * @type {function():void} + * @private + */ + this._onConfigChanged = this._onConfigChanged.bind(this); + + this.__setRadius(this.getEntity().getExtentsRadius()); + } + + /** + * Returns the url of the model file. + * @returns {string} + */ + getUrl() { + return this._url; + } + + /** + * Sets the url of the model file. + * @param {string} url + */ + setUrl(url) { + if (this._url !== '') { + this.getEntity().getScene().getEngine().getDownloader().cancel(this._url); + } + this.resetResources(); + this._modelRadius = NaN; + this._loading = false; + this._url = url; + } + + /** + * Sets an object to be hidden on the model. + * @param {string} name - The object name + * @param {boolean} hidden - Whether or not it should be hidden + */ + setHiddenObject(name, hidden) { + if (hidden && !this._hiddenObjects.has(name)) { + this._hiddenObjects.set(name, null); + } + else if (!hidden && this._hiddenObjects.has(name)) { + this._hiddenObjects.delete(name); + } + } + + /** + * Gets the translation of the model. + * @returns {Vector3} translation + */ + getTranslation() { + return this._translation; + } + + /** + * Sets the translation of the model. It defaults to the zero vector. + * @param {Vector3} translation + */ + setTranslation(translation) { + this._translation.thaw(); + this._translation = translation; + this._translation.freeze(); + } + + /** + * Gets the scale of the model. + * @returns {Vector3} scale + */ + getScale() { + return this._scale; + } + + /** + * Sets the scale of the model. It defaults to 0.001, since most models are in meters, not kilometers. + * @param {Vector3 | number} scale + */ + setScale(scale) { + this._scale.thaw(); + if (typeof scale === 'number') { + this._scale.set(scale, scale, scale); + } + else { + this._scale.copy(scale); + } + this._scale.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setScale(this.getThreeJsObjects()[0], this._scale); + if (!isNaN(this._modelRadius)) { + this.__setRadius(Math.max(this._scale.x, this._scale.y, this._scale.z) * this._modelRadius); + } + else { + this.__setRadius(this.getEntity().getExtentsRadius()); + } + } + + /** + * Gets the rotation applied to the model. Defaults to the identity rotation. + * @returns {Quaternion} + */ + getRotation() { + return this._rotation; + } + + /** + * Sets the rotation applied to the modeol. + * @param {Quaternion} rotation + */ + setRotation(rotation) { + this._rotation.thaw(); + this._rotation.copy(rotation); + this._rotation.freeze(); + } + + /** + * Gets the url of the environment cubemap applied to the model during loading + * @returns {string} + */ + getEnvironmentCubemapUrl() { + return this._environmentCubemapUrl; + } + + /** + * Sets the url of the environment cubemap applied to the model during loading + * @param {string} url - the url is used by TextureLoader.loadCubeTexture and follows its rules for the $FACE variable. + */ + setEnvironmentCubemapUrl(url) { + this._environmentCubemapUrl = url; + } + + /** + * Gets the intensity multiplier applied to environment lighting + * @returns {number} + */ + getEnvironmentIntensity() { + return this._environmentIntensity; + } + + /** + * Sets the intensity multiplier applied to environment lighting + * @param {number} environmentIntensity + */ + setEnvironmentIntensity(environmentIntensity) { + this._environmentIntensity = environmentIntensity; + for (let i = 0, l = this.getThreeJsMaterials().length; i < l; i++) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[i], 'environmentIntensity', this._environmentIntensity); + } + } + + /** + * Gets the url of the cylindrical cubemap applied to the model during loading + * @returns {string} + */ + getEnvironmentCylindricalUrl() { + return this._environmentCylindricalUrl; + } + + /** + * Sets the url of the cylindrical cubemap applied to the model during loading + * @param {string} url - url of the image to use + */ + setEnvironmentCylindricalUrl(url) { + this._environmentCylindricalUrl = url; + } + + /** + * Sets the pixel radius interval over which the model is visible. + * It will fade to nothing for 5% outside of these bounds. + * The material must already have transparency enabled for it to work. + * Defaults to [0, +infinity]. + * @param {Interval | undefined} interval + */ + setPixelRadiusVisibleInterval(interval) { + if (interval !== undefined) { + if (this._pixelRadiusVisibleInterval === undefined) { + this._pixelRadiusVisibleInterval = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(interval.min, interval.max); + } + else { + this._pixelRadiusVisibleInterval.copy(interval); + } + } + else { + this._pixelRadiusVisibleInterval = undefined; + for (const material of this.getThreeJsMaterials()) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'alphaMultiplier', 1); + } + this.getThreeJsObjects()[0].visible = true; + } + } + + /** + * Sets whether or not the dynamic environment map is enabled. + * @param {DynamicEnvironmentMapComponent} dynamicEnvironmentMapComponent + */ + setDynamicEnvironmentMapComponent(dynamicEnvironmentMapComponent) { + this._dynamicEnvironmentMapComponent = dynamicEnvironmentMapComponent; + for (let i = 0, l = this.getThreeJsMaterials().length; i < l; i++) { + const material = this.getThreeJsMaterials()[i]; + if (material.uniforms['dynEnvTexture'] !== undefined) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setDefine(material, 'dynEnvMap', true); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformTexture(material, 'dynEnvTexture', this._dynamicEnvironmentMapComponent.getTexture()); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'dynEnvFaceSize', dynamicEnvironmentMapComponent.getFaceSize()); + } + } + // Disable the static environment cube map. + if (this._environmentCubemap !== null) { + this._environmentCubemap.dispose(); + this._environmentCubemap = null; + } + } + + /** + * Gets the flag that if true, uses compressed textures. + * @returns {boolean} + */ + getUseCompressedTextures() { + return this._useCompressedTextures; + } + + /** + * Sets the flag that if true, uses compressed textures. + * @param {boolean} useCompressedTextures + */ + setUseCompressedTextures(useCompressedTextures) { + this._useCompressedTextures = useCompressedTextures; + } + + /** + * Sets the mapping of file names to urls when loading GLTF references. + * @param {Map} urlReferenceMap; + */ + setURLReferenceMap(urlReferenceMap) { + this._urlReferenceMap.clear(); + for (const entry of urlReferenceMap) { + this._urlReferenceMap.set(entry[0], entry[1]); + } + } + + /** + * Gets the Three.js animation clip of the given name. Returns null if the clip doesn't exist. + * @param {string} name + * @returns {THREE.AnimationClip} + */ + getAnimationClip(name) { + return this._threeJsAnimationClips.get(name) || null; + } + + /** + * Gets a material by name. + * @param {string} name + * @returns {THREE.ShaderMaterial | null} + */ + getMaterial(name) { + const materials = this.getThreeJsMaterials(); + for (let i = 0, l = materials.length; i < l; i++) { + if (materials[i].name === name) { + return materials[i]; + } + } + return null; + } + + /** + * Replaces a material with a new material. + * @param {string} name + * @param {THREE.ShaderMaterial} newMaterial + */ + updateMaterial(name, newMaterial) { + // Find the material by name and replace it in the materials list. + const materials = this.getThreeJsMaterials(); + let foundMaterial; + for (let i = 0; i < materials.length; i++) { + const material = materials[i]; + if (material.name === name) { + foundMaterial = material; + materials.splice(i, 1); + materials.push(newMaterial); + break; + } + } + if (!foundMaterial) { + throw new Error(`No material with the name ${name} was found in ${this}.`); + } + // Replace the material in every object that has it. + for (let i = 0, l = this.getThreeJsObjects().length; i < l; i++) { + const object = this.getThreeJsObjects()[i]; + if (object instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh) { + if (object.material === foundMaterial) { + object.material = newMaterial; + object.material.name = name; + } + } + } + } + + /** + * Gets the number of shadow entities. Can be used to enumerate the shadow entities. + * @returns {number} + */ + getNumShadowEntities() { + return this._shadowEntities.length; + } + + /** + * Returns the shadow entity or its name at the index. + * @param {number} index + * @returns {string | undefined} + */ + getShadowEntity(index) { + return this._shadowEntities[index]?.getName(); + } + + /** + * Sets the shadow entities. Each element can be either the name of an entity or an entity itself. + * @param {string[]} shadowEntities + */ + setShadowEntities(shadowEntities) { + this._shadowEntities = []; + for (const shadowEntity of shadowEntities) { + this._shadowEntities.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(), shadowEntity)); + } + const shadowEntitiesEnabled = (shadowEntities.length > 0); + for (let i = 0, l = this.getThreeJsMaterials().length; i < l; i++) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setDefine(this.getThreeJsMaterials()[i], 'shadowEntities', shadowEntitiesEnabled); + } + } + + /** + * Updates the camera-dependent parts of the component. + * @param {CameraComponent} camera + * @override + */ + __prepareForRender(camera) { + // Make any objects hidden that should be hidden. + for (let i = 0, l = this._hiddenObjects.size; i < l; i++) { + const entry = this._hiddenObjects.getAt(i); + if (entry.value === null) { + entry.value = this.getThreeJsObjectByName(entry.key); + } + if (entry.value !== null) { + entry.value.visible = false; + } + } + + // Set the alpha multiplier based on conditions. + if (this._pixelRadiusVisibleInterval !== undefined) { + const pixelRadius = this.getEntity().getPixelSpaceExtentsRadius(camera); + const alphaMultiplier = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(Math.min( + 1 + 2 * (pixelRadius - this._pixelRadiusVisibleInterval.min) / this._pixelRadiusVisibleInterval.min, + isFinite(this._pixelRadiusVisibleInterval.max) ? (1 - 2 * (pixelRadius - this._pixelRadiusVisibleInterval.max) / this._pixelRadiusVisibleInterval.max) : 1)); + for (const material of this.getThreeJsMaterials()) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'alphaMultiplier', alphaMultiplier); + } + if (alphaMultiplier === 0) { + this.getThreeJsObjects()[0].visible = false; + } + } + + // Apply the position to the ThreeJS object. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera, this._translation, true); + + // Apply the rotation and orientation to the ThreeJS object. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0], this.getEntity(), this._rotation); + + // Setup the regular uniforms. + _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setUniforms(this.getThreeJsMaterials(), camera, this.getEntity(), this._shadowEntities, null, false); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + const engine = this.getEntity().getScene().getEngine(); + + const binary = this._url.startsWith('blob:') || this._url.endsWith('.glb'); + try { + const download = await engine.getDownloader().download(this._url, binary); + + // If we're no longer loading or the download was canceled, do nothing. + if (this.getLoadState() !== 'loading' || download.status === 'cancelled') { + return; + } + // If the download failed, error. + else if (download.status === 'failed') { + throw new Error('Failed to load model component file "' + download.url + '": ' + download.errorMessage); + } + // If the download isn't the right format, error. + else if (!download.actualUrl.endsWith('.gltf') && !download.actualUrl.endsWith('.glb') && !download.actualUrl.startsWith('blob:')) { + throw new Error('Unknown model format.'); + } + + // Create and setup the Three.js loading manager needed by the ThreeJsGLTFLoader. + const manager = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LoadingManager(); + // Use the standard texture loaders only if there are no replacement URLs for the references. + if (this._urlReferenceMap.size === 0) { + manager.addHandler(/.$/, this._useCompressedTextures ? engine.getTextureLoaderCompressed() : engine.getTextureLoader()); + } + // If there is a reference map, replace every reference in the GLTF with the mapped URL. + manager.setURLModifier((url) => { + const urlFileName = url.substring(url.lastIndexOf('/') + 1); + if (this._urlReferenceMap.has(urlFileName)) { + return this._urlReferenceMap.get(urlFileName); + } + return url; + }); + + // Load and parse the rest of the model. + const loader = new _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsGLTFLoader(manager); + await new Promise((resolve, reject) => { + loader.parse(download.content, _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LoaderUtils.extractUrlBase(download.actualUrl), async (gltf) => { + // Save the root for use below. + const root = gltf.scene; + + // Populate the Three.js objects and materials lists. Even if we're no longer loading, this makes it easier to clean. + this._populateThreeJsObjectsAndMaterials(gltf.scene); + + // If we're no longer loading clean up and return. + if (this.getLoadState() !== 'loading') { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + } + + // Cleans up some of the extra objects. + this._clean(); + + // Set the initial properties of the root object. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupObject(this, root); + + // Set the scale of the model. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setScale(root, this._scale); + + // Set the radius based on the bounding box. + const boundingBox = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Box3().setFromObject(root); + this._modelRadius = Math.max(boundingBox.min.length(), boundingBox.max.length()); + this.__setRadius(Math.max(this._scale.x, this._scale.y, this._scale.z) * this._modelRadius); + + // Save the animation clips. + for (let i = 0; i < gltf.animations.length; i++) { + this._threeJsAnimationClips.set(gltf.animations[i].name, gltf.animations[i]); + } + + // Load the environment map if it does have a standard material. Dynamic has priority over static. + if (this._dynamicEnvironmentMapComponent === null && this._environmentCubemap === null) { + // Cubemap has priority over cylindrical + if (this._environmentCubemapUrl !== '') { + await engine.getTextureLoader().loadCubeTexture(this._environmentCubemapUrl, true).then((cubeTexture) => { + this._environmentCubemap = engine.getTextureLoader().generateEnvMap(cubeTexture); + }); + } + else if (this._environmentCylindricalUrl !== '') { + await engine.getTextureLoader().loadTexture(this._environmentCylindricalUrl, true).then((texture) => { + this._environmentCubemap = engine.getTextureLoader().generateEnvMap(texture); + }); + } + } + + // Update the materials to be the Pioneer compatible materials. + this._updateMaterials(); + + // If the config's gamma value changes, set the callback to update the model. + this.getEntity().getScene().getEngine().getConfig().addEventListener('gammaCorrection', this._onConfigChanged); + + resolve(); + }, (error) => { + reject(new Error(`Error loading gltf: ${error}`)); + }); + }); + } + catch (error) { + if (error instanceof Error) { + error.message = `While loading model "${this._url}": ${error.message}`; + } + throw error; + } + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + // Clear the hidden object references. + for (let i = 0, l = this._hiddenObjects.size; i < l; i++) { + this._hiddenObjects.getAt(i).value = null; + } + // Remove the gamma correction event listener. + this.getEntity().getScene().getEngine().getConfig().removeEventListener('gammaCorrection', this._onConfigChanged); + // Clear the objects and materials. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + this._lineMesh = null; + } + + /** + * Populates the Three.js object list with all objects, including the children. + * @param {THREE.Object3D} object + * @private + */ + _populateThreeJsObjectsAndMaterials(object) { + // Add the object to the list. + this.getThreeJsObjects().push(object); + // If the object's materials haven't already been added to the list, add them. + if (object instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh) { + /** @type {THREE.ShaderMaterial | THREE.ShaderMaterial[]} */ + let materials = object.material; + if (!Array.isArray(materials)) { + materials = [materials]; + } + for (const material of materials) { + let alreadyAdded = false; + for (let i = 0, l = this.getThreeJsMaterials().length; i < l; i++) { + if (this.getThreeJsMaterials()[i] === material) { + alreadyAdded = true; + break; + } + } + if (!alreadyAdded) { + this.getThreeJsMaterials().push(material); + } + } + } + // Go through the children. + for (let i = 0; i < object.children.length; i++) { + this._populateThreeJsObjectsAndMaterials(object.children[i]); + } + } + + /** + * Clean up a number of objects that aren't needed. + * @private + */ + _clean() { + // Remove lamps and hemis. + const removeRegex = /_(lamp|hemi)/i; + for (let i = 0; i < this.getThreeJsObjects().length; i++) { + const object = this.getThreeJsObjects()[i]; + if (object.name.match(removeRegex)) { + if (object.parent) { + object.parent.remove(object); + } + this.getThreeJsObjects().splice(i, 1); + i--; + } + } + + // Make invisible any object with a name starting with '_root' or having a material named 'transparent'. + // Only remove its attributes so that it doesn't break things too much. + for (let i = 0, l = this.getThreeJsObjects().length; i < l; i++) { + let shouldMakeInvisible = false; + const object = this.getThreeJsObjects()[i]; + if (object instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh && object.geometry instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferGeometry) { + if (object.name.startsWith('_root')) { + shouldMakeInvisible = true; + } + if (object instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh && object.material instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Material && object.material.name === 'transparent') { + shouldMakeInvisible = true; + } + if (shouldMakeInvisible) { + object.geometry.deleteAttribute('position'); + object.geometry.deleteAttribute('normal'); + } + } + } + } + + /** + * Manage pioneer config changes + * @private + */ + _onConfigChanged() { + this._updateMaterials(); + } + + /** + * Updates the existing object materials to be ones compatible with Pioneer. Creates tangents if necessary. + * @private + */ + _updateMaterials() { + for (let i = 0, l = this.getThreeJsMaterials().length; i < l; i++) { + const oldMaterial = this.getThreeJsMaterials()[i]; + if (!(oldMaterial instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.MeshStandardMaterial)) { + continue; + } + const newMaterial = this._getNewPioneerMaterial(oldMaterial); + this.getThreeJsMaterials()[i] = newMaterial; + + // Check if the new material requires a tangent attribute. + let needsTangents = false; + if (newMaterial.defines['normalMap']) { + needsTangents = true; + } + + // Go through each object and replace the materials, computing the tangents if necessary. + for (const object of this.getThreeJsObjects()) { + if (object instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh) { + let hasOldMaterial = false; + if (Array.isArray(object.material)) { + for (let j = 0, k = object.material.length; j < k; j++) { + if (object.material[j] === oldMaterial) { + object.material[j] = newMaterial; + hasOldMaterial = true; + } + } + } + else if (object.material === oldMaterial) { + object.material = newMaterial; + hasOldMaterial = true; + } + + // If the object's geometry doesn't have a tangent attribute defined, create it manually from the positions and uvs. + if (hasOldMaterial && needsTangents && object.geometry instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferGeometry && object.geometry.getAttribute('tangent') === undefined) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.computeTangents(object.geometry); + } + } + } + oldMaterial.dispose(); + } + } + + /** + * Use the Three.JS material as a basis to create a new Pioneer-compatible material. + * @param {THREE.MeshStandardMaterial} material + * @returns {THREE.ShaderMaterial} + * @private + */ + _getNewPioneerMaterial(material) { + const newMaterial = _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.getPBR(); + newMaterial.name = material.name; + newMaterial.transparent = material.transparent; + newMaterial.depthWrite = material.depthWrite; + newMaterial.side = material.side; + + if (material.map !== null) { + // Retrieve KTX compressed format from if available + // @ts-ignore + const ktxFormat = material.map.ktxFormat; + if (ktxFormat !== undefined) { + material.map.format = ktxFormat; + } + newMaterial.uniforms['colorTexture'].value = material.map; + newMaterial.defines['colorMap'] = true; + } + + if (material.roughnessMap) { + newMaterial.uniforms['roughnessTexture'].value = material.roughnessMap; + newMaterial.defines['roughnessMap'] = true; + } + + if (material.metalnessMap) { + newMaterial.uniforms['metalnessTexture'].value = material.metalnessMap; + newMaterial.defines['metalnessMap'] = true; + } + + if (material.normalMap !== null) { + newMaterial.uniforms['normalTexture'].value = material.normalMap; + newMaterial.uniforms['normalScale'].value = material.normalScale; + newMaterial.defines['normalMap'] = true; + } + + // Update the emissivity. + newMaterial.uniforms['emissiveColor'].value.copy(material.emissive); + newMaterial.uniforms['emissiveColor'].value.multiplyScalar(material.emissiveIntensity); + if (material.emissiveMap !== null) { + newMaterial.uniforms['emissiveTexture'].value = material.emissiveMap; + newMaterial.defines['emissiveMap'] = true; + } + + newMaterial.uniforms['color'].value = material.color; + newMaterial.uniforms['roughness'].value = material.roughness; + newMaterial.uniforms['metalness'].value = material.metalness; + + // Apply environment map + let textureSideLength = 0; + if (this._dynamicEnvironmentMapComponent !== null) { + newMaterial.defines['dynEnvMap'] = true; + newMaterial.uniforms['dynEnvTexture'].value = this._dynamicEnvironmentMapComponent.getTexture(); + newMaterial.uniforms['dynEnvFaceSize'].value = this._dynamicEnvironmentMapComponent.getFaceSize(); + } + else if (this._environmentCubemap !== null) { + newMaterial.defines['envMap'] = true; + newMaterial.defines['envIsCubeUV'] = true; + + newMaterial.uniforms['envTexture'].value = this._environmentCubemap; + textureSideLength = this._environmentCubemap.image.height; + newMaterial.uniforms['maxMipLevel'].value = Math.log(textureSideLength) * Math.LOG2E; + } + newMaterial.uniforms['environmentIntensity'].value = this._environmentIntensity; + + // Apply gamma correction. + newMaterial.uniforms['gammaCorrectionFactor'].value = this.getEntity().getScene().getEngine().getConfig().getValue('gammaCorrection'); + + // Apply shadow entity define. + if (this._shadowEntities.length > 0) { + newMaterial.defines['shadowEntities'] = true; + } + + // Trigger the update in Three.js. + newMaterial.needsUpdate = true; + + return newMaterial; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/orbital_particles_component.js": +/*!*****************************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/orbital_particles_component.js ***! + \*****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "OrbitalParticlesComponent": function() { return /* binding */ OrbitalParticlesComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * @typedef LoadFunctionReturnValue + * @property {OrbitalElements[]} orbitalElements + * @property {Color[]} colors + * @property {number[]} scales + */ + +/** + * @callback LoadFunction + * @returns {LoadFunctionReturnValue} + */ + +/** + * A particle cloud with orbital parameters. + */ +class OrbitalParticlesComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The size of each particle. + * @type {number} + * @private + */ + this._scaleOfParticles = 1.0; + + /** + * The function that loads the particle arrays. + * @type {LoadFunction} + * @private + */ + this._loadFunction = null; + + /** + * The orbital elements of each particle. + * @type {OrbitalElements[]} + * @private + */ + this._orbitalElementsList = []; + + /** + * The positions of the particles as an array. + * @type {Float32Array} + * @private + */ + this._offsetArray = new Float32Array(0); + + /** + * The sprite particles object. + * @type {SpriteParticles} + * @private + */ + this._spriteParticles = null; + + // Set the radius of the component to zero. It will be set to the furthest out particle. + this.__setRadius(this.getEntity().getExtentsRadius() * 100); + } + + /** + * Gets the scale of the particles flowing out. + * @returns {number} + */ + getScaleOfParticles() { + return this._scaleOfParticles; + } + + /** + * Sets the scale of the particles flowing out. Defaults to 1.0. + * @param {number} scaleOfParticles + */ + setScaleOfParticles(scaleOfParticles) { + this._scaleOfParticles = scaleOfParticles; + this.resetResources(); + } + + /** + * Sets the function that loads the particle arrays. It should return a { orbitalElements: OrbitalElements[], colors: Color[], scales: number[] } object. + * @param {LoadFunction} loadFunction + */ + setLoadFunction(loadFunction) { + this._loadFunction = loadFunction; + this.resetResources(); + } + + /** + * Updates the component. + * @override + * @internal + */ + __update() { + // Do nothing if there's no particles. + if (this._spriteParticles === null) { + return; + } + // Update the particle positions from the orbital elements. + const position = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const velocity = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const time = this.getEntity().getScene().getEngine().getTime(); + for (let i = 0, l = this._orbitalElementsList.length; i < l; i++) { + this._orbitalElementsList[i].project(position, velocity, time); + this._offsetArray[i * 3 + 0] = position.x; + this._offsetArray[i * 3 + 1] = position.y; + this._offsetArray[i * 3 + 2] = position.z; + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(velocity); + this._spriteParticles.setParticleOffsets(this._offsetArray); + } + + /** + * Prepares the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + this._spriteParticles.prepareForRender(camera); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + // Create the sprite particles. + this._spriteParticles = new _internal__WEBPACK_IMPORTED_MODULE_0__.SpriteParticles(this); + // Push the object and material to the list. + this.getThreeJsMaterials().push(this._spriteParticles.getThreeJsMaterial()); + this.getThreeJsObjects().push(this._spriteParticles.getThreeJsObject()); + // Initialize the particles. + await this._initializeParticles(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + this._spriteParticles = null; + } + + /** + * Initializes the particles. Resets them if they were already initialized. + * @private + */ + async _initializeParticles() { + if (this._loadFunction === null) { + return; + } + // Load the orbital elements. + const returnValue = await this._loadFunction(); + const numParticles = returnValue.orbitalElements.length; + // Set the orbital elements. + this._orbitalElementsList = []; + let maxParticleDistance = 0; + for (let i = 0, l = numParticles; i < l; i++) { + // Copy them over so they can't be changed outside of the class. + const orbitalElements = new _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements(); + orbitalElements.copy(returnValue.orbitalElements[i]); + this._orbitalElementsList.push(orbitalElements); + // Set the orbit apoapsis as the furthest distance the particle will go. + const apoapsis = orbitalElements.semiMajorAxis * (1 + orbitalElements.eccentricity); + maxParticleDistance = Math.max(maxParticleDistance, apoapsis); + } + // Set the radius. + this.__setRadius(maxParticleDistance); + // Initialize the offset array. It will be dynamic over time. + this._offsetArray = new Float32Array(numParticles * 3); + // Create and set the color and scale arrays, since they are static over time. + const colorArray = new Float32Array(numParticles * 4); + const scaleArray = new Float32Array(numParticles * 1); + for (let i = 0, l = numParticles; i < l; i++) { + colorArray[i * 4 + 0] = returnValue.colors[i].r; + colorArray[i * 4 + 1] = returnValue.colors[i].g; + colorArray[i * 4 + 2] = returnValue.colors[i].b; + colorArray[i * 4 + 3] = returnValue.colors[i].a; + scaleArray[i * 1 + 0] = returnValue.scales[i] * this._scaleOfParticles; + } + this._spriteParticles.setParticleColors(colorArray); + this._spriteParticles.setParticleScales(scaleArray); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/particle_spray_component.js": +/*!**************************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/particle_spray_component.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ParticleSprayComponent": function() { return /* binding */ ParticleSprayComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A bunch of sprite particles in a stream. + */ +class ParticleSprayComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The length of the particle stream. + * @type {number} + * @private + */ + this._length = 1; + + /** + * The spread in degrees of the particle stream. + * @type {number} + * @private + */ + this._spread = 30; + + /** + * The number of particles. + * @type {number} + * @private + */ + this._numberOfParticles = 0; + + /** + * The speed in units/sec of the particles flowing out. + * @type {number} + * @private + */ + this._speedOfParticles = 0.1; + + /** + * The size of each particle. + * @type {number} + * @private + */ + this._sizeOfParticles = 0.1; + + /** + * The flag that says whether the spacing between particles is random. If not, the particles are evenly spaced. Certain affects look better with even spacing. + * @type {boolean} + * @private + */ + this._particleSpacingRandom = true; + + /** + * The color of the particles. + * @type {Color} + * @private + */ + this._colorOfParticles = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(); + this._colorOfParticles.freeze(); + + /** + * The offset of the particle origin. If relativeToEntityOrientation is true, this is also relative to the entity orientation. + * @type {Vector3} + */ + this._originOffset = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._originOffset.freeze(); + + /** + * The direction of the particle stream. If relativeToEntityOrientation is true, this is also relative to the entity orientation. + * @type {Vector3} + * @private + */ + this._direction = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._direction.freeze(); + + /** + * The flag that says whether or not the offset origin and direction are relative to the entity orientation. + * @type {boolean} + * @private + */ + this._relativeToEntityOrientation = true; + + // Set the radius of the component. + this.__setRadius(this._length); + } + + /** + * Gets the length of the particle stream. + * @returns {number} + */ + getLength() { + return this._length; + } + + /** + * Sets the length of the particle stream. Defaults to 1. + * @param {number} length + */ + setLength(length) { + this._length = length; + this.__setRadius(this._length); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'length', this._length); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'totalTime', this._length / this._speedOfParticles); + } + + /** + * Gets the spread in degrees of the particle stream. + * @returns {number} + */ + getSpread() { + return this._spread; + } + + /** + * Sets the spread in degrees of the particle stream. Defaults to 30. + * @param {number} spread + */ + setSpread(spread) { + this._spread = spread; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'spread', _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(this._spread)); + } + + /** + * Gets the number of particles. + * @returns {number} + */ + getNumberOfParticles() { + return this._numberOfParticles; + } + + /** + * Sets the number of particles. Defaults to 0. + * @param {number} numberOfParticles + */ + setNumberOfParticles(numberOfParticles) { + this._numberOfParticles = numberOfParticles; + this.resetResources(); + } + + /** + * Gets the speed in units/sec of the particles flowing out. + * @returns {number} + */ + getSpeedOfParticles() { + return this._speedOfParticles; + } + + /** + * Sets the speed in km/sec of the particles flowing out. Defaults to 0.1. + * @param {number} speedOfParticles + */ + setSpeedOfParticles(speedOfParticles) { + this._speedOfParticles = speedOfParticles; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'totalTime', this._length / this._speedOfParticles); + } + + /** + * Gets the size in km of the particles flowing out. + * @returns {number} + */ + getSizeOfParticles() { + return this._sizeOfParticles; + } + + /** + * Sets the size in km of the particles flowing out. Defaults to 1.0. + * @param {number} sizeOfParticles + */ + setSizeOfParticles(sizeOfParticles) { + this._sizeOfParticles = sizeOfParticles; + this.resetResources(); + } + + /** + * Gets the flag that says whether the spacing between particles is random. If not, the particles are evenly spaced. Certain affects look better with even spacing. + * @returns {boolean} + */ + getParticleSpacingRandom() { + return this._particleSpacingRandom; + } + + /** + * Sets the flag that says whether the spacing between particles is random. If not, the particles are evenly spaced. Certain affects look better with even spacing. Defaults to true. + * @param {boolean} particleSpacingRandom + */ + setParticleSpacingRandom(particleSpacingRandom) { + this._particleSpacingRandom = particleSpacingRandom; + this.resetResources(); + } + + /** + * Gets the color of the particles. + * @return {Color} + */ + getColorOfParticles() { + return this._colorOfParticles; + } + + /** + * Sets the color of the particles. Defaults to white. + * @param {Color} color + */ + setColorOfParticles(color) { + this._colorOfParticles.thaw(); + this._colorOfParticles.copy(color); + this._colorOfParticles.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'globalColor', this._colorOfParticles); + } + + /** + * Gets the offset of the particle origin. If relativeToEntityOrientation is true, this is also relative to the entity orientation. + * @returns {Vector3} + */ + getOriginOffset() { + return this._originOffset; + } + + /** + * Sets the offset of the particle origin. If relativeToEntityOrientation is true, this is also relative to the entity orientation. Defaults to zero. + * @param {Vector3} originOffset + */ + setOriginOffset(originOffset) { + this._originOffset.thaw(); + this._originOffset.copy(originOffset); + this._originOffset.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'originOffset', this._originOffset); + } + + /** + * Gets the direction of the particle stream. If relativeToEntityOrientation is true, this is also relative to the entity orientation. + * @returns {Vector3} + */ + getDirection() { + return this._direction; + } + + /** + * Sets the direction of the particle stream. If relativeToEntityOrientation is true, this is also relative to the entity orientation. Defaults to the x-axis. + * @param {Vector3} direction + */ + setDirection(direction) { + this._direction.thaw(); + this._direction.normalize(direction); + this._direction.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'direction', this._direction); + + // Get the perpendicular direction for orienting the particles. + const directionPerp = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + directionPerp.cross(this._direction, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis); + if (directionPerp.isZero()) { + directionPerp.cross(this._direction, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis); + } + directionPerp.normalize(directionPerp); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'directionPerp', directionPerp); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(directionPerp); + } + + /** + * Gets the flag that says whether or not the offset origin and direction are relative to the entity orientation. + * @returns {boolean} + */ + getRelativeToEntityOrientation() { + return this._relativeToEntityOrientation; + } + + /** + * Sets the flag that says whether or not the offset origin and direction are relative to the entity orientation. Defaults to true. + * @param {boolean} relativeToEntityOrientation + */ + setRelativeToEntityOrientation(relativeToEntityOrientation) { + this._relativeToEntityOrientation = relativeToEntityOrientation; + } + + /** + * Prepares the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + const time = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(this.getEntity().getScene().getEngine().getTime(), 0, this._length / this._speedOfParticles); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'time', time); + + if (this._relativeToEntityOrientation) { + const originOffset = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const direction = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + originOffset.rotate(this.getEntity().getOrientation(), this._originOffset); + direction.rotate(this.getEntity().getOrientation(), this._direction); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'originOffset', originOffset); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'direction', direction); + + // Get the perpendicular direction for orienting the particles. + const directionPerp = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + directionPerp.cross(direction, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis); + if (directionPerp.isZero()) { + directionPerp.cross(direction, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis); + } + directionPerp.normalize(directionPerp); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'directionPerp', directionPerp); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(directionPerp); + + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(originOffset); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(direction); + } + + // Set the Three.js object position the entity's camera-space position. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + // Setup the Three.js material. + const threeJsMaterial = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RawShaderMaterial({ + uniforms: { + spread: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + originOffset: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()), + direction: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()), + directionPerp: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()), + length: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + time: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + totalTime: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + globalColor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4(1, 1, 1, 1)), + + ..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms + }, + vertexShader: ParticleSprayComponent.vertexShader, + fragmentShader: ParticleSprayComponent.fragmentShader, + transparent: true, + depthWrite: false, + blending: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.AdditiveBlending, + side: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide + }); + _internal__WEBPACK_IMPORTED_MODULE_0__.ShaderFix.fix(threeJsMaterial); + this.getThreeJsMaterials().push(threeJsMaterial); + + // Setup the attribute arrays. + const positionArray = new Float32Array([-1, -1, 1, -1, 1, 1, -1, 1]); + const paramsArray = new Float32Array(3 * this._numberOfParticles); + const colorArray = new Float32Array(4 * this._numberOfParticles); + const sizeArray = new Float32Array(1 * this._numberOfParticles); + const indexArray = new Uint16Array([0, 1, 2, 2, 3, 0]); + + // Setup the Three.js geometry. + const threeJsGeometry = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferGeometry(); + threeJsGeometry.setAttribute('position', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(positionArray, 2)); + threeJsGeometry.setAttribute('params', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(paramsArray, 3)); + threeJsGeometry.setAttribute('color', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(colorArray, 4)); + threeJsGeometry.setAttribute('size', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(sizeArray, 1)); + threeJsGeometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(indexArray, 1)); + threeJsGeometry.instanceCount = this._numberOfParticles; + + // Setup the Three.js object. + const threeJsObject = /** @type {THREE.Mesh} */ (_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObjectGivenGeometry(this, threeJsMaterial, threeJsGeometry)); + this.getThreeJsObjects().push(threeJsObject); + + // Set its orientation to the identity. The origin offset and direction vectors will be rotated if they are relative ot the entity. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(this.getThreeJsObjects()[0], _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + + // Initialize the particles. + this._initializeParticles(); + + // Setup uniforms. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'length', this._length); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'spread', _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(this._spread)); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'totalTime', this._length / this._speedOfParticles); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'originOffset', this._originOffset); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'direction', this._direction); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'globalColor', this._colorOfParticles); + + // Get the perpendicular direction for orienting the particles. + const directionPerp = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + directionPerp.cross(this._direction, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis); + if (directionPerp.isZero()) { + directionPerp.cross(this._direction, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis); + } + directionPerp.normalize(directionPerp); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0], 'directionPerp', directionPerp); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(directionPerp); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + } + + /** + * Initializes the particles. Resets them if they were already initialized. + * @private + */ + _initializeParticles() { + // Get the attributes and arrays. + const paramsAttribute = /** @type THREE.Mesh */(this.getThreeJsObjects()[0]).geometry.attributes['params']; + const colorAttribute = /** @type THREE.Mesh */(this.getThreeJsObjects()[0]).geometry.attributes['color']; + const sizeAttribute = /** @type THREE.Mesh */(this.getThreeJsObjects()[0]).geometry.attributes['size']; + const paramsArray = /** @type {Float32Array} */(paramsAttribute.array); + const colorArray = /** @type {Float32Array} */(colorAttribute.array); + const sizeArray = /** @type {Float32Array} */(sizeAttribute.array); + + // Setup the particles. + for (let i = 0, l = this._numberOfParticles; i < l; i++) { + paramsArray[i * 3 + 0] = Math.random() * 2 - 1; + paramsArray[i * 3 + 1] = Math.random() * 2 - 1; + if (this._particleSpacingRandom) { + paramsArray[i * 3 + 2] = Math.random(); + } + else { + paramsArray[i * 3 + 2] = i / this._numberOfParticles; + } + colorArray[i * 4 + 0] = 1; + colorArray[i * 4 + 1] = 1; + colorArray[i * 4 + 2] = 1; + colorArray[i * 4 + 3] = 1; + sizeArray[i * 1 + 0] = this._sizeOfParticles; + } + + // Flag to update the attributes. + paramsAttribute.needsUpdate = true; + colorAttribute.needsUpdate = true; + sizeAttribute.needsUpdate = true; + } +} + +ParticleSprayComponent.vertexShader = ` + attribute vec2 position; + attribute vec3 params; // x, y are in plane made by direction if z were 1, z is 0 to 1 where the particle is in the total length at time = 0 + attribute vec4 color; + attribute float size; + + uniform float spread; + uniform vec3 originOffset; // in model-space + uniform vec3 direction; // in model-space + uniform vec3 directionPerp; // in model-space + uniform float length; + uniform float time; + uniform float totalTime; + + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + varying vec2 vPosition; + varying vec4 vColor; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + float u = mod(params.z + time / totalTime, 1.0); + float sinSpread = sin(spread); + float uSpread = sinSpread > 0.0 ? u : (1.0 - u); + float sizeAtU = size * max(0.1, uSpread); + vec3 directionPerp2 = cross(direction, directionPerp); + vec3 modelPosition = originOffset + (directionPerp * params.x * sinSpread * uSpread + directionPerp2 * params.y * sinSpread * uSpread + direction * u) * length; + vec4 viewPosition = vec4(position.x * sizeAtU, 0, position.y * sizeAtU, 1) + modelViewMatrix * vec4(modelPosition, 1.0); + gl_Position = projectionMatrix * viewPosition; + gl_Position.w = viewPosition.y; + + // Set the varying variables. + vPosition = position; + vColor = color * (1.0 - u); + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`; + +ParticleSprayComponent.fragmentShader = ` + precision highp float; + + uniform vec4 globalColor; + + varying vec2 vPosition; + varying vec4 vColor; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main(void) { + // Set the color to be a circle tinted by the color and globalColor. + gl_FragColor = globalColor * vColor * max(0.0, 1.0 - dot(vPosition, vPosition)); + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`; + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/rings_component.js": +/*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/rings_component.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "RingsComponent": function() { return /* binding */ RingsComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * Rings, such as for Saturn. + */ +class RingsComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The url for the top texture. + * @type {string} + * @private + */ + this._topTextureUrl = ''; + + /** + * The url for the bottom texture. + * @type {string} + * @private + */ + this._bottomTextureUrl = ''; + + /** + * The inner radius. + * @type {number} + * @private + */ + this._innerRadius = 0; + + /** + * The outer radius. + * @type {number} + * @private + */ + this._outerRadius = 0; + + /** + * The distance at which the ring begins to fade (50% less than this number and it is completely gone). + * @type {number} + * @private + */ + this._fadeDistance = 0; + + /** + * The entities uses for shadows. Derived from the shadow entity names. + * @type {EntityRef[]} + * @private + */ + this._shadowEntities = []; + + /** + * A reference to the spheroid component. + * @type {ComponentRef} + * @private + */ + this._spheroidComponentRef = new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene()); + this._spheroidComponentRef.setByType(this.getEntity().getName(), 'spheroid'); + this._spheroidComponentRef.setRefChangedCallback(this._spheroidRefChangedCallback.bind(this)); + + // Bind the callbacks to this. + this._spheroidChangedCallback = this._spheroidChangedCallback.bind(this); + + // Lets the base component to check for valid orientation when determining whether this is visible. + this.__setUsesEntityOrientation(true); + } + + /** + * Gets the top texture url. + * @returns {string} + */ + getTopTextureUrl() { + return this._topTextureUrl; + } + + /** + * Sets the top texture url. + * @param {string} url + */ + setTopTextureUrl(url) { + this._topTextureUrl = url; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTextureIntoUniform(this, this.getThreeJsMaterials()[0], 'topTexture', this._topTextureUrl, true, false); + } + + /** + * Gets the bottom texture url. + * @returns {string} + */ + getBottomTextureUrl() { + return this._bottomTextureUrl; + } + + /** + * Sets the bottom texture url. + * @param {string} url + */ + setBottomTextureUrl(url) { + this._bottomTextureUrl = url; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTextureIntoUniform(this, this.getThreeJsMaterials()[0], 'bottomTexture', this._bottomTextureUrl, true, false); + } + + /** + * Gets the inner radius. + * @returns {number} + */ + getInnerRadius() { + return this._innerRadius; + } + + /** + * Sets the inner radius. + * @param {number} radius + */ + setInnerRadius(radius) { + this._innerRadius = radius; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'innerRadius', this._innerRadius); + } + + /** + * Gets the outer radius. + * @returns {number} + */ + getOuterRadius() { + return this._outerRadius; + } + + /** + * Sets the outer radius. + * @param {number} radius + */ + setOuterRadius(radius) { + this._outerRadius = radius; + this.__setRadius(this._outerRadius); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'outerRadius', this._outerRadius); + } + + /** + * Gets the top texture used for the rings. The alpha channel is used by the main material for shadows. + * @returns {THREE.Texture} + */ + getTopTexture() { + const material = this.getThreeJsMaterials()[0]; + if (material !== undefined) { + return material.uniforms['topTexture'].value; + } + return null; + } + + /** + * Gets the distance at which the ring begins to fade (50% less than this number and it is completely gone). + * @returns {number} + */ + getFadeDistance() { + return this._fadeDistance; + } + + /** + * Sets the distance at which the ring begins to fade (50% less than this number and it is completely gone). Defaults to 0. + * @param {number} fadeDistance + */ + setFadeDistance(fadeDistance) { + this._fadeDistance = fadeDistance; + } + + /** + * Returns the shadow entity or its name at the index. + * @param {number} index + * @returns {string | undefined} + */ + getShadowEntity(index) { + return this._shadowEntities[index]?.getName(); + } + + /** + * Sets the shadow entities. Each element can be either the name of an entity or an entity itself. + * @param {string[]} shadowEntities + */ + setShadowEntities(shadowEntities) { + this._shadowEntities = []; + for (const shadowEntity of shadowEntities) { + this._shadowEntities.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(), shadowEntity)); + } + const shadowEntitiesEnabled = (shadowEntities.length > 0); + for (let i = 0, l = this.getThreeJsMaterials().length; i < l; i++) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setDefine(this.getThreeJsMaterials()[i], 'shadowEntities', shadowEntitiesEnabled); + } + } + + /** + * Cleans up the component. + * @override + * @package + */ + __destroy() { + // Remove the spheroid changed callback. + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent !== null) { + spheroidComponent.removeChangedCallback(this._spheroidChangedCallback); + } + + super.__destroy(); + } + + /** + * Updates the camera-non-specific parts of the component. + * @override + * @package + */ + __update() { + // Update the spheroid component reference. + this._spheroidComponentRef.update(); + } + + /** + * Prepare the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + // Set the alpha fade distance multiplier. + if (this._fadeDistance > 0) { + const posInSpriteFrame = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const threeJsOrientation = this.getThreeJsObjects()[0].quaternion; + orientation.copyFromThreeJs(threeJsOrientation); + posInSpriteFrame.rotateInverse(this.getEntity().getOrientation(), this.getEntity().getCameraSpacePosition(camera)); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'alphaFadeMultiplier', + _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(0, 1, _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(2 * (Math.abs(posInSpriteFrame.z) / this._fadeDistance - 1) + 1))); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posInSpriteFrame); + } + + // Set the lightPosition and lightColor uniform. + _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setLightSourceUniforms(this.getThreeJsMaterials(), this.getEntity(), camera); + + // Setup the regular uniforms. + _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setUniforms(this.getThreeJsMaterials(), camera, this.getEntity(), this._shadowEntities, null, false); + + // Set the orientation to the entity's orientation. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0], this.getEntity()); + + // Set the Three.js object position the entity's camera-space position. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + // Load the textures. + const topPromise = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTexture(this, this._topTextureUrl, true, false); + const bottomPromise = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTexture(this, this._bottomTextureUrl, true, false); + + const [topTexture, bottomTexture] = await Promise.all([topPromise, bottomPromise]); + + // Check if the component has since been destroyed. + if (this.isDestroyed()) { + topTexture.dispose(); + bottomTexture.dispose(); + return; + } + + // Create the material. + const material = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ShaderMaterial({ + uniforms: { + ambientLightColor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Color()), + lightPositions: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0)]), + lightColors: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0)]), + lightRadii: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0, 0, 0, 0, 0]), + numLights: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + + entityPos: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()), + innerRadius: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._innerRadius), + outerRadius: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._outerRadius), + topTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(topTexture), + bottomTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(bottomTexture), + alphaFadeMultiplier: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1), + spheroidEquatorialRadius: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + spheroidPolarRadius: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + + // Shadow Entities + numShadowEntities: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + shadowEntityPositions: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()]), + shadowEntityRadii: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0, 0, 0, 0, 0]), + shadowEntitySunsetIntensity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0, 0, 0, 0, 0]), + shadowEntitySunsetColors: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()]), + + ..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms + }, + vertexShader: RingsComponent.vertexShader, + fragmentShader: RingsComponent.fragmentShader, + transparent: true, + depthWrite: false, + blending: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NormalBlending, + side: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide + }); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupLogDepthBuffering(material); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setDefine(material, 'shadowEntities', this._shadowEntities.length > 0); + this.getThreeJsMaterials().push(material); + + const object = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this, material, [ + { name: 'position', dimensions: 3 }, + { name: 'normal', dimensions: 3 }], false); + + const numSegments = 10; + const positions = new Float32Array(3 * numSegments * numSegments); + const normals = new Float32Array(3 * numSegments * numSegments); + const indices = new Uint16Array(6 * (numSegments - 1) * (numSegments - 1)); + for (let j = 0; j < numSegments; j++) { + for (let i = 0; i < numSegments; i++) { + const vertexIndex = i + j * numSegments; + positions[vertexIndex * 3 + 0] = (i / (numSegments - 1)) * 2.0 - 1.0; + positions[vertexIndex * 3 + 1] = (j / (numSegments - 1)) * 2.0 - 1.0; + positions[vertexIndex * 3 + 2] = 0.0; + normals[vertexIndex * 3 + 0] = 0.0; + normals[vertexIndex * 3 + 1] = 0.0; + normals[vertexIndex * 3 + 2] = 1.0; + if (i + 1 < numSegments && j + 1 < numSegments) { + indices[(i + j * (numSegments - 1)) * 6 + 0] = (i + 0) + (j + 0) * numSegments; + indices[(i + j * (numSegments - 1)) * 6 + 1] = (i + 0) + (j + 1) * numSegments; + indices[(i + j * (numSegments - 1)) * 6 + 2] = (i + 1) + (j + 0) * numSegments; + indices[(i + j * (numSegments - 1)) * 6 + 3] = (i + 1) + (j + 0) * numSegments; + indices[(i + j * (numSegments - 1)) * 6 + 4] = (i + 0) + (j + 1) * numSegments; + indices[(i + j * (numSegments - 1)) * 6 + 5] = (i + 1) + (j + 1) * numSegments; + } + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(object.geometry, 'position', positions); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(object.geometry, 'normal', normals); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(object.geometry, indices); + object.material = material; + this.getThreeJsObjects().push(object); + + // Update from the spheroid properties. + this._spheroidChangedCallback(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + } + + /** + * Callback called when the spheroid reference is found or lost. + * @param {SpheroidComponent} oldRef + * @param {SpheroidComponent} newRef + * @private + */ + _spheroidRefChangedCallback(oldRef, newRef) { + if (oldRef !== null) { + oldRef.removeChangedCallback(this._spheroidChangedCallback); + } + if (newRef !== null) { + newRef.addChangedCallback(this._spheroidChangedCallback); + } + this._spheroidChangedCallback(); + } + + /** + * Callback to be called when the spheroid component changed. + * @private + */ + _spheroidChangedCallback() { + // Set the radii uniforms. + const material = this.getThreeJsMaterials()[0]; + if (material !== null) { + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent !== null) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'spheroidEquatorialRadius', spheroidComponent.getEquatorialRadius()); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'spheroidPolarRadius', spheroidComponent.getPolarRadius()); + } + else { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'spheroidEquatorialRadius', 0); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'spheroidPolarRadius', 0); + } + } + } +} + +RingsComponent.vertexShader = ` + uniform float outerRadius; + + varying vec3 localPosition; + varying vec3 cameraSpacePosition; + varying vec3 modelNormal; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + localPosition = position * outerRadius; + cameraSpacePosition = (modelMatrix * vec4(localPosition, 1.)).xyz; + modelNormal = (modelMatrix * vec4(normal, 0.)).xyz; + vec4 viewPosition = viewMatrix * vec4(cameraSpacePosition, 1.); + gl_Position = projectionMatrix * viewPosition; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`; + +RingsComponent.fragmentShader = ` + precision highp float; + + #ifndef saturate + #define saturate(a) clamp(a, 0.0, 1.0) + #endif + + // Lights + uniform vec3 ambientLightColor; + uniform vec3 lightPositions[5]; + uniform vec3 lightColors[5]; + uniform float lightRadii[5]; + uniform int numLights; + + uniform float innerRadius; + uniform float outerRadius; + uniform sampler2D topTexture; + uniform sampler2D bottomTexture; + uniform float alphaFadeMultiplier; + uniform float spheroidEquatorialRadius; + uniform float spheroidPolarRadius; + uniform vec3 entityPos; + + // Shadow Entities. + #ifdef shadowEntities + uniform int numShadowEntities; + uniform vec3 shadowEntityPositions[5]; + uniform float shadowEntityRadii[5]; + uniform float shadowEntitySunsetIntensity[5]; + uniform vec3 shadowEntitySunsetColors[5]; + #endif + + // The varying attributes. + varying vec3 localPosition; + varying vec3 cameraSpacePosition; + varying vec3 modelNormal; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + float spheroidShadow(vec3 lightDir, float lightCosAngle, float spheroidScaling, vec3 normal, vec3 ringPos) { + vec3 sunDirScaled = normalize(lightDir - (spheroidScaling - 1.0) * lightCosAngle * normal); + float pDotLScaled = dot(ringPos, sunDirScaled); + if(dot(ringPos, ringPos) - pDotLScaled * pDotLScaled < spheroidEquatorialRadius * spheroidEquatorialRadius && pDotLScaled > 0.0) { + return 0.0; + } + else { + return 1.0; + } + } + + #ifdef shadowEntities + vec3 applyRayleighScattering(vec3 color, float amount) { + float value = (color.r + color.g + color.b); + if (value > 0.0) { + float rFactor = 1.0; // 6.3^-4 / 6.3^-4 + float gFactor = 1.602; // 5.6^-4 / 6.3^-4 + float bFactor = 3.228; // 4.7^-4 / 6.3^-4 + color.r *= pow(rFactor, -amount); + color.g *= pow(gFactor, -amount); + color.b *= pow(bFactor, -amount); + color = value * color / (color.r + color.g + color.b); + } + return color; + } + + vec3 getLightColorFromShadowEntities(vec3 lightColor, vec3 lightDir, vec3 lightPosition, float lightRadius, vec3 normal) { + vec3 color = lightColor; + for (int i = 0; i < 5; i++) { + if (i >= numShadowEntities) { + break; + } + vec3 origin = cameraSpacePosition - shadowEntityPositions[i]; + vec3 axis = normalize(shadowEntityPositions[i] - lightPosition); + float sd = dot(origin, axis); + if (sd > 0.0) { + float e = length(origin - sd * axis); + float ld = dot(cameraSpacePosition - lightPosition, axis); + float lr = lightRadius; + float sr = shadowEntityRadii[i]; + float e0 = (ld * sr - sd * lr) / (ld - sd); + float e1 = (ld * sr + sd * lr) / (ld - sd); + float lightLevel = 0.0; + if (e1 < 0.0 || sd < 0.0) { // light in front of shadow entity + lightLevel = 1.0; + } + else if (e0 < e1) { + e0 /= max(1.0, shadowEntitySunsetIntensity[i] * 2.0); + lightLevel = (e - e0) / (e1 - e0); + } + else { + lightLevel = e < e0 ? 0.0 : 1.0; // 0 radius light. + } + color = saturate(lightLevel) * applyRayleighScattering(color, saturate(1.5 - lightLevel) * saturate(shadowEntitySunsetIntensity[i])); + } +} + return color; + } + #endif + + void main(void) { + float spheroidScaling = spheroidEquatorialRadius / spheroidPolarRadius; + vec3 positionDir = normalize(cameraSpacePosition); + vec3 ringPos = cameraSpacePosition - entityPos; + vec3 normal = normalize(modelNormal); + float cameraCosAngle = -dot(positionDir, normal); + + // Calculate the UVs. + vec2 uv; + uv.x = (length(localPosition) - innerRadius) / (outerRadius - innerRadius); + if (uv.x < 0.0 || uv.x > 1.0) { + gl_FragColor = vec4(0, 0, 0, 0); + return; + } + uv.y = 0.0; + + // Get the pixels at those uvs. + vec4 topPixel = texture2D(topTexture, uv); + vec4 bottomPixel = texture2D(bottomTexture, uv); + + // Get the initial diffuse light. + vec3 diffuseLight = ambientLightColor; + + // For each light, + for (int i = 0; i < 5; i++) { + if (i >= numLights) { + break; + } + + vec3 lightDir = normalize(cameraSpacePosition - lightPositions[i]); + float lightCosAngle = -dot(lightDir, normal); + + vec3 incomingLight = lightColors[i]; + + #ifdef shadowEntities + incomingLight = getLightColorFromShadowEntities(incomingLight, lightDir, lightPositions[i], lightRadii[i], normal); + #endif + + float cameraDirDotLight = dot(positionDir, lightDir); + float bottomTopRatio = (1.0 + 0.2 * cameraDirDotLight) * sign(cameraCosAngle) * lightCosAngle; + float shadow = spheroidShadow(lightDir, lightCosAngle, spheroidScaling, normal, ringPos); + vec3 bottomColor = saturate(incomingLight * (1.0 - bottomTopRatio) * shadow); + vec3 topColor = 2.0 * saturate(incomingLight * bottomTopRatio * shadow); + + vec3 color = mix(bottomPixel.rgb * bottomColor, topPixel.rgb * topColor, bottomTopRatio); + gl_FragColor.rgb += color; + } + + gl_FragColor.a = topPixel.a; + gl_FragColor.a *= alphaFadeMultiplier; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`; + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/skybox_component.js": +/*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/skybox_component.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SkyboxComponent": function() { return /* binding */ SkyboxComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** The skybox component. */ +class SkyboxComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The number of latitudinal lines. The longitudinal lines will be double it. + * @type {number} + * @private + */ + this._numLatVerts = 20; + + /** + * The texture URL. + * @type {string} + * @private + */ + this._textureUrl = ''; + + // Set the radius to the whole universe. + this.__setRadius(1e24); + + // It uses the orientatin of the entity. + this.__setUsesEntityOrientation(true); + } + + /** + * Gets the texture url. + * @returns {string} + */ + getTextureUrl() { + return this._textureUrl; + } + + /** + * Sets the texture url. + * @param {string} url + */ + setTextureUrl(url) { + this._textureUrl = url; + this.resetResources(); + } + + /** + * Prepare the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + // Set the orientation to the entity's orientation. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0], this.getEntity()); + + // Set the Three.js object position the entity's camera-space position. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + // Load the texture. + const texture = await _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTexture(this, this._textureUrl, false, false); + + // Check if the component has since stopped loading. + if (this.getLoadState() !== 'loading') { + texture.dispose(); + return; + } + + // Create Three.js material. + const material = _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.get(); + this.getThreeJsMaterials().push(material); + material.defines['colorMapEmmissive'] = true; + material.needsUpdate = true; + material.uniforms['colorTexture'].value = texture; + + // Create the Three.js object. + const object = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this, material, [{ name: 'position', dimensions: 3 }, { name: 'uv', dimensions: 2 }], false); + this.getThreeJsObjects().push(object); + + // Make it used in the dynamic environment map. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.useInDynEnvMap(object, true); + + // Setup the geometry. + const latStep = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi / (this._numLatVerts - 1); + const lonStep = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi / this._numLatVerts; + const numVerts = (this._numLatVerts * 2 + 1) * this._numLatVerts; + + const meshPositions = new Float32Array(numVerts * 3); + const meshUVs = new Float32Array(numVerts * 2); + const meshIndices = new Uint16Array(this._numLatVerts * (this._numLatVerts - 1) * 12); + + const xyz = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + for (let latI = 0; latI < this._numLatVerts; latI++) { + for (let lonI = 0; lonI < this._numLatVerts * 2 + 1; lonI++) { + // Calculate the lla. + lla.lat = latI * latStep - _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi; + lla.lon = lonI * lonStep - _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi; + lla.alt = 0; + + // Calculate the xyz from the lla. + xyz.x = 5e23 * Math.cos(lla.lat) * Math.cos(lla.lon); + xyz.y = 5e23 * Math.cos(lla.lat) * Math.sin(lla.lon); + xyz.z = 5e23 * Math.sin(lla.lat); + + const vertexI = latI * (this._numLatVerts * 2 + 1) + lonI; + meshPositions[vertexI * 3 + 0] = xyz.x; + meshPositions[vertexI * 3 + 1] = xyz.y; + meshPositions[vertexI * 3 + 2] = xyz.z; + meshUVs[vertexI * 2 + 0] = 0.5 - lla.lon / _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + meshUVs[vertexI * 2 + 1] = 0.5 - lla.lat / _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi; + + const triangleI = latI * this._numLatVerts * 2 + lonI; + if (latI < this._numLatVerts - 1 && lonI < this._numLatVerts * 2) { + meshIndices[triangleI * 6 + 0] = (this._numLatVerts * 2 + 1) * (latI + 0) + (lonI + 0); + meshIndices[triangleI * 6 + 1] = (this._numLatVerts * 2 + 1) * (latI + 1) + (lonI + 0); + meshIndices[triangleI * 6 + 2] = (this._numLatVerts * 2 + 1) * (latI + 1) + (lonI + 1); + meshIndices[triangleI * 6 + 3] = (this._numLatVerts * 2 + 1) * (latI + 0) + (lonI + 0); + meshIndices[triangleI * 6 + 4] = (this._numLatVerts * 2 + 1) * (latI + 1) + (lonI + 1); + meshIndices[triangleI * 6 + 5] = (this._numLatVerts * 2 + 1) * (latI + 0) + (lonI + 1); + } + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(xyz); + const geometry = /** @type {THREE.Mesh} */(this.getThreeJsObjects()[0]).geometry; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(geometry, 'position', meshPositions); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(geometry, 'uv', meshUVs); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(geometry, meshIndices); + } + + /** + * Unloads the resources. + * @override + * @protected + */ + __unloadResources() { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/spheroid_component.js": +/*!********************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/spheroid_component.js ***! + \********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SpheroidComponent": function() { return /* binding */ SpheroidComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The spheroid component. + */ +class SpheroidComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The equatorial radius. + * @type {number} + * @private + */ + this._equatorialRadius = 1; + + /** + * The polar radius. + * @type {number} + * @private + */ + this._polarRadius = 1; + + /** + * The flag that if true is planetographic, otherwise is planetocentric. + * @type {boolean} + * @private + */ + this._planetographic = false; + + /** + * The flag that determines if the changedCallbacks need to be called on the next update. + * @type {boolean} + * @private + */ + this._changed = true; + + /** + * A set of callbacks to call when the spheroid properties change. + * @type {FastSet<() => any>} + * @private + */ + this._changedCallbacks = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastSet(); + } + + /** + * Gets the equatorial radius. + * @returns {number} + */ + getEquatorialRadius() { + return this._equatorialRadius; + } + + /** + * Sets the equatorial radius. + * @param {number} equatorialRadius + */ + setEquatorialRadius(equatorialRadius) { + this._equatorialRadius = equatorialRadius; + this._changed = true; + } + + /** + * Gets the polar radius. + * @returns {number} + */ + getPolarRadius() { + return this._polarRadius; + } + + /** + * Sets the polar radius. + * @param {number} polarRadius + */ + setPolarRadius(polarRadius) { + this._polarRadius = polarRadius; + this._changed = true; + } + + /** + * Gets the flag that if true is planetographic, otherwise is planetocentric. + * @returns {boolean} + */ + isPlanetographic() { + return this._planetographic; + } + + /** + * Sets flag that if true is planetographic, otherwise is planetocentric. Defaults to true. + * @param {boolean} planetographic + */ + setPlanetographic(planetographic) { + this._planetographic = planetographic; + this._changed = true; + } + + /** + * Adds a callback to be called when this changes. + * @param {() => any} changedCallback + */ + addChangedCallback(changedCallback) { + this._changedCallbacks.add(changedCallback); + } + + /** + * Removes a callback to be called when this changes. + * @param {() => any} changedCallback + */ + removeChangedCallback(changedCallback) { + this._changedCallbacks.delete(changedCallback); + } + + /** + * Updates the component. + * @override + * @package + */ + __update() { + // If one of the properties have changed, call the callbacks to notify other components or controllers. + if (this._changed) { + for (let i = 0, l = this._changedCallbacks.size; i < l; i++) { + this._changedCallbacks.getAt(i)(); + } + this._changed = false; + } + } + + /** + * Takes an LLA and sets out to the equivalent XYZ. + * @param {Vector3} out - the XYZ vector to be set + * @param {LatLonAlt} lla - the LLA vector to convert + */ + xyzFromLLA(out, lla) { + const cosLat = Math.cos(lla.lat); + const sinLat = Math.sin(lla.lat); + if (this._planetographic) { + const eSq = 1.0 - (this._polarRadius * this._polarRadius) / (this._equatorialRadius * this._equatorialRadius); + const radiusOfCurvature = this._equatorialRadius / Math.sqrt(1.0 - eSq * sinLat * sinLat); + out.x = (radiusOfCurvature + lla.alt) * cosLat * Math.cos(lla.lon); + out.y = (radiusOfCurvature + lla.alt) * cosLat * Math.sin(lla.lon); + out.z = ((1.0 - eSq) * radiusOfCurvature + lla.alt) * sinLat; + } + else { + const a = this._equatorialRadius; + const b = this._polarRadius; + const radius = a * b / Math.sqrt(b * b * cosLat * cosLat + a * a * sinLat * sinLat); + out.x = (radius + lla.alt) * cosLat * Math.cos(lla.lon); + out.y = (radius + lla.alt) * cosLat * Math.sin(lla.lon); + out.z = (radius + lla.alt) * sinLat; + } + } + + /** + * Gets the radius at the given XYZ. + * @param {Vector3} xyz - the xyz vector to use + * @param {number} [numIterations] - the number of iterations to use. Defaults to 5. + * @returns {number} + */ + radiusFromXYZ(xyz, numIterations = 5) { + if (this._planetographic) { + // Using http://mathforum.org/library/drmath/view/51834.html as a reference. The standard algorithm from the Astronomical Almanac. + const r = xyz.magnitudeXY(); + const eSq = 1.0 - (this._polarRadius * this._polarRadius) / (this._equatorialRadius * this._equatorialRadius); + let lat = Math.atan(xyz.z / ((1.0 - eSq) * r)); + let radius = 0; + for (let i = 0; i < numIterations; i++) { + const sinLat = Math.sin(lat); + radius = this._equatorialRadius / Math.sqrt(1.0 - eSq * sinLat * sinLat); + lat = Math.atan((xyz.z + radius * eSq * sinLat) / r); + } + return radius; + } + else { + const f = (xyz.z * xyz.z) / (xyz.x * xyz.x + xyz.y * xyz.y); + const cosLatSq = 1 / (1 + f); + const sinLatSq = f * cosLatSq; + const a = this._equatorialRadius; + const b = this._polarRadius; + return a * b / Math.sqrt(b * b * cosLatSq + a * a * sinLatSq); + } + } + + /** + * Takes an XYZ and sets out to the equivalent LLA. + * @param {LatLonAlt} out - the LLA vector to be set + * @param {Vector3} xyz - the XYZ vector to convert + * @param {number} [numIterations] - the number of iterations to use. Defaults to 5. + */ + llaFromXYZ(out, xyz, numIterations = 5) { + if (this._planetographic) { + out.lon = Math.atan2(xyz.y, xyz.x); + + // Using http://mathforum.org/library/drmath/view/51834.html as a reference. The standard algorithm from the Astronomical Almanac. + const r = xyz.magnitudeXY(); + const eSq = 1.0 - (this._polarRadius * this._polarRadius) / (this._equatorialRadius * this._equatorialRadius); + out.lat = Math.atan(xyz.z / ((1.0 - eSq) * r)); + let C = 0; + for (let i = 0; i < numIterations; i++) { + const sinLat = Math.sin(out.lat); + C = 1.0 / Math.sqrt(1.0 - eSq * sinLat * sinLat); + out.lat = Math.atan((xyz.z + this._equatorialRadius * C * eSq * sinLat) / r); + } + out.alt = r / Math.cos(out.lat) - this._equatorialRadius * C; + } + else { + const xyLength = xyz.magnitudeXY(); + out.lon = Math.atan2(xyz.y, xyz.x); + out.lat = Math.atan(xyz.z / xyLength); + const cosLat = Math.cos(out.lat); + const sinLat = Math.sin(out.lat); + const a = this._equatorialRadius; + const b = this._polarRadius; + const radius = a * b / Math.sqrt(b * b * cosLat * cosLat + a * a * sinLat * sinLat); + out.alt = xyz.magnitude() - radius; + } + } + + /** + * Sets out to lla but with the planetographic flag toggled, adjusting the latitude and altiude so that they represent the same location. + * @param {LatLonAlt} out - the LLA vector to be set + * @param {LatLonAlt} lla + */ + llaToggleGraphicCentric(out, lla) { + const xyz = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.xyzFromLLA(xyz, lla); + this._planetographic = !this._planetographic; + this.llaFromXYZ(out, xyz); + this._planetographic = !this._planetographic; + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(xyz); + } + + /** + * Returns the up vector from the LLA. + * @param {Vector3} out - the up vector to be set + * @param {LatLonAlt} lla - the LLA to use + */ + upFromLLA(out, lla) { + const llaPlanetographic = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + if (this._planetographic) { + llaPlanetographic.copy(lla); + } + else { + this.llaToggleGraphicCentric(llaPlanetographic, lla); + } + out.x = Math.cos(llaPlanetographic.lat) * Math.cos(llaPlanetographic.lon); + out.y = Math.cos(llaPlanetographic.lat) * Math.sin(llaPlanetographic.lon); + out.z = Math.sin(llaPlanetographic.lat); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(llaPlanetographic); + } + + /** + * Returns the east vector from the LLA. + * @param {Vector3} out - the east vector to be set + * @param {LatLonAlt} lla - the LLA to use + */ + eastFromLLA(out, lla) { + out.x = -Math.sin(lla.lon); + out.y = Math.cos(lla.lon); + out.z = 0; + } + + /** + * Returns the north vector from the LLA. + * @param {Vector3} out - the north vector to be set + * @param {LatLonAlt} lla - the LLA to use + */ + northFromLLA(out, lla) { + const llaPlanetographic = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + if (this._planetographic) { + llaPlanetographic.copy(lla); + } + else { + this.llaToggleGraphicCentric(llaPlanetographic, lla); + } + out.x = -Math.sin(llaPlanetographic.lat) * Math.cos(llaPlanetographic.lon); + out.y = -Math.sin(llaPlanetographic.lat) * Math.sin(llaPlanetographic.lon); + out.z = Math.cos(llaPlanetographic.lat); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(llaPlanetographic); + } + + /** + * Returns an orientation representing +x as east, +y as north, and +z as up from a LLA. + * @param {Quaternion} out - the orientation to be set + * @param {LatLonAlt} lla - the LLA to use + */ + orientationFromLLA(out, lla) { + const llaPlanetographic = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + if (this._planetographic) { + llaPlanetographic.copy(lla); + } + else { + this.llaToggleGraphicCentric(llaPlanetographic, lla); + } + const sLat = Math.sin(llaPlanetographic.lat); + const sLon = Math.sin(llaPlanetographic.lon); + const cLon = Math.cos(llaPlanetographic.lon); + out.w = 0.5 * Math.sqrt((1.0 + sLat) * (1.0 - sLon)); + out.x = 0.5 * Math.sqrt((1.0 - sLat) * (1.0 - sLon)); + out.y = 0.5 * Math.sqrt((1.0 - sLat) * (1.0 + sLon)) * Math.sign(cLon); + out.z = 0.5 * Math.sqrt((1.0 + sLat) * (1.0 + sLon)) * Math.sign(cLon); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(llaPlanetographic); + } + + /** + * Sets out to the AER of an XYZ from the viewpoint of an observer at a LLA. + * @param {AER} out - the AER vector to be set + * @param {Vector3} xyz - the XYZ point to observe + * @param {LatLonAlt} lla - the LLA from which to observe + */ + aerFromXYZRelToLLA(out, xyz, lla) { + // get the relative xyz at lla, as v + const v = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.xyzFromLLA(v, lla); + const llaPlanetographic = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + if (!this._planetographic) { + this.llaFromXYZ(llaPlanetographic, v); + } + else { + llaPlanetographic.copy(lla); + } + v.sub(xyz, v); + out.range = v.magnitude(); // the range + + // normalize it + v.mult(v, 1.0 / out.range); + + // get the angle between horizon and v, using up. this is the elevation + const up = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.upFromLLA(up, llaPlanetographic); + const vDotUp = v.dot(up); + out.elevation = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi - Math.acos(vDotUp); // get angle from horizontal + + // make v be just the tangent part + v.addMult(v, up, -vDotUp); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(up); + + // get the azimuth using the north/east directions + const north = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.northFromLLA(north, llaPlanetographic); + const east = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.eastFromLLA(east, llaPlanetographic); + out.azimuth = Math.atan2(v.dot(east), v.dot(north)); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(north); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(east); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(llaPlanetographic); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(v); + } + + /** + * Gets the location at the point of intersection of the ray and the spheroid. Origin and direction are in frame space. + * @param {Vector3} outPosition + * @param {Vector3} origin + * @param {Vector3} direction + */ + getRayIntersection(outPosition, origin, direction) { + const spheroidRatio = this._equatorialRadius / this._polarRadius; + const originAsSphere = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const directionAsSphere = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + originAsSphere.set(origin.x, origin.y, origin.z * spheroidRatio); + directionAsSphere.set(direction.x, direction.y, direction.z * spheroidRatio); + const intersectionDistance = _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLineSphereIntersectionWithSphereAtOrigin(originAsSphere, directionAsSphere, this._equatorialRadius); + outPosition.addMult(originAsSphere, directionAsSphere, intersectionDistance); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(originAsSphere); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(directionAsSphere); + outPosition.z /= spheroidRatio; + } + + /** + * Gets the frame-space position and up on the surface at the given frame-space position. + * Note that the height direction is not up with planetocentric coordinates. + * @param {Vector3} outPosition + * @param {Vector3} outHeightDir + * @param {Vector3} position + */ + getGroundPosition(outPosition, outHeightDir, position) { + // Get the position on the surface of the spheroid. + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + this.llaFromXYZ(lla, position); + lla.alt = 0; + this.xyzFromLLA(outPosition, lla); + const up = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.upFromLLA(outHeightDir, lla); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(up); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/spheroid_lod_component.js": +/*!************************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/spheroid_lod_component.js ***! + \************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SpheroidLODComponent": function() { return /* binding */ SpheroidLODComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The spheroid LOD component. + */ +class SpheroidLODComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * Texture URLs for the various textures. + * @type {FastMap} + * @private + */ + this._textureUrls = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The LOD objects (one per face and one per texture type) that determines the texture. + * @type {FastMap} + * @private + */ + this._textureLODs = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The pixel sizes used for the LOD textures. + * @type {FastMap} + * @private + */ + this._textureSizes = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The mapping used for the mesh and textures. + * @type {string} + * @private + */ + this._mapping = 'cylinder'; + + /** + * The longitudinal rotation in radians of the spheroid. + * @type {number} + * @private + */ + this._longitudinalRotation = 0; + + /** + * The number of faces, determined by the mapping. + * @type {number} + * @private + */ + this._numFaces = 1; + + /** + * The lower left coordinate of the bounds. + * @type {LatLonAlt} + * @private + */ + this._lowerLeftBounds = new _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt(-_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi, -_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi, 0); + + /** + * The upper right coordinate of the bounds. + * @type {LatLonAlt} + * @private + */ + this._upperRightBounds = new _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt(+_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi, _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi, 0); + + /** + * The layout used for the cubemap mapping. + * @type {Vector3[][]} + */ + this._cubeMapFaceFrames = _internal__WEBPACK_IMPORTED_MODULE_0__.CubeMap._defaultCubeMapFaceFrames; + + /** + * The entities uses for shadows. Derived from the shadow entity names. + * @type {EntityRef[]} + * @private + */ + this._shadowEntities = []; + + /** + * The features that are enabled. + * @type {Set} + * @private + */ + this._features = new Set(); + + /** + * The flag that if true, uses compressed textures. + * @type {boolean} + * @private + */ + this._useCompression = false; + + /** + * A reference to the atmosphere component. + * @type {ComponentRef} + * @private + */ + this._atmosphereComponentRef = new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene()); + this._atmosphereComponentRef.setByType(this.getEntity().getName(), 'atmosphere'); + + /** + * A reference to the spheroid component. + * @type {ComponentRef} + * @private + */ + this._spheroidComponentRef = new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene()); + this._spheroidComponentRef.setByType(this.getEntity().getName(), 'spheroid'); + this._spheroidComponentRef.setRefChangedCallback(this._spheroidRefChangedCallback.bind(this)); + + // Bind the callbacks to this. + this._spheroidChangedCallback = this._spheroidChangedCallback.bind(this); + + // Lets the base component to check for valid orientation when determining whether this is visible. + this.__setUsesEntityOrientation(true); + } + + /** + * Gets the list of texture names as a new array. + * @returns {string[]} + */ + getTextureNames() { + /** @type {string[]} */ + const names = []; + for (let i = 0; i < this._textureUrls.size; i++) { + names.push(this._textureUrls.getAt(i).key); + } + return names; + } + + /** + * Gets the texture URL for the given name. Returns undefined if it doesn't exist. + * @param {string} name + * @returns {string} + */ + getTextureUrl(name) { + return this._textureUrls.get(name); + } + + /** + * Gets the level-of-detail sizes of the named texture. Defaults to [16, 512, 4096]. + * @param {string} name + * @returns {number[]} + */ + getTextureSizes(name) { + return this._textureSizes.get(name); + } + + /** + * Sets the texture URL for the given name. + * @param {string} name + * @param {string} url + * @param {number[]} [sizes=[4, 512, 4096]] + */ + setTexture(name, url, sizes = [4, 512, 4096]) { + // Activate feature + if (SpheroidLODComponent._textureToFeature.has(name)) { + this.setFeature(SpheroidLODComponent._textureToFeature.get(name), url !== ''); + } + + this._textureUrls.set(name, url); + this._textureSizes.set(name, [...sizes]); + let textureLODs = this._textureLODs.get(name); + // If there is no texture LOD yet, add it. + if (textureLODs === undefined) { + textureLODs = []; + const materials = this.getThreeJsMaterials(); + for (let i = 0, l = this._numFaces; i < l; i++) { + const textureLOD = new _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLOD(this); + if (materials.length > 0) { + const uniform = materials[i].uniforms[name + 'Texture']; + if (uniform !== undefined) { + textureLOD.setUniform(uniform); + } + } + textureLODs.push(textureLOD); + } + this._textureLODs.set(name, textureLODs); + } + for (let i = 0, l = this._numFaces; i < l; i++) { + textureLODs[i].setUrl(url.replace('$FACE', i.toString())); + textureLODs[i].setSizes(sizes); + } + } + + /** + * Forces the texture to be at the texture size. If size is undefined, it does normal LOD levels. + * @param {string} name + * @param {number} size + */ + forceTextureSize(name, size) { + const textureLODs = this._textureLODs.get(name); + if (textureLODs === undefined) { + throw new Error('No texture named "' + name + '" has been defined.'); + } + for (let i = 0; i < textureLODs.length; i++) { + textureLODs[i].setForcedSize(size); + } + } + + /** + * Removes the texture from the material. + * @param {string} name + */ + unsetTexture(name) { + // Deactivate feature + if (SpheroidLODComponent._textureToFeature.has(name)) { + this.setFeature(SpheroidLODComponent._textureToFeature.get(name), false); + } + + this._textureUrls.delete(name); + this._textureLODs.delete(name); + this._textureSizes.delete(name); + const materials = this.getThreeJsMaterials(); + for (let i = 0, l = materials.length; i < l; i++) { + const uniform = materials[i].uniforms[name + 'Texture']; + if (uniform !== undefined) { + uniform.value.dispose(); + uniform.value = null; + } + } + } + + /** + * Gets the texture level-of-detail's current size. + * @param {string} name + * @param {number} face + * @returns {number} + */ + getTextureCurrentSize(name, face) { + const textureLODs = this._textureLODs.get(name); + if (textureLODs !== undefined && textureLODs[face] !== undefined) { + return textureLODs[face].getCurrentSize(); + } + return undefined; + } + + /** + * Returns true if the feature is enabled. All features disabled by default. + * @param {string} feature + * @returns {boolean} + */ + isFeatureEnabled(feature) { + return this._features.has(feature); + } + + /** + * Enables or disables a feature, one of 'normalMap', 'nightMap', 'decalMap', 'specularMap', 'shadowRings', 'shadowEntities', 'noShading'. + * @param {string} feature - the feature to enable or disable + * @param {boolean} enable - turn on or off the feature in the shader + */ + setFeature(feature, enable) { + const materials = this.getThreeJsMaterials(); + if (enable && !this._features.has(feature)) { + this._features.add(feature); + for (let i = 0, l = materials.length; i < l; i++) { + const material = materials[i]; + material.defines[feature] = true; + material.needsUpdate = true; + } + if (feature === 'normalMap') { + this._updateMeshes(); + } + } + else if (!enable && this._features.has(feature)) { + this._features.delete(feature); + for (let i = 0, l = materials.length; i < l; i++) { + const material = materials[i]; + delete material.defines[feature]; + material.needsUpdate = true; + } + if (feature === 'normalMap') { + this._updateMeshes(); + } + } + } + + /** + * Gets the mapping used. Defaults to 'cylinder'. + * @returns {string} + */ + getMapping() { + return this._mapping; + } + + /** + * Sets the mapping used. It can be 'cylinder' or 'cube'. + * @param {string} mapping - the mapping to use + */ + setMapping(mapping) { + // Determine the number of faces. + const oldNumFaces = this._numFaces; + if (mapping === 'cylinder') { + this._numFaces = 1; + } + else if (mapping === 'cube') { + this._numFaces = 6; + } + else { + throw new Error('Invalid mapping type.'); + } + + // If there are a different number of faces, redo the texture LODs. + if (this._numFaces !== oldNumFaces) { + for (let i = 0; i < this._textureLODs.size; i++) { + const name = this._textureLODs.getAt(i).key; + const textureLODs = []; + for (let face = 0, l = this._numFaces; face < l; face++) { + const textureLOD = new _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLOD(this); + textureLOD.setUrl(this._textureUrls.get(name).replace('$FACE', face.toString())); + textureLOD.setSizes(this._textureSizes.get(name)); + textureLODs.push(textureLOD); + } + this._textureLODs.set(name, textureLODs); + } + } + + // Set the mapping. + this._mapping = mapping; + + // Reset the resources, since the mapping changed. + this.resetResources(); + } + + /** + * Sets the lower left and upper right coordinates of the bounds. + * @param {LatLonAlt} lowerLeft + * @param {LatLonAlt} upperRight + */ + setBounds(lowerLeft, upperRight) { + this._lowerLeftBounds.copy(lowerLeft); + this._upperRightBounds.copy(upperRight); + + // Reset the resources, since the bounds changed. + this.resetResources(); + } + + /** + * Sets how the 6 cubemaps will be laid out. It takes an 6-array of a 3-array of strings, like [['+x', '-y', '+z'], ['-x', '+y', '-z'], ...]. + * The first component is u, the second component is v, and the third component is outward. + * @param {string[][]} layout + */ + setCubeMapLayout(layout) { + // Set the vectors up correctly. + this._cubeMapFaceFrames = []; + for (let i = 0; i < 6; i++) { + this._cubeMapFaceFrames.push([]); + for (let j = 0; j < 3; j++) { + let v = null; + switch (layout[i][j]) { + case '+x': + v = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis; break; + case '-x': + v = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg; break; + case '+y': + v = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis; break; + case '-y': + v = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg; break; + case '+z': + v = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis; break; + case '-z': + v = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxisNeg; break; + default: + throw new Error('Invalid cubemap layout component.'); + } + this._cubeMapFaceFrames[i][j] = v; + } + } + // Reset the resources, since the layout changed. + this.resetResources(); + } + + /** + * Gets the number of shadow entities. Can be used to enumerate the shadow entities. + * @returns {number} + */ + getNumShadowEntities() { + return this._shadowEntities.length; + } + + /** + * Returns the shadow entity or its name at the index. + * @param {number} index + * @returns {string | undefined} + */ + getShadowEntity(index) { + return this._shadowEntities[index]?.getName(); + } + + /** + * Sets the shadow entities. Each element can be either the name of an entity or an entity itself. + * @param {string[]} shadowEntities + */ + setShadowEntities(shadowEntities) { + this._shadowEntities = []; + for (const shadowEntity of shadowEntities) { + this._shadowEntities.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(), shadowEntity)); + } + const shadowEntitiesEnabled = (shadowEntities.length > 0); + for (let i = 0, l = this.getThreeJsMaterials().length; i < l; i++) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setDefine(this.getThreeJsMaterials()[i], 'shadowEntities', shadowEntitiesEnabled); + } + } + + /** + * Gets the flag that if true, uses compressed textures. + * @returns {boolean} + */ + getUseCompression() { + return this._useCompression; + } + + /** + * Sets the flag that if true, uses compressed textures. + * @param {boolean} useCompression + */ + setUseCompression(useCompression) { + this._useCompression = useCompression; + } + + /** + * Gets the longitudinal rotation in radians of the spheroid. + * @returns {number} + */ + getLongitudeRotation() { + return this._longitudinalRotation; + } + + /** + * Sets the longitudinal rotation in radians of the spheroid. + * @param {number} rotation + */ + setLongitudeRotation(rotation) { + this._longitudinalRotation = rotation; + } + + /** + * Gets a new promise that resolves when the component is loaded. + * @returns {Promise} + * @override + */ + getLoadedPromise() { + const promises = [super.getLoadedPromise()]; + for (let i = 0; i < this._textureLODs.size; i++) { + const textureLODs = this._textureLODs.getAt(i).value; + for (let i = 0, l = textureLODs.length; i < l; i++) { + promises.push(textureLODs[i].getLoadedPromise()); + } + } + return Promise.all(promises).then(); + } + + /** + * Gets the color of the named texture at the given position in frame-space. If the position is higher up, it reduces the lat/lon of the position to find the color. + * @param {Color} outColor + * @param {Vector3} position + * @param {string} textureName + */ + getColorAtPosition(outColor, position, textureName) { + const uvFace = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (this._mapping === 'cube') { + _internal__WEBPACK_IMPORTED_MODULE_0__.CubeMap.xyzToUVFace(uvFace, position, this._cubeMapFaceFrames); + } + else if (this._mapping === 'cylinder') { + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent === null) { + outColor.set(0, 0, 0); + return; + } + uvFace.set(lla.lon / _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi + 0.5, lla.lat / Math.PI + 0.5, 0); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + } + // Get the texture LOD corresponding to the face. + const textureLODs = this._textureLODs.get(textureName); + if (textureLODs === undefined) { + throw new Error('Invalid texture name.'); + } + // Get the texture. + /** @type {THREE.Texture} */ + const texture = textureLODs[uvFace.z].getUniform().value; + // Since we can't read from a loaded texture, we load it to a canvas. + const canvas = document.createElement('canvas'); + canvas.width = texture.image.width; + canvas.height = texture.image.height; + const context = canvas.getContext('2d'); + context.drawImage(texture.image, 0, 0); + const imageData = context.getImageData(0, 0, texture.image.width, texture.image.height); + // Get the pixel from the image data. + const numbersPerPixel = texture.format === _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RGBAFormat ? 4 : 3; + const pixelIndex = (Math.floor((1 - uvFace.y) * imageData.height) * imageData.width + Math.floor(uvFace.x * imageData.width)) * numbersPerPixel; + outColor.set(imageData.data[pixelIndex + 0], imageData.data[pixelIndex + 1], imageData.data[pixelIndex + 2], numbersPerPixel === 4 ? imageData.data[pixelIndex + 3] : 1.0); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(uvFace); + } + + /** + * Sets the reference to use for the spheroid component, by name or the type index. + * @param {string | number} nameOrTypeIndex + */ + setSpheroidReference(nameOrTypeIndex) { + if (typeof nameOrTypeIndex === 'string') { + this._spheroidComponentRef.setByName(this.getEntity().getName(), nameOrTypeIndex); + } + else { + this._spheroidComponentRef.setByType(this.getEntity().getName(), 'spheroid', nameOrTypeIndex); + } + } + + /** + * Cleans up the component. + * @override + * @package + */ + __destroy() { + // Remove the spheroid changed callback. + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent !== null) { + spheroidComponent.removeChangedCallback(this._spheroidChangedCallback); + } + + super.__destroy(); + } + + /** + * Updates the camera-non-specific parts of the component. + * @override + * @package + */ + __update() { + // Set the texture LOD target size. + for (let i = 0; i < this._textureLODs.size; i++) { + const textureLODs = this._textureLODs.getAt(i).value; + for (let i = 0, l = textureLODs.length; i < l; i++) { + textureLODs[i].update(); + } + } + + // Update the spheroid component reference. + this._spheroidComponentRef.update(); + } + + /** + * Prepares the component for render. + * @param {CameraComponent} camera + * @override + * @package + */ + __prepareForRender(camera) { + // Set the orientation and position to the entity's orientation and camera-space position. + const objects = this.getThreeJsObjects(); + const longitudinalRotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + longitudinalRotation.setFromAxisAngle(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, this._longitudinalRotation); + for (let i = 0; i < objects.length; i++) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(objects[i], this.getEntity(), longitudinalRotation); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(objects[i], this.getEntity(), camera); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(longitudinalRotation); + + // Get the atmosphere. + const atmosphere = this._atmosphereComponentRef.get(); + + // Setup the regular uniforms. + _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setUniforms(this.getThreeJsMaterials(), camera, this.getEntity(), this._shadowEntities, atmosphere, true); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + const textureLODPromises = []; + for (let i = 0; i < this._numFaces; i++) { + // Create the material. + const material = _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.get(); + this.getThreeJsMaterials().push(material); + for (const feature of this._features) { + material.defines[feature] = true; + material.needsUpdate = true; + } + + // Create the object. + const object = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this, material, [ + { name: 'position', dimensions: 3 }, + { name: 'normal', dimensions: 3 }, + { name: 'uv', dimensions: 2 }], false); + this.getThreeJsObjects().push(object); + + // Make it used in the dynamic environment map. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.useInDynEnvMap(object, true); + + // Set the texture LODs uniforms. + for (let j = 0; j < this._textureLODs.size; j++) { + const name = this._textureLODs.getAt(j).key; + const uniform = material.uniforms[name + 'Texture']; + if (uniform !== undefined) { + const textureLOD = this._textureLODs.get(name)[i]; + textureLOD.setUniform(uniform); + textureLOD.update(); + textureLODPromises.push(textureLOD.getLoadedPromise()); + } + } + } + + return Promise.all(textureLODPromises).then(() => { + this._updateMeshes(); + }); + } + + /** + * Destroys the triangle meshes and LOD objects. + * @override + * @protected + */ + __unloadResources() { + // Destroy al of the objects and materials and textures. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + + // Set the texture LODs uniforms to null. + for (let i = 0; i < this._textureLODs.size; i++) { + const name = this._textureLODs.getAt(i).key; + for (let face = 0; face < this._numFaces; face++) { + this._textureLODs.get(name)[face].setUniform(null); + } + } + } + + /** + * Updates the ThreeJS mesh with the latest parameters. + * @private + */ + _updateMeshes() { + // No triangle meshes or spheroid, so do nothing. + if (this.getThreeJsObjects().length === 0) { + return; + } + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent === null) { + return; + } + + if (this._mapping === 'cylinder') { + const latDistance = this._upperRightBounds.lat - this._lowerLeftBounds.lat; + const lonDistance = this._upperRightBounds.lon - this._lowerLeftBounds.lon; + const numLatVerts = Math.max(Math.ceil(100 * latDistance / _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi), 4); + const numLonVerts = Math.max(Math.ceil(200 * lonDistance / _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi), 4); + const latStep = latDistance / (numLatVerts - 1); + const lonStep = lonDistance / (numLonVerts - 1); + const numVerts = numLonVerts * numLatVerts; + + const meshPositions = new Float32Array(numVerts * 3); + const meshNormals = new Float32Array(numVerts * 3); + const meshUVs = new Float32Array(numVerts * 2); + const meshIndices = new Uint16Array((numLonVerts - 1) * (numLatVerts - 1) * 6); + + const xyz = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + for (let latI = 0; latI < numLatVerts; latI++) { + for (let lonI = 0; lonI < numLonVerts; lonI++) { + lla.lat = this._lowerLeftBounds.lat + latI * latStep; + lla.lon = this._lowerLeftBounds.lon + lonI * lonStep; + lla.alt = 0; + + const vertexI = latI * numLonVerts + lonI; + spheroidComponent.xyzFromLLA(xyz, lla); + meshPositions[vertexI * 3 + 0] = xyz.x; + meshPositions[vertexI * 3 + 1] = xyz.y; + meshPositions[vertexI * 3 + 2] = xyz.z; + spheroidComponent.upFromLLA(xyz, lla); + meshNormals[vertexI * 3 + 0] = xyz.x; + meshNormals[vertexI * 3 + 1] = xyz.y; + meshNormals[vertexI * 3 + 2] = xyz.z; + meshUVs[vertexI * 2 + 0] = lonI / (numLonVerts - 1); + meshUVs[vertexI * 2 + 1] = 1.0 - latI / (numLatVerts - 1); + + if (latI + 1 < numLatVerts && lonI + 1 < numLonVerts) { + const triangleI = latI * (numLonVerts - 1) + lonI; + meshIndices[triangleI * 6 + 0] = numLonVerts * (latI + 0) + (lonI + 0); + meshIndices[triangleI * 6 + 1] = numLonVerts * (latI + 1) + (lonI + 1); + meshIndices[triangleI * 6 + 2] = numLonVerts * (latI + 1) + (lonI + 0); + meshIndices[triangleI * 6 + 3] = numLonVerts * (latI + 0) + (lonI + 0); + meshIndices[triangleI * 6 + 4] = numLonVerts * (latI + 0) + (lonI + 1); + meshIndices[triangleI * 6 + 5] = numLonVerts * (latI + 1) + (lonI + 1); + } + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(xyz); + + const mesh = /** @type {THREE.Mesh} */ (this.getThreeJsObjects()[0]); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(mesh.geometry, 'position', meshPositions); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(mesh.geometry, 'normal', meshNormals); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(mesh.geometry, 'uv', meshUVs); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(mesh.geometry, meshIndices); + if (this._features.has('normalMap')) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.computeTangents(mesh.geometry); + } + } + else if (this._mapping === 'cube') { + const numGridLines = 50; + + const xyz = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + for (let i = 0; i < 6; i++) { + const meshPositions = new Float32Array(numGridLines * numGridLines * 3); + const meshNormals = new Float32Array(numGridLines * numGridLines * 3); + const meshUVs = new Float32Array(numGridLines * numGridLines * 2); + const meshIndices = new Uint16Array((numGridLines - 1) * (numGridLines - 1) * 6); + + // Check the handed-ness of the cubemap vectors. + let flipped = false; + const zVector = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + zVector.cross(this._cubeMapFaceFrames[i][0], this._cubeMapFaceFrames[i][1]); + if (zVector.x !== this._cubeMapFaceFrames[i][2].x || zVector.y !== this._cubeMapFaceFrames[i][2].y || zVector.z !== this._cubeMapFaceFrames[i][2].z) { + flipped = true; + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(zVector); + + // Create the vertices, normals, and uvs. + let vertexI = 0; + let triangleI = 0; + for (let k = 0; k < numGridLines; k++) { + for (let j = 0; j < numGridLines; j++) { + xyz.mult(this._cubeMapFaceFrames[i][0], (2 * j) / (numGridLines - 1) - 1); + xyz.addMult(xyz, this._cubeMapFaceFrames[i][1], (2 * k) / (numGridLines - 1) - 1); + xyz.addMult(xyz, this._cubeMapFaceFrames[i][2], 1.0); + xyz.normalize(xyz); + + // Convert to lla as if xyz was on a sphere, then using it as a geodetic lla. + _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLLAFromXYZOnSphere(lla, xyz, 0); + lla.alt = 0; + + // Set the position. + spheroidComponent.xyzFromLLA(xyz, lla); + meshPositions[vertexI * 3 + 0] = xyz.x; + meshPositions[vertexI * 3 + 1] = xyz.y; + meshPositions[vertexI * 3 + 2] = xyz.z; + + // Set the normals. + spheroidComponent.upFromLLA(xyz, lla); + meshNormals[vertexI * 3 + 0] = xyz.x; + meshNormals[vertexI * 3 + 1] = xyz.y; + meshNormals[vertexI * 3 + 2] = xyz.z; + + // Set the UVs. + meshUVs[vertexI * 2 + 0] = j / (numGridLines - 1); + meshUVs[vertexI * 2 + 1] = 1.0 - k / (numGridLines - 1); + + // Set the indices. + if (j < numGridLines - 1 && k < numGridLines - 1) { + meshIndices[triangleI * 6 + 0] = (k + 0) * numGridLines + (j + 0); + meshIndices[triangleI * 6 + 3] = (k + 1) * numGridLines + (j + 1); + if (!flipped) { + meshIndices[triangleI * 6 + 1] = (k + 0) * numGridLines + (j + 1); + meshIndices[triangleI * 6 + 2] = (k + 1) * numGridLines + (j + 1); + meshIndices[triangleI * 6 + 4] = (k + 1) * numGridLines + (j + 0); + meshIndices[triangleI * 6 + 5] = (k + 0) * numGridLines + (j + 0); + } + else { + meshIndices[triangleI * 6 + 1] = (k + 1) * numGridLines + (j + 1); + meshIndices[triangleI * 6 + 2] = (k + 0) * numGridLines + (j + 1); + meshIndices[triangleI * 6 + 4] = (k + 0) * numGridLines + (j + 0); + meshIndices[triangleI * 6 + 5] = (k + 1) * numGridLines + (j + 0); + } + triangleI += 1; + } + + vertexI += 1; + } + } + + const mesh = /** @type {THREE.Mesh} */ (this.getThreeJsObjects()[i]); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(mesh.geometry, 'position', meshPositions); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(mesh.geometry, 'normal', meshNormals); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(mesh.geometry, 'uv', meshUVs); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(mesh.geometry, meshIndices); + if (this._features.has('normalMap')) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.computeTangents(mesh.geometry); + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(xyz); + } + } + + /** + * Callback called when the spheroid reference is found or lost. + * @param {SpheroidComponent} oldRef + * @param {SpheroidComponent} newRef + * @private + */ + _spheroidRefChangedCallback(oldRef, newRef) { + if (oldRef !== null) { + oldRef.removeChangedCallback(this._spheroidChangedCallback); + } + if (newRef !== null) { + newRef.addChangedCallback(this._spheroidChangedCallback); + } + this._spheroidChangedCallback(); + } + + /** + * Callback to be called when the spheroid component changed. + * @private + */ + _spheroidChangedCallback() { + // Set the radii uniforms. + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent !== null) { + this.__setRadius(Math.max(spheroidComponent.getEquatorialRadius(), spheroidComponent.getPolarRadius())); + } + else { + this.__setRadius(0); + } + this.resetResources(); + } +} + +/** + * Maps texture names to features to activate/deactivate automatically. + * @type {Map} + */ +SpheroidLODComponent._textureToFeature = new Map([ + ['normal', 'normalMap'], + ['night', 'nightMap'], + ['decal', 'decalMap'], + ['specular', 'specularMap'] +]); + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/spout_component.js": +/*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/spout_component.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SpoutComponent": function() { return /* binding */ SpoutComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * Spout component. The entity should also have a camera component. + */ +class SpoutComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.CameraComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The render width. + * @type {number} + * @private + */ + this._renderWidth = 2048; + + /** + * The distance to which the globe cameras should render. + * @private + */ + this._globeDistance = 1; + + // STUFF FOR RENDERING FACES + + /** + * The three js cameras. + * @type {THREE.PerspectiveCamera[]} + * @private + */ + this._threeJsFaceCameras = []; + + /** + * This render targets. + * @type {THREE.WebGLRenderTarget[]} + * @private + */ + this._threeJsFaceRenderTargets = []; + + // STUFF FOR RENDERING FINAL TEXTURE + + /** + * The ThreeJS quad. + * @type {THREE.Mesh} + * @private + */ + this._threeJsQuad = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh(); + + /** + * The ThreeJS scene. + * @type {THREE.Scene} + * @private + */ + this._threeJsSpoutScene = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Scene(); + + /** + * The ThreeJS cube camera. + * @type {THREE.OrthographicCamera} + * @private + */ + this._threeJsCubeCamera = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.OrthographicCamera(-1, 1, -1, 1, -1, 1); + + /** + * This render target is used to mark the start of the shared texture render block. + * @private + */ + this._tagStart = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderTarget(2, 3, { minFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter, magFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NearestFilter }); + + /** + * This render target is used to mark the end of the shared texture render block. + * @private + */ + this._tagEnd = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderTarget(3, 2, { minFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter, magFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NearestFilter }); + + /** + * This render target is used to signal that all the shared textures are rendered and can be sent to Spout. + * @private + */ + this._tagSend = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderTarget(3, 3, { minFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter, magFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NearestFilter }); + + /** + * This render target is the texture that will be read by Spout. + * @private + */ + this._spoutTexture = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderTarget(this._renderWidth, this._renderWidth / 2, { minFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter, magFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NearestFilter }); + + // Setup the cameras. + this._setupFaceCameras(); + + // Setup the quad for the final render. + this._setupQuad(); + } + + /** + * Gets the render width. + * @returns {number} + */ + getRenderWidth() { + return this._renderWidth; + } + + /** + * Sets the render width. + * @param {number} renderWidth + */ + setRenderWidth(renderWidth) { + this._renderWidth = renderWidth; + if (this._spoutTexture.width !== this._renderWidth) { + this._spoutTexture.setSize(this._renderWidth, this._renderWidth / 2); + } + for (let face = 0; face < 6; face++) { + this._threeJsFaceRenderTargets[face].setSize(this._renderWidth / 4, this._renderWidth / 4); + } + } + + /** + * Gets if this is for a globe projection. + * @return {boolean} + */ + getForGlobe() { + return this.getInvertDepth() === 1; + } + + /** + * Sets if this is for a globe projection. + * @param {boolean} forGlobe + * @param {number} globeDistance - The distance to which the camera should render. + */ + setForGlobe(forGlobe, globeDistance) { + this.setInvertDepth(forGlobe ? 1 : 0); + this._globeDistance = globeDistance; + } + + // INTERNALS + + /** + * Renders the camera. Called by Viewport. + * @override + * @internal + */ + __render() { + // Set the near and mid distances manually to work with the globe. + if (this.getForGlobe()) { + this.setNearDistance(Math.max(0.1, this.getEntity().getParent().getOcclusionRadius() * 0.5)); + this.setMidDistance(this.getAutoNearDistance()); + } + + // Update the projection matrix. + this._updateProjectionMatrices(); + + // Set the camera's orientation for each of the face cameras. + const sqrt2 = 0.7071067811865476; + const ori = this.getEntity().getOrientation(); + _tempThreeJsQuaternion.set(ori.x, ori.y, ori.z, ori.w); + this._threeJsFaceCameras[0].setRotationFromQuaternion(_tempThreeJsQuaternion); + _tempThreeJsQuaternion.set(sqrt2 * (ori.x - ori.y), sqrt2 * (ori.x + ori.y), sqrt2 * (-ori.w + ori.z), sqrt2 * (ori.w + ori.z)); + this._threeJsFaceCameras[1].setRotationFromQuaternion(_tempThreeJsQuaternion); + _tempThreeJsQuaternion.set(ori.y, -ori.x, ori.w, -ori.z); + this._threeJsFaceCameras[2].setRotationFromQuaternion(_tempThreeJsQuaternion); + _tempThreeJsQuaternion.set(sqrt2 * (ori.x + ori.y), sqrt2 * (-ori.x + ori.y), sqrt2 * (ori.w + ori.z), sqrt2 * (ori.w - ori.z)); + this._threeJsFaceCameras[3].setRotationFromQuaternion(_tempThreeJsQuaternion); + _tempThreeJsQuaternion.set(sqrt2 * (ori.w + ori.x), sqrt2 * (ori.y + ori.z), sqrt2 * (-ori.y + ori.z), sqrt2 * (ori.w - ori.x)); + this._threeJsFaceCameras[4].setRotationFromQuaternion(_tempThreeJsQuaternion); + _tempThreeJsQuaternion.set(sqrt2 * (-ori.w + ori.x), sqrt2 * (ori.y - ori.z), sqrt2 * (ori.y + ori.z), sqrt2 * (ori.w + ori.x)); + this._threeJsFaceCameras[5].setRotationFromQuaternion(_tempThreeJsQuaternion); + + // If we're using the globe, flip all of the face culling, since depth is inverted. + if (this.getForGlobe()) { + this._threeJsRenderer.state.setCullFace(_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CullFaceFront); + } + + // Render each of the face cameras to the render targets. + for (let face = 0; face < 6; face++) { + this._threeJsRenderer.setRenderTarget(this._threeJsFaceRenderTargets[face]); + this._threeJsRenderer.render(this.getEntity().getScene().getThreeJsScene(), this._threeJsFaceCameras[face]); + } + + // If we're using the globe, revert all of the face culling. + if (this.getForGlobe()) { + this._threeJsRenderer.state.setCullFace(_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CullFaceBack); + } + + // All of the render targets cleared between 'tagStart' and 'tagEnd', will be recorded as Spout textures. + this._threeJsRenderer.setRenderTarget(this._tagStart); + this._threeJsRenderer.clearColor(); + this._threeJsRenderer.setRenderTarget(this._spoutTexture); + this._threeJsRenderer.clearColor(); + this._threeJsRenderer.setRenderTarget(this._tagEnd); + this._threeJsRenderer.clearColor(); + + // Render to the Spout texture using the render targets. + this._threeJsRenderer.setRenderTarget(this._spoutTexture); + // this._threeJsRenderer.setRenderTarget(null); // Uncomment this to make it render to the viewport for debugging. + this._threeJsRenderer.render(this._threeJsSpoutScene, this._threeJsCubeCamera); + + // Signal that all of the recorded textures have been rendered and can be sent to Spout. + this._threeJsRenderer.setRenderTarget(this._tagSend); + this._threeJsRenderer.clearColor(); + + // Make the render target back to default. + this._threeJsRenderer.setRenderTarget(null); + } + + /** + * Sets up the cameras. + * @private + */ + _setupFaceCameras() { + for (let face = 0; face < 6; face++) { + this._threeJsFaceCameras.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.PerspectiveCamera(90.0, 1.0, 0.1, 1000)); + const projectionMatrix = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix4(); + projectionMatrix.set( + 1, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + 0, 1, 0, 0); + this._threeJsFaceCameras[face].projectionMatrix = projectionMatrix; + this._threeJsFaceCameras[face].projectionMatrixInverse.copy(projectionMatrix).invert(); + + // Setup the render target for the camera. + const renderTarget = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderTarget(this._renderWidth / 4, this._renderWidth / 4, { minFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter, magFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter }); + this._threeJsFaceRenderTargets.push(renderTarget); + } + } + + /** + * Updates the projection. + * @private + */ + _updateProjectionMatrices() { + const n = this.getAutoNearDistance(); + let f1 = Number.EPSILON - 1.0; + let f2 = n * (2.0 - Number.EPSILON); + if (this.getInvertDepth() === 1) { + const f = this._globeDistance; + f1 = (n + f) * (1 - Number.EPSILON) / (n - f); + f2 = -2 * n * f * (1 - Number.EPSILON) / (n - f); + } + for (let face = 0; face < 6; face++) { + this._threeJsFaceCameras[face].projectionMatrix.elements[6] = f1; + this._threeJsFaceCameras[face].projectionMatrix.elements[14] = f2; + } + } + + /** + * Sets the quad meshes up. + */ + _setupQuad() { + // Setup geometry. + const geometry = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferGeometry(); + const meshPositions = new Float32Array([-1, -1, 1, -1, 1, 1, -1, 1]); + const meshIndices = new Uint16Array([0, 1, 2, 0, 2, 3]); + geometry.setAttribute('position', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(meshPositions, 2)); + geometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(meshIndices, 1)); + + // Setup material uniforms. + const uniforms = { + textures: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([]) + }; + for (let face = 0; face < 6; face++) { + uniforms['textures'].value.push(this._threeJsFaceRenderTargets[face].texture); + } + + // Setup material. + const material = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RawShaderMaterial({ + uniforms: uniforms, + vertexShader: ` + attribute vec2 position; + varying vec2 xy; + void main() { + gl_Position = vec4(position.x, position.y, 0.0, 1.0); + xy = position; + }`, + fragmentShader: ` + precision highp float; + + uniform sampler2D textures[6]; + + varying vec2 xy; + const float PI = 3.1415926535897932384626433832795; + + vec3 xyToUvFace(vec2 xy) { + vec3 xyz = vec3( + cos(xy.y * PI / 2.0) * cos(xy.x * PI), + cos(xy.y * PI / 2.0) * sin(xy.x * PI), + sin(-xy.y * PI / 2.0)); + + vec3 basis[3]; + float face; + if (xyz.x * xyz.x >= xyz.y * xyz.y && xyz.x * xyz.x >= xyz.z * xyz.z) { + if (xyz.x >= 0.0) { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(1, 0, 0); + face = 0.0; + } + else { + basis[0] = vec3(0, -1, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(-1, 0, 0); + face = 2.0; + } + } + else if (xyz.y * xyz.y >= xyz.x * xyz.x && xyz.y * xyz.y >= xyz.z * xyz.z) { + if (xyz.y >= 0.0) { + basis[0] = vec3(-1, 0, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(0, 1, 0); + face = 1.0; + } + else { + basis[0] = vec3(1, 0, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(0, -1, 0); + face = 3.0; + } + } + else { + if (xyz.z >= 0.0) { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(-1, 0, 0); basis[2] = vec3(0, 0, 1); + face = 4.0; + } + else { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(1, 0, 0); basis[2] = vec3(0, 0, -1); + face = 5.0; + } + } + + vec3 uv = vec3( + basis[0].x * xyz.x + basis[0].y * xyz.y + basis[0].z * xyz.z, + basis[1].x * xyz.x + basis[1].y * xyz.y + basis[1].z * xyz.z, + basis[2].x * xyz.x + basis[2].y * xyz.y + basis[2].z * xyz.z); + uv.x /= uv.z; + uv.y /= uv.z; + + return vec3(0.5 * (uv.x + 1.0), 0.5 * (uv.y + 1.0), face); + } + + void main() { + vec3 uvFace = xyToUvFace(xy); + + vec4 pixel; + int face = int(uvFace.z); + + if (face == 0) { + pixel = texture2D(textures[0], vec2(uvFace.x, uvFace.y)); + } + else if (face == 1) { + pixel = texture2D(textures[1], vec2(uvFace.x, uvFace.y)); + } + else if (face == 2) { + pixel = texture2D(textures[2], vec2(uvFace.x, uvFace.y)); + } + else if (face == 3) { + pixel = texture2D(textures[3], vec2(uvFace.x, uvFace.y)); + } + else if (face == 4) { + pixel = texture2D(textures[4], vec2(uvFace.x, uvFace.y)); + } + else if (face == 5) { + pixel = texture2D(textures[5], vec2(uvFace.x, uvFace.y)); + } + + gl_FragColor = pixel; + }`, + depthTest: false, + depthWrite: false, + side: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide + }); + + // Setup object. + this._threeJsQuad = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh(geometry, material); + this._threeJsQuad.frustumCulled = false; + this._threeJsSpoutScene.add(this._threeJsQuad); + } +} + +/** + * A temporary ThreeJs Quaternion. + * @type {THREE.Quaternion} + * @private + */ +const _tempThreeJsQuaternion = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Quaternion(); + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/sprite_component.js": +/*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/sprite_component.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SpriteComponent": function() { return /* binding */ SpriteComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A 2D sprite in the X-Y plane relative to an entity. + */ +class SpriteComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The url for the texture. + * @type {string} + * @private + */ + this._textureUrl = ''; + + /** + * The size of the sprite. If a component is NaN, it uses the aspect ratio of the texture to determine that component's size. + * @type {Vector2} + * @private + */ + this._size = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(1, Number.NaN); + this._size.freeze(); + + /** + * The units of the size. It can be 'pixels' or 'km'. + * @type {string} + * @private + */ + this._sizeUnits = 'km'; + + /** + * Each pixel in the texture is multiplied by this value. + * @type {Color} + * @private + */ + this._colorMultiplier = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1); + this._colorMultiplier.freeze(); + + /** + * The alignment of the sprite along the x-y plane. + * @type {Vector2} + * @private + */ + this._alignment = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0.5, 0.5); + this._alignment.freeze(); + + /** + * The distance at which the sprite begins to fade (50% less than this number and it is completely gone). + * @type {number} + * @private + */ + this._fadeDistance = 0; + + /** + * A flag that determines if the sprite has transparent pixels. + * @type {boolean} + * @private + */ + this._transparent = false; + + /** + * A flag that determines if the sprite has blending mode. + * @type {string} + * @private + */ + this._blending = 'normal'; + + /** + * A flag that determines if the sprite is a billboard (always facing the camera). + * @type {boolean} + * @private + */ + this._billboard = false; + + /** + * The render ordering of the sprite. Lesser numbers are rendered behind greater numbers. + * @type {number} + * @private + */ + this._renderOrder = 0; + } + + /** + * Gets the url of the texture. + * @returns {string} + */ + getTextureUrl() { + return this._textureUrl; + } + + /** + * Sets the url of the texture. + * @param {string} url + */ + setTextureUrl(url) { + this._textureUrl = url; + this.resetResources(); + } + + /** + * Gets the size of the sprite. + * @return {Vector2} + */ + getSize() { + return this._size; + } + + /** + * Sets the size of the sprite. If a component is NaN, it uses the aspect ratio of the texture to determine that component's size. + * @param {Vector2} size + */ + setSize(size) { + this._size.thaw(); + this._size.copy(size); + this._size.freeze(); + this._updateSizeUniform(); + } + + /** + * Gets the units of the size. It can be 'pixels' or 'km'. Defaults to 'km'. + * @returns {string} + */ + getSizeUnits() { + return this._sizeUnits; + } + + /** + * Sets the units of the size. It can be 'pixels' or 'km'. + * @param {string} sizeUnits + */ + setSizeUnits(sizeUnits) { + this._sizeUnits = sizeUnits; + this._updateSizeUniform(); + } + + /** + * Gets the color multiplier of the sprite. Each pixel in the texture is multiplied by this color. + * @returns {Color} + */ + getColorMultiplier() { + return this._colorMultiplier; + } + + /** + * Sets the color multiplier of the sprite. Each pixel in the texture is multiplied by this color. + * @param {Color} colorMultiplier + */ + setColorMultiplier(colorMultiplier) { + this._colorMultiplier.thaw(); + this._colorMultiplier.copy(colorMultiplier); + this._colorMultiplier.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'colorMultiplier', colorMultiplier); + } + + /** + * Gets the sprite alignment on the X-Y plane. Defaults to being center aligned on both axes. + * @returns {Vector2} + */ + getAlignment() { + return this._alignment; + } + + /** + * Sets the alignment. + * @param {Vector2} alignment - the alignment to set + */ + setAlignment(alignment) { + this._alignment.thaw(); + this._alignment.copy(alignment); + this._alignment.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0], 'origin', this._alignment); + } + + /** + * Gets the distance at which the sprite begins to fade (50% less than this number and it is completely gone). + * @returns {number} + */ + getFadeDistance() { + return this._fadeDistance; + } + + /** + * Sets the distance at which the sprite begins to fade (50% less than this number and it is completely gone). Defaults to 0. + * @param {number} fadeDistance + */ + setFadeDistance(fadeDistance) { + this._fadeDistance = fadeDistance; + } + + /** + * Returns true if the sprite is a billboard (always facing the camera). Defaults to false. + * @returns {boolean} + */ + isBillboard() { + return this._billboard; + } + + /** + * Sets whether the sprite is a billboard (always facing the camera). + * @param {boolean} billboard + */ + setBillboard(billboard) { + this._billboard = billboard; + } + + /** + * Gets the transparency of the sprite. Determines whether or not the sprite has alpha values other than 0 or 1. + * @returns {boolean} + */ + getTransparent() { + return this._transparent; + } + + /** + * Sets whether or not the sprite has alpha values other than 0 or 1. Defaults to false. + * @param {boolean} transparent + */ + setTransparent(transparent) { + this._transparent = transparent; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setTransparent(this.getThreeJsMaterials()[0], this._transparent); + } + + /** + * Sets blending mode. Mode is one of 'normal', 'additive', 'subtractive', 'multliply', 'custom', or 'none'. Defaults to 'normal'. + * @param {string} blending + */ + setBlending(blending) { + this._blending = blending; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setBlending(this.getThreeJsMaterials()[0], this._blending); + } + + /** + * Gets the render ordering of the sprite. Lesser numbers are rendered behind greater numbers. + * @returns {number} + */ + getRenderOrder() { + return this._renderOrder; + } + + /** + * Sets the render ordering of the sprite. Lesser numbers are rendered behind greater numbers. Defaults to 0. + * @param {number} renderOrder + */ + setRenderOrder(renderOrder) { + this._renderOrder = renderOrder; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setRenderOrder(this.getThreeJsObjects()[0], this._renderOrder); + } + + /** + * Updates the camera-dependent parts of the component. + * @param {CameraComponent} camera - the camera being used in the render + * @override + */ + __prepareForRender(camera) { + // If the size units are in pixels, adjust the size accordingly. + if (this._sizeUnits === 'pixels') { + const size = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + const sizeMultiplier = this.getEntity().getExtentsRadius() / this.getEntity().getPixelSpaceExtentsRadius(camera); + size.mult(this._size, sizeMultiplier); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0], 'size', size); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(size); + } + + // If it is a billboard, set the orientation to always face the camera. + if (this.getThreeJsObjects().length > 0) { + if (this._billboard) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToBillboard(this.getThreeJsObjects()[0], this.getEntity(), camera); + } + else { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0], this.getEntity()); + } + } + + // Set the alpha fade distance multiplier. + if (this._fadeDistance > 0) { + const posInSpriteFrame = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const threeJsOrientation = this.getThreeJsObjects()[0].quaternion; + orientation.copyFromThreeJs(threeJsOrientation); + posInSpriteFrame.rotateInverse(this.getEntity().getOrientation(), this.getEntity().getCameraSpacePosition(camera)); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'alphaFadeMultiplier', + _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(0, 1, _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(2 * (Math.abs(posInSpriteFrame.z) / this._fadeDistance - 1) + 1))); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posInSpriteFrame); + } + + // Set the Three.js object position the entity's camera-space position. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + // Load the texture. + const texture = await _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTexture(this, this._textureUrl, false, false); + + // Check if the component has since stopped loading. + if (this.getLoadState() !== 'loading') { + texture.dispose(); + return; + } + + // Create the Three.js object. + if (SpriteComponent._useCount === 0) { + // Create the shared geometry as a square 0, 0 to 1, 1. + SpriteComponent._threeJsGeometry = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createGeometry([{ name: 'position', dimensions: 3 }, { name: 'uv', dimensions: 2 }], false); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(SpriteComponent._threeJsGeometry, 'position', new Float32Array([0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0])); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(SpriteComponent._threeJsGeometry, 'uv', new Float32Array([0, 1, 1, 1, 1, 0, 0, 0])); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(SpriteComponent._threeJsGeometry, new Uint16Array([0, 1, 2, 2, 3, 0])); + + // Create the shared material. + SpriteComponent._threeJsMaterial = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ShaderMaterial({ + uniforms: { + colorMultiplier: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4(1.0, 1.0, 1.0, 1.0)), + alphaFadeMultiplier: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1), + size: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(1.0, 1.0)), + colorTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + origin: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(0, 0)), + + ..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms + }, + vertexShader: ` + uniform vec2 size; + uniform vec2 origin; + varying vec2 fUV; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + vec4 viewPosition = modelViewMatrix * vec4((position.x - origin.x) * size.x, (position.y - origin.y) * size.y, 0.0, 1.0); + gl_Position = projectionMatrix * viewPosition; + fUV = uv; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`, + fragmentShader: ` + precision highp float; + + uniform vec4 colorMultiplier; + uniform float alphaFadeMultiplier; + uniform sampler2D colorTexture; + varying vec2 fUV; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main(void) { + gl_FragColor = texture2D(colorTexture, fUV); + gl_FragColor *= colorMultiplier; + gl_FragColor.a *= alphaFadeMultiplier; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`, + side: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide + }); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupLogDepthBuffering(SpriteComponent._threeJsMaterial); + } + SpriteComponent._useCount += 1; + + // Create the material. + const material = SpriteComponent._threeJsMaterial.clone(); + this.getThreeJsMaterials().push(material); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setTransparent(material, this._transparent); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setBlending(material, this._blending); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(material, 'colorMultiplier', this._colorMultiplier); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'alphaFadeMultiplier', 1); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(material, 'origin', this._alignment); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformTexture(material, 'colorTexture', texture); + + // Create the object. + const object = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObjectGivenGeometry(this, material, SpriteComponent._threeJsGeometry); + this.getThreeJsObjects().push(object); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setRenderOrder(object, this._renderOrder); + + this._updateSizeUniform(); + } + + /** + * Unloads the resources. + * @override + * @protected + */ + __unloadResources() { + // Destroy the material. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyMaterial(this.getThreeJsMaterials()[0]); + // Remove the object from the scene. + const object = this.getThreeJsObjects()[0]; + if (object.parent !== undefined) { + object.parent.remove(object); + } + // If there are no more sprites, destroy the geometry and material. + SpriteComponent._useCount -= 1; + if (SpriteComponent._useCount === 0) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyGeometry(SpriteComponent._threeJsGeometry); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyMaterial(SpriteComponent._threeJsMaterial); + } + } + + /** + * Updates the size of the sprite given the size of this component and the texture size. + * @private + */ + _updateSizeUniform() { + if (this.getThreeJsMaterials().length > 0) { + /** @type {THREE.Texture} */ + const texture = this.getThreeJsMaterials()[0].uniforms['colorTexture'].value; + if (texture !== null) { + const textureAspectRatio = texture.image.width / texture.image.height; + const size = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + if (Number.isNaN(this._size.x)) { + size.set(this._size.y * textureAspectRatio, this._size.y); + } + else if (Number.isNaN(this._size.y)) { + size.set(this._size.x, this._size.x / textureAspectRatio); + } + else { + size.set(this._size.x, this._size.y); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0], 'size', size); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(size); + + if (this._sizeUnits === 'km') { + this.__setRadius(Math.max(size.x, size.y)); + } + else { // pixels + this.__setRadius(Number.POSITIVE_INFINITY); + } + } + } + else { + if (this._sizeUnits === 'km') { + if (Number.isNaN(this._size.x)) { + this.__setRadius(this._size.y); + } + else if (Number.isNaN(this._size.y)) { + this.__setRadius(this._size.y); + } + else { + this.__setRadius(Math.max(this._size.x, this._size.y)); + } + } + else { + this.__setRadius(Number.POSITIVE_INFINITY); + } + } + } +} + +/** + * A global shared material, copied by sprites. + * @type {THREE.ShaderMaterial} + */ +SpriteComponent._threeJsMaterial = null; + +/** + * A global shared geometry unit square with a corner at (0, 0), copied by sprites. + * @type {THREE.BufferGeometry} + */ +SpriteComponent._threeJsGeometry = null; + +/** + * The count for the number of sprites used. + * @type {number} + */ +SpriteComponent._useCount = 0; + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/starfield_component.js": +/*!*********************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/starfield_component.js ***! + \*********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "StarfieldComponent": function() { return /* binding */ StarfieldComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +const eclipJ2000ToJ200Rotation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(0.9791532214288992, 0.2031230389823101, 0, 0); + +// Star used in the Starfield component. +class Star { + constructor() { + this.mag = 0; + this.absMag = 0; + this.color = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(); + this.position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this.particle = null; + } +} + +/** + * The starfield component. Loads a star file. + * @todo Document the star file format. + */ +class StarfieldComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The database URL. + * @type {string} + * @private + */ + this._url = ''; + + // Set the radius to the whole universe. + this.__setRadius(1e24); + } + + /** + * Gets the url of the star database. + * @returns {string} + */ + getUrl() { + return this._url; + } + + /** + * Sets the url. + * @param {string} url - the url to set + */ + setUrl(url) { + this._url = url; + this.resetResources(); + } + + /** + * Prepare the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + // If the camera is a Spout camera, use Spout for the render size. + const renderSize = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + if (camera.getType() === 'spout') { + const spoutComponent = /** @type {SpoutComponent} */(camera); + renderSize.set(spoutComponent.getRenderWidth(), spoutComponent.getRenderWidth() * 0.5); + } + // Otherwise use the viewport size. + else { + renderSize.copy(camera.getViewport().getBounds().size); + } + + const resolutionFactor = Math.sqrt(Math.max(renderSize.x, renderSize.y) * window.devicePixelRatio) / 60; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'resolutionFactor', resolutionFactor); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(renderSize); + + // Set the Three.js object position the entity's camera-space position. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + // Load the stars from the database. + const stars = await this._loadStars(); + + // Check if the component has since been destroyed. + if (this.isDestroyed()) { + return; + } + + // Setup the Three.js material. + const material = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ShaderMaterial({ + vertexShader: StarfieldComponent.vertexShader, + fragmentShader: StarfieldComponent.fragmentShader, + transparent: true, + blending: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.AdditiveBlending, + depthWrite: false, + uniforms: { + resolutionFactor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1.0), + + ..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms + } + }); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupLogDepthBuffering(material); + this.getThreeJsMaterials().push(material); + + // Setup the Three.js geometry. + const threeJsGeometry = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferGeometry(); + threeJsGeometry.setAttribute('position', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Float32Array(0), 3)); + threeJsGeometry.setAttribute('color', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Float32Array(0), 4)); + threeJsGeometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Uint16Array(0), 1)); + + // Setup the Three.js object. + const threeJsObject = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Points(threeJsGeometry, material); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupObject(this, threeJsObject); + threeJsObject.renderOrder = -2; // Make it render before other transparent objects. + this.getThreeJsObjects().push(threeJsObject); + + // Update the particle geometry from the star database. + const meshPositions = new Float32Array(stars.length * 3); + const meshColors = new Float32Array(stars.length * 4); + const meshIndices = new Uint16Array(stars.length); + for (let i = 0; i < stars.length; i++) { + const star = stars[i]; + meshPositions[i * 3 + 0] = star.position.x; + meshPositions[i * 3 + 1] = star.position.y; + meshPositions[i * 3 + 2] = star.position.z; + meshColors[i * 4 + 0] = star.color.r; + meshColors[i * 4 + 1] = star.color.g; + meshColors[i * 4 + 2] = star.color.b; + meshColors[i * 4 + 3] = star.absMag; // The alpha channel is for the absolute magnitude, used in the shader. + meshIndices[i] = i; + } + + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(threeJsGeometry, 'position', meshPositions); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(threeJsGeometry, 'color', meshColors); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(threeJsGeometry, meshIndices); + } + + /** + * Unloads the resources. + * @override + * @protected + */ + __unloadResources() { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + } + + /** + * Loads the star database. + * @returns {Promise} + * @private + */ + _loadStars() { + // The promise that is used to tell when the animdef is loaded. + return this.getEntity().getScene().getEngine().getDownloader().download(this._url, true).then((download) => { + if (download.status === 'cancelled') { + return Promise.resolve([]); + } + else if (download.status === 'failed') { + return Promise.reject(new Error('Failed to load starfield component file "' + download.url + '": ' + download.errorMessage)); + } + if (!(download.content instanceof ArrayBuffer)) { + return Promise.reject(new Error('Failed to load starfield component file "' + download.url + '": Not a binary file.')); + } + const reader = new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content); + const numStars = reader.readInt32(); + /** @type {Star[]} */ + const stars = []; + for (let i = 0; i < numStars; i++) { + const star = new Star(); + star.mag = reader.readFloat32(); + star.absMag = reader.readFloat32(); + star.color.r = reader.readByte() / 255; + star.color.g = reader.readByte() / 255; + star.color.b = reader.readByte() / 255; + star.color.div(star.color, star.color.max()); + star.position.y = -reader.readFloat32(); + star.position.z = reader.readFloat32(); + star.position.x = reader.readFloat32(); + star.position.rotate(eclipJ2000ToJ200Rotation, star.position); + stars.push(star); + } + + return stars; + }); + } +} + +StarfieldComponent.vertexShader = ` + #define PI 3.1415926538 + + attribute vec4 color; + varying vec4 fColor; + + uniform float resolutionFactor; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + // Returns the watts per km^2. + float absoluteMagnitudeToFlux(float absoluteMagnitude, float distance) { + float luminosityInWatts = 3.0128e28 * pow(10.0, absoluteMagnitude / -2.5); + return luminosityInWatts / (4.0 * PI * distance * distance); + } + + void main() { + vec4 viewPosition = modelViewMatrix * vec4(position, 1.0); + gl_Position = projectionMatrix * viewPosition; + gl_Position.w = viewPosition.y; + fColor = color; + + // Get the flux and brightness of the star at the camera's point. + float absMag = color.a; + float distance = length(viewPosition); + float flux = absoluteMagnitudeToFlux(absMag, distance); + float brightness = 2.0 * log(1.0 + flux * 1e4); + + // Adjust the color and size so that it is visually pleasing. + fColor.a = clamp(brightness * resolutionFactor, 0.05, 1.0); + gl_PointSize = clamp(brightness * 4.0 * resolutionFactor, 5.0, 24.0); + + // If it is too close, fade the star. + fColor.a = mix(0.0, fColor.a, clamp((distance - 1.0e12) / 9.0e12, 0.0, 1.0)); + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`; + +StarfieldComponent.fragmentShader = ` + precision highp float; + + varying vec4 fColor; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main(void) { + float distanceFromEdge = clamp(1.0 - 2.0 * length(gl_PointCoord - vec2(0.5, 0.5)), 0.0, 1.0); + float a = pow(distanceFromEdge, 5.0); + gl_FragColor.rgb = fColor.rgb; + gl_FragColor.a = fColor.a * a; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`; + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/components/trail_component.js": +/*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/trail_component.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TrailComponent": function() { return /* binding */ TrailComponent; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * Point used in Trail component. + * @private + */ +class Point { + /** + * Constructor. + */ + constructor() { + /** + * The time of the point. + * @type {number} + */ + this.time = 0; + + /** + * The position of the entity at this time. + * @type {Vector3} + */ + this.position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + /** + * The velocity of the entity at this time. + * @type {Vector3} + */ + this.velocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + } +} + +/** + * The trail component. + */ +class TrailComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The color of the trail. + * @type {Color} + * @private + */ + this._color = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1); + this._color.freeze(); + + /** + * The alpha value to which the trail fades (_points[0] is this value) + * @type {number} + * @private + */ + this._alphaFade = 0; + + /** + * The minimum width for the trail. + * @type {number} + * @private + */ + this._widthMin = 0; + + /** + * The maximum width for the trail. + * @type {number} + * @private + */ + this._widthMax = 2; + + /** + * A flag the determines whether or not the trail ignores the distance when determining visibility. + * @type {boolean} + * @private + */ + this._ignoreDistance = false; + + /** + * The start time. May be absolute or relative. + * @type {number | undefined} + * @private + */ + this._startTime = undefined; + + /** + * The end time. May be absolute or relative. + * @type {number|undefined} + * @private + */ + this._endTime = 0; + + /** + * Whether the start time is absolute or relative. + * @type {boolean} + * @private + */ + this._relativeStartTime = true; + + /** + * Whether the end time is absolute or relative. + * @type {boolean} + * @private + */ + this._relativeEndTime = true; + + /** + * The multiplier of the start time to use. Only valid when startTime is relative. + * @type {number} + * @private + */ + this._startTimeMultiplier = 1; + + /** + * The multiplier of the end time to use. Only valid when endTime is relative. + * @type {number} + * @private + */ + this._endTimeMultiplier = 1; + + /** + * The entity that the trail is relative to. Defaults to entity's parent if null. + * @type {EntityRef} + * @private + */ + this._relativeToEntity = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + + /** + * Flag if the trail is relative to the parent entity's orientation. + * @type {boolean} + * @private + */ + this._relativeToEntityOrientation = false; + + /** + * The maximum angle in radians allowed between segments before they are split. + * @type {number} + * @private + */ + this._angleCurveThreshold = 0.05235987755; // 3 degrees + + /** + * The initial time step for following the trail. Undefined means the trail length / the angular curve threshold. + * @type {number | undefined} + * @private + */ + this._initialTimeStep = undefined; + + /** + * The circular buffer of points. + * @type {Array} + * @private + */ + this._points = []; + + /** + * The start index for the points array. + * @type {number} + * @private + */ + this._pointsStart = 0; + + /** + * The number of items in the points array. + * @type {number} + * @private + */ + this._pointsCount = 0; + + /** + * The entity that the trail is relative-to. + * @type {EntityRef} + * @private + */ + this._currentRelativeToEntity = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + + /** + * The dash length for dashed lines. + * @type {number} + * @private + */ + this._dashLength = 1; + + /** + * The dash gap length for dashed lines. + * @type {number} + * @private + */ + this._dashGapLength = 0; + + /** + * The glow width for the lines. + * @type {number} + * @private + */ + this._glowWidth = 0; + + /** + * An offset time for the dash offset. + * @type {number} + * @private + */ + this._dashOffsetTime = 0; + + // Make the radius infinite since this should always show. + this.__setRadius(Number.POSITIVE_INFINITY); + } + + /** + * Gets the color of the trail. + * @returns {Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the color of the trail. Defaults to white. + * @param {Color} color - The color to set + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._color); + } + + /** + * Gets the value to which the trail alpha fades, between 0 and 1. Defaults to 0. + * @returns {number} + */ + getAlphaFade() { + return this._alphaFade; + } + + /** + * Sets the min and max widths for the trail. + * @param {number} min + * @param {number} max + */ + setWidths(min, max) { + this._widthMin = min; + this._widthMax = max; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'widthMin', min); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'widthMax', max); + } + + /** + * Sets the value to which trail alpha fades, between 0 and 1. Defaults to 0. + * @param {number} alphaFade - the value to set + */ + setAlphaFade(alphaFade) { + this._alphaFade = alphaFade; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'alphaFade', alphaFade); + } + + /** + * Sets the line dash and gap length. + * @param {number} dashLength + * @param {number} dashGapLength + */ + setDashLength(dashLength, dashGapLength) { + this._dashLength = dashLength; + this._dashGapLength = dashGapLength; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'dashLength', dashLength); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'dashGapLength', dashGapLength); + } + + /** + * Sets the glow for the lines. + * @param {number} glowWidth + */ + setGlowWidth(glowWidth) { + this._glowWidth = glowWidth; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'glowWidth', this._glowWidth); + } + + /** + * Gets the start time of the trail. If relative start time is true, this is a positive offset time. Otherwise it is absolute. If it is undefined and relative time is true, it is a dynamic length. Defaults to undefined. + * @returns {number | undefined} + */ + getStartTime() { + return this._startTime; + } + + /** + * Sets the start time of the trail. If relative start time is true, this is a positive offset time. Otherwise it is absolute. + * If it is undefined and relative start time is true, the length is dynamic. Default is undefined. + * @param {number | undefined} value - The value to set + */ + setStartTime(value) { + this._startTime = value; + } + + /** + * Gets the end time of the trail. If relative time is true, this is a positive offset time. Otherwise it is absolute. If it is undefined and relative time is true, it is a dynamic length. Defaults to 0. + * @returns {number | undefined} + */ + getEndTime() { + return this._endTime; + } + + /** + * Sets the end time of the trail. If relative end time is true, this is a positive offset time. Otherwise it is absolute. + * If it is undefined and relative time is true, the length is dynamic. + * @param {number | undefined} value - The value to set + */ + setEndTime(value) { + this._endTime = value; + } + + /** + * Returns true if the trail start time is relative to the current time. Defaults to true. + * @returns {boolean} + */ + isRelativeStartTime() { + return this._relativeStartTime; + } + + /** + * Sets if the trail start time is relative to the current time. + * @param {boolean} value - The value to set + */ + setRelativeStartTime(value) { + this._relativeStartTime = value; + this.resetPoints(); + } + + /** + * Returns true if the trail end time is relative to the current time. Defaults to true. + * @returns {boolean} + */ + isRelativeEndTime() { + return this._relativeEndTime; + } + + /** + * Sets if the trail end time is relative to the current time. + * @param {boolean} value - The value to set + */ + setRelativeEndTime(value) { + this._relativeEndTime = value; + this.resetPoints(); + } + + /** + * Gets the multiplier of the start time to use. Only valid when startTime is relative. Defaults to 1. + * @returns {number} + */ + getStartTimeMultiplier() { + return this._startTimeMultiplier; + } + + /** + * Sets the multiplier of the start time to use. Only valid when startTime is relative. Defaults to 1. + * @param {number} startTimeMultiplier + */ + setStartTimeMultiplier(startTimeMultiplier) { + this._startTimeMultiplier = startTimeMultiplier; + } + + /** + * Gets the multiplier of the end time to use. Only valid when endTime is relative. Defaults to 1. + * @returns {number} + */ + getEndTimeMultiplier() { + return this._endTimeMultiplier; + } + + /** + * Sets the multiplier of the end time to use. Only valid when endTime is relative. Defaults to 1. + * @param {number} endTimeMultiplier + */ + setEndTimeMultiplier(endTimeMultiplier) { + this._endTimeMultiplier = endTimeMultiplier; + } + + /** + * Gets the entity name that the trail is relative to. + * @returns {string} + */ + getRelativeToEntity() { + return this._relativeToEntity.getName(); + } + + /** + * Sets the entity name that the trail is relative to. Defaults to the parent if ''. + * @param {string} entityName + */ + setRelativeToEntity(entityName) { + this._relativeToEntity.setName(entityName); + this._currentRelativeToEntity.setName(entityName); + this.resetPoints(); + } + + /** + * Returns true if the trail is relative to the parent entity's orientation. Defaults to false. + * @returns {boolean} + */ + isRelativeToEntityOrientation() { + return this._relativeToEntityOrientation; + } + + /** + * Sets if the trail is relative to the parent entity's orientation. Used for landers and ground objects. + * @param {boolean} enable + */ + setRelativeToEntityOrientation(enable) { + this._relativeToEntityOrientation = enable; + if (!enable) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(this.getThreeJsObjects(), _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + this.resetPoints(); + } + + /** + * Gets the maximum angle in radians allowed between segments before they are split. + * @returns {number} + */ + getAngleCurveThreshold() { + return this._angleCurveThreshold; + } + + /** + * Sets the maximum angle in radians allowed between segments before they are split. Defaults to 3 degrees. + * @param {number} angleCurveThreshold + */ + setAngleCurveThreshold(angleCurveThreshold) { + this._angleCurveThreshold = angleCurveThreshold; + this.resetPoints(); + } + + /** + * Gets the initial time step for following the trail. Undefined means the trail length / the angular curve threshold. + * @returns {number | undefined} + */ + getInitialTimeStep() { + return this._initialTimeStep; + } + + /** + * Sets the initial time step for following the trail. Undefined means the trail length / the angular curve threshold. Defaults to undefined. + * @param {number | undefined} initialTimeStep + */ + setInitialTimeStep(initialTimeStep) { + this._initialTimeStep = initialTimeStep; + this.resetPoints(); + } + + /** + * Ignores the distance when determining whether it should show the trail or not. Defaults to false. + * @param {boolean} enable + */ + setIgnoreDistance(enable) { + this._ignoreDistance = enable; + } + + /** + * Resets the points on the trail, so that they will be newly added. Useful for when the entity's controllers have bee modified and the whole trail needs to be updated. + */ + resetPoints() { + this._points = []; + this._pointsCount = 0; + this._pointsStart = 0; + + if (this.getThreeJsObjects().length > 0) { + const geometry = (/** @type {THREE.Mesh} */(this.getThreeJsObjects()[0])).geometry; + const newArray = new Float32Array(0); + const buffer = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBuffer(newArray, TrailComponent.VERTEX_SIZE); + geometry.setAttribute('position', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 3, 0, false)); + geometry.setAttribute('positionPrev', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 3, 3, false)); + geometry.setAttribute('positionNext', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 3, 6, false)); + geometry.setAttribute('side', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 1, 9, false)); + geometry.setAttribute('index', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 1, 10, false)); + geometry.setAttribute('dashOffset', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 1, 11, false)); + + // Setup the index buffer. + geometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Uint16Array(0), 1)); + } + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + // Create the material. + const material = this.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('trail'); + this.getThreeJsMaterials().push(material); + material.uniforms['dashLength'].value = this._dashLength; + material.uniforms['dashGapLength'].value = this._dashGapLength; + material.uniforms['indexStart'].value = 0; + material.uniforms['indexCount'].value = 0; + material.uniforms['indexLength'].value = 0; + material.uniforms['color'].value.set(this._color.r, this._color.g, this._color.b, this._color.a); + material.uniforms['widthMin'].value = this._widthMin; + material.uniforms['widthMax'].value = this._widthMax; + material.uniforms['glowWidth'].value = this._glowWidth; + material.uniforms['alphaFade'].value = this._alphaFade; + + // Create the object. + const threeJsObject = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this, material, [ + { name: 'position', dimensions: 3 }, + { name: 'positionPrev', dimensions: 3 }, + { name: 'positionNext', dimensions: 3 }, + { name: 'side', dimensions: 1 }, + { name: 'index', dimensions: 1 }, + { name: 'dashOffset', dimensions: 1 } + ], true); + this.getThreeJsObjects().push(threeJsObject); + + // Return the resolved promise. + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + this.getEntity().getScene().getEngine().getMaterialManager().release(this.getThreeJsMaterials()[0]); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + this._points = []; + this._pointsCount = 0; + this._pointsStart = 0; + } + + /** + * Prepare the component for rendering. + * @param {CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + // If the parent has changed, we need to reset the points so that they work with the new parent. + if (this._relativeToEntity.getName() === '' && this.getEntity().getParent() !== null && this._currentRelativeToEntity.get() !== this.getEntity().getParent()) { + this._currentRelativeToEntity.setName(this.getEntity().getParent().getName()); + this.resetPoints(); + } + if (this._currentRelativeToEntity === null) { + return; + } + + // Update the points and set the calculated positions and colors. + this._updatePoints(); + + // Set the index start, count, and length uniforms. + const material = this.getThreeJsMaterials()[0]; + material.uniforms['indexStart'].value = this._pointsStart; + material.uniforms['indexCount'].value = this._pointsCount; + material.uniforms['indexLength'].value = this._points.length; + + // Set the alpha multiplier based on conditions. + let alphaMultiplier = 1.0; + if (!this._ignoreDistance) { + // Set the alpha multiplier based on the camera distance to the entity. + const normalizedSizeOfEntity = this.getEntity().getNormalSpaceExtentsRadius(camera); + alphaMultiplier *= (0.02 - normalizedSizeOfEntity) / 0.02; + + // When the position is too far, there's imprecision "wiggle" in the shader. This fades the trail before the wiggle occurs. + const camDistOverPosDist = this.getEntity().getCameraSpacePosition(camera).magnitude() / this.getEntity().getPosition().magnitude(); + alphaMultiplier *= _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(camDistOverPosDist * 1000); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material, 'alphaMultiplier', alphaMultiplier); + + // Set the pixel size. + // If the camera is a Spout camera, make the lines thicker and use Spout for the render size. + const pixelSize = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + if (camera instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.SpoutComponent) { + pixelSize.set(camera.getRenderWidth() * 0.1, camera.getRenderWidth() * 0.5 * 0.1); + } + // Otherwise use the viewport size. + else { + pixelSize.copy(camera.getViewport().getBounds().size); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(material, 'pixelSize', pixelSize); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelSize); + + // Set the position and orientation of the Three.js objects. + const currentRelativeToEntity = this._currentRelativeToEntity.get(); + if (currentRelativeToEntity !== null) { + // Set the Three.js object position the relative-to-entity's camera-space position. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPosition(this.getThreeJsObjects(), currentRelativeToEntity.getCameraSpacePosition(camera)); + + // If relativeToEntityOrientation is set, set the orientation to that entity. + if (this._relativeToEntityOrientation) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(this.getThreeJsObjects(), currentRelativeToEntity.getOrientation()); + } + } + } + + /** + * Updates the points array. + * @private + */ + _updatePoints() { + const intervalForUpdate = _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get(); + + // Determine the interval that will be updated. + this._getIntervalForUpdate(intervalForUpdate); + + // If one of the values is NaN, don't update the trail. + if (isNaN(intervalForUpdate.min) || isNaN(intervalForUpdate.max)) { + _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(intervalForUpdate); + return; + } + + // Determine the step for the vertices to be added. + // For a circular trail, 360 degrees total / 3 degrees each = 120 steps. + const initialTimeStep = this._initialTimeStep ?? (intervalForUpdate.length() * this._angleCurveThreshold / (2 * Math.PI)); + + // Get the start and end index ranges. + const updateRange = _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get(); + updateRange.set(Number.POSITIVE_INFINITY, 0); + + // FRONT POINTS + + // Pop off one end point. + if (this._relativeStartTime && this._pointsCount > 0 && this._points[this._pointsStart].time !== intervalForUpdate.min) { + this._popFrontPoint(updateRange); + } + + // Clear off any excess end points. + while (this._pointsCount > 0 && this._points[this._pointsStart].time < intervalForUpdate.min) { + this._popFrontPoint(updateRange); + } + + // Add on any new end points. + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + while (this._pointsCount === 0 || this._points[this._pointsStart].time > intervalForUpdate.min) { + // If we have a ton of points and we're in relative mode, don't add any more. + if (this._pointsCount >= 16000 && this._relativeStartTime) { + break; + } + + // Create new point. + this._pushFrontPoint(updateRange); + const nextPoint = this._points[this._pointsStart]; + + // Get a starting step. + let minStep = 1; + let maxStep = Number.POSITIVE_INFINITY; + let step = initialTimeStep; + if (this._pointsCount > 2) { + step = this._points[(this._pointsStart + 2) % this._points.length].time + - this._points[(this._pointsStart + 1) % this._points.length].time; + } + + // Get the next time, taking into account curvature. + let curvatureCheckCount = 0; + while (curvatureCheckCount < 20) { + let nextTime = intervalForUpdate.max; + if (this._pointsCount > 1) { + nextTime = this._points[(this._pointsStart + 1) % this._points.length].time - step; + } + if (nextTime < intervalForUpdate.min) { + nextTime = intervalForUpdate.min; + } + + // Get the next position and/or orientation states. + nextPoint.time = nextTime; + this._getPositionAndVelocity(nextPoint.position, nextPoint.velocity, nextPoint.time); + + // Invalid position and/or orientation states, so we can't draw any more trail. + if (nextPoint.position.isNaN() || (this._relativeToEntityOrientation && orientation.isNaN())) { + break; + } + + // Get angle for curvature checking. + let angle = 0; + if (this._pointsCount >= 2) { + angle = this._points[(this._pointsStart + 1) % this._points.length].velocity.angle(nextPoint.velocity); + } + + // Grow or shrink the step depending on the angle. + if (angle > this._angleCurveThreshold) { // too big of an angle, so shrink the step. + maxStep = step; + step = (minStep + step) / 2.0; + } + else if (this._pointsCount > 1 && step < initialTimeStep * 10 && (isNaN(angle) || angle < this._angleCurveThreshold / 3) && nextTime !== intervalForUpdate.min) { // too small of an angle, so grow the step. + minStep = step; + if (maxStep === Number.POSITIVE_INFINITY) { + step *= 2; + } + else { + step = (step + maxStep) / 2.0; + } + } + else { + break; + } + curvatureCheckCount++; + } + if (nextPoint.position.isNaN() || (this._relativeToEntityOrientation && orientation.isNaN())) { + this._popFrontPoint(updateRange); + break; + } + } + + // BACK POINTS + + // Pop off one end point. + if (this._relativeEndTime && this._pointsCount > 0 && this._points[(this._pointsStart + this._pointsCount - 1) % this._points.length].time !== intervalForUpdate.max) { + this._popBackPoint(updateRange); + } + + // Clear off any excess end points. + while (this._pointsCount > 0 && this._points[(this._pointsStart + this._pointsCount - 1) % this._points.length].time > intervalForUpdate.max) { + this._popBackPoint(updateRange); + } + + // Add on any new end points. + while (this._pointsCount === 0 || this._points[(this._pointsStart + this._pointsCount - 1) % this._points.length].time < intervalForUpdate.max) { + // If we have a ton of points and we're in relative mode, don't add any more. + if (this._pointsCount >= 16000 && this._relativeEndTime) { + break; + } + + // Create new point. + this._pushBackPoint(updateRange); + const nextPoint = this._points[(this._pointsStart + this._pointsCount - 1) % this._points.length]; + + // Get a starting step. + let minStep = 1; + let maxStep = Number.POSITIVE_INFINITY; + let step = initialTimeStep; + if (this._pointsCount > 2) { + step = this._points[(this._pointsStart + this._pointsCount - 2) % this._points.length].time + - this._points[(this._pointsStart + this._pointsCount - 3) % this._points.length].time; + } + + // Get the next time, taking into account curvature. + let curvatureCheckCount = 0; + while (curvatureCheckCount < 20) { + let nextTime = intervalForUpdate.min; + if (this._pointsCount > 1) { + nextTime = this._points[(this._pointsStart + this._pointsCount - 2) % this._points.length].time + step; + } + if (nextTime > intervalForUpdate.max) { + nextTime = intervalForUpdate.max; + } + + // Get the next position and/or orientation states. + nextPoint.time = nextTime; + this._getPositionAndVelocity(nextPoint.position, nextPoint.velocity, nextPoint.time); + + // Invalid position and/or orientation states, so we can't draw any more trail. + if (nextPoint.position.isNaN() || (this._relativeToEntityOrientation && orientation.isNaN())) { + break; + } + + // Get angle for curvature checking. + let angle = 0; + if (this._pointsCount >= 2) { + angle = this._points[(this._pointsStart + this._pointsCount - 2) % this._points.length].velocity.angle(nextPoint.velocity); + } + + // Grow or shrink the step depending on the angle. + if (angle > this._angleCurveThreshold) { // too big of an angle, so shrink the step. + maxStep = step; + step = (minStep + step) / 2.0; + } + else if (this._pointsCount > 1 && step < initialTimeStep * 10 && (isNaN(angle) || angle < this._angleCurveThreshold / 3) && nextTime !== intervalForUpdate.max) { // too small of an angle, so grow the step. + minStep = step; + if (maxStep === Number.POSITIVE_INFINITY) { + step *= 2; + } + else { + step = (step + maxStep) / 2.0; + } + } + else { + break; + } + curvatureCheckCount++; + } + if (nextPoint.position.isNaN() || (this._relativeToEntityOrientation && orientation.isNaN())) { + this._popBackPoint(updateRange); + break; + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(intervalForUpdate); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + + // UPDATE THE VERTEX ARRAY + + const geometry = (/** @type {THREE.Mesh} */(this.getThreeJsObjects()[0])).geometry; + const buffer = /** @type {THREE.InterleavedBufferAttribute} */(geometry.attributes['positionCurr']).data; + const array = /** @type {Float32Array} */(buffer.array); + for (let i = updateRange.min, max = Math.min(this._points.length - 1, updateRange.max); i <= max; i++) { + const thisPosition = this._points[i].position; + const prevPosition = !isNaN(this._points[(i + this._points.length - 1) % this._points.length].position.x) + ? this._points[(i + this._points.length - 1) % this._points.length].position + : thisPosition; + const nextPosition = !isNaN(this._points[(i + 1) % this._points.length].position.x) + ? this._points[(i + 1) % this._points.length].position + : thisPosition; + + array[i * 2 * TrailComponent.VERTEX_SIZE + 0] = thisPosition.x; + array[i * 2 * TrailComponent.VERTEX_SIZE + 1] = thisPosition.y; + array[i * 2 * TrailComponent.VERTEX_SIZE + 2] = thisPosition.z; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 0] = thisPosition.x; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 1] = thisPosition.y; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 2] = thisPosition.z; + array[i * 2 * TrailComponent.VERTEX_SIZE + 3] = prevPosition.x; + array[i * 2 * TrailComponent.VERTEX_SIZE + 4] = prevPosition.y; + array[i * 2 * TrailComponent.VERTEX_SIZE + 5] = prevPosition.z; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 3] = prevPosition.x; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 4] = prevPosition.y; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 5] = prevPosition.z; + array[i * 2 * TrailComponent.VERTEX_SIZE + 6] = nextPosition.x; + array[i * 2 * TrailComponent.VERTEX_SIZE + 7] = nextPosition.y; + array[i * 2 * TrailComponent.VERTEX_SIZE + 8] = nextPosition.z; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 6] = nextPosition.x; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 7] = nextPosition.y; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 8] = nextPosition.z; + array[i * 2 * TrailComponent.VERTEX_SIZE + 9] = +1; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 9] = -1; + array[i * 2 * TrailComponent.VERTEX_SIZE + 10] = i; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 10] = i; + array[i * 2 * TrailComponent.VERTEX_SIZE + 11] = this._points[i].time - this._dashOffsetTime; + array[(i * 2 + 1) * TrailComponent.VERTEX_SIZE + 11] = this._points[i].time - this._dashOffsetTime; + } + buffer.needsUpdate = true; + buffer.updateRange.offset = updateRange.max < updateRange.min ? 0 : updateRange.min * 2 * TrailComponent.VERTEX_SIZE; + buffer.updateRange.count = updateRange.max < updateRange.min ? -1 : (updateRange.length() + 1) * 2 * TrailComponent.VERTEX_SIZE; + + _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(updateRange); + } + + /** + * Gets the interval for updating the points. + * @param {Interval} intervalForUpdate + * @private + */ + _getIntervalForUpdate(intervalForUpdate) { + const currentTime = (this._relativeStartTime || this._relativeEndTime) + ? this.getEntity().getScene().getEngine().getTime() + : undefined; + // Set the interval min from the start time. + if (this._relativeStartTime) { + if (this._startTime !== undefined) { + intervalForUpdate.min = currentTime - this._startTimeMultiplier * this._startTime; + } + else { // We're using a dynamic length, dependent on the orbital parameters. + intervalForUpdate.min = currentTime - this._startTimeMultiplier * this._getAutoLength(currentTime); + } + } + else { + intervalForUpdate.min = this._startTime; + } + // Set the interval max from the end time. + if (this._relativeEndTime) { + if (this._endTime !== undefined) { + intervalForUpdate.max = currentTime + this._endTimeMultiplier * this._endTime; + } + else { // We're using a dynamic length, dependent on the position, speed, and orbital parameters. + intervalForUpdate.max = currentTime + this._endTimeMultiplier * this._getAutoLength(currentTime); + } + } + else { + intervalForUpdate.max = this._endTime; + } + intervalForUpdate.intersection(intervalForUpdate, this.getEntity().getPositionCoverage()); + } + + /** + * Pops the front of the positions array. + * @param {Interval} updateRange + * @private + */ + _popFrontPoint(updateRange) { + if (this._pointsCount > 0) { + this._resize(this._pointsCount - 1, updateRange); + updateRange.expandTo(this._pointsStart); + if (this._pointsCount > 1) { + updateRange.expandTo((this._pointsStart + 1) % this._points.length); + } + this._points[this._pointsStart].position.x = NaN; + this._pointsStart = (this._pointsStart + 1) % this._points.length; + this._pointsCount -= 1; + } + } + + /** + * Pops the back of the positions array. + * @param {Interval} updateRange + * @private + */ + _popBackPoint(updateRange) { + if (this._pointsCount > 0) { + this._resize(this._pointsCount - 1, updateRange); + this._pointsCount -= 1; + updateRange.expandTo((this._pointsStart + this._pointsCount) % this._points.length); + if (this._pointsCount > 0) { + updateRange.expandTo((this._pointsStart + this._pointsCount - 1) % this._points.length); + } + this._points[(this._pointsStart + this._pointsCount) % this._points.length].position.x = NaN; + } + } + + /** + * Pushes a value to the front of the positions array. + * @param {Interval} updateRange + * @private + */ + _pushFrontPoint(updateRange) { + this._resize(this._pointsCount + 1, updateRange); + this._pointsStart = (this._pointsStart + this._points.length - 1) % this._points.length; + updateRange.expandTo(this._pointsStart); + if (this._pointsCount > 0) { + updateRange.expandTo((this._pointsStart + 1) % this._points.length); + } + this._pointsCount += 1; + } + + /** + * Pushes a value to the back of the positions array. + * @param {Interval} updateRange + * @private + */ + _pushBackPoint(updateRange) { + this._resize(this._pointsCount + 1, updateRange); + this._pointsCount += 1; + updateRange.expandTo((this._pointsStart + this._pointsCount - 1) % this._points.length); + if (this._pointsCount > 1) { + updateRange.expandTo((this._pointsStart + this._pointsCount - 2) % this._points.length); + } + } + + /** + * Pops the front of the positions array. + * @param {number} newCount + * @param {Interval} updateRange + * @private + */ + _resize(newCount, updateRange) { + let resizing = false; + let newSize = this._points.length; + if (newCount + 1 > this._points.length + || (newCount <= this._points.length / 4 && newCount >= 8)) { + resizing = true; + } + if (resizing) { + newSize = Math.max(8, _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.ceilPow2(newCount + 1)); + const points = /** @type {Point[]} */([]); + // Copy over the original array of points, moving everything to start at 0. + for (let i = 0, l = this._pointsCount; i < l; i++) { + points.push(this._points[(this._pointsStart + i) % this._points.length]); + } + this._pointsStart = 0; + // Double the size of the array of points. + for (let i = this._pointsCount, l = newSize; i < l; i++) { + const point = new Point(); + point.position.x = Number.NaN; + points.push(point); + } + this._points = points; + + // Update the vertex buffer. + const geometry = (/** @type {THREE.Mesh} */(this.getThreeJsObjects()[0])).geometry; + const newArray = new Float32Array(this._points.length * 2 * TrailComponent.VERTEX_SIZE); + const buffer = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBuffer(newArray, TrailComponent.VERTEX_SIZE); + geometry.setAttribute('positionCurr', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 3, 0, false)); + geometry.setAttribute('positionPrev', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 3, 3, false)); + geometry.setAttribute('positionNext', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 3, 6, false)); + geometry.setAttribute('side', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 1, 9, false)); + geometry.setAttribute('index', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 1, 10, false)); + geometry.setAttribute('dashOffset', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 1, 11, false)); + + // Setup the index buffer. + const indices = new Uint16Array(this._points.length * 6); + for (let i = 0; i < this._points.length; i++) { + indices[i * 6 + 0] = (i * 2 + 0) % (this._points.length * 2); + indices[i * 6 + 1] = (i * 2 + 2) % (this._points.length * 2); + indices[i * 6 + 2] = (i * 2 + 3) % (this._points.length * 2); + indices[i * 6 + 3] = (i * 2 + 3) % (this._points.length * 2); + indices[i * 6 + 4] = (i * 2 + 1) % (this._points.length * 2); + indices[i * 6 + 5] = (i * 2 + 0) % (this._points.length * 2); + } + geometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(indices, 1)); + + // Set the dash offset time, since every vertex will be updated anyway. + this._dashOffsetTime = this._points[this._pointsStart].time; + + updateRange.min = 0; + updateRange.max = newSize; + } + } + + /** + * Gets the auto-length of a trail, if the start or end time is undefined. + * @param {number} time + * @returns {number} + * @private + */ + _getAutoLength(time) { + // Find the last dynamo that contains the time. + let dynamoController = null; + for (let i = 0; ; i++) { + const aDynamoController = this.getEntity().getControllerByClass(_internal__WEBPACK_IMPORTED_MODULE_0__.DynamoController, i); + if (aDynamoController === null) { + break; + } + if (aDynamoController.getPointType() === 'orb' && aDynamoController.getCoverage().contains(time)) { + dynamoController = aDynamoController; + } + } + // Get the specific angular momentum and velocity for the calcs. + const specificAngularMomentum = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const velocityAtTime = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.getEntity().getPositionAtTime(specificAngularMomentum, time); + this.getEntity().getVelocityAtTime(velocityAtTime, time); + specificAngularMomentum.cross(specificAngularMomentum, velocityAtTime); + let period = 0; + if (dynamoController !== null) { + // Get the dynamo params for the calcs. + const eccentricity = dynamoController.getEccentricity(time); + const gravParameter = dynamoController.getHeaderValue('gravitationalParameter1') + dynamoController.getHeaderValue('gravitationalParameter2'); + const specificOrbitalEnergy = -0.5 * (gravParameter * gravParameter / specificAngularMomentum.magnitudeSqr()) * (1 - eccentricity * eccentricity); + period = 2 * Math.PI * gravParameter / Math.sqrt(8.0 * Math.abs(Math.min(1.0, specificOrbitalEnergy * specificOrbitalEnergy * specificOrbitalEnergy))); + } + else { + period = 2 * Math.PI * specificAngularMomentum.magnitude() / velocityAtTime.magnitudeSqr(); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(specificAngularMomentum); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(velocityAtTime); + return period; + } + + /** + * Gets the position and the velocity relative to the relative-to entity at the given time. + * @param {Vector3} position + * @param {Vector3} velocity + * @param {number} time + * @private + */ + _getPositionAndVelocity(position, velocity, time) { + const relativeToEntity = this._relativeToEntity.getName() !== '' ? this._relativeToEntity.get() : this.getEntity().getParent(); + if (this._relativeToEntity.getName() === '') { // The relative to entity is the parent at the given time. + this.getEntity().getPositionAtTime(position, time); + this.getEntity().getVelocityAtTime(velocity, time); + const parentOfPositionName = this.getEntity().getParentAtTime(time); + const currentRelativeToEntity = this._currentRelativeToEntity.get(); + if (currentRelativeToEntity !== null && parentOfPositionName !== '' && parentOfPositionName !== currentRelativeToEntity.getName()) { + const parentOfPosition = this.getEntity().getScene().getEntity(parentOfPositionName); + if (parentOfPosition !== null) { + parentOfPosition.getPositionRelativeToEntity(position, position, currentRelativeToEntity, time); + parentOfPosition.getVelocityRelativeToEntity(velocity, velocity, currentRelativeToEntity, time); + } + else { + position.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + velocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + } + } + else if (relativeToEntity !== null) { + this.getEntity().getPositionRelativeToEntity(position, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, relativeToEntity, time); + this.getEntity().getVelocityRelativeToEntity(velocity, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, relativeToEntity, time); + } + else { + position.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + velocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + if (this._relativeToEntityOrientation && relativeToEntity !== null) { + const relativeToEntityOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + relativeToEntity.getOrientationAtTime(relativeToEntityOrientation, time); + position.rotateInverse(relativeToEntityOrientation, position); + velocity.rotateInverse(relativeToEntityOrientation, velocity); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(relativeToEntityOrientation); + } + } +} + +TrailComponent.VERTEX_SIZE = 12; + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/align_controller.js": +/*!*******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/align_controller.js ***! + \*******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AlignController": function() { return /* binding */ AlignController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A controller that aligns an entity with another entity on arbitrary axes. + */ +class AlignController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The align type for primary alignment. It can be 'none', 'align', 'velocity', 'point', or 'position'. + * @type {string} + * @private + */ + this._primaryAlignType = 'none'; + + /** + * The axis of this entity that will be used for primary alignment. + * @type {Vector3} + * @private + */ + this._primaryAxis = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(1, 0, 0); + this._primaryAxis.freeze(); + + /** + * The target entity for primary alignment. + * @type {EntityRef} + * @private + */ + this._primaryTargetEntity = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + this._primaryTargetEntity.setRefChangedCallback((oldRef, newRef) => { + this._removeDependentStates(oldRef, this._primaryAlignType); + this._addDependentStates(newRef, this._primaryAlignType); + }); + + /** + * The axis of the target entity with which this entity will align or point for primary alignment. + * @type {Vector3} + * @private + */ + this._primaryTargetAxis = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(1, 0, 0); + this._primaryTargetAxis.freeze(); + + /** + * The align type for secondary alignment. It can be 'none', 'align', 'velocity', 'point', or 'position'. + * @type {string} + * @private + */ + this._secondaryAlignType = 'none'; + + /** + * The axis of this entity that will align with the target entity's axis for secondary alignment. + * @type {Vector3} + * @private + */ + this._secondaryAxis = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 1, 0); + this._secondaryAxis.freeze(); + + /** + * The target entity for secondary alignment. + * @type {EntityRef} + * @private + */ + this._secondaryTargetEntity = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + this._secondaryTargetEntity.setRefChangedCallback((oldRef, newRef) => { + this._removeDependentStates(oldRef, this._secondaryAlignType); + this._addDependentStates(newRef, this._secondaryAlignType); + }); + + /** + * The axis of the target entity with which this entity will align for secondary alignment. + * @type {Vector3} + * @private + */ + this._secondaryTargetAxis = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 1, 0); + this._secondaryTargetAxis.freeze(); + + /** + * The joint for the model to align. If empty, the entity itself is used. + * @type {string} + * @private + */ + this._joint = ''; + + /** + * The joint's ThreeJs object. + * @type {THREE.Object3D} + * @private + */ + this._jointObject = null; + + /** + * The model for the joint. + * @type {ModelComponent} + * @private + */ + this._model = null; + + /** + * The id of the root of the model. Used to tell if the model's Three.js object has been destroyed and reloaded. + * @type {number} + * @private + */ + this._modelRootId = 0; + + // Let the base controller know that this changes the orientation. + this.addModifiedState('orientation'); + } + + /** + * Gets the align type for the primary alignment. + * @returns {string} + */ + getPrimaryAlignType() { + return this._primaryAlignType; + } + + /** + * Sets the align type for the primary alignment. It can be 'none', 'align', 'velocity', or 'point'. + * 'none' means no alignment + * 'align' aligns the entity with the target entity's axis + * 'velocity' aligns the entity with the target entity's velocity + * 'point' points the entity at the target entity. + * 'position' aligns the entity with the target entity's local position + * @param {string} alignType + */ + setPrimaryAlignType(alignType) { + if (this._primaryAlignType === alignType) { + return; + } + this._removeDependentStates(this._primaryTargetEntity.get(), this._primaryAlignType); + this._primaryAlignType = alignType; + this._addDependentStates(this._primaryTargetEntity.get(), this._primaryAlignType); + } + + /** + * Gets the axis of this entity that will align with the target entity's axis for the primary alignment + * @returns {Vector3} + */ + getPrimaryAxis() { + return this._primaryAxis; + } + + /** + * Sets the axis of this entity that will be used in the primary alignment. The axis must be normalized. + * @param {Vector3} axis + */ + setPrimaryAxis(axis) { + this._primaryAxis.thaw(); + this._primaryAxis.copy(axis); + this._primaryAxis.freeze(); + } + + /** + * Gets the target entity name with which this entity will align or point for primary alignment. + * @returns {string} + */ + getPrimaryTargetEntity() { + return this._primaryTargetEntity.getName(); + } + + /** + * Sets the target entity name with which this entity will align or point for primary alignment. + * @param {string} targetEntityName + */ + setPrimaryTargetEntity(targetEntityName) { + this._primaryTargetEntity.setName(targetEntityName); + } + + /** + * Gets the axis of the target entity with which this entity will align for primary alignment. The axis is in the target entity's oriented frame. + * @returns {Vector3} + */ + getPrimaryTargetAxis() { + return this._primaryTargetAxis; + } + + /** + * Sets the axis of the target entity with which this entity will align for primary alignment. The axis is in the target entity's oriented frame. The axis must be normalized. + * @param {Vector3} targetAxis + */ + setPrimaryTargetAxis(targetAxis) { + this._primaryTargetAxis.thaw(); + this._primaryTargetAxis.copy(targetAxis); + this._primaryTargetAxis.freeze(); + } + + /** + * Gets the align type for the secondary alignment. + * @returns {string} + */ + getSecondaryAlignType() { + return this._secondaryAlignType; + } + + /** + * Sets the align type for the secondary alignment. It can be 'none', 'align', 'velocity', 'point', or 'position'. + * 'none' means no alignment + * 'align' aligns the entity with the target entity's axis + * 'velocity' aligns the entity with the target entity's velocity + * 'point' points the entity at the target entity + * 'position' aligns the entity with the target entity's local position + * @param {string} alignType + */ + setSecondaryAlignType(alignType) { + if (this._secondaryAlignType === alignType) { + return; + } + this._removeDependentStates(this._secondaryTargetEntity.get(), this._secondaryAlignType); + this._secondaryAlignType = alignType; + this._addDependentStates(this._secondaryTargetEntity.get(), this._secondaryAlignType); + } + + /** + * Gets the axis of this entity that will align with the target entity's axis for the secondary alignment + * @returns {Vector3} + */ + getSecondaryAxis() { + return this._secondaryAxis; + } + + /** + * Sets the axis of this entity that will be used in the secondary alignment. The axis must be normalized. + * @param {Vector3} axis + */ + setSecondaryAxis(axis) { + this._secondaryAxis.thaw(); + this._secondaryAxis.copy(axis); + this._secondaryAxis.freeze(); + } + + /** + * Gets the target entity name with which this entity will align or point for secondary alignment. + * @returns {string} + */ + getSecondaryTargetEntity() { + return this._secondaryTargetEntity.getName(); + } + + /** + * Sets the target entity name with which this entity will align or point for secondary alignment. + * @param {string} targetEntityName + */ + setSecondaryTargetEntity(targetEntityName) { + this._secondaryTargetEntity.setName(targetEntityName); + } + + /** + * Gets the axis of the target entity with which this entity will align for secondary alignment. The axis is in the target entity's oriented frame. + * @returns {Vector3} + */ + getSecondaryTargetAxis() { + return this._secondaryTargetAxis; + } + + /** + * Sets the axis of the target entity with which this entity will align for secondary alignment. The axis is in the target entity's oriented frame. The axis must be normalized. + * @param {Vector3} targetAxis + */ + setSecondaryTargetAxis(targetAxis) { + this._secondaryTargetAxis.thaw(); + this._secondaryTargetAxis.copy(targetAxis); + this._secondaryTargetAxis.freeze(); + } + + /** + * Sets the alignment to be at the joint on the specified model. If no model is given, the first model in the entity is used. + * @param {string} joint + * @param {ModelComponent} [model] + */ + setJoint(joint, model) { + this._joint = joint; + if (!model) { + const modelFromEntity = /** @type {ModelComponent} */(this.getEntity().get('model')); + if (modelFromEntity !== null) { + this._model = modelFromEntity; + } + } + else { + this._model = model; + } + if (this._joint !== '') { + this.addDependentState(this.getEntity().getName(), 'orientation'); + this.removeModifiedState('orientation'); + } + else { + this.removeDependentState(this.getEntity().getName(), 'orientation'); + this.addModifiedState('orientation'); + } + } + + /** + * Sets the orientation at the given time. + * @param {Quaternion} orientation + * @param {number} [time] + * @override + * @internal + */ + __updateOrientationAtTime(orientation, time) { + if (this._joint !== '') { + return; + } + this._getOrientation(orientation, time); + } + + /** + * Updates the orientation. + * @override + * @internal + */ + __update() { + const newOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + if (this._jointObject !== null) { + newOrientation.copy(this.getEntity().getOrientation()); + } + else { + newOrientation.copy(this.getEntity().getOrientation()); + } + this._getOrientation(newOrientation); + + // Set the orientation. + if (this._jointObject !== null) { + // Get the orientation back into the ThreeJS object coordinates. + this._jointObject.quaternion.set(newOrientation.x, newOrientation.y, newOrientation.z, newOrientation.w); + } + else { + this.getEntity().setOrientation(newOrientation); + } + + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation); + } + + /** + * Gets the orientation of the entity or joint at the given time. + * The orientation should be initialized to the existing orientation of the entity. + * @param {Quaternion} orientation + * @param {number} [time] + * @private + */ + _getOrientation(orientation, time) { + // If a joint is specified, setup the joint's ThreeJs object. + if (this._joint !== '' && this._model !== null) { + const root = this._model.getThreeJsObjects()[0]; + if (root !== undefined && (this._jointObject === null || this._jointObject.name !== this._joint || root.id !== this._modelRootId)) { + const subObject = this._model.getThreeJsObjectByName(this._joint); + if (subObject !== null) { + this._jointObject = subObject; + this._modelRootId = root.id; + } + } + // No joint object yet when there should be, so do nothing. + if (this._jointObject === null) { + return; + } + } + + // Get the temporaries. + const targetAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + + // Get the primary axis from local to world coordinates. + const primaryAxisGlobal = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const primaryRotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const localToWorld = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + if (this._jointObject !== null) { + let jointAncestor = this._jointObject; + AlignController._tempThreeJsQuaternion.set(0, 0, 0, 1); + while (jointAncestor.parent !== null && jointAncestor.parent !== this._model.getThreeJsObjects()[0]) { + jointAncestor = jointAncestor.parent; + AlignController._tempThreeJsQuaternion.multiplyQuaternions(jointAncestor.quaternion, AlignController._tempThreeJsQuaternion); + } + localToWorld.copyFromThreeJs(AlignController._tempThreeJsQuaternion); + localToWorld.mult(this._model.getRotation(), localToWorld); + localToWorld.mult(orientation, localToWorld); + } + else { + localToWorld.copy(orientation); + } + if (localToWorld.isNaN()) { + localToWorld.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + primaryAxisGlobal.rotate(localToWorld, this._primaryAxis); + + // Get the primary axis. + this._getAxis(targetAxis, this._primaryAlignType, this._primaryTargetEntity, this._primaryTargetAxis, primaryAxisGlobal, time); + + if (targetAxis.isNaN()) { + targetAxis.set(1, 0, 0); + } + + // Get the rotation needed to align it, and apply it to the new orientation. + primaryRotation.setFromVectorFromTo(primaryAxisGlobal, targetAxis); + orientation.mult(primaryRotation, localToWorld); + if (orientation.isNaN()) { + orientation.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(primaryAxisGlobal); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(primaryRotation); + + // Nothing to do if there is no secondary target entity. + if (this._secondaryAlignType !== 'none' && this._secondaryTargetEntity !== null) { + // Get the secondary axis. + this._getAxis(targetAxis, this._secondaryAlignType, this._secondaryTargetEntity, this._secondaryTargetAxis, primaryAxisGlobal, time); + + // Get the rotation required to align this entity. The rotation is around the primary target axis. + if (!targetAxis.isNaN()) { + const secondaryRotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const primaryAxisOriented = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const secondaryAxisOriented = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + primaryAxisOriented.rotate(orientation, this._primaryAxis); + secondaryAxisOriented.rotate(orientation, this._secondaryAxis); + const angle = secondaryAxisOriented.angleAroundAxis(targetAxis, primaryAxisOriented); + secondaryRotation.setFromAxisAngle(primaryAxisOriented, angle); + orientation.mult(secondaryRotation, orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(secondaryRotation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(primaryAxisOriented); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(secondaryAxisOriented); + } + } + + // Set the orientation. + orientation.normalize(orientation); + if (this._jointObject !== null) { + // Get the orientation back into the ThreeJS object coordinates. + orientation.multInverseL(localToWorld, orientation); + } + + // Release the temporaries. + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(localToWorld); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(targetAxis); + } + + /** + * Gets the axis to aligning. + * @param {Vector3} outAxis + * @param {string} alignType + * @param {EntityRef} targetEntityRef + * @param {Vector3} targetAxis + * @param {Vector3} axisGlobal + * @param {number} time + */ + _getAxis(outAxis, alignType, targetEntityRef, targetAxis, axisGlobal, time) { + const targetEntity = targetEntityRef.get(); + if (alignType === 'align' && targetEntity !== null) { + // Get the primary target entity axis in the global frame. + const primaryOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + targetEntity.getOrientationAtTime(primaryOrientation, time); + outAxis.rotate(primaryOrientation, targetAxis); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(primaryOrientation); + } + else if (alignType === 'velocity' && targetEntity !== null) { + // Get the primary target entity velocity. + targetEntity.getVelocityAtTime(outAxis, time); + outAxis.normalize(outAxis); + } + else if (alignType === 'point' && targetEntity !== null) { + // Get the position of the primary target entity in this entity's frame. + targetEntity.getPositionRelativeToEntity(outAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, this.getEntity(), time); + outAxis.normalize(outAxis); + } + else if (alignType === 'position' && targetEntity !== null) { + // Get the position of the primary target entity in this entity's frame. + outAxis.normalize(targetEntity.getPosition()); + } + else { + outAxis.copy(axisGlobal); + } + } + + /** + * Removes the dependent states based on the align entities. + * @param {Entity} entity + * @param {string} alignType + */ + _removeDependentStates(entity, alignType) { + if (entity !== null) { + if (alignType === 'align') { + this.removeDependentState(entity.getName(), 'orientation'); + } + else if (alignType === 'velocity') { + this.removeDependentState(entity.getName(), 'velocity'); + } + else if (alignType === 'point') { + this.removeDependentState(this.getEntity().getName(), 'position'); + this.removeDependentState(entity.getName(), 'position'); + } + else if (alignType === 'position') { + this.removeDependentState(entity.getName(), 'position'); + } + } + } + + /** + * Adds the dependent states based on the align entities. + * @param {Entity} entity + * @param {string} alignType + */ + _addDependentStates(entity, alignType) { + if (entity !== null) { + if (alignType === 'align') { + this.addDependentState(entity.getName(), 'orientation'); + } + else if (alignType === 'velocity') { + this.addDependentState(entity.getName(), 'velocity'); + } + else if (alignType === 'point') { + this.addDependentState(this.getEntity().getName(), 'position'); + this.addDependentState(entity.getName(), 'position'); + } + else if (alignType === 'position') { + this.addDependentState(entity.getName(), 'position'); + } + } + } +} + +/** + * A temporary ThreeJs Quaternion. + * @type {THREE.Quaternion} + */ +AlignController._tempThreeJsQuaternion = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Quaternion(); + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/animdata_controller.js": +/*!**********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/animdata_controller.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AnimdataController": function() { return /* binding */ AnimdataController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +const eclipJ2000ToJ200Rotation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(0.9791532214288992, 0.2031230389823101, 0, 0); + +class State { + /** + * Takes a Reader and populates the values. + * @param {Reader} _reader + */ + read(_reader) { + } + + /** + * Sets this to an interpolated state between state a and state b with an applied offset. + * @param {State} _state0 - the state at the beginning of the interval + * @param {State} _state1 - the state at the end of the interval + * @param {number} _intervalLength - the length of the interval + * @param {number} _u - the factor between 0 and 1 + */ + interpolate(_state0, _state1, _intervalLength, _u) { + } +} + +/** A state that represents a position and velocity. Used by {@link Animdata}. + * @private */ +class PosState extends State { + /** + * Constructor + */ + constructor() { + super(); + + /** + * Position in km at the start of this interval. + * @type {Vector3} + */ + this.position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + /** + * Velocity in km/s at the start of this interval. + * @type {Vector3} + */ + this.velocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + } + + /** + * Takes a Reader and populates the values. + * @param {Reader} reader + * @override + */ + read(reader) { + this.position.y = -reader.readFloat64(); + this.position.z = reader.readFloat64(); + this.position.x = reader.readFloat64(); + this.velocity.y = -reader.readFloat64(); + this.velocity.z = reader.readFloat64(); + this.velocity.x = reader.readFloat64(); + this.position.rotate(eclipJ2000ToJ200Rotation, this.position); + this.velocity.rotate(eclipJ2000ToJ200Rotation, this.velocity); + } + + /** + * Sets this to an interpolated state between state a and state b with an applied offset. + * @param {PosState} state0 - the state at the beginning of the interval + * @param {PosState} state1 - the state at the end of the interval + * @param {number} intervalLength - the length of the interval + * @param {number} u - the factor between 0 and 1 + * @override + */ + interpolate(state0, state1, intervalLength, u) { + const oneMinusU = 1.0 - u; + const oneMinusUQuantitySquared = oneMinusU * oneMinusU; + const uSquared = u * u; + const a = (1.0 + 2.0 * u) * oneMinusUQuantitySquared; + const b = u * oneMinusUQuantitySquared; + const c = uSquared * (3.0 - 2.0 * u); + const d = uSquared * -oneMinusU; + this.position.mult(state0.position, a); + this.position.addMult(this.position, state0.velocity, intervalLength * b); + this.position.addMult(this.position, state1.position, c); + this.position.addMult(this.position, state1.velocity, intervalLength * d); + const sixUSquaredMinusU = 6.0 * (uSquared - u); + const aV = sixUSquaredMinusU; + const bV = 3.0 * uSquared - 4.0 * u + 1.0; + const cV = -sixUSquaredMinusU; + const dV = 3.0 * uSquared - 2.0 * u; + this.velocity.mult(state0.position, aV / intervalLength); + this.velocity.addMult(this.velocity, state0.velocity, bV); + this.velocity.addMult(this.velocity, state1.position, cV / intervalLength); + this.velocity.addMult(this.velocity, state1.velocity, dV); + } +} + +/** A state that represents an orientation. Used by {@link Animdata}. + * @private */ +class OriState extends State { + /** + * Constructor + */ + constructor() { + super(); + + /** + * Orientation in radians at the start of this interval. + * @type {Quaternion} + */ + this.orientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + } + + /** + * Takes a Reader and populates the values. + * @param {Reader} reader + * @override + */ + read(reader) { + this.orientation.y = reader.readFloat32(); + this.orientation.z = -reader.readFloat32(); + this.orientation.x = -reader.readFloat32(); + this.orientation.w = reader.readFloat32(); + this.orientation.mult(eclipJ2000ToJ200Rotation, this.orientation); + } + + /** + * Sets this to an interpolated state between state a and state b with an applied offset. + * @param {OriState} state0 - the state at the beginning of the interval + * @param {OriState} state1 - the state at the end of the interval + * @param {number} _intervalLength - the length of the interval (not used) + * @param {number} u - the factor between 0 and 1 + * @override + */ + interpolate(state0, state1, _intervalLength, u) { + this.orientation.slerp(state0.orientation, state1.orientation, u); + } +} + +/** Data for a point in time. Used by {@link Animdata}. + * @private */ +class DataPoint { + /** + * Constructor + * @param {AnimdataController} controller - The controller. + */ + constructor(controller) { + /** + * Interval for this data point. Really only start is used. + * @type {Interval} + */ + this.interval = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(); + + /** + * The state at the start of the data point. + * @type {State} + */ + this.state = controller.__getNewState(); + } + + /** + * Read binary data into the data point. + * @param {Reader} reader - The reader to read data + */ + read(reader) { + this.interval.min = reader.readFloat64(); + this.interval.max = reader.readFloat64(); + this.state.read(reader); + } +} + +/** The animdata file. Contains list of intervals and states. Used by {@link Animdata}. + * @private */ +class AnimdataFile { + /** + * Constructor. Starts loading the data. + * @param {AnimdataController} controller - The controller + * @param {number} coverageIndex - The coverage index + * @param {number} animdataIndex - The animdata index + */ + constructor(controller, coverageIndex, animdataIndex) { + /** + * The interval covered by this animdata. It goes from the beginning of the first data point to the beginning of the last data point. + * @type {Interval} + */ + this.interval = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(); + + /** + * The list of data points contained in this animdata. + * @type {DataPoint[]} + */ + this.dataPoints = []; + + const url = controller.getUrl() + '/' + controller.getStateType() + '_data/' + ('00' + coverageIndex).slice(-3) + '.' + ('000' + (animdataIndex + 1)).slice(-4) + '.animdata'; + /** + * The promise that is used to tell when the animdata is loaded. + * @type {Promise} + */ + this.promise = controller.getEntity().getScene().getEngine().getDownloader().download(url, true).then(async (download) => { + if (download.status === 'cancelled') { + return Promise.resolve(); + } + else if (download.status === 'failed') { + return Promise.reject(new Error('Failed to load animdata controller file "' + download.url + '": ' + download.errorMessage)); + } + if (!(download.content instanceof ArrayBuffer)) { + return Promise.reject(new Error('Failed to load animdata controller file "' + download.url + '": Not a binary file.')); + } + const reader = new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content); + this.interval.min = reader.readFloat64(); + this.interval.max = reader.readFloat64(); + const numDataPoints = reader.readInt32(); + for (let dataPointIndex = 0; dataPointIndex < numDataPoints; dataPointIndex++) { + const dataPoint = new DataPoint(controller); + dataPoint.read(reader); + this.dataPoints.push(dataPoint); + } + }); + } +} + +/** A single animdata file index and the interval it covers. Used by {@link Animdata}. + * @private */ +class FileOverlap { + /** + * Constructor + */ + constructor() { + /** + * The file index of this animdata file. + * @type {number} + */ + this.fileIndex = 0; + + /** + * The coverage of this animdata file. + * @type {Interval} + */ + this.interval = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(); + } +} + +/** A list of data point locations in the bucket. Used by {@link Animdata}. + * @private */ +class BucketOverlap { + /** + * Constructor + */ + constructor() { + /** + * The animdata file index for this bucket overlap. + * @type {number} + */ + this.fileIndex = 0; + + /** + * Data point indices in this file in this bucket. + * @type {number[]} + */ + this.dataPointIndices = []; + } +} + +/** A list of bucket overlaps in the animinfo file. Used by {@link Animdata}. + * @private */ +class Bucket { + /** + * Constructor + */ + constructor() { + /** + * List of animdata file indices and data point indices for this bucket. + * @type {BucketOverlap[]} + */ + this.bucketOverlaps = []; + } +} + +/** The animinfo file, containing file overlaps and bucket overlaps. Used by {@link Animdata}. + * @private */ +class AniminfoFile { + /** + * Constructor. Starts loading the data. + * @param {AnimdataController} controller - The controller + * @param {number} coverageIndex - The coverage index + * @param {number} animinfoIndex - The animinfo index + */ + constructor(controller, coverageIndex, animinfoIndex) { + /** + * List of files & intervals to which the buckets refer, hashed by fileIndex. + * @type {Map.} + */ + this.fileOverlaps = new Map(); + + /** + * List of buckets in animinfo file. + * @type {Bucket[]} + */ + this.buckets = []; + + const url = controller.getUrl() + '/' + controller.getStateType() + '_info/' + ('00' + coverageIndex).slice(-3) + '.' + ('000' + animinfoIndex).slice(-4) + '.animinfo'; + /** + * The promise that is used to tell when the animinfo is loaded. + * @type {Promise} + */ + this.promise = controller.getEntity().getScene().getEngine().getDownloader().download(url, true).then(async (download) => { + if (download.status === 'cancelled') { + return Promise.resolve(); + } + else if (download.status === 'failed') { + return Promise.reject(new Error('Failed to load animdata controller file "' + download.url + '": ' + download.errorMessage)); + } + if (!(download.content instanceof ArrayBuffer)) { + return Promise.reject(new Error('Failed to load animdata controller file "' + download.url + '": Not a binary file.')); + } + const reader = new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content); + const numFileOverlaps = reader.readInt16(); + for (let fileOverlapIndex = 0; fileOverlapIndex < numFileOverlaps; fileOverlapIndex++) { + const fileOverlap = new FileOverlap(); + fileOverlap.fileIndex = reader.readInt16(); + fileOverlap.interval.min = reader.readFloat64(); + fileOverlap.interval.max = reader.readFloat64(); + this.fileOverlaps.set(fileOverlap.fileIndex, fileOverlap); + } + const numBuckets = reader.readInt16(); + for (let bucketIndex = 0; bucketIndex < numBuckets; bucketIndex++) { + const bucket = new Bucket(); + const numBucketOverlaps = reader.readInt16(); + for (let bucketOverlapIndex = 0; bucketOverlapIndex < numBucketOverlaps; bucketOverlapIndex++) { + const bucketOverlap = new BucketOverlap(); + bucketOverlap.fileIndex = reader.readInt16(); + const numDataPointIndices = reader.readInt16(); + for (let dataPointIndex = 0; dataPointIndex < numDataPointIndices; dataPointIndex++) { + bucketOverlap.dataPointIndices.push(reader.readInt16()); + } + bucket.bucketOverlaps.push(bucketOverlap); + } + this.buckets.push(bucket); + } + }); + } +} + +/** The bookkeeping information for a given coverage defined in the animdef file. Used by {@link Animdata}. + * @private */ +class Coverage { + /** + * Constructor + */ + constructor() { + /** + * The interval that this coverage covers. + * @type {Interval} + */ + this.interval = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(); + + /** + * The number of data files. + * @type {number} + */ + this.numDataFiles = 0; + + /** + * The number of buckets. + * @type {number} + */ + this.numBuckets = 0; + + /** + * The size in seconds of each bucket. + * @type {number} + */ + this.bucketStepSize = 0; + + /** + * The number of buckets contained in each animinfo file. + * @type {number} + */ + this.numBucketsPerAniminfoFile = 0; + + /** + * Currently loaded or downloading animinfo files, keyed by index. + * @type {Map.} + */ + this.animinfos = new Map(); + + /** + * Currently loaded or downloading animdata files, keyed by index. + * @type {Map.} + */ + this.animdatas = new Map(); + } +} + +/** The animdef file, containing all of the coverages. Used by {@link Animdata}. + * @private */ +class AnimdefFile { + /** + * Constructor. Starts loading the data. + * @param {AnimdataController} controller - The controller + */ + constructor(controller) { + /** + * List of coverages defined in animdef file. + * @type {Coverage[]} + */ + this.coverages = []; + + const url = controller.getUrl() + '/' + controller.getStateType() + '.animdef'; + /** + * The promise that is used to tell when the animdef is loaded. + * @type {Promise} + */ + this.promise = controller.getEntity().getScene().getEngine().getDownloader().download(url, true).then(async (download) => { + if (download.status === 'cancelled') { + return Promise.resolve(); + } + else if (download.status === 'failed') { + return Promise.reject(new Error('Failed to load animdata controller file "' + download.url + '": ' + download.errorMessage)); + } + if (!(download.content instanceof ArrayBuffer)) { + return Promise.reject(new Error('Failed to load animdata controller file "' + download.url + '": Not a binary file.')); + } + const reader = new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content); + const numCoverages = reader.readInt16(); + for (let coverageIndex = 0; coverageIndex < numCoverages; coverageIndex++) { + const coverage = new Coverage(); + coverage.interval.min = reader.readFloat64(); + coverage.interval.max = reader.readFloat64(); + coverage.numDataFiles = reader.readInt16(); + coverage.numBuckets = reader.readInt32(); + coverage.bucketStepSize = reader.readFloat64(); + coverage.numBucketsPerAniminfoFile = reader.readInt16(); + this.coverages.push(coverage); + } + controller.__updateCoverage(); + }); + } +} + +/** The animdata controller. Downloads animdata files to control the position and orientation of entities. */ +class AnimdataController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The base url used to construct the other urls for the animdef, animinfo, and animdata files. + * @type {string} + * @private + */ + this._baseUrl = ''; + + /** + * The state, currently either 'pos' or 'ori'. + * @type {string} + * @private + */ + this._stateType = ''; + + /** + * The animdef file that contains all the other data. + * @type {AnimdefFile} + * @private + */ + this._animdef = null; + + /** + * The current data point used for updates. + * @type {DataPoint} + * @private + */ + this._currentDataPoint = null; + + /** + * Temporary data point used in calculations. + * @type {DataPoint} + * @private + */ + this._tempDataPoint = null; + + /** + * A shortcut for to get to the download method. + * @type {Engine} + * @private + */ + this._engine = this.getEntity().getScene().getEngine(); + + /** + * The coverage set by setCoverage. + * @type {Interval} + * @private + */ + this._forcedCoverage = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(); + this._forcedCoverage.copy(this.getCoverage()); + } + + /** + * Returns the base url used to download the animdata. + * @returns {string} + */ + getUrl() { + return this._baseUrl; + } + + /** + * Returns the state type (pos or ori) + * @returns {string} + */ + getStateType() { + return this._stateType; + } + + /** + * Sets the base url used to download the animdata. + * @param {string} baseUrl + * @param {string} stateType + */ + setBaseUrlAndStateType(baseUrl, stateType) { + this._baseUrl = baseUrl; + this._stateType = stateType; + this._currentDataPoint = new DataPoint(this); + this._tempDataPoint = new DataPoint(this); + this._animdef = new AnimdefFile(this); + + // Let the base controller know that this changes the position or orientation. + if (this._stateType === 'pos') { + this.addModifiedState('position'); + this.addModifiedState('velocity'); + } + else if (this._stateType === 'ori') { + this.addModifiedState('orientation'); + } + } + + /** + * Sets the time interval over which the controller is valid. + * @param {Interval} coverage + * @override + */ + setCoverage(coverage) { + this._forcedCoverage.copy(coverage); + this.__updateCoverage(); + } + + /** + * Since animdata has a possibly narrower coverage than the base controller (forced) coverage, this updates the base controller coverage to reflect that. + * @internal + */ + __updateCoverage() { + const realCoverage = _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get(); + if (this._animdef !== null && this._animdef.coverages.length > 0) { + realCoverage.copy(this._animdef.coverages[0].interval); + for (let i = 1; i < this._animdef.coverages.length; i++) { + realCoverage.union(realCoverage, this._animdef.coverages[i].interval); + } + realCoverage.intersection(realCoverage, this._forcedCoverage); + } + else { + realCoverage.copy(this._forcedCoverage); + realCoverage.max = realCoverage.min; + } + super.setCoverage(realCoverage); + _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(realCoverage); + } + + /** + * If the animdata is pos, updates the position. + * @param {Vector3} position + * @param {number} time + * @override + * @internal + */ + __updatePositionAtTime(position, time) { + if (this._stateType === 'pos') { + const state = /** @type {PosState} */(this._tempDataPoint.state); + if (this._tempDataPoint.interval.min !== time) { + if (this._getDataPointAtTime(this._tempDataPoint, time)) { + position.copy(state.position); + } + } + else { + position.copy(state.position); + } + } + } + + /** + * If the animdata is pos, updates the velocity. + * @param {Vector3} velocity + * @param {number} time + * @override + * @internal + */ + __updateVelocityAtTime(velocity, time) { + if (this._stateType === 'pos') { + const state = /** @type {PosState} */(this._tempDataPoint.state); + if (this._tempDataPoint.interval.min !== time) { + if (this._getDataPointAtTime(this._tempDataPoint, time)) { + velocity.copy(state.velocity); + } + } + else { + velocity.copy(state.velocity); + } + } + } + + /** + * If the animdata is ori, updates the orientation. + * @param {Quaternion} orientation + * @param {number} time + * @override + * @internal + */ + __updateOrientationAtTime(orientation, time) { + if (this._stateType === 'ori') { + const state = /** @type {OriState} */(this._tempDataPoint.state); + if (this._getDataPointAtTime(this._tempDataPoint, time)) { + orientation.copy(state.orientation); + } + } + } + + /** + * Returns a new promise that resolves when the controller is loaded. + * @returns {Promise} + * @override + */ + getLoadedPromise() { + return this.downloadDataForInterval(new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(this._engine.getTime(), this._engine.getTime())); + } + + /** + * This does whatever is necessary to download the data for the given interval. Returns a promise that will resolve when all the data is loaded. + * @param {Interval} interval - The interval over which to download the data. + * @returns {Promise} + */ + downloadDataForInterval(interval) { + if (this._animdef === null) { + return null; + } + return this._animdef.promise.then(async () => { + const animinfoPromises = []; + + // For each coverage... + for (let coverageIndex = 0; coverageIndex < this._animdef.coverages.length; coverageIndex++) { + const coverage = this._animdef.coverages[coverageIndex]; + + // If the interval is within the coverage, + if (coverage.interval.intersects(interval)) { + // Calculate the set of animinfos that would cover the interval. + const animinfoIndexStart = Math.floor((Math.max(interval.min, coverage.interval.min) - coverage.interval.min) / coverage.bucketStepSize / coverage.numBucketsPerAniminfoFile); + const animinfoIndexEnd = Math.floor((Math.min(interval.max, coverage.interval.max) - 0.0001 - coverage.interval.min) / coverage.bucketStepSize / coverage.numBucketsPerAniminfoFile); + + // For each animinfo in that set... + for (let animinfoIndex = animinfoIndexStart; animinfoIndex <= animinfoIndexEnd; animinfoIndex++) { + // If that animinfo hasn't been loaded yet, + if (!coverage.animinfos.has(animinfoIndex)) { + coverage.animinfos.set(animinfoIndex, new AniminfoFile(this, coverageIndex, animinfoIndex)); + } + + const animinfo = coverage.animinfos.get(animinfoIndex); + animinfoPromises.push(animinfo.promise.then(() => { + const animdataPromises = []; + + // For each file overlap in the animinfo... + for (const fileOverlap of animinfo.fileOverlaps.values()) { + // If the interval overlaps with the file overlap, + if (fileOverlap.interval.intersects(interval)) { + const animdataIndex = fileOverlap.fileIndex; + + // If that animdata hasn't been downloaded yet, + if (!coverage.animdatas.has(animdataIndex)) { + coverage.animdatas.set(animdataIndex, new AnimdataFile(this, coverageIndex, animdataIndex)); + } + + const animdata = coverage.animdatas.get(animdataIndex); + animdataPromises.push(animdata.promise); + } + } + return Promise.all(animdataPromises).then(); + })); + } + return Promise.all(animinfoPromises).then(); + } + } + }); + } + + /** + * Returns a new state of the controller type. + * @returns {State} + * @internal */ + __getNewState() { + if (this._stateType === 'pos') { + return new PosState(); + } + else if (this._stateType === 'ori') { + return new OriState(); + } + else { + return null; + } + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + if (this._currentDataPoint !== null) { + if (this._getDataPointAtTime(this._currentDataPoint, this._engine.getTime())) { + if (this._stateType === 'pos') { + const state = /** @type {PosState} */(this._currentDataPoint.state); + this.getEntity().setPosition(state.position); + this.getEntity().setVelocity(state.velocity); + } + if (this._stateType === 'ori') { + const state = /** @type {OriState} */(this._currentDataPoint.state); + this.getEntity().setOrientation(state.orientation); + } + } + } + } + + /** + * Sets outDataPoint to the state associated with the time and returns true. If it doesn't exist, it starts the download process for that time and returns false. + * @param {DataPoint} outDataPoint - the state to be set + * @param {number} time - the time to check + * @returns {boolean} + * @private + */ + _getDataPointAtTime(outDataPoint, time) { + // For every coverage in the animdef, + for (let coverageIndex = 0; coverageIndex < this._animdef.coverages.length; coverageIndex++) { + const coverage = this._animdef.coverages[coverageIndex]; + + // If the time is within the coverage, + if (coverage.interval.contains(time)) { + // Calculate the animinfo that would cover the time. + const animinfoIndex = Math.floor((time - coverage.interval.min) / coverage.bucketStepSize / coverage.numBucketsPerAniminfoFile); + + // If that animinfo has been downloaded, else download it. + if (coverage.animinfos.has(animinfoIndex)) { + const animinfo = coverage.animinfos.get(animinfoIndex); + + // Calculate the bucket of the animinfo that would cover the time. + const bucketIndexInAniminfoFile = Math.floor((time - coverage.interval.min) / coverage.bucketStepSize) - animinfoIndex * coverage.numBucketsPerAniminfoFile; + const bucket = animinfo.buckets[bucketIndexInAniminfoFile]; + + if (bucket === undefined) { + return false; + } + + // For each bucket overlap in the bucket (should be a very small number)... + for (let bucketOverlapIndex = 0; bucketOverlapIndex < bucket.bucketOverlaps.length; bucketOverlapIndex++) { + const bucketOverlap = bucket.bucketOverlaps[bucketOverlapIndex]; + const animdataIndex = bucketOverlap.fileIndex; + + // If the animdata covers the time, + if (animinfo.fileOverlaps.get(animdataIndex).interval.contains(time)) { + // If the animdata has been downloaded, else download it. + if (coverage.animdatas.has(animdataIndex)) { + const animdata = coverage.animdatas.get(animdataIndex); + + // For each data point index in the bucket overlap... + for (let dataPointIndexIndex = 0; dataPointIndexIndex < bucketOverlap.dataPointIndices.length; dataPointIndexIndex++) { + const dataPointIndex = bucketOverlap.dataPointIndices[dataPointIndexIndex]; + const dataPoint = animdata.dataPoints[dataPointIndex]; + + if (dataPoint === undefined) { + return false; + } + + // If the data point covers the time, return the data point. + if (dataPoint.interval.contains(time)) { + const u = (time - dataPoint.interval.min) / dataPoint.interval.length(); + outDataPoint.interval.min = time; + outDataPoint.interval.max = time; + outDataPoint.state.interpolate(dataPoint.state, animdata.dataPoints[dataPointIndex + 1].state, dataPoint.interval.length(), u); + return true; + } + } + return false; + } + else { + coverage.animdatas.set(animdataIndex, new AnimdataFile(this, coverageIndex, animdataIndex)); + return false; + } + } + } + return false; + } + else { + coverage.animinfos.set(animinfoIndex, new AniminfoFile(this, coverageIndex, animinfoIndex)); + return false; + } + } + } + return false; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/base_controller.js": +/*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/base_controller.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "BaseController": function() { return /* binding */ BaseController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The base class for all controllers. + */ +class BaseController extends _internal__WEBPACK_IMPORTED_MODULE_0__.EntityItem { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The interval over which the controller is valid. + * @type {Interval} + * @private + */ + this._coverage = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); + this._coverage.freeze(); + + /** + * The modified states. + * @type {Set} + * @private + */ + this._modifiedStates = new Set(); + + /** + * The dependent states. In the format of '.'. + * @type {Set} + * @private + */ + this._dependentStates = new Set(); + + // Add this to the controller dependency graph. + this.getEntity().getScene().getControllerDependencyGraph().addItem(this); + } + + /** + * Destroys the controller resources. + * @override + * @internal + */ + __destroy() { + this.getEntity().getScene().getControllerDependencyGraph().removeItem(this); + super.__destroy(); + } + + // STATES AND DEPENDENCIES + + /** + * Adds a modified state to the controller. + * @param {string} modifiedState + * @protected + */ + addModifiedState(modifiedState) { + if (!this._modifiedStates.has(modifiedState)) { + this._modifiedStates.add(modifiedState); + this.getEntity().getScene().getControllerDependencyGraph().needsSorting(); + if (modifiedState === 'position' || modifiedState === 'orientation') { + this.getEntity().__updateCoverage(); + } + } + } + + /** + * Removes a modified state. + * @param {string} modifiedState + * @protected + */ + removeModifiedState(modifiedState) { + if (this._modifiedStates.delete(modifiedState)) { + this.getEntity().getScene().getControllerDependencyGraph().needsSorting(); + if (modifiedState === 'position' || modifiedState === 'orientation') { + this.getEntity().__updateCoverage(); + } + } + } + + /** + * Returns true if this has the modified state. + * @param {string} modifiedState + * @returns {boolean} + */ + hasModifiedState(modifiedState) { + return this._modifiedStates.has(modifiedState); + } + + /** + * Adds a dependent state. + * @param {string} entityName + * @param {string} dependentState + * @protected + */ + addDependentState(entityName, dependentState) { + if (!this._dependentStates.has(entityName + '.' + dependentState)) { + this._dependentStates.add(entityName + '.' + dependentState); + this.getEntity().getScene().getControllerDependencyGraph().needsSorting(); + } + } + + /** + * Removes a dependent state. + * @param {string} entityName + * @param {string} dependentState + * @protected + */ + removeDependentState(entityName, dependentState) { + if (this._dependentStates.delete(entityName + '.' + dependentState)) { + this.getEntity().getScene().getControllerDependencyGraph().needsSorting(); + } + } + + /** + * Returns true if this has the dependent state. + * @param {string} entityName + * @param {string} dependentState + * @returns {boolean} + */ + hasDependentState(entityName, dependentState) { + return this._dependentStates.has(entityName + '.' + dependentState); + } + + /** + * Gets an iterator to the modified states. + * @returns {Set} + * @internal + */ + get __modifiedStates() { + return this._modifiedStates; + } + + /** + * Gets the time interval over which the controller is valid. + * @returns {Interval} + */ + getCoverage() { + return this._coverage; + } + + /** + * Sets the time interval over which the controller is valid. + * @param {Interval} coverage + */ + setCoverage(coverage) { + this._coverage.thaw(); + this._coverage.copy(coverage); + this._coverage.freeze(); + this.getEntity().__updateCoverage(); + } + + /** + * Updates the given position for the given time. + * @param {Vector3} _position - The position to update. + * @param {number} _time - The time to check + */ + __updatePositionAtTime(_position, _time) { } + + /** + * Updates the given velocity for the given time. + * @param {Vector3} _velocity - The velocity to update. + * @param {number} _time - The time to check + */ + __updateVelocityAtTime(_velocity, _time) { } + + /** + * Updates given orientation for the given time. + * @param {Quaternion} _orientation - The orientation to update. + * @param {number} _time - The time to check. + */ + __updateOrientationAtTime(_orientation, _time) { } + + /** + * Converts the entity item to a nice string. + * @returns {string} + * @override + */ + toString() { + let typeIndex = 0; + // Search the controllers for the type. + for (let i = 0, l = this.getEntity().getNumControllers(); i < l; i++) { + const controller = this.getEntity().getController(i); + if (this === controller) { + break; + } + if (this.getType() === controller.getType()) { + typeIndex += 1; + } + } + return this.getEntity().getName() + '.' + this.getType() + '.' + typeIndex; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/coverage_controller.js": +/*!**********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/coverage_controller.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CoverageController": function() { return /* binding */ CoverageController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A controller that calls enter and functions based on a coverage. + */ +class CoverageController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The time interval over which the coverage is active. + * @type {Interval} + * @private + */ + this.coverage = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(); + + /** + * The function called when the time enters the coverage. + * @type {((entity: Entity) => any) | undefined} + * @private + */ + this.enterFunction = undefined; + + /** + * The function called when the time exits the coverage. + * @type {((entity: Entity) => any) | undefined} + * @private + */ + this.exitFunction = undefined; + + /** + * The function called when the time is inside the coverage, every frame. + * @type {((entity: Entity) => any) | undefined} + * @private + */ + this.updateFunction = undefined; + + /** + * Flag determining if the coverage is active or not. + * @type {boolean} + * @private + */ + this.active = false; + + /** + * The last real time the update function ran. + * @type {number} + * @private + */ + this.lastUpdateTime = Number.NEGATIVE_INFINITY; + + /** + * How often to run the update function, in milliseconds. 0 means run every frame. + * @type {number} + * @private + */ + this.updateInterval = 0; + } + + /** + * Sets the coverage. + * @param {Interval} coverage + * @override + */ + setCoverage(coverage) { + this.coverage.copy(coverage); + } + + /** + * Sets the enter function. This function will be triggered once when the time enters the coverage. + * @param {((entity: Entity) => any) | undefined} enterFunction + */ + setEnterFunction(enterFunction) { + this.enterFunction = enterFunction; + } + + /** + * Sets the exit function. This function will be triggered once when the time exits the coverage. + * @param {((entity: Entity) => any) | undefined} exitFunction + */ + setExitFunction(exitFunction) { + this.exitFunction = exitFunction; + } + + /** + * Sets the update function. This function will be triggered every frame that the time is within the coverage. + * @param {((entity: Entity) => any) | undefined} updateFunction + */ + setUpdateFunction(updateFunction) { + this.updateFunction = updateFunction; + } + + /** + * Sets how often to run the update function, in seconds. The default 0 means run every frame. + * @param {number} updateInterval + */ + setUpdateInterval(updateInterval) { + this.updateInterval = updateInterval * 1000; + } + + /** + * Updates the position and orientation if they are fixed. + * @override + * @internal + */ + __update() { + const time = this.getEntity().getScene().getEngine().getTime(); + + // If this is the first coverage controller, we'll trigger all of the exit functions() necessary. + if (this.getTypeIndex() === 0) { + for (let i = 0; ; i++) { + const coverageController = this.getEntity().getControllerByClass(CoverageController, i); + if (coverageController === null) { + break; + } + const newActive = coverageController.coverage.contains(time); + if (coverageController.active && !newActive) { + if (coverageController.exitFunction) { + coverageController.exitFunction(this.getEntity()); + } + } + } + } + + // Now call the enter function. + const newActive = this.coverage.contains(time); + if (!this.active && newActive) { + if (this.enterFunction) { + this.enterFunction(this.getEntity()); + } + } + + // Call the update function. + if (newActive && this.updateFunction) { + const now = Date.now(); + if (now - this.lastUpdateTime >= this.updateInterval) { + this.lastUpdateTime = now; + this.updateFunction(this.getEntity()); + } + } + this.active = newActive; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/dynamo_controller.js": +/*!********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/dynamo_controller.js ***! + \********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "DynamoController": function() { return /* binding */ DynamoController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +class Point { + /** + * Load the point from the reader. + * @param {Reader} reader + */ + load(reader) { + /** + * @type {number} + */ + this.time = reader.readFloat64(); + } + + /** + * Sets this to the calculated point in between two points. + * @param {[Point, Point]} _points + * @param {number} _time + * @param {Object} _header + * @param {boolean} _incremental + * @abstract + */ + calculate(_points, _time, _header, _incremental) { } + + /** + * Apply the point to the entity. + * @param {Entity} _entity + * @abstract + */ + apply(_entity) { } + + /** + * Sets the entity's point to NaN to clear out any data. + * @param {Entity} _entity + * @abstract + */ + setNaN(_entity) { } + + /** + * Reads the header information for this type from the reader. + * @param {Reader} _reader + * @returns {Object} + */ + static readHeader(_reader) { + return {}; + } +} + +class PosPoint extends Point { + constructor() { + super(); + this.position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this.velocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + } + + /** + * Load the point from the reader. + * @param {Reader} reader + * @override + */ + load(reader) { + super.load(reader); + + this.position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(reader.readFloat64(), reader.readFloat64(), reader.readFloat64()); + this.velocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(reader.readFloat64(), reader.readFloat64(), reader.readFloat64()); + } + + /** + * Sets this to the calculated point in between two points. + * @param {[PosPoint, PosPoint]} points + * @param {number} time + * @param {Object} _header + * @param {boolean} _incremental + * @override + */ + calculate(points, time, _header, _incremental) { + this.time = time; + const totalT = points[1].time - points[0].time; + const u = (time - points[0].time) / totalT; + const oneSubU = 1.0 - u; + const oneSubUSq = oneSubU * oneSubU; + const uSq = u * u; + const a = (1.0 + 2.0 * u) * oneSubUSq; + const b = u * oneSubUSq; + const c = uSq * (3.0 - 2.0 * u); + const d = uSq * -oneSubU; + this.position.mult(points[0].position, a); + this.position.addMult(this.position, points[0].velocity, totalT * b); + this.position.addMult(this.position, points[1].position, c); + this.position.addMult(this.position, points[1].velocity, totalT * d); + const sixUSqSubU = 6.0 * (uSq - u); + const aV = sixUSqSubU; + const bV = 3.0 * uSq - 4.0 * u + 1.0; + const cV = -sixUSqSubU; + const dV = 3.0 * uSq - 2.0 * u; + this.velocity.mult(points[0].position, aV / totalT); + this.velocity.addMult(this.velocity, points[0].velocity, bV); + this.velocity.addMult(this.velocity, points[1].position, cV / totalT); + this.velocity.addMult(this.velocity, points[1].velocity, dV); + } + + /** + * Apply the point to the entity. + * @param {Entity} entity + * @override + */ + apply(entity) { + entity.setPosition(this.position); + entity.setVelocity(this.velocity); + } + + /** + * Sets the entity's point to NaN to clear out any data. + * @param {Entity} entity + * @override + */ + setNaN(entity) { + entity.setPosition(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + entity.setVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + + /** + * Reads the header information for this type from the reader. + * @param {Reader} _reader + * @returns {Object} + * @override + */ + static readHeader(_reader) { + return {}; + } +} + +class LinPoint extends Point { + constructor() { + super(); + this.position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this.velocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + } + + /** + * Load the point from the reader. + * @param {Reader} reader + * @override + */ + load(reader) { + super.load(reader); + this.position.set(reader.readFloat64(), reader.readFloat64(), reader.readFloat64()); + this.velocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero); + } + + /** + * Sets this to the calculated point in between two points. + * @param {[LinPoint, LinPoint]} points + * @param {number} time + * @param {Object} _header + * @param {boolean} _incremental + * @override + */ + calculate(points, time, _header, _incremental) { + this.time = time; + if (points[1].time > points[0].time) { + const u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time - points[0].time) / (points[1].time - points[0].time)); + this.position.lerp(points[0].position, points[1].position, u); + this.velocity.sub(points[1].position, points[0].position); + this.velocity.div(this.velocity, points[1].time - points[0].time); + } + else { + this.position.copy(points[1].position); + this.velocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero); + } + } + + /** + * Apply the point to the entity. + * @param {Entity} entity + * @override + */ + apply(entity) { + entity.setPosition(this.position); + entity.setVelocity(this.velocity); + } + + /** + * Sets the entity's point to NaN to clear out any data. + * @param {Entity} entity + * @override + */ + setNaN(entity) { + entity.setPosition(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + entity.setVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + + /** + * Reads the header information for this type from the reader. + * @param {Reader} _reader + * @returns {Object} + * @override + */ + static readHeader(_reader) { + return {}; + } +} + +class OriPoint extends Point { + constructor() { + super(); + this.orientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + this.angularVelocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + } + + /** + * Load the point from the reader. + * @param {Reader} reader + * @override + */ + load(reader) { + super.load(reader); + + this.orientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(reader.readFloat64(), reader.readFloat64(), reader.readFloat64(), reader.readFloat64()); + this.angularVelocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(reader.readFloat64(), reader.readFloat64(), reader.readFloat64()); + } + + /** + * Sets this to the calculated point in between two points. + * @param {[OriPoint, OriPoint]} points + * @param {number} time + * @param {Object} _header + * @param {boolean} incremental + * @override + */ + calculate(points, time, _header, incremental) { + this.time = time; + const orientation0 = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const orientation1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const u = (time - points[0].time) / (points[1].time - points[0].time); + points[0]._project(orientation0, time, incremental); + points[1]._project(orientation1, time, incremental); + this.orientation.slerp(orientation0, orientation1, u); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation0); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation1); + this.angularVelocity.slerp(points[0].angularVelocity, points[1].angularVelocity, u); + this.angularVelocity.neg(this.angularVelocity); + this.angularVelocity.rotate(this.orientation, this.angularVelocity); + } + + /** + * Apply the point to the entity. + * @param {Entity} entity + * @override + */ + apply(entity) { + entity.setOrientation(this.orientation); + entity.setAngularVelocity(this.angularVelocity); + } + + /** + * Apply the point, projected in time, to the orientation, if it applies. + * @param {Quaternion} orientation + * @param {number} time + * @param {boolean} incremental + */ + _project(orientation, time, incremental) { + const rotationAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const rotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + rotationAxis.normalize(this.angularVelocity); + rotation.setFromAxisAngle(rotationAxis, this.angularVelocity.magnitude() * (time - this.time)); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(rotationAxis); + if (incremental) { + rotation.multInverseR(this.orientation, rotation); + orientation.mult(orientation, rotation); + } + else { + orientation.multInverseR(this.orientation, rotation); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation); + } + + /** + * Sets the entity's point to NaN to clear out any data. + * @param {Entity} entity + * @override + */ + setNaN(entity) { + entity.setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]); + entity.setAngularVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + + /** + * Reads the header information for this type from the reader. + * @param {Reader} _reader + * @returns {Object} + * @override + */ + static readHeader(_reader) { + return {}; + } +} + +class QuatPoint extends Point { + constructor() { + super(); + this.orientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + this.angularVelocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + } + + /** + * Load the point from the reader. + * @param {Reader} reader + * @override + */ + load(reader) { + super.load(reader); + + this.orientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(reader.readFloat64(), reader.readFloat64(), reader.readFloat64(), reader.readFloat64()); + } + + /** + * Sets this to the calculated point in between two points. + * @param {[QuatPoint, QuatPoint]} points + * @param {number} time + * @param {Object} _header + * @param {boolean} _incremental + * @override + */ + calculate(points, time, _header, _incremental) { + this.time = time; + const u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time - points[0].time) / (points[1].time - points[0].time)); + this.orientation.slerp(points[0].orientation, points[1].orientation, u); + } + + /** + * Apply the point to the entity. + * @param {Entity} entity + * @override + */ + apply(entity) { + entity.setOrientation(this.orientation); + entity.setAngularVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero); + } + + /** + * Sets the entity's point to NaN to clear out any data. + * @param {Entity} entity + * @override + */ + setNaN(entity) { + entity.setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]); + entity.setAngularVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + + /** + * Reads the header information for this type from the reader. + * @param {Reader} _reader + * @returns {Object} + * @override + */ + static readHeader(_reader) { + return {}; + } +} + +class OrbPoint extends Point { + constructor() { + super(); + this.oe = new _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements(); + this.oe.orbitOrientation.freeze(); + + this.position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this.velocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + } + + /** + * Load the point from the reader. + * @param {Reader} reader + * @override + */ + load(reader) { + super.load(reader); + this.oe.epoch = this.time; + + this.oe.semiMajorAxis = reader.readFloat64(); + this.oe.eccentricity = reader.readFloat64(); + this.oe.meanAngularMotion = reader.readFloat64(); + this.oe.meanAnomalyAtEpoch = reader.readFloat64(); + this.oe.orbitOrientation.thaw(); + this.oe.orbitOrientation.set(reader.readFloat64(), reader.readFloat64(), reader.readFloat64(), reader.readFloat64()); + this.oe.orbitOrientation.freeze(); + } + + /** + * Sets this to the calculated point in between two points. + * @param {[OrbPoint, OrbPoint]} points + * @param {number} time + * @param {Object} header + * @param {boolean} incremental + * @override + */ + calculate(points, time, header, incremental) { + this.time = time; + this.oe.epoch = time; + const position0 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const position1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const velocity0 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const velocity1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time - points[0].time) / (points[1].time - points[0].time)); + points[0]._project(position0, velocity0, time, header, incremental); + points[1]._project(position1, velocity1, time, header, incremental); + this.position.lerp(position0, position1, u); + this.velocity.lerp(velocity0, velocity1, u); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position0); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position1); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(velocity0); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(velocity1); + } + + /** + * Apply the point to the entity. + * @param {Entity} entity + * @override + */ + apply(entity) { + entity.setPosition(this.position); + entity.setVelocity(this.velocity); + } + + /** + * Apply the point, projected in time, to the position, if it applies. + * @param {Vector3} position + * @param {Vector3} velocity + * @param {number} time + * @param {Object} header + * @param {boolean} incremental + */ + _project(position, velocity, time, header, incremental) { + const newPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const newVelocity = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + + // Project the position and velocity. + this.oe.project(newPosition, newVelocity, time); + + // Get and multiply by the body factor so that the orbit works relative to the other object and not the focus. + let bodyFactor = 1; + if (header['body'] === 1) { + bodyFactor = header['gravitationalParameter2'] / (header['gravitationalParameter1'] + header['gravitationalParameter2']); + } + else if (header['body'] === 2) { + bodyFactor = -header['gravitationalParameter1'] / (header['gravitationalParameter1'] + header['gravitationalParameter2']); + } + newPosition.mult(newPosition, bodyFactor); + newVelocity.mult(newVelocity, bodyFactor); + + // Rotate the vectors by the orbit orientation. + if (incremental) { + position.add(newPosition, position); + } + else { + position.copy(newPosition); + } + velocity.copy(newVelocity); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newVelocity); + } + + /** + * Sets the entity's point to NaN to clear out any data. + * @param {Entity} entity + * @override + */ + setNaN(entity) { + entity.setPosition(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + entity.setVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + + /** + * Reads the header information for this type from the reader. + * @param {Reader} reader + * @returns {Object} + * @override + */ + static readHeader(reader) { + return { + gravitationalParameter1: reader.readFloat64(), + gravitationalParameter2: reader.readFloat64() + }; + } +} + +class PointSet { + /** + * @param {typeof Point} PointClass + * @param {number} version + * @param {number} numberOfDigits + * @param {string} name + */ + constructor(PointClass, version, numberOfDigits, name) { + /** + * The type of data. + * @type {typeof Point} + */ + this._PointClass = PointClass; + + /** + * The version of the dynamo type. + * @type {number} + * @private + */ + this._version = version; + + /** + * The number of digits for every index file's level. + * @type {number} + * @private + */ + this._numberOfDigits = numberOfDigits; + + /** + * The name to be used when loading the point set. + * @type {string} + */ + this._name = name; + + /** + * The array of points sets. + * @type {PointSet[]} + */ + this._pointSets = []; + + /** + * The array of points. + * @type {Point[]} + */ + this._points = []; + + /** + * The hint index used for getting the point or point set index. + * @type {number} + * @private + */ + this._hintIndex = 0; + + /** + * The interval which covers the points. + * @type {Interval} + */ + this._interval = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY); + + /** + * State that determines whether the point set data is not loaded, loading, or loaded. + * @type {number} + */ + this._loadedState = PointSet.State.NOT_LOADED; + + /** + * The timestamp when this point set was loaded. + * @type {number} + */ + this._accessedTime = Number.POSITIVE_INFINITY; + } + + /** + * Returns the name of the point set, used in downloading the file. + * @returns {string} + */ + getName() { + return this._name; + } + + /** + * Returns the loaded state of the point set. + * @returns {number} + */ + getLoadedState() { + return this._loadedState; + } + + /** + * Returns the loaded state of the point set. + * @returns {number} + */ + getLoadedTime() { + return this._accessedTime; + } + + /** + * Returns true if the point set has point sets. + * @returns {boolean} + */ + hasPointSets() { + return this._pointSets.length !== 0; + } + + /** + * Returns true if the point set has points. + * @returns {boolean} + */ + hasPoints() { + return this._points.length !== 0; + } + + /** + * Loads the data from a reader. + * @param {Reader} reader + */ + load(reader) { + // Point set if it is in the definition file. + let containsPoints = true; + if (this._version === 2 || (this._version === 1 && this._name === 'def')) { + containsPoints = (reader.readByte() === 1); + } + + if (containsPoints) { + // Read the data points. + const numPoints = reader.readInt32(); + for (let i = 0; i < numPoints; i++) { + const point = new this._PointClass(); + point.load(reader); + this._points.push(point); + } + // Adjust the interval to match the data points. + if (this._points.length > 0) { + this._interval.min = this._points[0].time; + this._interval.max = this._points[this._points.length - 1].time; + } + } + else { + // Read the data sets. + const numPointSets = reader.readInt32(); + if (this._version === 1) { + this._numberOfDigits = Math.ceil(Math.log10(numPointSets)); + } + for (let i = 0; i < numPointSets; i++) { + let newName = ''; + if (this._name === 'def') { + newName = (i + '').padStart(this._numberOfDigits, '0'); + } + else { + newName = this._name + '_' + (i + '').padStart(this._numberOfDigits, '0'); + } + const pointSet = new PointSet(this._PointClass, this._version, this._numberOfDigits, newName); + pointSet._interval.min = reader.readFloat64(); + if (this._version === 1) { + pointSet._interval.max = reader.readFloat64(); + } + else { + if (i > 0) { + this._pointSets[i - 1]._interval.max = pointSet._interval.min; + } + } + this._pointSets.push(pointSet); + } + if (this._version === 2) { + this._pointSets.splice(this._pointSets.length - 1, 1); + } + // Adjust the interval to match the data points. + if (this._pointSets.length > 0) { + this._interval.min = this._pointSets[0]._interval.min; + this._interval.max = this._pointSets[this._pointSets.length - 1]._interval.max; + } + } + + // Set the loaded flag to true and set the time loaded. + this._loadedState = PointSet.State.LOADED; + this._accessedTime = Date.now(); + } + + /** + * Loads the point set from a url. + * @param {Downloader} downloader + * @param {string} baseUrl + */ + loadFromUrl(downloader, baseUrl) { + this._loadedState = PointSet.State.LOADING; + downloader.download(baseUrl + '/' + this._name + '.dyn', true).then(async (download) => { + if (download.status === 'cancelled') { + return Promise.resolve(); + } + else if (download.status === 'failed') { + return Promise.reject(new Error('Failed to load dynamo controller file "' + download.url + '": ' + download.errorMessage)); + } + if (!(download.content instanceof ArrayBuffer)) { + return Promise.reject(new Error('Failed to load dynamo controller file "' + download.url + '": Not a binary file.')); + } + const reader = new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content); + this.load(reader); + }); + } + + /** + * Unloads one point set that hasn't been accessed recently. Returns true if a point set was unloaded. + * @returns {boolean} + */ + unloadOldPointSet() { + // Remove the oldest point set. + for (let i = 0, l = this._pointSets.length; i < l; i++) { + const pointSet = this._pointSets[i]; + if (pointSet._loadedState === PointSet.State.LOADED) { + if (Date.now() - pointSet._accessedTime > 15000) { // If this point set hasn't been accessed in 15 seconds, expire it. + pointSet.unload(); + return true; + } + else { + if (pointSet.unloadOldPointSet()) { + return true; + } + } + } + } + return false; + } + + /** + * Unloads the data. + */ + unload() { + this._loadedState = PointSet.State.NOT_LOADED; + this._accessedTime = Number.POSITIVE_INFINITY; + this._pointSets = []; + this._points = []; + } + + /** + * Gets the point set index for the given time, using a starting index as a hint to make things faster. + * @param {number} time + * @returns {PointSet} + */ + getPointSet(time) { + this._accessedTime = Date.now(); + if (this._pointSets.length === 0) { + return null; + } + // Use hint index to see if we can quickly find the right point set. + if (this._pointSets[this._hintIndex]._interval.contains(time)) { + // do nothing + } + else if (this._hintIndex - 1 >= 0 && this._pointSets[this._hintIndex - 1]._interval.contains(time)) { + this._hintIndex -= 1; + } + else if (this._hintIndex + 1 < this._pointSets.length && this._pointSets[this._hintIndex + 1]._interval.contains(time)) { + this._hintIndex += 1; + } + // Do a binary search to find the right point set index. + else { + let min = 0; + let max = this._pointSets.length - 1; + let index = 0; + while (min !== max) { + index = Math.ceil((min + max) / 2); + if (time < this._pointSets[index]._interval.min) { + max = index - 1; + } + else { + min = index; + } + } + this._hintIndex = min; + } + return this._pointSets[this._hintIndex]; + } + + /** + * Gets the point index for the given time, using a starting index as a hint to make things faster. + * @param {[Point | null, Point | null]} points + * @param {number} time + */ + getPoints(points, time) { + this._accessedTime = Date.now(); + if (this._points.length === 0) { + points[0] = null; + points[1] = null; + return; + } + // Use hint index to see if we can quickly find the right point. + if (this._hintIndex + 1 < this._points.length && this._points[this._hintIndex].time <= time && time < this._points[this._hintIndex + 1].time) { + // do nothing + } + else if (this._hintIndex - 1 >= 0 && this._points[this._hintIndex - 1].time <= time && time < this._points[this._hintIndex].time) { + this._hintIndex -= 1; + } + else if (this._hintIndex + 2 < this._points.length && this._points[this._hintIndex + 1].time <= time && time < this._points[this._hintIndex + 2].time) { + this._hintIndex += 1; + } + // Do a binary search to find the right point index. + else { + let min = 0; + let max = this._points.length - 2; + let index = 0; + while (min !== max) { + index = Math.ceil((min + max) / 2); + if (time < this._points[index].time) { + max = index - 1; + } + else { + min = index; + } + } + this._hintIndex = min; + } + points[0] = this._points[this._hintIndex]; + points[1] = this._points[this._hintIndex + 1]; + } +} + +PointSet.State = { + NOT_LOADED: 0, + LOADING: 1, + LOADED: 2 +}; + +/** + * A controller that animates via the Dynamo file format. + */ +class DynamoController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The base url within which the Dynamo files are contained. + * @type {string} + * @private + */ + this._baseUrl = ''; + + /** + * The flag that says whether all data is loaded for the current time. + * @type {boolean} + * @private + */ + this._dataLoadedAtCurrentTime = false; + + /** + * The time offset that is applied to the dynamo when reading data. + * @type {number} + * @private + */ + this._timeOffset = 0; + + /** + * The version of the dynamo type. + * @type {number} + * @private + */ + this._version = 0; + + /** + * The point type. + * @type {string} + * @private + */ + this._pointType = ''; + + /** + * The class of the point type. + * @type {typeof Point} + * @private + */ + this._PointClass = null; + + /** + * The number of digits for every index file's level. + * @type {number} + * @private + */ + this._numberOfDigits = 0; + + /** + * Point-specific header information for use in calculations. + * @type {Object} + * @private + */ + this._header = { + body: 0 + }; + + /** + * A flag that determines whether the controller incrementally changes the position each frame instead of setting the position. + * @type {boolean} + * @private + */ + this._incremental = false; + + /** + * The root point set in the definition file. + * @type {PointSet} + * @private + */ + this._pointSet = null; + + /** + * A reference to the downloader for downloading files. + * @type {Downloader} + * @private + */ + this._downloader = entity.getScene().getEngine().getDownloader(); + + /** + * Temporary point for calculations. + * @type {[Point | null, Point | null]} + * @private + */ + this._points = [null, null]; + + /** + * The last known good points used in the update function. + * @type {[Point | null, Point | null]} + * @private + */ + this._lastPoints = [null, null]; + + /** + * The last time used in the update function. + * @type {number} + * @private + */ + this._lastTime = Number.NaN; + + /** + * Temporary point for calculations. + * @type {Point} + * @private + */ + this._pCalc = null; + + /** + * The user coverage that limits the coverage coming from the data. + * @type {Interval} + * @private + */ + this._userCoverage = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); + this._userCoverage.freeze(); + } + + /** + * Gets the point type. It can be 'pos', 'lin', 'orb', 'ori', or 'quat'. + * @returns {string} + */ + getPointType() { + return this._pointType; + } + + /** + * Gets the value of a header key. + * @param {string} key + * @returns {number} + */ + getHeaderValue(key) { + return this._header[key]; + } + + /** + * Sets a key and value in the header information that the controller may use when updating. + * @param {string} key + * @param {number} value + */ + setHeaderValue(key, value) { + this._header[key] = value; + } + + /** + * Returns true if the controller incrementally changes the position each frame instead of setting the position. Defaults to false. + * @returns {boolean} + */ + isIncremental() { + return this._incremental; + } + + /** + * Sets whether the controller incrementally changes the position each frame instead of setting the position. + * @param {boolean} incremental + */ + setIncremental(incremental) { + this._incremental = incremental; + } + + /** + * Gets the base url within which the Dynamo files are contained. + * @returns {string} + */ + getBaseUrl() { + return this._baseUrl; + } + + /** + * Sets the base url within which the Dynamo files are contained. + * @param {string} baseUrl + */ + setBaseUrl(baseUrl) { + // Clear out previous dynamo. + if (this._baseUrl !== '') { + this._downloader.cancel(this._baseUrl + '/def.dyn'); + this._pointSet = null; + this._PointClass = null; + this._userCoverage.thaw(); + this._userCoverage = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); + this._userCoverage.freeze(); + super.setCoverage(new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY)); + this.addModifiedState('position'); + this.addModifiedState('velocity'); + this.addModifiedState('orientation'); + this.addModifiedState('angularVelocity'); + this._dataLoadedAtCurrentTime = false; + } + + this._baseUrl = baseUrl; + if (this._baseUrl.endsWith('/')) { + this._baseUrl = this._baseUrl.slice(0, -1); + } + + this._loadDef(); + } + + /** + * Gets a promise when the initial dynamo (the def file) is loaded. + * @returns {Promise} + * @override + */ + getLoadedPromise() { + return new Promise((resolve) => { + const engine = this.getEntity().getScene().getEngine(); + const callback = () => { + const time = engine.getTime(); + if (this.isDestroyed() || !this.isEnabled() || !this.getEntity().isEnabled() || this._baseUrl === '' || (this._pointSet !== null && !this.getCoverage().contains(time)) || this._dataLoadedAtCurrentTime) { + engine.removeCallback(callback); + resolve(); + } + }; + engine.addCallback(callback, true); + }); + } + + /** + * Gets the time offset that is applied to the dynamo when reading data. + * @returns {number} + */ + getTimeOffset() { + return this._timeOffset; + } + + /** + * Sets the time offset that is applied to the dynamo when reading data. + * @param {number} timeOffset + */ + setTimeOffset(timeOffset) { + const oldTimeOffset = this._timeOffset; + this._timeOffset = timeOffset; + // Adjust the coverage offset to reflect new offset. + const newCoverage = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(); + newCoverage.copy(this.getCoverage()); + newCoverage.min += this._timeOffset - oldTimeOffset; + newCoverage.max += this._timeOffset - oldTimeOffset; + super.setCoverage(newCoverage); + // It doesn't change the point set intervals. + } + + /** + * Sets the time interval over which the controller is valid. + * @param {Interval} coverage + * @override + */ + setCoverage(coverage) { + this._userCoverage.thaw(); + this._userCoverage.copy(coverage); + this._userCoverage.freeze(); + const finalCoverage = _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get(); + if (this._pointSet !== null) { + finalCoverage.intersection(this._userCoverage, this._pointSet._interval); + } + else { + finalCoverage.copy(new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY)); + } + finalCoverage.min += this._timeOffset; + finalCoverage.max += this._timeOffset; + super.setCoverage(finalCoverage); + _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(finalCoverage); + } + + /** + * Gets the orbital elements at the given time. + * @param {OrbitalElements} orbitalElements + * @param {number} time + */ + getOrbitalElements(orbitalElements, time) { + if (this._PointClass === OrbPoint && this._pointSet !== null) { + this._getPointsAtTime(this._points, time); + if (this._points[0] !== null) { + this._lastPoints[0] = this._points[0]; + this._lastPoints[1] = this._points[1]; + } + if (this._lastPoints[0] !== null) { + const oe0 = /** @type {OrbPoint} */(this._lastPoints[0]).oe; + const oe1 = /** @type {OrbPoint} */(this._lastPoints[1]).oe; + const u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time - this._lastPoints[0].time) / (this._lastPoints[1].time - this._lastPoints[0].time)); + orbitalElements.eccentricity = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(oe0.eccentricity, oe1.eccentricity, u); + orbitalElements.semiMajorAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(oe0.semiMajorAxis, oe1.semiMajorAxis, u); + orbitalElements.epoch = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(oe0.epoch, oe1.epoch, u); + orbitalElements.meanAngularMotion = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(oe0.meanAngularMotion, oe1.meanAngularMotion, u); + orbitalElements.meanAnomalyAtEpoch = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerpAngle(oe0.meanAnomalyAtEpoch, oe1.meanAnomalyAtEpoch, u); + orbitalElements.orbitOrientation.slerp(oe0.orbitOrientation, oe1.orbitOrientation, u); + } + } + } + + /** + * Gets the eccentricity of the orbit at the given time, assuming it is the 'orb' type. + * @param {number} time + * @returns {number} + */ + getEccentricity(time) { + if (this._PointClass === OrbPoint && this._pointSet !== null) { + this._getPointsAtTime(this._points, time); + if (this._points[0] !== null) { + this._lastPoints[0] = this._points[0]; + this._lastPoints[1] = this._points[1]; + } + if (this._lastPoints[0] !== null) { + const u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time - this._lastPoints[0].time) / (this._lastPoints[1].time - this._lastPoints[0].time)); + return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(/** @type {OrbPoint} */(this._lastPoints[0]).oe.eccentricity, /** @type {OrbPoint} */(this._lastPoints[1]).oe.eccentricity, u); + } + } + return Number.NaN; + } + + /** + * Gets the semi-major axis of the orbit at the given time, assuming it is the 'orb' type. + * @param {number} time + * @returns {number} + */ + getSemiMajorAxis(time) { + if (this._PointClass === OrbPoint && this._pointSet !== null) { + this._getPointsAtTime(this._points, time); + if (this._points[0] !== null) { + this._lastPoints[0] = this._points[0]; + this._lastPoints[1] = this._points[1]; + } + if (this._lastPoints[0] !== null) { + const u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time - this._lastPoints[0].time) / (this._lastPoints[1].time - this._lastPoints[0].time)); + return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(/** @type {OrbPoint} */(this._lastPoints[0]).oe.semiMajorAxis, /** @type {OrbPoint} */(this._lastPoints[1]).oe.semiMajorAxis, u); + } + } + return Number.NaN; + } + + /** + * Gets the orbit orientation of the orbit at the given time, assuming it is the 'orb' type. The x-axis points toward the periapsis and the z-axis points in the direction of the angular momentum. + * @param {Quaternion} outOrbitOrientation + * @param {number} time + */ + getOrbitOrientation(outOrbitOrientation, time) { + if (this._PointClass === OrbPoint && this._pointSet !== null) { + this._getPointsAtTime(this._points, time); + if (this._points[0] !== null) { + this._lastPoints[0] = this._points[0]; + this._lastPoints[1] = this._points[1]; + } + if (this._lastPoints[0] !== null) { + const u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time - this._lastPoints[0].time) / (this._lastPoints[1].time - this._lastPoints[0].time)); + outOrbitOrientation.slerp(/** @type {OrbPoint} */(this._lastPoints[0]).oe.orbitOrientation, /** @type {OrbPoint} */(this._lastPoints[1]).oe.orbitOrientation, u); + } + } + } + + /** + * Destroys any resources with the dynamo. + * @override + * @internal + */ + __destroy() { + // Cancel any download. + if (this._baseUrl !== '') { + this._downloader.cancel(this._baseUrl + '/def.dyn'); + } + super.__destroy(); + } + + /** + * If the type has positions, updates the position. + * @param {Vector3} position + * @param {number} time + * @override + * @internal + */ + __updatePositionAtTime(position, time) { + if (this._pointSet === null) { // No def file loaded yet, so the time may or may not be covered, so set it to NaN. + position.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + if (/** @type {PosPoint | LinPoint | OrbPoint} */(this._pCalc).position === undefined || !this.getCoverage().contains(time)) { + return; // It's not a position type or it's not covered. + } + if (this._pCalc.time !== time) { + this._getPointsAtTime(this._points, time); + if (this._points[0] === null) { // No valid data yet, so set to NaN. + position.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + this._pCalc.calculate(this._points, time - this._timeOffset, this._header, this._incremental); + } + position.copy(/** @type {PosPoint | LinPoint | OrbPoint} */(this._pCalc).position); + } + + /** + * If the type has positions, updates the velocity. + * @param {Vector3} velocity + * @param {number} time + * @override + * @internal + */ + __updateVelocityAtTime(velocity, time) { + if (this._pointSet === null) { // No def file loaded yet, so the time may or may not be covered, so set it to NaN. + velocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + else if (/** @type {PosPoint | LinPoint | OrbPoint} */(this._pCalc).velocity === undefined || !this.getCoverage().contains(time)) { + return; // It's not a velocity type or it's not covered. + } + if (this._pCalc.time !== time) { + this._getPointsAtTime(this._points, time); + if (this._points[0] === null) { // No valid data yet, so set to NaN. + velocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + this._pCalc.calculate(this._points, time - this._timeOffset, this._header, this._incremental); + } + velocity.copy(/** @type {PosPoint | LinPoint | OrbPoint} */(this._pCalc).velocity); + } + + /** + * If the type has orientations, updates the orientation. + * @param {Quaternion} orientation + * @param {number} time + * @override + * @internal + */ + __updateOrientationAtTime(orientation, time) { + if (this._pointSet === null) { // No def file loaded yet, so the time may or may not be covered, so set it to NaN. + orientation.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]); + return; + } + if (/** @type {OriPoint | QuatPoint} */(this._pCalc).orientation === undefined || !this.getCoverage().contains(time)) { + return; // It's not an orientation type or it's not covered. + } + if (this._pCalc.time !== time) { + this._getPointsAtTime(this._points, time); + if (this._points[0] === null) { // No valid data yet, so set to NaN. + orientation.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]); + return; + } + this._pCalc.calculate(this._points, time - this._timeOffset, this._header, this._incremental); + } + orientation.copy(/** @type {OriPoint | QuatPoint} */(this._pCalc).orientation); + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + const entity = this.getEntity(); + const engine = entity.getScene().getEngine(); + const time = engine.getTime(); + if (this._pointSet !== null) { + this._pointSet.unloadOldPointSet(); + this._getPointsAtTime(this._points, time); + if (this._points[0] !== null) { + // Apply the data. + this._pCalc.calculate(this._points, time - this._timeOffset, this._header, this._incremental); + this._pCalc.apply(entity); + // Record these as the last known good values. + this._lastPoints[0] = this._points[0]; + this._lastPoints[1] = this._points[1]; + this._dataLoadedAtCurrentTime = true; + } + // Data for the current time is still loading. + else { + // If we've got good previous data, apply it, otherwise do nothing. + if (this._lastPoints[0] !== null && this._lastPoints[1] !== null) { + // Apply the last known good data. + this._pCalc.calculate(this._lastPoints, time - this._timeOffset, this._header, this._incremental); + this._pCalc.apply(entity); + } + this._dataLoadedAtCurrentTime = false; + } + } + else { // No def.dyn file has yet been loaded. + this.getEntity().setPosition(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + this.getEntity().setVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]); + this.getEntity().setAngularVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + this._dataLoadedAtCurrentTime = false; + } + this._lastTime = time; + } + + async _loadDef() { + // Save the url here since it may change in the async process. + const url = this._baseUrl; + + /** + * The promise that is used to tell when the dyndef is loaded. + * @type {Promise} + */ + return this._downloader.download(this._baseUrl + '/def.dyn', true).then(async (download) => { + if (download.status === 'cancelled') { + return Promise.resolve(); + } + else if (download.status === 'failed') { + return Promise.reject(new Error('Failed to load dynamo controller file "' + download.url + '": ' + download.errorMessage)); + } + if (!(download.content instanceof ArrayBuffer)) { + return Promise.reject(new Error('Failed to load dynamo controller file "' + download.url + '": Not a binary file.')); + } + + // Open the reader. + const reader = new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content); + + // Version + this._version = reader.readInt16(); + if (this._version !== 1 && this._version !== 2) { + throw new Error(download.url + ' is not Dynamo version 1 or 2'); + } + + // Type + this._pointType = reader.readString(); + if (this._pointType === 'pos') { + this._PointClass = PosPoint; + } + else if (this._pointType === 'lin') { + this._PointClass = LinPoint; + } + else if (this._pointType === 'ori') { + this._PointClass = OriPoint; + } + else if (this._pointType === 'quat') { + this._PointClass = QuatPoint; + } + else if (this._pointType === 'orb') { + this._PointClass = OrbPoint; + } + + // Set the calculation point. + this._pCalc = new this._PointClass(); + + // Let the base controller know that this changes the position or orientation. + if (this._PointClass === PosPoint || this._PointClass === LinPoint || this._PointClass === OrbPoint) { + this.addModifiedState('position'); + this.addModifiedState('velocity'); + this.removeModifiedState('orientation'); + this.removeModifiedState('angularVelocity'); + } + else if (this._PointClass === OriPoint || this._PointClass === QuatPoint) { + this.addModifiedState('orientation'); + this.addModifiedState('angularVelocity'); + this.removeModifiedState('position'); + this.removeModifiedState('velocity'); + } + + // Read the number of digits for each level of the file names. + if (this._version === 2) { + this._numberOfDigits = reader.readByte(); + } + + // Header + this._header = Object.assign(this._header, this._PointClass.readHeader(reader)); + + this._pointSet = new PointSet(this._PointClass, this._version, this._numberOfDigits, 'def'); + this._pointSet.load(reader); + + // Update the coverage. + const finalCoverage = _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get(); + finalCoverage.intersection(this._userCoverage, this._pointSet._interval); + finalCoverage.min += this._timeOffset; + finalCoverage.max += this._timeOffset; + super.setCoverage(finalCoverage); + _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(finalCoverage); + }).catch((error) => { + if (error instanceof Error) { + error.message = `While loading dynamo "${url}/def.dyn": ${error.message}`; + } + throw error; + }); + } + + /** + * Gets the points p0 and p1 at the given time. + * @param {[Point | null, Point | null]} points + * @param {number} time + */ + _getPointsAtTime(points, time) { + let pointSet = this._pointSet; + while (true) { + if (pointSet.hasPoints()) { + pointSet.getPoints(points, time - this._timeOffset); + return; + } + else if (pointSet.getLoadedState() === PointSet.State.LOADED) { + pointSet = pointSet.getPointSet(time - this._timeOffset); + if (pointSet === null) { + points[0] = null; + points[1] = null; + return; + } + } + else if (pointSet.getLoadedState() === PointSet.State.NOT_LOADED) { + pointSet.loadFromUrl(this._downloader, this._baseUrl); + points[0] = null; + points[1] = null; + return; + } + else { + points[0] = null; + points[1] = null; + return; + } + } + } +} + +DynamoController.maxLoadedPointSetsPerController = 5; + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/fixed_controller.js": +/*!*******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/fixed_controller.js ***! + \*******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FixedController": function() { return /* binding */ FixedController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A controller that sets a fixed position and/or orientation. */ +class FixedController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + // The position to be updated. If null, the position is not fixed. + this._position = null; + + // The orientation to be updated. If null, the orientation is not fixed. + this._orientation = null; + } + + /** + * Gets the position to be fixed, or null if the position is not fixed. Don't modify this directly. + * @returns {Vector3} + */ + getPosition() { + return this._position; + } + + /** + * Sets the position. Use null to unfix the position. + * @param {Vector3} position + */ + setPosition(position) { + if (position !== null) { + if (this._position === null) { + this._position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + } + this._position.thaw(); + this._position.copy(position); + this._position.freeze(); + } + else { + this._position = null; + } + if (position !== null) { + this.addModifiedState('position'); + this.addModifiedState('velocity'); + } + else { + this.removeModifiedState('position'); + this.removeModifiedState('velocity'); + } + } + + /** + * Gets the orientation to be fixed, or null if the orientation is not fixed. Don't modify this directly. + * @returns {Quaternion} + */ + getOrientation() { + return this._orientation; + } + + /** + * Sets the orientation. + * @param {Quaternion} orientation + */ + setOrientation(orientation) { + if (orientation !== null) { + if (this._orientation === null) { + this._orientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + } + this._orientation.thaw(); + this._orientation.copy(orientation); + this._orientation.freeze(); + } + else { + this._orientation = null; + } + if (orientation !== null) { + this.addModifiedState('orientation'); + } + else { + this.removeModifiedState('orientation'); + } + } + + /** + * If the position is fixed, updates the position to the fixed position. + * @param {Vector3} position + * @param {number} _time + * @override + * @internal + */ + __updatePositionAtTime(position, _time) { + if (this._position !== null) { + position.copy(this._position); + } + } + + /** + * If the position is fixed, updates the velocity to zero. + * @param {Vector3} velocity + * @param {number} _time + * @override + * @internal + */ + __updateVelocityAtTime(velocity, _time) { + if (this._position !== null) { + velocity.set(0, 0, 0); + } + } + + /** + * If the orientation is fixed, updates the orientation to the fixed orientation. + * @param {Quaternion} orientation + * @param {number} _time + * @override + * @internal + */ + __updateOrientationAtTime(orientation, _time) { + if (this._orientation !== null) { + orientation.copy(this._orientation); + } + } + + /** + * Updates the position and orientation if they are fixed. + * @override + * @internal + */ + __update() { + if (this._position !== null) { + this.getEntity().setPosition(this._position); + this.getEntity().setVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero); + } + if (this._orientation !== null) { + this.getEntity().setOrientation(this._orientation); + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/fixed_to_parent_controller.js": +/*!*****************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/fixed_to_parent_controller.js ***! + \*****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FixedToParentController": function() { return /* binding */ FixedToParentController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A controller that rotates the position and orientation by the parent's orientation last frame change. + * Great for objects that are connected to their parents or landers. + * It needs to added as the last controller to work. */ +class FixedToParentController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The parent's last orientation. + * @type {Quaternion} + * @private + */ + this._lastParentOrientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + + // Start off with the correct last orientation. + const parent = this.getEntity().getParent(); + if (parent !== null) { + this._lastParentOrientation.copy(parent.getOrientation()); + } + + // Let the base controller know that this changes the orientation. + this.addModifiedState('position'); + this.addModifiedState('orientation'); + + // Add the dependency on the parent's orientation. + this.addDependentState('parent', 'orientation'); + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + const parent = this.getEntity().getParent(); + if (parent !== null) { + const rotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + rotation.inverse(this._lastParentOrientation); + rotation.mult(parent.getOrientation(), rotation); + const position = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + position.rotate(rotation, this.getEntity().getPosition()); + this.getEntity().setPosition(position); + orientation.mult(rotation, this.getEntity().getOrientation()); + this.getEntity().setOrientation(orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation); + this._lastParentOrientation.copy(parent.getOrientation()); + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/free_fly_controller.js": +/*!**********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/free_fly_controller.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FreeFlyController": function() { return /* binding */ FreeFlyController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A camera controller that flies around freely. + */ +class FreeFlyController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The sensitivity for dragging. + * @type {number} + * @private + */ + this._dragSensitivity = 0.07; + + /** + * The smoothness of the dragging. Zero means no smoothness. + * @type {number} + * @private + */ + this._dragSmoothness = 0.8; + + /** + * The current value applied every frame to the movement. + * @type {Vector3} + * @private + */ + this._moveSmoothedValue = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0.0, 0.0, 0.0); + + /** + * The flag that determines whether the camera changes parent to whatever it is closer to. + * @type {boolean} + * @private + */ + this._changeParentToNearestEntity = true; + + /** + * The vector that runs every frame emulating user input. + * @type {Vector3} + * @private + */ + this._forcedMoving = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + this._isMoving = false; + + // Let the base controller know that this changes the position. + this.addModifiedState('position'); + + this.addDependentState('parent', 'orientation'); + this.addDependentState('parent', 'radius'); + } + + /** + * Gets the drag sensitivity. Defaults to 0.01. + * @returns {number} + */ + getDragSensitivity() { + return this._dragSensitivity; + } + + /** + * Sets the drag sensitivity. + * @param {number} dragSensitivity + */ + setDragSensitivity(dragSensitivity) { + this._dragSensitivity = dragSensitivity; + } + + /** + * Gets the drag smoothness. Defaults to 0.8. + * @returns {number} + */ + getDragSmoothness() { + return this._dragSmoothness; + } + + /** + * Sets the drag smoothness, between 0 and 1. + * @param {number} dragSmoothness + */ + setDragSmoothness(dragSmoothness) { + this._dragSmoothness = dragSmoothness; + } + + /** + * Gets the flag that determines whether the camera changes parent to whatever it is closer to. Defaults to true. + * @returns {boolean} + */ + getChangeParentToNearestEntity() { + return this._changeParentToNearestEntity; + } + + /** + * Sets the flag that determines whether the camera changes parent to whatever it is closer to. This requires this entity to have a camera component for faster checking. + * @param {boolean} changeParentToNearestEntity + */ + setChangeParentToNearestEntity(changeParentToNearestEntity) { + this._changeParentToNearestEntity = changeParentToNearestEntity; + } + + /** + * Gets the vector that runs every frame emulating user input. Defaults to Vector3.Zero. + * @returns {Vector3} + */ + getForcedMoving() { + return this._forcedMoving; + } + + /** + * Sets the vector that runs every frame emulating user input. + * @param {Vector3} forcedMoving + */ + setForcedMoving(forcedMoving) { + this._forcedMoving = forcedMoving; + } + + /** + * Updates the entity's position. + * @override + * @internal + */ + __update() { + // If it has no parent, don't do anything. + if (this.getEntity().getParent() === null) { + return; + } + + // Update the parent, if needed. Only do it if there was any input. + if (this._changeParentToNearestEntity && (this.getEntity().getParent() === null || this._isMoving)) { + const scene = this.getEntity().getScene(); + const cameraComponent = /** @type {CameraComponent} */(this.getEntity().get('camera')); + let nearestEntity = null; + let nearestDistance = Number.POSITIVE_INFINITY; + for (let i = 0, l = scene.getNumEntities(); i < l; i++) { + const entity = scene.getEntity(i); + if (entity === this.getEntity() || !entity.canOcclude()) { + continue; + } + const distance = entity.getCameraSpacePosition(cameraComponent).magnitude() - entity.getOcclusionRadius(); + if (nearestDistance > distance) { + nearestDistance = distance; + nearestEntity = entity; + } + } + + // Switch parents. Since it's happening in the update function. + if (nearestEntity !== null && nearestEntity !== this.getEntity().getParent()) { + this.getEntity().setParent(nearestEntity); + } + } + + // Set the position and orientation if they have never been set before. + if (this.getEntity().getOrientation().isNaN()) { + this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + if (this.getEntity().getPosition().isNaN()) { + this.getEntity().setPosition(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, -1, 0)); + } + + // Get the move value from the controls. + const move = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + move.set(0.0, 0.0, 0.0); + const input = this.getEntity().getScene().getEngine().getInput(); + const viewport = input.getActiveViewport(); + if (viewport !== null) { + const camera = viewport.getCamera(); + if (camera !== null && camera.getEntity() === this.getEntity()) { + // Get the multipliers. + let moveMultiplier = 1; + if (input.isKeyPressed('x')) { + moveMultiplier = 0.05; + } + if (input.isShiftPressed()) { + moveMultiplier = 5; + } + + // Add zoom movement. + const zoomOffset = input.getZoomedOffset(); + if (zoomOffset !== 0) { + move.y += -zoomOffset * this._dragSensitivity * moveMultiplier; + } + + // Add key movement. + if (input.isKeyPressed('w')) { + move.y += this._dragSensitivity * moveMultiplier; + } + if (input.isKeyPressed('s')) { + move.y -= this._dragSensitivity * moveMultiplier; + } + if (input.isKeyPressed('d')) { + move.x += this._dragSensitivity * moveMultiplier; + } + if (input.isKeyPressed('a')) { + move.x -= this._dragSensitivity * moveMultiplier; + } + if (input.isKeyPressed('e')) { + move.z += this._dragSensitivity * moveMultiplier; + } + if (input.isKeyPressed('q')) { + move.z -= this._dragSensitivity * moveMultiplier; + } + move.y += this._dragSensitivity * moveMultiplier * cameraFreeFlyParameters.velocity; + } + } + + // Add the forced moving. + move.add(move, this._forcedMoving); + + this._isMoving = (move.magnitudeSqr() > 0); + + // Apply smoothing. + this._moveSmoothedValue.lerp(move, this._moveSmoothedValue, this._dragSmoothness); + if (!this._isMoving && this._moveSmoothedValue.magnitudeSqr() < 0.0000001) { + this._moveSmoothedValue.set(0.0, 0.0, 0.0); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(move); + + // Get the distance to the current parent. + let distance = Number.POSITIVE_INFINITY; + const spheroid = /** @type {SpheroidComponent} */(this.getEntity().getParent().getComponentByType('spheroid')); + if (spheroid !== null && !this.getEntity().getParent().getOrientation().isNaN()) { + const position = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + position.rotateInverse(this.getEntity().getParent().getOrientation(), this.getEntity().getPosition()); + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + spheroid.llaFromXYZ(lla, position); + distance = Math.min(distance, lla.alt); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + } + else { + distance = Math.min(distance, this.getEntity().getPosition().magnitude() - this.getEntity().getParent().getOcclusionRadius()); + } + distance = Math.max(0.1, distance); + + // Do the move. + const oldPosition = this.getEntity().getPosition(); + const newPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const rotatedMove = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + rotatedMove.rotate(this.getEntity().getOrientation(), this._moveSmoothedValue); + newPosition.addMult(oldPosition, rotatedMove, distance); + this.getEntity().setPosition(newPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(rotatedMove); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/ground_clamp_controller.js": +/*!**************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/ground_clamp_controller.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "GroundClampController": function() { return /* binding */ GroundClampController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * @typedef {Object} HasGetGroundPosition + * @property {(outPosition: Vector3, outHeightDir: Vector3, position: Vector3) => void} getGroundPosition + */ + +/** + * A controller that clamps an entty to the ground. + */ +class GroundClampController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The component to clamp to. + * @type {ComponentRef} + * @private + */ + this._groundComponentRef = new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene()); + + /** + * The offset in the up direction. + * @type {number} + * @private + */ + this._distanceFromGround = 0; + + /** + * The frame-up vector for use in clamping correctly to slanted surfaces. + * @type {Vector3} + * @private + */ + this._up = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 1); + + // Let the base controller know that this changes the position. + this.addModifiedState('position'); + } + + /** + * Sets the component to clamp to. Defaults to the nearest ancestor spheroid or null. + * @param {string} entityName + * @param {string} componentType + * @param {number} [componentTypeIndex] + */ + setGroundComponentRef(entityName, componentType, componentTypeIndex) { + this.removeDependentState(this._groundComponentRef.getEntityName(), 'orientation'); + this._groundComponentRef.setByType(entityName, componentType, componentTypeIndex); + this.addDependentState(entityName, 'orientation'); + } + + /** + * Gets the distance in the up direction from the ground. + * @returns {number} + */ + getDistanceFromGround() { + return this._distanceFromGround; + } + + /** + * Sets the distance in the up direction from the ground. Negative is below the ground. Defaults to 0. + * @param {number} distanceFromGround + */ + setDistanceFromGround(distanceFromGround) { + this._distanceFromGround = distanceFromGround; + } + + /** + * Sets the frame-up vector for use in clamping correctly to slanted surfaces. + * @param {Vector3} up + */ + setUp(up) { + this._up.copy(up); + } + + /** + * Updates a position for the given time. + * @param {Vector3} position + * @param {number} time + * @override + * @internal + */ + __updatePositionAtTime(position, time) { + // Get the entity parent. + const entityParentNameAtTime = this.getEntity().getParentAtTime(time); + const entityParentAtTime = this.getEntity().getScene().getEntity(entityParentNameAtTime); + if (entityParentAtTime === null) { + return; + } + // Get the ground component, or get the nearest ancestor with a spheroid. + let groundComponent = this._groundComponentRef.get(); + if (groundComponent === null) { + let parent = this.getEntity().getParent(); + while (parent !== null) { + groundComponent = /** @type {SpheroidComponent} */(parent.getComponentByType('spheroid')); + if (groundComponent !== null) { + break; + } + parent = parent.getParent(); + } + if (groundComponent === null) { + return; + } + } + const groundComponentEntity = groundComponent.getEntity(); + // Get the position of the entity in the component entity's frame-space. + const entityPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const heightDir = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const groundOrientationAtTime = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + groundComponentEntity.getOrientationAtTime(groundOrientationAtTime, time); + entityParentAtTime.getPositionRelativeToEntity(entityPosition, position, groundComponentEntity, time); + entityPosition.rotateInverse(groundOrientationAtTime, entityPosition); + // Get the height at the given position. + if (groundComponent.getGroundPosition !== undefined) { + groundComponent.getGroundPosition(entityPosition, heightDir, entityPosition); + } + if (!entityPosition.isNaN()) { + const entityUp = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const entityOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + this.getEntity().getOrientationAtTime(entityOrientation, time); + entityUp.rotate(entityOrientation, this._up); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(entityOrientation); + entityUp.rotateInverse(groundOrientationAtTime, entityUp); + const cosUpAndGroundUp = Math.abs(entityUp.dot(heightDir)); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityUp); + // Add on the up offset. + entityPosition.addMult(entityPosition, heightDir, Math.min(this._distanceFromGround / cosUpAndGroundUp, this._distanceFromGround + this.getEntity().getExtentsRadius())); + // Get the position back into the entity-space of the parent. + entityPosition.rotate(groundOrientationAtTime, entityPosition); + groundComponentEntity.getPositionRelativeToEntity(position, entityPosition, entityParentAtTime, time); + } + else { + position.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + // Cleanup. + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(heightDir); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(groundOrientationAtTime); + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + if (this.getEntity().getParent() === null) { + return; + } + // Get the ground component, or get the nearest ancestor with a spheroid. + let groundComponent = this._groundComponentRef.get(); + if (groundComponent === null) { + let parent = this.getEntity().getParent(); + while (parent !== null) { + groundComponent = /** @type {SpheroidComponent} */(parent.getComponentByType('spheroid')); + if (groundComponent !== null) { + break; + } + parent = parent.getParent(); + } + if (groundComponent === null) { + return; + } + } + const groundComponentEntity = groundComponent.getEntity(); + // Get the position of the entity in the component entity's frame-space. + const entityPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const heightDir = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.getEntity().getPositionRelativeToEntity(entityPosition, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, groundComponentEntity); + entityPosition.rotateInverse(groundComponentEntity.getOrientation(), entityPosition); + // Get the height at the given position. + if (groundComponent.getGroundPosition !== undefined) { + groundComponent.getGroundPosition(entityPosition, heightDir, entityPosition); + } + if (!entityPosition.isNaN()) { + const entityUp = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + entityUp.rotate(this.getEntity().getOrientation(), this._up); + entityUp.rotateInverse(groundComponentEntity.getOrientation(), entityUp); + const cosUpAndGroundUp = Math.abs(entityUp.dot(heightDir)); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityUp); + // Add on the up offset. + entityPosition.addMult(entityPosition, heightDir, Math.min(this._distanceFromGround / cosUpAndGroundUp, this._distanceFromGround + this.getEntity().getExtentsRadius())); + // Get the position back into the entity-space of the parent. + entityPosition.rotate(groundComponentEntity.getOrientation(), entityPosition); + groundComponentEntity.getPositionRelativeToEntity(entityPosition, entityPosition, this.getEntity().getParent()); + } + else { + entityPosition.copy(this.getEntity().getLastPosition()); + } + // Set the position. + this.getEntity().setPosition(entityPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(heightDir); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/keyframe_controller.js": +/*!**********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/keyframe_controller.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "KeyframeController": function() { return /* binding */ KeyframeController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A controller animates the position and orientation of an entity via keyframes. + */ +class KeyframeController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The position keyframes. + * @type {Array<{0: number, 1: PositionKeyframe}>} + * @private + */ + this._positionKeyframes = []; + + /** + * The orientation keyframes. + * @type {Array<{0: number, 1: OrientationKeyframe}>} + * @private + */ + this._orientationKeyframes = []; + + /** + * The flag that if true says that the times given are relative to the first update in real time, + * and if false says that the times are in ET time. + * @type {boolean} + * @private + */ + this._timesAreRealTime = false; + + /** + * The time of the first update, used when _timesAreRealTime is true. + * @type {number} + * @private + */ + this._timeOfFirstUpdate = NaN; + + // Set the coverage to nothing, since there are no keyframes. + this.setCoverage(new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY)); + + // Helper vectors and quaternions for calculations. + this._position0 = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._position1 = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._orientation0 = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + this._orientation1 = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + this._newPosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._newVelocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._newOrientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + this._tangent0 = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._tangent1 = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._tempA = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._tempB = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + } + + /** + * Adds a position keyframe. + * If positionOrEntity is an entity, the entity's position at the given time is used instead. + * @param {number} time + * @param {Vector3} position + * @param {string} [relativeToEntityPosition] + * @param {number} [relativeToEntityPositionTime] + * @param {string} [relativeToEntityOrientation] + * @param {number} [relativeToEntityOrientationTime] + */ + addPositionKeyframe(time, position, relativeToEntityPosition, relativeToEntityPositionTime, relativeToEntityOrientation, relativeToEntityOrientationTime) { + /** @type {{0: number, 1: PositionKeyframe}} */ + const entry = [time, { + position, + relativeToEntityPosition: relativeToEntityPosition ? new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(), relativeToEntityPosition) : undefined, + relativeToEntityPositionTime, + relativeToEntityOrientation: relativeToEntityOrientation ? new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(), relativeToEntityOrientation) : undefined, + relativeToEntityOrientationTime + }]; + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(entry, this._positionKeyframes, isLessAdd); + if (this._positionKeyframes.length === 1) { + this.addModifiedState('position'); + this.addModifiedState('velocity'); + } + this._updateCoverage(); + } + + /** + * Removes a position keyframe. Returns true if the key was removed. + * @param {number} time + */ + removePositionKeyframe(time) { + const found = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.remove(time, this._positionKeyframes, isLess, isEqual); + if (found) { + if (this._positionKeyframes.length === 0) { + this.removeModifiedState('position'); + this.removeModifiedState('velocity'); + } + this._updateCoverage(); + } + return found; + } + + /** + * Adds an orientation keyframe. + * If orientationOrEntity is an entity, the entity's orientation at the given time is used instead. + * @param {number} time + * @param {Quaternion} orientation + * @param {string} [relativeToEntityOrientation] + * @param {number} [relativeToEntityOrientationTime] + */ + addOrientationKeyframe(time, orientation, relativeToEntityOrientation, relativeToEntityOrientationTime) { + /** @type {{0: number, 1: OrientationKeyframe}} */ + const entry = [time, { + orientation, + relativeToEntityOrientation: relativeToEntityOrientation ? new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(), relativeToEntityOrientation) : undefined, + relativeToEntityOrientationTime + }]; + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(entry, this._orientationKeyframes, isLessAdd); + if (this._orientationKeyframes.length === 1) { + this.addModifiedState('orientation'); + } + this._updateCoverage(); + } + + /** + * Removes an orientation keyframe. Returns true if the key was removed. + * @param {number} time + */ + removeOrientationKeyframe(time) { + const found = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.remove(time, this._orientationKeyframes, isLess, isEqual); + if (found) { + if (this._orientationKeyframes.length === 0) { + this.removeModifiedState('orientation'); + } + this._updateCoverage(); + } + return found; + } + + /** + * Gets the flag that if true says that the times given are relative to the first update in real time, + * and if false says that the times are in ET time. + * @returns {boolean} + */ + areTimesRealTime() { + return this._timesAreRealTime; + } + + /** + * Sets the flag that if true says that the times given are relative to the first update in real time, + * and if false says that the times are in ET time. + * @param {boolean} timesAreRealTime + */ + setTimesAreRealTime(timesAreRealTime) { + this._timesAreRealTime = timesAreRealTime; + this._updateCoverage(); + } + + /** + * Sets the position to the keyframed position at the given time. + * @param {Vector3} position + * @param {number} time + * @override + * @internal + */ + __updatePositionAtTime(position, time) { + this._getPositionAtTime(position, time); + } + + /** + * Sets the velocity to the keyframed velocity at the given time. + * @param {Vector3} velocity + * @param {number} time + * @override + * @internal + */ + __updateVelocityAtTime(velocity, time) { + this._getVelocityAtTime(velocity, time); + } + + /** + * Sets the orientation to the keyframed orientation at the given time. + * @param {Quaternion} orientation + * @param {number} time + * @override + * @internal + */ + __updateOrientationAtTime(orientation, time) { + this._getOrientationAtTime(orientation, time); + } + + /** + * Updates the position and orientation from the keyframes. + * @override + * @internal + */ + __update() { + const engine = this.getEntity().getScene().getEngine(); + let time = 0; + if (this._timesAreRealTime) { + if (isNaN(this._timeOfFirstUpdate)) { + this._timeOfFirstUpdate = Date.now() / 1000; + } + else { + time = Date.now() / 1000 - this._timeOfFirstUpdate; + } + } + else { + time = engine.getTime(); + } + if (this._getPositionAtTime(this._newPosition, time)) { + this.getEntity().setPosition(this._newPosition); + } + if (this._getVelocityAtTime(this._newVelocity, time)) { + this.getEntity().setVelocity(this._newVelocity); + } + if (this._getOrientationAtTime(this._newOrientation, time)) { + this.getEntity().setOrientation(this._newOrientation); + } + } + + /** + * Sets outPosition to the position at the given time. Returns true if they were set. + * @param {Vector3} outPosition + * @param {number} time + * @returns {boolean} + * @private + */ + _getPositionAtTime(outPosition, time) { + const index = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._positionKeyframes, isLess); + if (index < this._positionKeyframes.length) { // Any time before or at the ending time. + if (index === 0) { // Any time before or at the beginning time. + if (this._positionKeyframes[0][0] === time) { // It's right at the beginning time. + this._getPositionOfKeyframe(outPosition, this._positionKeyframes[0]); + return true; + } + } + else { // Any time after the beginning time. + const index0 = index - 1; + const index1 = index; + const time0 = this._positionKeyframes[index0][0]; + const time1 = this._positionKeyframes[index1][0]; + this._getPositionOfKeyframe(this._position0, this._positionKeyframes[index0]); + this._getPositionOfKeyframe(this._position1, this._positionKeyframes[index1]); + if (index0 > 0) { + const timeA = this._positionKeyframes[index0 - 1][0]; + this._getPositionOfKeyframe(this._tempA, this._positionKeyframes[index0 - 1]); + this._tempA.sub(this._position0, this._tempA); + this._tempB.sub(this._position1, this._position0); + this._tempB.mult(this._tempB, 0.5); + this._tangent0.addMult(this._tempB, this._tempA, 0.5 * (time1 - time0) / (time0 - timeA)); + } + else { + this._tangent0.sub(this._position1, this._position0); + } + if (index1 < this._positionKeyframes.length - 1) { + const timeB = this._positionKeyframes[index1 + 1][0]; + this._getPositionOfKeyframe(this._tempB, this._positionKeyframes[index1 + 1]); + this._tempA.sub(this._position1, this._position0); + this._tempB.sub(this._tempB, this._position1); + this._tempA.mult(this._tempA, 0.5); + this._tangent1.addMult(this._tempA, this._tempB, 0.5 * (time1 - time0) / (timeB - time1)); + } + else { + this._tangent1.sub(this._position1, this._position0); + } + const u = (time - time0) / (time1 - time0); + this._cubicHermiteSpline(outPosition, this._position0, this._position1, this._tangent0, this._tangent1, u); + return true; + } + } + return false; + } + + /** + * Sets outVelocity to the velocity at the given time. Returns true if they were set. + * @param {Vector3} outVelocity + * @param {number} time + * @returns {boolean} + * @private + */ + _getVelocityAtTime(outVelocity, time) { + const index = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._positionKeyframes, isLess); + if (index < this._positionKeyframes.length) { // Any time before or at the ending time. + if (index === 0) { // Any time before or at the beginning time. + if (this._positionKeyframes[0][0] === time) { // It's right at the beginning time. + if (this._positionKeyframes.length > 1) { + const time0 = this._positionKeyframes[0][0]; + const time1 = this._positionKeyframes[1][0]; + this._getPositionOfKeyframe(this._position0, this._positionKeyframes[0]); + this._getPositionOfKeyframe(this._position1, this._positionKeyframes[1]); + outVelocity.sub(this._position1, this._position0); + outVelocity.div(outVelocity, time1 - time0); + } + else { + outVelocity.set(0, 0, 0); + } + return true; + } + } + else { // Any time after the beginning time. + const index0 = index - 1; + const index1 = index; + const time0 = this._positionKeyframes[index0][0]; + const time1 = this._positionKeyframes[index1][0]; + this._getPositionOfKeyframe(this._position0, this._positionKeyframes[index0]); + this._getPositionOfKeyframe(this._position1, this._positionKeyframes[index1]); + if (index0 > 0) { + const timeA = this._positionKeyframes[index0 - 1][0]; + this._getPositionOfKeyframe(this._tempA, this._positionKeyframes[index0 - 1]); + this._tempA.sub(this._position0, this._tempA); + this._tempB.sub(this._position1, this._position0); + this._tempB.mult(this._tempB, 0.5); + this._tangent0.addMult(this._tempB, this._tempA, 0.5 * (time1 - time0) / (time0 - timeA)); + } + else { + this._tangent0.sub(this._position1, this._position0); + } + if (index1 < this._positionKeyframes.length - 1) { + const timeB = this._positionKeyframes[index1 + 1][0]; + this._getPositionOfKeyframe(this._tempB, this._positionKeyframes[index1 + 1]); + this._tempA.sub(this._position1, this._position0); + this._tempB.sub(this._tempB, this._position1); + this._tempA.mult(this._tempA, 0.5); + this._tangent1.addMult(this._tempA, this._tempB, 0.5 * (time1 - time0) / (timeB - time1)); + } + else { + this._tangent1.sub(this._position1, this._position0); + } + const u = (time - time0) / (time1 - time0); + this._cubicHermiteSplineDerivative(outVelocity, this._position0, this._position1, this._tangent0, this._tangent1, u); + outVelocity.div(outVelocity, time1 - time0); + return true; + } + } + return false; + } + + /** + * Sets outOrientation to the orientation at the given time. Returns true if it was set. + * @param {Quaternion} outOrientation + * @param {number} time + * @returns {boolean} + * @private + */ + _getOrientationAtTime(outOrientation, time) { + const index = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._orientationKeyframes, isLess); + if (index < this._orientationKeyframes.length) { // Any time before or at the ending time. + if (index === 0) { // Any time before or at the beginning time. + if (this._orientationKeyframes[0][0] === time) { // It's right at the beginning time. + this._getOrientationOfKeyframe(outOrientation, this._orientationKeyframes[0]); + return true; + } + } + else { // Any time after the beginning time. + const index0 = index - 1; + const index1 = index; + const time0 = this._orientationKeyframes[index0][0]; + this._getOrientationOfKeyframe(this._orientation0, this._orientationKeyframes[index0]); + const time1 = this._orientationKeyframes[index1][0]; + this._getOrientationOfKeyframe(this._orientation1, this._orientationKeyframes[index1]); + outOrientation.slerp(this._orientation0, this._orientation1, (time - time0) / (time1 - time0)); + return true; + } + } + return false; + } + + /** + * Gets the position from a keyframe value. + * @param {Vector3} outPosition + * @param {{0: number, 1: PositionKeyframe}} keyframe + * @private + */ + _getPositionOfKeyframe(outPosition, keyframe) { + const positionKeyframe = keyframe[1]; + outPosition.copy(positionKeyframe.position); + if (positionKeyframe.relativeToEntityOrientation !== undefined) { + const time = keyframe[1].relativeToEntityOrientationTime !== undefined ? keyframe[1].relativeToEntityOrientationTime : keyframe[0]; + const otherEntity = positionKeyframe.relativeToEntityOrientation.get(); + if (otherEntity !== null) { + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + otherEntity.getOrientationAtTime(orientation, time); + outPosition.rotate(orientation, outPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + } + else { + outPosition.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + } + if (positionKeyframe.relativeToEntityPosition !== undefined) { + const time = keyframe[1].relativeToEntityPositionTime !== undefined ? keyframe[1].relativeToEntityPositionTime : keyframe[0]; + const relativeToEntityPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const otherEntity = positionKeyframe.relativeToEntityPosition.get(); + if (otherEntity !== null) { + otherEntity.getPositionRelativeToEntity(relativeToEntityPosition, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, this.getEntity().getParent(), time); + outPosition.add(relativeToEntityPosition, outPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(relativeToEntityPosition); + } + else { + outPosition.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + } + } + + /** + * Gets the orientation from a keyframe value. + * @param {Quaternion} outOrientation + * @param {{0: number, 1: OrientationKeyframe}} keyframe + * @private + */ + _getOrientationOfKeyframe(outOrientation, keyframe) { + const orientationKeyframe = keyframe[1]; + if (orientationKeyframe.relativeToEntityOrientation !== undefined) { + const time = keyframe[1].relativeToEntityOrientationTime !== undefined ? keyframe[1].relativeToEntityOrientationTime : keyframe[0]; + const otherEntity = orientationKeyframe.relativeToEntityOrientation.get(); + if (otherEntity !== null) { + otherEntity.getOrientationAtTime(outOrientation, time); + outOrientation.mult(outOrientation, orientationKeyframe.orientation); + } + else { + outOrientation.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]); + } + } + else { + outOrientation.copy(orientationKeyframe.orientation); + } + } + + /** + * Updates the coverage. + * @private + */ + _updateCoverage() { + if (this._timesAreRealTime) { + this.setCoverage(_internal__WEBPACK_IMPORTED_MODULE_0__.Interval.Infinite); + } + else { + const coverage = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY); + if (this._positionKeyframes.length > 0) { + coverage.min = Math.min(coverage.min, this._positionKeyframes[0][0]); + coverage.max = Math.max(coverage.max, this._positionKeyframes[this._positionKeyframes.length - 1][0]); + } + if (this._orientationKeyframes.length > 0) { + coverage.min = Math.min(coverage.min, this._orientationKeyframes[0][0]); + coverage.max = Math.max(coverage.max, this._orientationKeyframes[this._orientationKeyframes.length - 1][0]); + } + this.setCoverage(coverage); + } + } + + /** + * Sets outP to the cubic hermite spline of the given parameters. + * @param {Vector3} outP + * @param {Vector3} p0 + * @param {Vector3} p1 + * @param {Vector3} t0 + * @param {Vector3} t1 + * @param {number} u + */ + _cubicHermiteSpline(outP, p0, p1, t0, t1, u) { + const u2 = u * u; + const u3 = u * u2; + const c0 = 2 * u3 - 3 * u2 + 1; + const c1 = u3 - 2 * u2 + u; + const c2 = -2 * u3 + 3 * u2; + const c3 = u3 - u2; + outP.x = c0 * p0.x + c1 * t0.x + c2 * p1.x + c3 * t1.x; + outP.y = c0 * p0.y + c1 * t0.y + c2 * p1.y + c3 * t1.y; + outP.z = c0 * p0.z + c1 * t0.z + c2 * p1.z + c3 * t1.z; + } + + /** + * Sets outP to the derivative of the cubic hermite spline of the given parameters. + * @param {Vector3} outV + * @param {Vector3} p0 + * @param {Vector3} p1 + * @param {Vector3} t0 + * @param {Vector3} t1 + * @param {number} u + */ + _cubicHermiteSplineDerivative(outV, p0, p1, t0, t1, u) { + const u2 = u * u; + const c0 = 6 * u2 - 6 * u; + const c1 = 3 * u2 - 4 * u + 1; + const c2 = -6 * u2 + 6 * u; + const c3 = 3 * u2 - 2 * u; + outV.x = c0 * p0.x + c1 * t0.x + c2 * p1.x + c3 * t1.x; + outV.y = c0 * p0.y + c1 * t0.y + c2 * p1.y + c3 * t1.y; + outV.z = c0 * p0.z + c1 * t0.z + c2 * p1.z + c3 * t1.z; + } +} + +/** + * @typedef PositionKeyframe + * @property {Vector3} position + * @property {EntityRef} [relativeToEntityPosition] + * @property {number} [relativeToEntityPositionTime] + * @property {EntityRef} [relativeToEntityOrientation] + * @property {number} [relativeToEntityOrientationTime] + */ + +/** + * @typedef OrientationKeyframe + * @property {Quaternion} orientation + * @property {EntityRef} [relativeToEntityOrientation] + * @property {number} [relativeToEntityOrientationTime] + */ + +/** + * An isLess function that uses two keyframes. + * @callback IsLessAddFunction + * @param {{0: number, 1: PositionKeyframe | OrientationKeyframe}} a + * @param {{0: number, 1: PositionKeyframe | OrientationKeyframe}} b + * @returns {boolean} + */ + +/** + * An isLess function that uses a keyframe and a time. + * @callback IsLessFunction + * @param {{0: number, 1: PositionKeyframe | OrientationKeyframe}} a + * @param {number} b + * @returns {boolean} + */ + +/** + * An isLess function that uses a keyframe and a time. + * @callback IsEqualFunction + * @param {{0: number, 1: PositionKeyframe | OrientationKeyframe}} a + * @param {number} b + * @returns {boolean} + */ + +/** + * A helper function for the keyframe sorting. + * @type {IsLessAddFunction} + */ +const isLessAdd = (a, b) => (a[0] < b[0]); + +/** + * A helper function for the keyframe sorting. + * @type {IsLessFunction} + */ +const isLess = (a, b) => (a[0] < b); + +/** + * A helper function for the keyframe sorting. + * @type {IsEqualFunction} + */ +const isEqual = (a, b) => (a[0] === b); + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/look_controller.js": +/*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/look_controller.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LookController": function() { return /* binding */ LookController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A camera controller that looks around the user with an optional axis. + */ +class LookController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The sensitivity for dragging. + * @type {number} + * @private + */ + this._dragSensitivity = 0.03; + + /** + * The smoothness of the dragging. Zero means no smoothness. + * @type {number} + * @private + */ + this._dragSmoothness = 0.8; + + /** + * The current value applied every frame to the yaw axis rotation. + * @type {number} + * @private + */ + this._yawAngleSmoothedValue = 0.0; + + /** + * The current value applied every frame to the pitch axis rotation. + * @type {number} + * @private + */ + this._pitchAngleSmoothedValue = 0.0; + + /** + * The axis around which to yaw. It can be 'none', 'x-axis', 'y-axis', 'z-axis', or 'position'. + * @type {string} + * @private + */ + this._yawAxisType = 'none'; + + /** + * The yaw axis reference entity. + * @type {Entity} + * @private + */ + this._yawAxisEntity = null; + + // Let the base controller know that this changes the orientation. + this.addModifiedState('orientation'); + } + + /** + * Gets the drag sensitivity. Defaults to 0.01. + * @returns {number} + */ + getDragSensitivity() { + return this._dragSensitivity; + } + + /** + * Sets the drag sensitivity. + * @param {number} dragSensitivity + */ + setDragSensitivity(dragSensitivity) { + this._dragSensitivity = dragSensitivity; + } + + /** + * Gets the drag smoothness. Defaults to 0.8. + * @returns {number} + */ + getDragSmoothness() { + return this._dragSmoothness; + } + + /** + * Sets the drag smoothness, between 0 and 1. + * @param {number} dragSmoothness + */ + setDragSmoothness(dragSmoothness) { + this._dragSmoothness = dragSmoothness; + } + + /** + * Gets the axis around which to yaw. + * @returns {string} + */ + getYawAxisType() { + return this._yawAxisType; + } + + /** + * Sets the axis around which to yaw. It can be 'none', 'x-axis', 'y-axis', 'z-axis', or 'position'. + * @param {string} yawAxisType + */ + setYawAxisType(yawAxisType) { + if (this._yawAxisType === yawAxisType) { + return; + } + if (this._yawAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._yawAxisType)) { + this.removeDependentState(this._yawAxisEntity.getName(), 'orientation'); + } + else if (this._yawAxisType === 'position') { + this.removeDependentState(this._yawAxisEntity.getName(), 'position'); + } + } + this._yawAxisType = yawAxisType; + if (this._yawAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._yawAxisType)) { + this.addDependentState(this._yawAxisEntity.getName(), 'orientation'); + } + else if (this._yawAxisType === 'position') { + this.addDependentState(this._yawAxisEntity.getName(), 'position'); + } + } + } + + /** + * Gets the yaw axis reference entity. Defaults to this entity's parent. + * @returns {Entity} + */ + getYawAxisEntity() { + return this._yawAxisEntity; + } + + /** + * Sets the yaw axis reference entity. + * @param {Entity} yawAxisEntity + */ + setYawAxisEntity(yawAxisEntity) { + if (this._yawAxisEntity === yawAxisEntity) { + return; + } + if (this._yawAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._yawAxisType)) { + this.removeDependentState(this._yawAxisEntity.getName(), 'orientation'); + } + else if (this._yawAxisType === 'position') { + this.removeDependentState(this._yawAxisEntity.getName(), 'position'); + } + } + this._yawAxisEntity = yawAxisEntity; + if (this._yawAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._yawAxisType)) { + this.addDependentState(this._yawAxisEntity.getName(), 'orientation'); + } + else if (this._yawAxisType === 'position') { + this.addDependentState(this._yawAxisEntity.getName(), 'position'); + } + } + } + + /** + * Updates the entity's position and orientation. + * @override + * @internal + */ + __update() { + // If the yaw axis entity is null, set it to the parent. + if (this._yawAxisEntity === null) { + this._yawAxisEntity = this.getEntity().getParent(); + if (this._yawAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._yawAxisType)) { + this.addDependentState(this._yawAxisEntity.getName(), 'orientation'); + } + else if (this._yawAxisType === 'position') { + this.addDependentState(this._yawAxisEntity.getName(), 'position'); + } + } + } + + // Set the position and orientation if they have never been set before. + if (this.getEntity().getOrientation().isNaN()) { + this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + + // Get the look multiplier for if 'x' is pressed. + const input = this.getEntity().getScene().getEngine().getInput(); + let lookMultiplier = 2; + if (input.isKeyPressed('x')) { + lookMultiplier = 0.05; + } + + // Factor in the field of view of the camera. + const camera = /** @type {CameraComponent} */(this.getEntity().getComponentByType('camera')); + if (camera !== null) { + lookMultiplier *= Math.min(1, camera.getFieldOfView()); + } + + // Get the yaw and pitch from input. + let yawAngle = 0; + let pitchAngle = 0; + const viewport = input.getActiveViewport(); + if (viewport !== null) { + const camera = viewport.getCamera(); + if (camera !== null && camera.getEntity() === this.getEntity()) { + // Add mouse movement. + const draggedOffset = input.getDraggedOffset(); + yawAngle = -cameraFreeFlyParameters.xAngleDv * this._dragSensitivity; + pitchAngle = -cameraFreeFlyParameters.yAngleDv * this._dragSensitivity; + } + } + + // Apply smoothing. + this._yawAngleSmoothedValue = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(yawAngle, this._yawAngleSmoothedValue, this._dragSmoothness); + this._pitchAngleSmoothedValue = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(pitchAngle, this._pitchAngleSmoothedValue, this._dragSmoothness); + if (Math.abs(this._yawAngleSmoothedValue) < 0.0001 * lookMultiplier) { + this._yawAngleSmoothedValue = 0; + } + if (Math.abs(this._pitchAngleSmoothedValue) < 0.0001 * lookMultiplier) { + this._pitchAngleSmoothedValue = 0; + } + + // Get the yaw axis. + const yawAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (this._yawAxisType === 'x-axis' && this._yawAxisEntity !== null) { // Use the x-axis of the reference entity. + this._yawAxisEntity.getOrientation().getAxis(yawAxis, 0); + } + else if (this._yawAxisType === 'y-axis' && this._yawAxisEntity !== null) { // Use the y-axis of the reference entity. + this._yawAxisEntity.getOrientation().getAxis(yawAxis, 1); + } + else if (this._yawAxisType === 'z-axis' && this._yawAxisEntity !== null) { // Use the z-axis of the reference entity. + this._yawAxisEntity.getOrientation().getAxis(yawAxis, 2); + } + else if (this._yawAxisType === 'position' && this._yawAxisEntity !== null) { // Use the position of the reference entity. + yawAxis.normalize(this._yawAxisEntity.getPosition()); + } + else { + this.getEntity().getOrientation().getAxis(yawAxis, 2); // Use the entity's z-axis. + } + + // If the yaw axis isn't ready, just work as if the yaw axis type is 'none'. + if (yawAxis.isNaN()) { + this.getEntity().getOrientation().getAxis(yawAxis, 2); + } + + // Get the current orientation. + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + orientation.copy(this.getEntity().getOrientation()); + + // Rotate the orientation so that its z-axis is upright. + const rotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const zAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const yAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.getEntity().getOrientation().getAxis(yAxis, 1); + this.getEntity().getOrientation().getAxis(zAxis, 2); + const angle = zAxis.angleAroundAxis(yawAxis, yAxis); + rotation.setFromAxisAngle(yAxis, angle); + rotation.normalize(rotation); + orientation.mult(rotation, orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(zAxis); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(yAxis); + + // Get the pitch axis. + const pitchAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + orientation.getAxis(pitchAxis, 0); + + // Rotate the target orientation by the pitch axis. + rotation.setFromAxisAngle(pitchAxis, this._pitchAngleSmoothedValue); + orientation.mult(rotation, orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(pitchAxis); + + // Rotate the target orientation by the yaw axis. + rotation.setFromAxisAngle(yawAxis, this._yawAngleSmoothedValue); + orientation.mult(rotation, orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(yawAxis); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation); + + // Set the current position. + this.getEntity().setOrientation(orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/model_animate_controller.js": +/*!***************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/model_animate_controller.js ***! + \***************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ModelAnimateController": function() { return /* binding */ ModelAnimateController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A controller animates using the model's keyframed animations. + */ +class ModelAnimateController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The animations. + * @type {Animation[]} + * @private + */ + this._animations = []; + } + + /** + * Sets the animation to be at the joint on the specified model. + * @param {ModelComponent} model - the model of the joint + * @param {string} jointName - the joint on which the animation will be played + * @param {string} animationName - the name of the animation + * @param {Interval} interval - the interval over which the animation will be played + */ + setAnimation(model, jointName, animationName, interval) { + if (model === null) { + throw new Error('Null model specified.'); + } + this._animations.push({ + model, + jointName, + animationName, + interval, + animationClip: null, + rootObject: null, + jointObject: null, + animationMixer: null + }); + } + + /** + * Updates the position and orientation from the keyframes. + * @override + * @internal + */ + __update() { + const time = this.getEntity().getScene().getEngine().getTime(); + + for (let i = 0, l = this._animations.length; i < l; i++) { + const animation = this._animations[i]; + // If the model component no longer exists, remove the animation. + if (animation.model.isDestroyed()) { + this._animations.splice(i, 1); + i--; + continue; + } + // If the Three.js object doesn't yet exist, it's still loading. + if (animation.model.getThreeJsObjects()[0] === null) { + animation.rootObject = null; + continue; + } + // If the model within the model component has been unloaded or reloaded, reset things. + if (animation.rootObject !== animation.model.getThreeJsObjects()[0]) { + animation.rootObject = animation.model.getThreeJsObjects()[0]; + animation.animationClip = null; + animation.jointObject = null; + animation.animationMixer = null; + } + // Get the animation clip if we don't yet have it. + if (animation.animationClip === null) { + animation.animationClip = animation.model.getAnimationClip(animation.animationName); + } + // Get the joint object if we don't yet have it. + if (animation.jointObject === null) { + const subObject = animation.model.getThreeJsObjectByName(animation.jointName); + if (subObject !== null) { + animation.jointObject = subObject; + } + } + // If we have both the animation clip and joint object, but not the mixer, create it. + if (animation.animationMixer === null && animation.animationClip !== null && animation.jointObject !== null) { + animation.animationMixer = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.AnimationMixer(animation.jointObject); + animation.animationMixer.clipAction(animation.animationClip).play(); + } + + if (animation.animationMixer !== null) { + const timeWithinAnimation = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time - animation.interval.min) / (animation.interval.max - animation.interval.min)); + const keyFrameTime = (animation.animationClip.duration * timeWithinAnimation) * (animation.animationClip.tracks[0].times.length - 1) / animation.animationClip.tracks[0].times.length; + animation.animationMixer.setTime(keyFrameTime); + animation.animationMixer.update(0); + } + } + } +} + +/** + * @typedef Animation + * @property {ModelComponent} model + * @property {string} jointName + * @property {string} animationName + * @property {Interval} interval + * @property {THREE.Object3D} rootObject + * @property {THREE.Object3D} jointObject + * @property {THREE.AnimationClip} animationClip + * @property {THREE.AnimationMixer } animationMixer + */ + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/orbit_controller.js": +/*!*******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/orbit_controller.js ***! + \*******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "OrbitController": function() { return /* binding */ OrbitController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * An orbit camera controller orbiting around a specific axis. + */ +class OrbitController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The sensitivity for dragging. + * @type {number} + * @private + */ + this._dragSensitivity = 0.01; + + /** + * The smoothness of the dragging. Zero means no smoothness. + * @type {number} + * @private + */ + this._dragSmoothness = 0.8; + + /** + * The current value applied every frame to the yaw axis rotation. + * @type {number} + * @private + */ + this._yawChangeSmoothedValue = 0.0; + + /** + * The current value applied every frame to the pitch axis rotation. + * @type {number} + * @private + */ + this._pitchChangeSmoothedValue = 0.0; + + /** + * The axis around which to yaw. It can be 'none', 'x-axis', 'y-axis', 'z-axis', or 'position'. + * @type {string} + * @private + */ + this._yawAxisType = 'none'; + + /** + * The yaw axis reference entity. + * @type {Entity} + * @private + */ + this._yawAxisEntity = null; + + /** + * The axis around which to pitch. It can be 'none', 'x-axis', 'y-axis', 'z-axis', or 'position'. + * @type {string} + * @private + */ + this._pitchAxisType = 'none'; + + /** + * The pitch axis reference entity. + * @type {Entity} + * @private + */ + this._pitchAxisEntity = null; + + /** + * When true, the entity will slow as it gets closer to its parent's occlusion radius. + * @type {boolean} + * @private + */ + this._slowWhenCloseToParent = false; + + /** + * The limits of the yaw angle. + * @type {Interval} + * @private + */ + this._yawAngleLimits = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); + this._yawAngleLimits.freeze(); + + /** + * The limits of the pitch angle. + * @type {Interval} + * @private + */ + this._pitchAngleLimits = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); + this._pitchAngleLimits.freeze(); + + // Let the base controller know that this changes the position and orientation. + this.addModifiedState('position'); + this.addModifiedState('orientation'); + } + + /** + * Gets the drag sensitivity. Defaults to 0.01. + * @returns {number} + */ + getDragSensitivity() { + return this._dragSensitivity; + } + + /** + * Sets the drag sensitivity. + * @param {number} dragSensitivity + */ + setDragSensitivity(dragSensitivity) { + this._dragSensitivity = dragSensitivity; + } + + /** + * Gets the drag smoothness. Defaults to 0.8. + * @returns {number} + */ + getDragSmoothness() { + return this._dragSmoothness; + } + + /** + * Sets the drag smoothness, between 0 and 1. + * @param {number} dragSmoothness + */ + setDragSmoothness(dragSmoothness) { + this._dragSmoothness = dragSmoothness; + } + + /** + * Gets the axis around which to yaw. It defaults to 'none'. + * @returns {string} + */ + getYawAxisType() { + return this._yawAxisType; + } + + /** + * Sets the axis around which to yaw. It can be 'none', 'x-axis', 'y-axis', 'z-axis', or 'position'. + * @param {string} yawAxisType + */ + setYawAxisType(yawAxisType) { + if (this._yawAxisType === yawAxisType) { + return; + } + if (this._yawAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._yawAxisType)) { + this.removeDependentState(this._yawAxisEntity.getName(), 'orientation'); + } + else if (this._yawAxisType === 'position') { + this.removeDependentState(this._yawAxisEntity.getName(), 'position'); + } + } + this._yawAxisType = yawAxisType; + if (this._yawAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._yawAxisType)) { + this.addDependentState(this._yawAxisEntity.getName(), 'orientation'); + } + else if (this._yawAxisType === 'position') { + this.addDependentState(this._yawAxisEntity.getName(), 'position'); + } + } + } + + /** + * Gets the axis around which to pitch. It defaults to 'none'. + * @returns {string} + */ + getPitchAxisType() { + return this._pitchAxisType; + } + + /** + * Sets the axis around which to pitch. It can be 'none', 'x-axis', 'y-axis', 'z-axis', or 'position'. + * @param {string} pitchAxisType + */ + setPitchAxisType(pitchAxisType) { + if (this._pitchAxisType === pitchAxisType) { + return; + } + if (this._pitchAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._pitchAxisType)) { + this.removeDependentState(this._pitchAxisEntity.getName(), 'orientation'); + } + else if (this._pitchAxisType === 'position') { + this.removeDependentState(this._pitchAxisEntity.getName(), 'position'); + } + } + this._pitchAxisType = pitchAxisType; + if (this._pitchAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._pitchAxisType)) { + this.addDependentState(this._pitchAxisEntity.getName(), 'orientation'); + } + else if (this._pitchAxisType === 'position') { + this.addDependentState(this._pitchAxisEntity.getName(), 'position'); + } + } + } + + /** + * Gets the yaw axis reference entity. Defaults to this entity's parent. + * @returns {Entity} + */ + getYawAxisEntity() { + return this._yawAxisEntity; + } + + /** + * Sets the yaw axis reference entity. + * @param {Entity} yawAxisEntity + */ + setYawAxisEntity(yawAxisEntity) { + if (this._yawAxisEntity === yawAxisEntity) { + return; + } + if (this._yawAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._yawAxisType)) { + this.removeDependentState(this._yawAxisEntity.getName(), 'orientation'); + } + else if (this._yawAxisType === 'position') { + this.removeDependentState(this._yawAxisEntity.getName(), 'position'); + } + } + this._yawAxisEntity = yawAxisEntity; + if (this._yawAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._yawAxisType)) { + this.addDependentState(this._yawAxisEntity.getName(), 'orientation'); + } + else if (this._yawAxisType === 'position') { + this.addDependentState(this._yawAxisEntity.getName(), 'position'); + } + } + } + + /** + * Gets the pitch axis reference entity. Defaults to this entity's parent. + * @returns {Entity} + */ + getPitchAxisEntity() { + return this._pitchAxisEntity; + } + + /** + * Sets the pitch axis reference entity. + * @param {Entity} pitchAxisEntity + */ + setPitchAxisEntity(pitchAxisEntity) { + if (this._pitchAxisEntity === pitchAxisEntity) { + return; + } + if (this._pitchAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._pitchAxisType)) { + this.removeDependentState(this._pitchAxisEntity.getName(), 'orientation'); + } + else if (this._pitchAxisType === 'position') { + this.removeDependentState(this._pitchAxisEntity.getName(), 'position'); + } + } + this._pitchAxisEntity = pitchAxisEntity; + if (this._pitchAxisEntity !== null) { + if (['x-axis', 'y-axis', 'z-axis'].includes(this._pitchAxisType)) { + this.addDependentState(this._pitchAxisEntity.getName(), 'orientation'); + } + else if (this._pitchAxisType === 'position') { + this.addDependentState(this._pitchAxisEntity.getName(), 'position'); + } + } + } + + /** + * Gets the limits of the yaw angle. + * @returns {Interval} + */ + getYawAngleLimits() { + return this._yawAngleLimits; + } + + /** + * Sets the limits of the yaw angle. + * @param {Interval} yawAngleLimits + */ + setYawAngleLimits(yawAngleLimits) { + this._yawAngleLimits.thaw(); + this._yawAngleLimits.copy(yawAngleLimits); + this._yawAngleLimits.freeze(); + } + + /** + * Gets the limits of the pitch angle. + * @returns {Interval} + */ + getPitchAngleLimits() { + return this._pitchAngleLimits; + } + + /** + * Sets the limits of the pitch angle. + * @param {Interval} pitchAngleLimits + */ + setPitchAngleLimits(pitchAngleLimits) { + this._pitchAngleLimits.thaw(); + this._pitchAngleLimits.copy(pitchAngleLimits); + this._pitchAngleLimits.freeze(); + } + + /** + * Returns whether the entity will slow as it gets closer to its parent's occlusion radius. + * @returns {boolean} + */ + isSlowWhenCloseToParent() { + return this._slowWhenCloseToParent; + } + + /** + * Sets whether the entity will slow as it gets closer to its parent's occlusion radius. + * @param {boolean} enabled + */ + slowWhenCloseToParent(enabled) { + this._slowWhenCloseToParent = enabled; + } + + /** + * Updates the entity's position and orientation. + * @override + * @internal + */ + __update() { + // There is no pivot, so don't do anything. + if (this.getEntity().getParent() === null) { + return; + } + + // Set the position and orientation if they have never been set before. + if (this.getEntity().getOrientation().isNaN()) { + this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + if (this.getEntity().getPosition().isNaN()) { + this.getEntity().setPosition(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, -1, 0)); + } + + // Get the orbit multiplier for if 'x' or 'shift' is pressed. + const input = this.getEntity().getScene().getEngine().getInput(); + let orbitMultiplier = 1; + if (input.isKeyPressed('x')) { + orbitMultiplier = 0.05; + } + if (input.isShiftPressed()) { + orbitMultiplier = 5; + } + // Factor in the field of view of the camera. + const camera = /** @type {CameraComponent} */(this.getEntity().getComponentByType('camera')); + if (camera !== null) { + orbitMultiplier *= Math.min(1, camera.getFieldOfView()); + } + + // Get the azimuth and elevation change from the input. + let yawChange = 0; + let pitchChange = 0; + const viewport = input.getActiveViewport(); + if (viewport !== null) { + const camera = viewport.getCamera(); + if (camera !== null && camera.getEntity() === this.getEntity()) { + // Add mouse/touch movement. + const draggedOffset = input.getDraggedOffset(); + yawChange = -draggedOffset.x * this._dragSensitivity * orbitMultiplier; + pitchChange = draggedOffset.y * this._dragSensitivity * orbitMultiplier; + + // Add key movement. + if (input.isKeyPressed('d')) { + yawChange += this._dragSensitivity * orbitMultiplier; + } + if (input.isKeyPressed('a')) { + yawChange -= this._dragSensitivity * orbitMultiplier; + } + if (input.isKeyPressed('e')) { + pitchChange -= this._dragSensitivity * orbitMultiplier; + } + if (input.isKeyPressed('q')) { + pitchChange += this._dragSensitivity * orbitMultiplier; + } + yawChange += this._dragSensitivity * orbitMultiplier * cameraOrbitParameters.yaw; + pitchChange += this._dragSensitivity * orbitMultiplier * cameraOrbitParameters.pitch; + } + } + + // Apply smoothing. + this._yawChangeSmoothedValue = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(yawChange, this._yawChangeSmoothedValue, this._dragSmoothness); + this._pitchChangeSmoothedValue = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(pitchChange, this._pitchChangeSmoothedValue, this._dragSmoothness); + if (Math.abs(this._yawChangeSmoothedValue) < 0.0001 * orbitMultiplier) { + this._yawChangeSmoothedValue = 0; + } + if (Math.abs(this._pitchChangeSmoothedValue) < 0.0001 * orbitMultiplier) { + this._pitchChangeSmoothedValue = 0; + } + + // Get the yaw axis. + const yawAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + // If the yaw axis entity is null, set it to the parent. + if (this._yawAxisEntity === null) { + this._yawAxisEntity = this.getEntity().getParent(); + } + if (this._yawAxisType === 'x-axis' && this._yawAxisEntity !== null) { // Use the x-axis of the reference entity. + this._yawAxisEntity.getOrientation().getAxis(yawAxis, 0); + } + else if (this._yawAxisType === 'y-axis' && this._yawAxisEntity !== null) { // Use the y-axis of the reference entity. + this._yawAxisEntity.getOrientation().getAxis(yawAxis, 1); + } + else if (this._yawAxisType === 'z-axis' && this._yawAxisEntity !== null) { // Use the z-axis of the reference entity. + this._yawAxisEntity.getOrientation().getAxis(yawAxis, 2); + } + else if (this._yawAxisType === 'position' && this._yawAxisEntity !== null) { // Use the position of the reference entity. + yawAxis.normalize(this._yawAxisEntity.getPosition()); + } + else { + this.getEntity().getOrientation().getAxis(yawAxis, 2); // Use the entity's z-axis. + } + + // If the yaw axis isn't ready, just work as if the yaw axis type is 'none'. + if (yawAxis.isNaN() || yawAxis.isZero()) { + this.getEntity().getOrientation().getAxis(yawAxis, 2); + } + + // Get the pitch axis. + const pitchAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + // If the pitch axis entity is null, set it to the parent. + if (this._pitchAxisEntity === null) { + this._pitchAxisEntity = this.getEntity().getParent(); + } + if (this._pitchAxisType === 'x-axis' && this._pitchAxisEntity !== null) { // Use the x-axis of the reference entity. + this._pitchAxisEntity.getOrientation().getAxis(pitchAxis, 0); + } + else if (this._pitchAxisType === 'y-axis' && this._pitchAxisEntity !== null) { // Use the y-axis of the reference entity. + this._pitchAxisEntity.getOrientation().getAxis(pitchAxis, 1); + } + else if (this._pitchAxisType === 'z-axis' && this._pitchAxisEntity !== null) { // Use the z-axis of the reference entity. + this._pitchAxisEntity.getOrientation().getAxis(pitchAxis, 2); + } + else if (this._pitchAxisType === 'position' && this._pitchAxisEntity !== null) { // Use the position of the reference entity. + pitchAxis.normalize(this._pitchAxisEntity.getPosition()); + } + else { + this.getEntity().getOrientation().getAxis(pitchAxis, 0); // Use the entity's x-axis. + } + + // If the pitch axis isn't ready, just work as if the pitch axis type is 'none'. + if (pitchAxis.isNaN() || pitchAxis.isZero()) { + this.getEntity().getOrientation().getAxis(pitchAxis, 0); + } + + // Make the pitch axis orthonormal to the yaw axis. + pitchAxis.setNormalTo(yawAxis, pitchAxis); + + // Get the axes as a quaternion frame. + const axisFrame = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + axisFrame.setFromAxes(pitchAxis, undefined, yawAxis); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(pitchAxis); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(yawAxis); + + // Get the current position angles relative to the axes. + const position = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + position.rotateInverse(axisFrame, this.getEntity().getPosition()); + + // Calculate the slow factor. + let slowFactor = 1.0; + if (this._slowWhenCloseToParent) { + const radius = this.getEntity().getParent().getOcclusionRadius(); + slowFactor = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp((position.magnitude() - radius) / radius, 0.001, 1.0); + } + + // Add in the pitch and yaw changes. + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLLAFromXYZOnSphere(lla, position, 0); + lla.lat += this._pitchChangeSmoothedValue * slowFactor; + lla.lon += this._yawChangeSmoothedValue * slowFactor; + + // Set upper limits for pitch so that it doesn't go beyond the yaw axis. + if (lla.lat < 0.0001 - _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi) { + lla.lat = 0.0001 - _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi; + } + if (lla.lat > _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi - 0.0001) { + lla.lat = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi - 0.0001; + } + + // Apply pitch and yaw limits. + if (lla.lat < this._pitchAngleLimits.min) { + lla.lat = this._pitchAngleLimits.min; + } + if (lla.lat > this._pitchAngleLimits.max) { + lla.lat = this._pitchAngleLimits.max; + } + if (lla.lon < this._yawAngleLimits.min) { + lla.lon = this._yawAngleLimits.min; + } + if (lla.lon > this._yawAngleLimits.max) { + lla.lon = this._yawAngleLimits.max; + } + + // Set the position from the new LLA and clean up. + _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getXYZFromLLAOnSphere(position, lla, 0); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + position.rotate(axisFrame, position); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(axisFrame); + this.getEntity().setPosition(position); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/orbit_keyframe_controller.js": +/*!****************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/orbit_keyframe_controller.js ***! + \****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "OrbitKeyframeController": function() { return /* binding */ OrbitKeyframeController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +class OrbitKeyframeController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The positions that this entity will be in. + * @type {PositionKeyframe[]} + * @private + */ + this._positionKeyframes = []; + + /** + * The entities that will be focused on by the camera. + * @type {FocusKeyframe[]} + * @private + */ + this._focusKeyframes = []; + + /** + * The up directions that this entity will orient to. + * @type {UpKeyframe[]} + * @private + */ + this._upKeyframes = []; + + /** + * The time of the first update. + * @type {number} + * @private + */ + this._timeOfFirstUpdate = NaN; + + /** + * The direction of the first update. + * @type {Vector3} + * @private + */ + this._directionOfFirstUpdate = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + /** + * The resolve function that will be called when the keyframes complete. + * @type {function():void} + * @private + */ + this._resolvePromise = null; + + /** + * The reject function that will be called if the keyframes fail to complete. + * @type {function():void} + * @private + */ + this._rejectPromise = null; + + /** + * The promise that resolves or rejects at the end of the keyframes. + * @type {Promise} + * @private + */ + this._endPromise = new Promise((resolve, reject) => { + this._resolvePromise = resolve; + this._rejectPromise = reject; + }); + + this.addModifiedState('position'); + this.addModifiedState('velocity'); + this.addModifiedState('orientation'); + this.addModifiedState('angularVelocity'); + } + + /** + * Sets a position keyframe. Use undefined to remove the keyframe. + * @param {number} time + * @param {Vector3 | undefined} position + * @param {string} relativeToEntity + */ + setPositionKeyframe(time, position, relativeToEntity) { + if (position !== undefined) { + const keyframe = new PositionKeyframe(this.getEntity().getScene()); + keyframe.time = time; + keyframe.position.copy(position); + keyframe.relativeTo.setName(relativeToEntity); + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(keyframe, this._positionKeyframes, isLess); + } + else { + const index = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._positionKeyframes, isLessThanTime); + if (index < this._positionKeyframes.length && time === this._positionKeyframes[index].time) { + this._positionKeyframes.splice(index, 1); + } + } + } + + /** + * Sets a focus keyframe. Use undefined to remove the keyframe. + * @param {number} time + * @param {string | undefined} focus + */ + setFocusKeyframe(time, focus) { + if (focus !== undefined) { + const keyframe = new FocusKeyframe(this.getEntity().getScene()); + keyframe.time = time; + keyframe.focus.setName(focus); + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(keyframe, this._focusKeyframes, isLess); + } + else { + const index = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._focusKeyframes, isLessThanTime); + if (index < this._focusKeyframes.length && time === this._focusKeyframes[index].time) { + this._focusKeyframes.splice(index, 1); + } + } + } + + /** + * Sets a position keyframe. Use undefined to remove the keyframe. + * @param {number} time + * @param {Vector3 | undefined} up + */ + setUpKeyframe(time, up) { + if (up !== undefined) { + const keyframe = new UpKeyframe(); + keyframe.time = time; + keyframe.up.copy(up); + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(keyframe, this._upKeyframes, isLess); + } + else { + const index = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._upKeyframes, isLessThanTime); + if (index < this._upKeyframes.length && time === this._upKeyframes[index].time) { + this._upKeyframes.splice(index, 1); + } + } + } + + /** + * Gets the promise that resolves at the end of the keyframes. + * @returns {Promise} + */ + getEndPromise() { + return this._endPromise; + } + + /** + * Destroys the controller. + * @override + * @internal + */ + __destroy() { + super.__destroy(); + + if (this._rejectPromise !== null) { + this._rejectPromise(); + } + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + // Get the entity, since it is used a lot. + const entity = this.getEntity(); + + // Get the time since the start. + let time = 0; + if (isNaN(this._timeOfFirstUpdate)) { + // Get the parent. + const parent = entity.getParent(); + if (parent === null) { + return; + } + + // Set the time and direction of the first update to now the y-axis of the entity, respectively. + this._timeOfFirstUpdate = Date.now() / 1000; + entity.getOrientation().getAxis(this._directionOfFirstUpdate, 1); + + // Add an initial position keyframe. + const positionKeyframe = new PositionKeyframe(entity.getScene()); + positionKeyframe.time = 0; + positionKeyframe.position.copy(entity.getPosition()); + positionKeyframe.relativeTo.setName(parent.getName()); + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(positionKeyframe, this._positionKeyframes, isLess); + + // Add an initial focus keyframe. The '' focus means use the first frame's direction (set above). + const keyframe = new FocusKeyframe(entity.getScene()); + keyframe.time = 0; + keyframe.focus.setName(''); + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(keyframe, this._focusKeyframes, isLess); + + // Add an initial up keyframe. + const upKeyframe = new UpKeyframe(); + upKeyframe.time = 0; + entity.getOrientation().getAxis(upKeyframe.up, 2); + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(upKeyframe, this._upKeyframes, isLess); + } + else { + time = Date.now() / 1000 - this._timeOfFirstUpdate; + } + + // Apply the position keyframes. + let doneWithPositionKeyframes = false; + const positionKeyframeIndex = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._positionKeyframes, isLessThanTime); + if (positionKeyframeIndex > 0 && positionKeyframeIndex < this._positionKeyframes.length) { + // Get the keyframes. + const keyframe0 = this._positionKeyframes[positionKeyframeIndex - 1]; + const keyframe1 = this._positionKeyframes[positionKeyframeIndex]; + + // Get the relative-to entities for the corresponding names. + const relativeToEntity0 = keyframe0.relativeTo.get(); + const relativeToEntity1 = keyframe1.relativeTo.get(); + if (relativeToEntity0 !== null && relativeToEntity1 !== null) { + // Get the lerp value. + let u = (time - keyframe0.time) / (keyframe1.time - keyframe0.time); + + // Update the parent entity depending on if we're in the first or second half. + let parentEntity = relativeToEntity0; + if (u >= 0.5) { + parentEntity = relativeToEntity1; + } + if (entity.getParent() !== parentEntity) { + entity.setParent(parentEntity); + } + + // Get the positions relative to the appropriate entity. + const position0 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const position1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + relativeToEntity0.getPositionRelativeToEntity(position0, keyframe0.position, relativeToEntity1); + relativeToEntity1.getPositionRelativeToEntity(position1, keyframe1.position, relativeToEntity0); + + // Get the u lerp value scaled so that is exponential, relating to the radius of the current parent. + let dist00 = Math.max(0, keyframe0.position.magnitude() - relativeToEntity0.getOcclusionRadius()); + let dist10 = Math.max(0, position1.magnitude() - relativeToEntity0.getOcclusionRadius()); + let dist01 = Math.max(0, position0.magnitude() - relativeToEntity1.getOcclusionRadius()); + let dist11 = Math.max(0, keyframe1.position.magnitude() - relativeToEntity1.getOcclusionRadius()); + dist00 = Math.max(dist00, dist10 / 10000); // Make sure they aren't too far different. + dist10 = Math.max(dist10, dist00 / 10000); // Otherwise the smaller distance starts out + dist01 = Math.max(dist01, dist11 / 10000); // way to slow. + dist11 = Math.max(dist11, dist10 / 10000); + if (dist00 !== dist10 && dist01 !== dist11) { + const u0 = (Math.pow(dist10, u) * Math.pow(dist00, 1 - u) - dist00) / (dist10 - dist00); + const u1 = (Math.pow(dist11, u) * Math.pow(dist01, 1 - u) - dist01) / (dist11 - dist01); + u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(u0, u1, u); + } + + // Adjust the lerp value to ease-in-out. + const sq = u * u; + u = sq / (2 * (sq - u) + 1); + + // Get the positions relative to the current parent. + relativeToEntity0.getPositionRelativeToEntity(position0, keyframe0.position, parentEntity); + relativeToEntity1.getPositionRelativeToEntity(position1, keyframe1.position, parentEntity); + + // Set the position. + const newPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (relativeToEntity0 === relativeToEntity1) { + newPosition.slerp(position0, position1, u); + } + else { + newPosition.lerp(position0, position1, u); + } + entity.setPosition(newPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position0); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position1); + } + } + // Flag that we're done with position keyframes. + else if (positionKeyframeIndex === this._positionKeyframes.length) { + // Get the last keyframe. + const keyframe = this._positionKeyframes[this._positionKeyframes.length - 1]; + + // Get the focus entity. + const relativeToEntity = keyframe.relativeTo.get(); + + // Update the parent entity depending on if we're in the first or second half. + if (entity.getParent() !== relativeToEntity) { + entity.setParent(relativeToEntity); + } + + // Set the position. + entity.setPosition(keyframe.position); + + // Flag that we're done with position keyframes. + doneWithPositionKeyframes = true; + } + + // Set the forward vector by default to the current parent. + const forward = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + forward.setMagnitude(entity.getPosition(), -1); + + // Set the up vector by default to the current up. + const up = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + entity.getOrientation().getAxis(up, 2); + + // Apply the focus keyframes. Apply the result to the forward vector if valid. + let doneWithFocusKeyframes = false; + const focusKeyframeIndex = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._focusKeyframes, isLessThanTime); + if (focusKeyframeIndex > 0 && focusKeyframeIndex < this._focusKeyframes.length) { + // Get the keyframes. + const keyframe0 = this._focusKeyframes[focusKeyframeIndex - 1]; + const keyframe1 = this._focusKeyframes[focusKeyframeIndex]; + + // Get the focus entities for the corresponding names. + const focusEntity0 = keyframe0.focus.get(); + const focusEntity1 = keyframe1.focus.get(); + const parentEntity = entity.getParent(); + + if ((keyframe0.focus.getName() === '' || focusEntity0 !== null) + && (keyframe1.focus.getName() === '' || focusEntity1 !== null) + && parentEntity !== null) { + // Get the u lerp value. + let u = (time - keyframe0.time) / (keyframe1.time - keyframe0.time); + + // Adjust the lerp value to ease-in-out. + const sq = u * u; + u = sq / (2 * (sq - u) + 1); + + // Get the two focus directions. + const direction0 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const direction1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (keyframe0.focus.getName() !== '') { + parentEntity.getPositionRelativeToEntity(direction0, entity.getPosition(), focusEntity0); + direction0.setMagnitude(direction0, -1); + } + else { + direction0.copy(this._directionOfFirstUpdate); + } + if (keyframe1.focus.getName() !== '') { + parentEntity.getPositionRelativeToEntity(direction1, entity.getPosition(), focusEntity1); + direction1.setMagnitude(direction1, -1); + } + else { + direction1.copy(this._directionOfFirstUpdate); + } + forward.slerp(direction0, direction1, u); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(direction0); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(direction1); + } + } + else if (focusKeyframeIndex === this._focusKeyframes.length) { + // Get the last keyframe. + const keyframe = this._focusKeyframes[this._focusKeyframes.length - 1]; + + // Get the focus entity. + const focusEntity = keyframe.focus.get(); + const parentEntity = entity.getParent(); + + // Set the forward vector. + if ((keyframe.focus.getName() === '' || focusEntity !== null) && parentEntity !== null) { + parentEntity.getPositionRelativeToEntity(forward, entity.getPosition(), focusEntity); + forward.setMagnitude(forward, -1); + } + + // Flag that we're done with focus keyframes. + doneWithFocusKeyframes = true; + } + else { + // Get te first keyframe. + const keyframe = this._focusKeyframes[0]; + + // Get the focus entity. + const focusEntity = keyframe.focus.get(); + const parentEntity = entity.getParent(); + + // Set the forward vector. + if ((keyframe.focus.getName() === '' || focusEntity !== null) && parentEntity !== null) { + if (keyframe.focus.getName() !== '') { + parentEntity.getPositionRelativeToEntity(forward, entity.getPosition(), focusEntity); + forward.setMagnitude(forward, -1); + } + else { + forward.copy(this._directionOfFirstUpdate); + } + } + } + + // Apply the focus keyframes. Apply the result to the forward vector if valid. + let doneWithUpKeyframes = false; + const upKeyframeIndex = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._upKeyframes, isLessThanTime); + if (upKeyframeIndex > 0 && upKeyframeIndex < this._upKeyframes.length) { + // Get the keyframes. + const keyframe0 = this._upKeyframes[upKeyframeIndex - 1]; + const keyframe1 = this._upKeyframes[upKeyframeIndex]; + + // Get the u lerp value. + let u = (time - keyframe0.time) / (keyframe1.time - keyframe0.time); + + // Adjust the lerp value to ease-in-out. + const sq = u * u; + u = sq / (2 * (sq - u) + 1); + + // Get the two up directions. + up.slerp(keyframe0.up, keyframe1.up, u); + } + else if (upKeyframeIndex === this._upKeyframes.length) { + // Get the last keyframe. + const keyframe = this._upKeyframes[this._upKeyframes.length - 1]; + + // Set the up vector. + up.copy(keyframe.up); + + // Flag that we're done with up keyframes. + doneWithUpKeyframes = true; + } + + // Set the orientation from the forward and up vectors. + const newOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + up.setNormalTo(forward, up); + newOrientation.setFromAxes(undefined, forward, up); + entity.setOrientation(newOrientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(forward); + + // If done with all of the keyframes, call the end promise. + if (doneWithPositionKeyframes && doneWithFocusKeyframes && doneWithUpKeyframes) { + this._rejectPromise = null; + this._resolvePromise(); + } + } +} + +class Keyframe { + constructor() { + /** + * The time for the keyframe. + * @type {number} + */ + this.time = NaN; + } +} + +/** + * A position keyframe. + */ +class PositionKeyframe extends Keyframe { + /** @param {Scene} scene */ + constructor(scene) { + super(); + + /** + * The position for the keyframe. + * @type {Vector3} + */ + this.position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + /** + * The reference to the relative-to entity. + * @type {EntityRef} + */ + this.relativeTo = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(scene); + } +} + +/** + * A focus keyframe. + */ +class FocusKeyframe extends Keyframe { + /** @param {Scene} scene */ + constructor(scene) { + super(); + + /** + * The reference to the focus entity. + * @type {EntityRef} + */ + this.focus = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(scene); + } +} + +/** + * An up keyframe. + */ +class UpKeyframe extends Keyframe { + constructor() { + super(); + + /** + * The up for the keyframe. + * @type {Vector3} + */ + this.up = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + } +} + +/** + * A helper function for the keyframe sorting. + * @param {Keyframe} a + * @param {Keyframe} b + */ +function isLess(a, b) { + return a.time < b.time; +} + +/** + * A helper function for the keyframe sorting. + * @param {Keyframe} a + * @param {number} time + */ +function isLessThanTime(a, time) { + return a.time < time; +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/orbital_elements_controller.js": +/*!******************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/orbital_elements_controller.js ***! + \******************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "OrbitalElementsController": function() { return /* binding */ OrbitalElementsController; }, +/* harmony export */ "OrbitalElementsKeyFrame": function() { return /* binding */ OrbitalElementsKeyFrame; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A controller animates the position and orientation of an entity via orbital elements. + */ +class OrbitalElementsController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The position keyframes. + * @type {OrbitalElementsKeyFrame[]} + * @private + */ + this._orbitalElementsKeyFrames = []; + + // Set the coverage to nothing, since there are no orbital elements. + this.setCoverage(new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY)); + + // Modifies the position. + this.addModifiedState('position'); + this.addModifiedState('velocity'); + } + + /** + * Gets the number of orbital elements. + * @returns {number} + */ + getNumOrbitalElements() { + return this._orbitalElementsKeyFrames.length; + } + + /** + * Gets an orbital element at the index. + * @param {number} index + * @returns {OrbitalElementsKeyFrame} + */ + getOrbitalElements(index) { + return this._orbitalElementsKeyFrames[index]; + } + + /** + * Adds an orbital element. + * @param {number} time + * @param {OrbitalElements} orbitalElements + */ + addOrbitalElements(time, orbitalElements) { + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add({ time: time, oe: orbitalElements }, this._orbitalElementsKeyFrames, isLessAdd, isEqualAdd); + this._updateCoverage(); + } + + /** + * Removes an orbital element at the index. + * @param {number} index + */ + removeOrbitalElements(index) { + if (index < 0 || this._orbitalElementsKeyFrames.length <= index) { + throw new Error(`Invalid index for ${this}.removeOrbitalElements`); + } + this._orbitalElementsKeyFrames.splice(index, 1); + this._updateCoverage(); + } + + /** + * Sets the position to the keyframed position at the given time. + * @param {Vector3} position + * @param {number} time + * @override + * @internal + */ + __updatePositionAtTime(position, time) { + this._getPositionAtTime(position, time); + } + + /** + * Sets the velocity to the keyframed velocity at the given time. + * @param {Vector3} velocity + * @param {number} time + * @override + * @internal + */ + __updateVelocityAtTime(velocity, time) { + this._getVelocityAtTime(velocity, time); + } + + /** + * Updates the position and orientation from the keyframes. + * @override + * @internal + */ + __update() { + const engine = this.getEntity().getScene().getEngine(); + const time = engine.getTime(); + if (this._getPositionAtTime(_tempPosition, time)) { + this.getEntity().setPosition(_tempPosition); + } + if (this._getVelocityAtTime(_tempVelocity, time)) { + this.getEntity().setVelocity(_tempVelocity); + } + } + + /** + * Sets outPosition to the position at the given time. Returns true if they were set. + * @param {Vector3} outPosition + * @param {number} time + * @returns {boolean} + * @private + */ + _getPositionAtTime(outPosition, time) { + const index = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._orbitalElementsKeyFrames, isLess); + const keyFrame0 = this._orbitalElementsKeyFrames[Math.max(index - 1, 0)]; + const keyFrame1 = this._orbitalElementsKeyFrames[Math.min(index, this._orbitalElementsKeyFrames.length - 1)]; + const position0 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const position1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + keyFrame0.oe.project(position0, _tempVelocity, time); + keyFrame1.oe.project(position1, _tempVelocity, time); + const u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(keyFrame1.time !== keyFrame0.time ? ((time - keyFrame0.time) / (keyFrame1.time - keyFrame0.time)) : 0); + outPosition.slerp(position0, position1, u); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position0); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position1); + return true; + } + + /** + * Sets outVelocity to the velocity at the given time. Returns true if they were set. + * @param {Vector3} outVelocity + * @param {number} time + * @returns {boolean} + * @private + */ + _getVelocityAtTime(outVelocity, time) { + const index = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._orbitalElementsKeyFrames, isLess); + const keyFrame0 = this._orbitalElementsKeyFrames[Math.max(index - 1, 0)]; + const keyFrame1 = this._orbitalElementsKeyFrames[Math.min(index, this._orbitalElementsKeyFrames.length - 1)]; + const velocity0 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const velocity1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + keyFrame0.oe.project(_tempPosition, velocity0, time); + keyFrame1.oe.project(_tempPosition, velocity1, time); + const u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(keyFrame1.time !== keyFrame0.time ? ((time - keyFrame0.time) / (keyFrame1.time - keyFrame0.time)) : 0); + outVelocity.slerp(velocity0, velocity1, u); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(velocity0); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(velocity1); + return true; + } + + /** + * Updates the coverage. + * @private + */ + _updateCoverage() { + const coverage = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY); + if (this._orbitalElementsKeyFrames.length > 1) { + coverage.min = Math.min(coverage.min, this._orbitalElementsKeyFrames[0].time); + coverage.max = Math.max(coverage.max, this._orbitalElementsKeyFrames[this._orbitalElementsKeyFrames.length - 1].time); + } + this.setCoverage(coverage); + } +} + +/** + * Orbital elements key frame as a time-orbital elements pair. + */ +class OrbitalElementsKeyFrame { + constructor() { + /** + * The time for the key frame. + * @type {number} + */ + this.time = 0; + + /** + * The orbital elements. + * @type {OrbitalElements} + */ + this.oe = new _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements(); + } +}; + +/** + * @callback CompareAdd + * @param {OrbitalElementsKeyFrame} a + * @param {OrbitalElementsKeyFrame} b + * @returns {boolean} + */ + +/** + * @callback Compare + * @param {OrbitalElementsKeyFrame} a + * @param {number} b + * @returns {boolean} + */ + +/** + * A helper function for sorting. + * @type {CompareAdd} + */ +const isLessAdd = (a, b) => (a.time < b.time); + +/** + * A helper function for sorting. + * @type {Compare} + */ +const isLess = (a, time) => (a.time < time); + +/** + * A helper function for sorting. + * @type {CompareAdd} + */ +const isEqualAdd = (a, b) => (a.time === b.time); + +/** + * Helper vector for calculations. + * @type {Vector3} + */ +const _tempPosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + +/** + * Helper vector for calculations. + * @type {Vector3} + */ +const _tempVelocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/pick_controller.js": +/*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/pick_controller.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "PickController": function() { return /* binding */ PickController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A pick controller. It lets the user pick a location on a given entity. + */ +class PickController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The entity to be picked. + * @type {Entity} + * @private + */ + this._pickedEntity = null; + + /** + * The callback to be called when the user picks a location on the entity. + * @type {(position: Vector3) => void} + * @private + */ + this._callback = null; + + /** + * @type {boolean} + * @private + */ + this._triggerOnHover = false; + + /** + * @type {Vector3} + * @private + */ + this._pickedPosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._pickedPosition.freeze(); + } + + /** + * Gets the entity to be picked. + * @returns {Entity} + */ + getPickedEntity() { + return this._pickedEntity; + } + + /** + * Sets the entity to be picked. + * @param {Entity} entity + */ + setPickedEntity(entity) { + this._pickedEntity = entity; + } + + /** + * Returns the callback to be called when the user picks a position on the entity. The position is in the entity-frame of the picked entity. + * @returns {(position: Vector3) => void} + */ + getCallback() { + return this._callback; + } + + /** + * Sets the callback to be called when the user picks a position on the entity. The position is in the entity-frame of the picked entity. + * @param {(position: Vector3) => void} callback + */ + setCallback(callback) { + this._callback = callback; + } + + /** + * Gets whether the callback is triggered when hovering or just selecting. + * @returns {boolean} + */ + getTriggerOnHover() { + return this._triggerOnHover; + } + + /** + * Sets whether the callback is triggered when hovering or just selecting. + * @param {boolean} triggerOnHover + */ + setTriggerOnHover(triggerOnHover) { + this._triggerOnHover = triggerOnHover; + } + + /** + * Gets the last picked position. The position is in the entity-frame of the picked entity. + * @returns {Vector3} + */ + getPickedPosition() { + return this._pickedPosition; + } + + /** + * Takes input and calls the callback if there is any selection. + * @override + * @internal + */ + __update() { + const input = this.getEntity().getScene().getEngine().getInput(); + + if ((input.isSelected() || this._triggerOnHover) && this._callback !== null && this._pickedEntity !== null) { + const viewport = input.getActiveViewport(); + if (viewport !== null) { + const camera = viewport.getCamera(); + if (camera !== null && camera.getEntity() === this.getEntity()) { + const pickedPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + // Get the picked position in normal space. + viewport.getNormalSpacePositionFromPixelSpacePosition(pickedPosition, input.getCursorPosition()); + + // Get the picked position in camera space. + camera.getCameraSpacePositionFromNormalSpacePosition(pickedPosition, pickedPosition); + + // Turn it into a ray of length 1, going from the camera. + pickedPosition.normalize(pickedPosition); + + // If there is a spheroid, we want to intersect with that. If not, we'll just use a sphere. + const interval = _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get(); + const spheroid = /** @type {SpheroidComponent} */(this.getEntity().getParent().getComponentByType('spheroid')); + if (spheroid !== null) { + // We scale up the ray and entity position and rotate them into the picked entity's orientation frame. + const ratio = spheroid.getEquatorialRadius() / spheroid.getPolarRadius(); + pickedPosition.rotateInverse(this._pickedEntity.getOrientation(), pickedPosition); + pickedPosition.z *= ratio; + const entityPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + entityPosition.copy(this._pickedEntity.getCameraSpacePosition(camera)); + entityPosition.rotateInverse(this._pickedEntity.getOrientation(), entityPosition); + entityPosition.z *= ratio; + _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLineSphereIntersectionWithLineStartAtOrigin(interval, pickedPosition, entityPosition, spheroid.getEquatorialRadius()); + pickedPosition.z /= ratio; + pickedPosition.rotate(this._pickedEntity.getOrientation(), pickedPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityPosition); + } + else { + const entityPosition = this._pickedEntity.getCameraSpacePosition(camera); + _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLineSphereIntersectionWithLineStartAtOrigin(interval, pickedPosition, entityPosition, this._pickedEntity.getOcclusionRadius()); + } + if (!Number.isNaN(interval.min)) { + // Convert the picked position from camera space to entity space. + this._pickedPosition.thaw(); + this._pickedPosition.mult(pickedPosition, interval.min); + camera.getEntity().getPositionRelativeToEntity(this._pickedPosition, this._pickedPosition, this._pickedEntity); + this._pickedPosition.freeze(); + + // Call the callback. + this.getEntity().getScene().getEngine().addCallback(this._callback.bind(undefined, this._pickedPosition), false); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(interval); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(pickedPosition); + } + } + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/roll_controller.js": +/*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/roll_controller.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "RollController": function() { return /* binding */ RollController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A roll camera controller. + */ +class RollController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The sensitivity for rolling. + * @type {number} + * @private + */ + this._rollSensitivity = 0.1; + + /** + * The smoothness of the rolling. Zero means no smoothness. + * @type {number} + * @private + */ + this._rollSmoothness = 0.8; + + /** + * The current value applied every frame to the roll axis rotation. + * @type {number} + * @private + */ + this._rollAngleSmoothedValue = 0.0; + + // Let the base controller know that this changes the orientation. + this.addModifiedState('orientation'); + } + + /** + * Gets the roll sensitivity. Defaults to 0.01. + * @returns {number} + */ + getRollSensitivity() { + return this._rollSensitivity; + } + + /** + * Sets the roll sensitivity. + * @param {number} rollSensitivity + */ + setRollSensitivity(rollSensitivity) { + this._rollSensitivity = rollSensitivity; + } + + /** + * Gets the roll smoothness. Defaults to 0.8. + * @returns {number} + */ + getRollSmoothness() { + return this._rollSmoothness; + } + + /** + * Sets the roll smoothness, between 0 and 1. + * @param {number} rollSmoothness + */ + setRollSmoothness(rollSmoothness) { + this._rollSmoothness = rollSmoothness; + } + + /** + * Updates the entity's position and orientation. + * @override + * @internal + */ + __update() { + // Set the position and orientation if they have never been set before. + if (this.getEntity().getOrientation().isNaN()) { + this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + + // Get the azimuth, elevation, and roll from input. + let rollAngle = 0; + const input = this.getEntity().getScene().getEngine().getInput(); + const viewport = input.getActiveViewport(); + if (viewport !== null) { + const camera = viewport.getCamera(); + if (camera !== null && camera.getEntity() === this.getEntity()) { + let rollMultiplier = 1; + if (input.isKeyPressed('x')) { + rollMultiplier = 0.05; + } + if (input.isShiftPressed()) { + rollMultiplier = 5; + } + + // Do touch rotate movement. + const rotatedOffset = input.getRotatedOffset(); + if (rotatedOffset !== 0) { + rollAngle += _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(rotatedOffset * this._rollSensitivity * rollMultiplier, -0.1, +0.1); + } + + // Add key movement. + if (input.isKeyPressed('c')) { + rollAngle += this._rollSensitivity * rollMultiplier; + } + if (input.isKeyPressed('z')) { + rollAngle -= this._rollSensitivity * rollMultiplier; + } + rollAngle += rollAngle + this._rollSensitivity * rollMultiplier * cameraOrbitParameters.roll; + } + } + + // Apply smoothing. + this._rollAngleSmoothedValue = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(rollAngle, this._rollAngleSmoothedValue, this._rollSmoothness); + if (Math.abs(this._rollAngleSmoothedValue) < 0.0001) { + this._rollAngleSmoothedValue = 0; + } + + // Apply the roll. + if (this._rollAngleSmoothedValue !== 0) { + // Rotate the orientation by the forward (y) axis. + const newOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const rotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + rotation.setFromAxisAngle(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis, this._rollAngleSmoothedValue); + newOrientation.mult(this.getEntity().getOrientation(), rotation); + this.getEntity().setOrientation(newOrientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation); + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/rotate_by_entity_orientation_controller.js": +/*!******************************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/rotate_by_entity_orientation_controller.js ***! + \******************************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "RotateByEntityOrientationController": function() { return /* binding */ RotateByEntityOrientationController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A controller that rotates the position and orientation by the parent's orientation. + * Great for objects that are connected to their parents or landers. + * It needs to added as the last controller to work. */ +class RotateByEntityOrientationController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The entity whose orientation will be used. + * @type {EntityRef} + * @private + */ + this._entityRef = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + + /** + * A flag that determines whether the controller is rotating the position of the entity. + * @type {boolean} + * @private + */ + this._rotatingPosition = true; + + /** + * A flag that determines whether the controller is rotating the orientation of the entity. + * @type {boolean} + * @private + */ + this._rotatingOrientation = true; + + // Let the base controller know that this changes the position and orientation. + this.addModifiedState('position'); + this.addModifiedState('orientation'); + } + + /** + * Sets the entity whose orientation will be used. If the name is '', the current parent will be used. + * @param {string} name + */ + setEntityForOrientation(name) { + // Remove the dependency on the previous entity's orientation. + if (this._entityRef.getName() !== '') { + this.addDependentState(this._entityRef.getName(), 'orientation'); + } + + // Set the entity reference. + this._entityRef.setName(name); + + // Add the dependency on the new entity's orientation. + this.addDependentState(name, 'orientation'); + } + + /** + * Returns whether the controller is rotating the position of the entity. Defaults to true. + * @returns {boolean} + */ + isRotatingPosition() { + return this._rotatingPosition; + } + + /** + * Sets whether the controller is rotating the position of the entity. + * @param {boolean} rotatingPosition + */ + setRotatingPosition(rotatingPosition) { + this._rotatingPosition = rotatingPosition; + if (rotatingPosition) { + this.addModifiedState('position'); + } + else { + this.removeModifiedState('position'); + } + } + + /** + * Returns true if the controller is rotating the orientation of the entity. Defaults to true. + * @returns {boolean} + */ + isRotatingOrientation() { + return this._rotatingOrientation; + } + + /** + * Sets whether the controller is rotating the orientation of the entity. + * @param {boolean} rotatingOrientation + */ + setRotatingOrientation(rotatingOrientation) { + this._rotatingOrientation = rotatingOrientation; + if (rotatingOrientation) { + this.addModifiedState('orientation'); + } + else { + this.removeModifiedState('orientation'); + } + } + + /** + * Updates the position to be rotated by the parent orientation. + * @param {Vector3} position + * @param {number} time + * @override + * @internal + */ + __updatePositionAtTime(position, time) { + if (this._rotatingPosition) { + const entity = this._entityRef.getName() !== '' ? this._entityRef.get() : this.getEntity().getScene().getEntity(this.getEntity().getParentAtTime(time)); + if (entity !== null) { + const entityOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + entity.getOrientationAtTime(entityOrientation, time); + position.rotate(entityOrientation, position); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(entityOrientation); + } + } + } + + /** + * Updates the velocity to be rotated by the parent orientation. + * @param {Vector3} velocity + * @param {number} time + * @override + * @internal + */ + __updateVelocityAtTime(velocity, time) { + if (this._rotatingPosition) { + const entity = this._entityRef.getName() !== '' ? this._entityRef.get() : this.getEntity().getScene().getEntity(this.getEntity().getParentAtTime(time)); + if (entity !== null) { + const entityOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + entity.getOrientationAtTime(entityOrientation, time); + velocity.rotate(entityOrientation, velocity); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(entityOrientation); + } + } + } + + /** + * If the orientation is fixed, updates the orientation to the fixed orientation. + * @param {Quaternion} orientation + * @param {number} time + * @override + * @internal + */ + __updateOrientationAtTime(orientation, time) { + if (this._rotatingOrientation) { + const entity = this._entityRef.getName() !== '' ? this._entityRef.get() : this.getEntity().getScene().getEntity(this.getEntity().getParentAtTime(time)); + if (entity !== null) { + const entityOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + entity.getOrientationAtTime(entityOrientation, time); + orientation.mult(entityOrientation, orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(entityOrientation); + } + } + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + const entity = this._entityRef.getName() !== '' ? this._entityRef.get() : this.getEntity().getParent(); + if (entity !== null) { + if (this._rotatingPosition) { + const position = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + position.rotate(entity.getOrientation(), this.getEntity().getPosition()); + this.getEntity().setPosition(position); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + } + if (this._rotatingOrientation) { + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + orientation.mult(entity.getOrientation(), this.getEntity().getOrientation()); + this.getEntity().setOrientation(orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + } + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/rotate_controller.js": +/*!********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/rotate_controller.js ***! + \********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "RotateController": function() { return /* binding */ RotateController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A controller that rotates an entity's position and/or orientation by a rotation quaternion. + */ +class RotateController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The rotation. + * @type {Quaternion} + * @private + */ + this._rotation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + this._rotation.freeze(); + + /** + * A flag that determines whether the controller is rotating the position of the entity. + * @type {boolean} + * @private + */ + this._rotatingPosition = true; + + /** + * A flag that determines whether the controller is rotating the orientation of the entity. + * @type {boolean} + * @private + */ + this._rotatingOrientation = true; + + // Let the base controller know that this changes the position and orientation. + this.addModifiedState('position'); + this.addModifiedState('orientation'); + } + + /** + * Gets the rotation. Defaults to Quaterion(1, 0, 0, 0). + * @returns {Quaternion} + */ + getRotation() { + return this._rotation; + } + + /** + * Sets the rotation. + * @param {Quaternion} rotation + */ + setRotation(rotation) { + this._rotation.thaw(); + this._rotation.copy(rotation); + this._rotation.freeze(); + } + + /** + * Returns whether the controller is rotating the position of the entity. Defaults to true. + * @returns {boolean} + */ + isRotatingPosition() { + return this._rotatingPosition; + } + + /** + * Sets whether the controller is rotating the position of the entity. + * @param {boolean} rotatingPosition + */ + setRotatingPosition(rotatingPosition) { + this._rotatingPosition = rotatingPosition; + if (rotatingPosition) { + this.addModifiedState('position'); + } + else { + this.removeModifiedState('position'); + } + } + + /** + * Returns true if the controller is rotating the orientation of the entity. Defaults to true. + * @returns {boolean} + */ + isRotatingOrientation() { + return this._rotatingOrientation; + } + + /** + * Sets whether the controller is rotating the orientation of the entity. + * @param {boolean} rotatingOrientation + */ + setRotatingOrientation(rotatingOrientation) { + this._rotatingOrientation = rotatingOrientation; + if (rotatingOrientation) { + this.addModifiedState('orientation'); + } + else { + this.removeModifiedState('orientation'); + } + } + + /** + * Updates a position for the given time. + * @param {Vector3} position + * @param {number} _time + * @override + * @internal + */ + __updatePositionAtTime(position, _time) { + if (this._rotatingPosition) { + position.rotate(this._rotation, position); + } + } + + /** + * Updates a velocity for the given time. + * @param {Vector3} velocity + * @param {number} _time + * @override + * @internal + */ + __updateVelocityAtTime(velocity, _time) { + if (this._rotatingPosition) { + velocity.rotate(this._rotation, velocity); + } + } + + /** + * Updates given orientation for the given time. + * @param {Quaternion} orientation - The orientation to update. + * @param {number} _time - The time to check. + * @override + * @internal + */ + __updateOrientationAtTime(orientation, _time) { + if (this._rotatingOrientation) { + orientation.mult(this._rotation, orientation); + } + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + if (this._rotatingPosition) { + const newPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + newPosition.rotate(this._rotation, this.getEntity().getPosition()); + this.getEntity().setPosition(newPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition); + } + if (this._rotatingOrientation) { + const newOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + newOrientation.mult(this._rotation, this.getEntity().getOrientation()); + this.getEntity().setOrientation(newOrientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation); + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/scale_controller.js": +/*!*******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/scale_controller.js ***! + \*******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ScaleController": function() { return /* binding */ ScaleController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A controller that scales the position of the entity. + */ +class ScaleController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + // The amount to scale the position. + this._scale = 1.0; + + // Let the base controller know that this changes the position. + this.addModifiedState('position'); + } + + /** + * Gets the scale factor. Defaults to 1. + * @return {number} + */ + getScale() { + return this._scale; + } + + /** + * Sets the scale factor. + * @param {number} scale + */ + setScale(scale) { + this._scale = scale; + } + + /** + * Updates the position based on time. + * @param {Vector3} position + * @param {number} _time + * @override + * @internal + */ + __updatePositionAtTime(position, _time) { + position.mult(position, this._scale); + } + + /** + * Updates the velocity based on time. + * @param {Vector3} velocity + * @param {number} _time + * @override + * @internal + */ + __updateVelocityAtTime(velocity, _time) { + velocity.mult(velocity, this._scale); + } + + /** + * Takes input and updates the target distance. Then updates the entity's position. + * @override + * @internal + */ + __update() { + const newPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + newPosition.mult(this.getEntity().getPosition(), this._scale); + this.getEntity().setPosition(newPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/select_controller.js": +/*!********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/select_controller.js ***! + \********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SelectController": function() { return /* binding */ SelectController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A selection controller. */ +class SelectController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * @type {(entity: Entity) => any} + * @private + */ + this._callback = null; + } + + /** + * Returns the callback to be called when the user selects an entity. + * @returns {(entity: Entity) => any} + */ + getCallback() { + return this._callback; + } + + /** + * Sets the callback to be called when the user selects an entity. If the user selects but does not select an entity, the param passed is null. + * @param {(entity: Entity) => any} callback + */ + setCallback(callback) { + this._callback = callback; + } + + /** + * Takes input and calls the callback if there is any selection. + * @override + * @internal + */ + __update() { + const input = this.getEntity().getScene().getEngine().getInput(); + + if (input.isSelected() && this._callback !== null) { + const viewport = input.getActiveViewport(); + if (viewport !== null) { + const camera = viewport.getCamera(); + if (camera !== null && camera.getEntity() === this.getEntity()) { + // Get the selected position in normal space. + const entityPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + viewport.getNormalSpacePositionFromPixelSpacePosition(entityPosition, input.getSelectedPosition()); + + // Search every entity for label that contains the normal-space position. Choose the nearest one. + let intersectedEntity = null; + let intersectedEntityDistance = 0; + const entityPosition2D = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + entityPosition2D.set(entityPosition.x, entityPosition.y); + const numEntities = this.getEntity().getScene().getNumEntities(); + for (let entityI = 0; entityI < numEntities; entityI++) { + const entity = this.getEntity().getScene().getEntity(entityI); + if (entity.isEnabled()) { + const label = /** @type {LabelComponent} */(entity.getComponentByType('label')); + if (label !== null && label.getLoadState() === 'loaded') { + const labelBounds = label.getNormalSpaceBounds(camera); + if (labelBounds !== undefined && labelBounds.contains(entityPosition2D)) { + const entityDistance = entity.getCameraSpacePosition(camera).magnitude(); + if (intersectedEntity === null || intersectedEntityDistance > entityDistance) { + intersectedEntity = entity; + intersectedEntityDistance = entityDistance; + } + } + } + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(entityPosition2D); + + // If it didn't find a label selection, check the entities themselves. + if (intersectedEntity === null) { + camera.getCameraSpacePositionFromNormalSpacePosition(entityPosition, entityPosition); + entityPosition.mult(entityPosition, 1 / entityPosition.magnitude()); + + // Get a ray in camera coordinates to search for intersecting entities. + intersectedEntity = camera.getNearestIntersectingEntity(entityPosition); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityPosition); + + // Call the callback whether something was selected or not. + this.getEntity().getScene().getEngine().addCallback(this._callback.bind(null, intersectedEntity), false); + } + } + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/set_parent_controller.js": +/*!************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/set_parent_controller.js ***! + \************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SetParentController": function() { return /* binding */ SetParentController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A controller that sets the parent every frame. Not normally needed except when another controller sets the parent, + * such as the transition controller. + */ +class SetParentController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The parent to transition to. + * @type {EntityRef} + * @private + */ + this._parent = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + } + + /** + * Gets the parent to set. + * @returns {string} + */ + getParent() { + return this._parent.getName(); + } + + /** + * Sets the parent to set. + * @param {string} parent + */ + setParent(parent) { + if (this._parent.getName() !== '') { + this.removeDependentState(this._parent.getName(), 'position'); + } + this._parent.setName(parent); + if (this._parent.getName() !== '') { + this.addDependentState(this._parent.getName(), 'position'); + } + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + const parent = this._parent.get(); + this.getEntity().setParent(parent); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/spin_controller.js": +/*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/spin_controller.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SpinController": function() { return /* binding */ SpinController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A controller that rotates an entity by an axis at a certain rate. + */ +class SpinController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The axis around which to rotate the entity. + * @type {Vector3} + * @private + */ + this._axis = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 1); + this._axis.freeze(); + + /** + * The flag that determines whether the axis is relative to the entity's orientation. + * @type {boolean} + * @private + */ + this._axisRelativeToEntity = true; + + /** + * The rate in radians per second to rotate the entity. + * @type {number} + * @private + */ + this._rate = 0; + + /** + * The reference angle in radians, the phase, of the entity at the reference time. + * @type {number} + * @private + */ + this._referenceAngle = 0; + + /** + * The reference time when the entity is at the reference phase angle. + * @type {number} + * @private + */ + this._referenceTime = undefined; + + /** + * A flag that determines whether to clamp the rate at the real-time rate. + * @type {boolean} + * @private + */ + this._clampedToRealTime = false; + + /** + * A flag that says whether real-time or Pioneer time is used. + * @type {boolean} + * @private + */ + this._usingRealTime = false; + + /** + * A flag that says whether the position is also rotating. + * @type {boolean} + * @private + */ + this._rotatingPosition = false; + + /** + * The joint for the model to spin. If empty, the entity itself is used. + * @type {string} + * @private + */ + this._joint = ''; + + /** + * The joint's ThreeJs object. + * @type {THREE.Object3D} + * @private + */ + this._jointObject = null; + + /** + * The model for the joint. + * @type {ModelComponent} + * @private + */ + this._model = null; + + /** + * A recording of the last time of Pioneer. + * @type {number} + * @private + */ + this._lastTime = entity.getScene().getEngine().getTime(); + + // Let the base controller know that this changes the orientation. + this.addModifiedState('orientation'); + } + + /** + * Gets the axis around which to rotate the entity. It defaults to the z-axis. + * @returns {Vector3} + */ + getAxis() { + return this._axis; + } + + /** + * Gets the flag that determines whether the axis is relative to the entity's orientation. Defaults to true. + * @returns {boolean} + */ + isAxisRelativeToEntity() { + return this._axisRelativeToEntity; + } + + /** + * Sets the axis around which to rotate the entity. + * @param {Vector3} axis - The axis. + * @param {boolean} relativeToEntity - If true, the axis is relative to the entity's orientation. + */ + setAxis(axis, relativeToEntity) { + this._axis.thaw(); + this._axis.copy(axis); + this._axis.freeze(); + this._axisRelativeToEntity = relativeToEntity; + } + + /** + * Gets the rate in radians per second to rotate the entity. Defaults to 0. + * @returns {number} + */ + getRate() { + return this._rate; + } + + /** + * Sets the rate in radians per second to rotate the entity. + * @param {number} rate + */ + setRate(rate) { + this._rate = rate; + } + + /** + * Gets the reference angle in radians, the phase, of the entity at the reference time. Defaults to 0. + * @returns {number} + */ + getReferenceAngle() { + return this._referenceAngle; + } + + /** + * Sets the reference angle in radians, the phase, of the entity at the reference time. + * @param {number} referenceAngle + */ + setReferenceAngle(referenceAngle) { + this._referenceAngle = referenceAngle; + } + + /** + * Gets the reference time when the entity is at the reference phase angle. If this is undefined, the previous frame's time is used. Defaults to undefined. + * @returns {number} + */ + getReferenceTime() { + return this._referenceTime; + } + + /** + * Sets the reference time when the entity is at the reference phase angle. + * @param {number} referenceTime + */ + setReferenceTime(referenceTime) { + this._referenceTime = referenceTime; + } + + /** + * Gets whether to clamp the rate at the real-time rate. Defaults to false. Ignored when there is a reference time. + * @returns {boolean} + */ + isClampedToRealTime() { + return this._clampedToRealTime; + } + + /** + * Sets whether to clamp the rate at the real-time rate. + * @param {boolean} clampedToRealTime + */ + setClampedToRealTime(clampedToRealTime) { + this._clampedToRealTime = clampedToRealTime; + } + + /** + * Gets the flag that says whether real-time or Pioneer time is used. + * @returns {boolean} + */ + isUsingRealTime() { + return this._usingRealTime; + } + + /** + * Sets the flag that says whether real-time or Pioneer time is used. + * @param {boolean} usingRealTime + */ + setUsingRealTime(usingRealTime) { + this._usingRealTime = usingRealTime; + } + + /** + * Gets the flag that says whether the position is also rotating. + * @returns {boolean} + */ + isRotatingPosition() { + return this._rotatingPosition; + } + + /** + * Sets the flag that says whether the position is also rotating. + * @param {boolean} rotatingPosition + */ + setRotatingPosition(rotatingPosition) { + this._rotatingPosition = rotatingPosition; + if (rotatingPosition) { + this.addModifiedState('position'); + } + else { + this.removeModifiedState('position'); + } + } + + /** + * Sets the spin to be at the joint on the specified model. If no model is given, the first model in the entity is used. + * @param {string} joint + * @param {ModelComponent} [model] + */ + setJoint(joint, model) { + this._joint = joint; + if (!model) { + const modelFromEntity = /** @type {ModelComponent} */(this.getEntity().get('model')); + if (modelFromEntity !== null) { + this._model = modelFromEntity; + } + } + else { + this._model = model; + } + if (this._joint !== '') { + this.removeModifiedState('orientation'); + } + else { + this.addModifiedState('orientation'); + } + } + + /** + * If the position is fixed, updates the position to the fixed position. + * @param {Vector3} position + * @param {number} time + * @override + * @internal + */ + __updatePositionAtTime(position, time) { + if (this._rotatingPosition) { + // Get the deltaTime, the time since the last update, possibly clamped. + let deltaTime = 0; + if (!this._usingRealTime) { // Using real time. + if (this._referenceTime !== undefined) { + deltaTime = time - this._referenceTime; + deltaTime -= this._referenceAngle / this._rate; + } + } + + // Calculate the rotation quaternion from the deltaTime. + const rotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + rotation.setFromAxisAngle(this._axis, this._rate * deltaTime); + + // If the joint object is valid, + if (this._jointObject === null) { + // Apply the rotation to the new orientation. + if (this._axisRelativeToEntity) { + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + this.getEntity().getOrientationAtTime(orientation, time); + rotation.mult(orientation, rotation); + rotation.multInverseR(rotation, orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + } + + // Set the position if flagged. + position.rotate(rotation, position); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation); + } + } + + /** + * If the orientation is fixed, updates the orientation to the fixed orientation. + * @param {Quaternion} orientation + * @param {number} time + * @override + * @internal + */ + __updateOrientationAtTime(orientation, time) { + // Make sure there is a valid orientation to start. + if (orientation.isNaN()) { + orientation.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + + // Get the deltaTime, the time since the last update, possibly clamped. + let deltaTime = 0; + if (!this._usingRealTime) { // Using real time. + if (this._referenceTime !== undefined) { + deltaTime = time - this._referenceTime; + deltaTime -= this._referenceAngle / this._rate; + } + } + + // Calculate the rotation quaternion from the deltaTime. + const rotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + rotation.setFromAxisAngle(this._axis, this._rate * deltaTime); + + // If the joint object is valid, + if (this._jointObject === null) { + // Apply the rotation to the new orientation. + if (this._axisRelativeToEntity) { + rotation.mult(orientation, rotation); + rotation.multInverseR(rotation, orientation); + } + orientation.mult(rotation, orientation); + orientation.normalize(orientation); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation); + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + // Make sure there is a valid orientation to start. + if (this.getEntity().getOrientation().isNaN()) { + this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + + // Get the deltaTime, the time since the last update, possibly clamped. + const engine = this.getEntity().getScene().getEngine(); + let deltaTime = 0; + if (this._usingRealTime) { // Using real time. + deltaTime = engine.getDeltaTime(); + } + else { // Using Pioneer time. + if (this._referenceTime !== undefined) { + deltaTime = engine.getTime() - this._referenceTime; + deltaTime -= this._referenceAngle / this._rate; + } + else { + deltaTime = engine.getTime() - this._lastTime; + if (this._clampedToRealTime) { + const deltaRealTime = engine.getDeltaTime(); + deltaTime = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(deltaTime, -deltaRealTime, deltaRealTime); + } + } + } + + // Calculate the rotation quaternion from the deltaTime. + const rotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + rotation.setFromAxisAngle(this._axis, this._rate * deltaTime); + + // If a joint is specified, setup the joint's ThreeJs object. + if (this._jointObject !== null && this._model.getThreeJsObjects()[0] !== null) { + this._jointObject = null; + } + if (this._joint !== '' && (this._jointObject === null || this._jointObject.name !== this._joint) && this._model !== null) { + const subObject = this._model.getThreeJsObjectByName(this._joint); + if (subObject !== null) { + this._jointObject = subObject; + } + } + // If the joint object is valid, + const entityOrientation = this.getEntity().getOrientation(); + if (this._jointObject !== null) { + if (!this._axisRelativeToEntity) { + rotation.multInverseL(entityOrientation, rotation); + rotation.mult(rotation, entityOrientation); + } + _tempThreeJsQuaternion.set(rotation.x, rotation.y, rotation.z, rotation.w); + this._jointObject.quaternion.multiplyQuaternions(_tempThreeJsQuaternion, this._jointObject.quaternion); + if (this._rotatingPosition) { + this._jointObject.position.applyQuaternion(_tempThreeJsQuaternion); + } + } + else { + // Apply the rotation to the new orientation. + const newOrientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + if (this._axisRelativeToEntity) { + rotation.mult(entityOrientation, rotation); + rotation.multInverseR(rotation, entityOrientation); + } + newOrientation.mult(rotation, entityOrientation); + newOrientation.normalize(newOrientation); + + // Set the orientation and angular velocity. + const newAngularVelocity = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + newAngularVelocity.mult(this._axis, this._rate); + if (this._axisRelativeToEntity) { + newAngularVelocity.rotate(newOrientation, newAngularVelocity); + } + this.getEntity().setOrientation(newOrientation); + this.getEntity().setAngularVelocity(newAngularVelocity); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newAngularVelocity); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation); + + // Set the position if flagged. + if (this._rotatingPosition) { + const newPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + newPosition.rotate(rotation, this.getEntity().getPosition()); + this.getEntity().setPosition(newPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition); + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation); + + this._lastTime = engine.getTime(); + } +} + +/** + * A temporary ThreeJs Quaternion. + * @type {THREE.Quaternion} + */ +const _tempThreeJsQuaternion = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Quaternion(); + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/tap_controller.js": +/*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/tap_controller.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TapController": function() { return /* binding */ TapController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * An tap controller calls a callback when the user taps the view. + */ +class TapController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The callback to call when the user taps. + * @type {() => any} + * @private + */ + this._tapCallback = null; + } + + /** + * Gets the callback to call when the user taps. + * @returns {() => any} + */ + getTapCallback() { + return this._tapCallback; + } + + /** + * Sets a callback to call when the user taps. + * @param {() => any} callback + */ + setTapCallback(callback) { + this._tapCallback = callback; + } + + /** + * Updates the entity's position and orientation. + * @override + * @internal + */ + __update() { + // Get the input system. + const input = this.getEntity().getScene().getEngine().getInput(); + // If the user clicked/tapped and didn't drag. + if (input.isSelected() || !input.getDraggedOffset().isZero()) { + // Call the callback. + if (this._tapCallback !== null) { + this._tapCallback(); + } + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/transition_controller.js": +/*!************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/transition_controller.js ***! + \************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TransitionController": function() { return /* binding */ TransitionController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * @callback TransitionFunction + * @param {Entity} entity + * @param {Vector3} initialPosition + * @param {Vector3} finalPosition + * @param {Quaternion} initialOrientation + * @param {Quaternion} finalOrientation + * @param {number} u + */ + +/** + * A transition controller. + */ +class TransitionController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * @type {Vector3} + * @private + */ + this._initialPosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._initialPosition.copy(entity.getPosition()); + + /** + * @type {Quaternion} + * @private + */ + this._initialOrientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + this._initialOrientation.copy(entity.getOrientation()); + + /** + * @type {EntityRef} + * @private + */ + this._initialParent = new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + + /** + * @type {number} + * @private + */ + this._transitionStart = Number.NaN; + + /** + * @type {number} + * @private + */ + this._transitionTime = 1; + + /** + * @type {TransitionFunction} + * @private + */ + this._transitionFunction = this._lerpTransitionFunction; + + /** + * The resolve function that will be called when the transition completes. + * @type {function():void} + * @private + */ + this._resolvePromise = null; + + /** + * The reject function that will be called if the endPromise rejects. + * @type {function(string):void} + * @private + */ + this._rejectPromise = null; + + /** + * The promise that resolves at the end of the transition. + * @type {Promise} + * @private + */ + this._endPromise = new Promise((resolve, reject) => { + this._resolvePromise = resolve; + this._rejectPromise = reject; + }); + + // Set the initial parent to the current parent. + const parent = this.getEntity().getParent(); + if (parent !== null) { + this._initialParent.setName(parent.getName()); + } + + // If there is another transition controller already, destroy it. + const existingController = this.getEntity().getControllerByType('transition'); + if (existingController !== null) { + this.getEntity().removeController(existingController); + } + + // Add a beginning setParent controller, since the controllers before this one expect to be in the destination parent frame. + const setParentController = /** @type {SetParentController} */(this.getEntity().addController('setParent', 'transitionSetParent', this.getEntity().getController(0))); + if (parent !== null) { + setParentController.setParent(parent.getName()); + } + } + + /** + * Gets the transition time in seconds. + * @returns {number} + */ + getTransitionTime() { + return this._transitionTime; + } + + /** + * Sets the transition time in seconds. + * @param {number} transitionTime + */ + setTransitionTime(transitionTime) { + this._transitionTime = transitionTime; + } + + /** + * Sets the transition function. + * @param {TransitionFunction} transitionFunction + */ + setTransitionFunction(transitionFunction) { + this._transitionFunction = transitionFunction; + } + + /** + * Gets the parent to transition to. + * @returns {string} + */ + getParent() { + const setParentController = /** @type {SetParentController} */(this.getEntity().getController('transitionSetParent')); + if (setParentController !== null) { + return setParentController.getName(); + } + else { + const parent = this.getEntity().getParent(); + if (parent !== null) { + return parent.getName(); + } + return null; + } + } + + /** + * Sets the parent to transition to. + * @param {string} parent + */ + setParent(parent) { + const setParentController = /** @type {SetParentController} */(this.getEntity().getController('transitionSetParent')); + if (setParentController !== null) { + setParentController.setParent(parent); + } + } + + /** + * Gets the promise that resolves at the end of the transition. + * On a failure, the reject function takes a string describing what went wrong. + * @returns {Promise} + */ + getEndPromise() { + return this._endPromise; + } + + /** + * Destroys the controller resources. + * @override + * @internal + */ + __destroy() { + super.__destroy(); + + // Remove the setParent controller. + const setParentController = this.getEntity().getController('transitionSetParent'); + if (setParentController !== null) { + this.getEntity().removeController(setParentController); + } + + // Reject if the transition controller completed early. + if (this._transitionTime !== 0) { + this._rejectPromise('Transition controller was destroyed before completing.'); + } + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + // When this update runs, the previous controllers in the entity controller list have updated themselves, + // including the first setParent controller created by this. Now we just interpolate between the + // initialPosition/Orientation variables and the entity's updated position and orientation. + + // Get the initial parent and final parent. + const initialParent = this._initialParent.get(); + const finalParent = this.getEntity().getParent(); + + // There's no final parent any more, so we error. + if (finalParent === null) { + this._transitionTime = 0; + this.getEntity().removeController(this); + this._rejectPromise('The final parent was destroyed or disabled before the transition could complete.'); + } + + // Set the start time for the transition on the first update. + if (Number.isNaN(this._transitionStart)) { + this._transitionStart = Date.now() / 1000.0; + } + + // If we're before the half-way point or just went over it this frame. + const setParentController = /** @type {SetParentController} */(this.getEntity().getController('transitionSetParent')); + if (setParentController !== null) { + // If there's no initial parent, + if (initialParent === null) { + this.getEntity().getScene().getEngine().addCallback(() => { + this._transitionTime = 0; + this.getEntity().removeController(this); + if (this._initialParent.getName() !== '') { // There's supposed to be an initial parent, but no more. + this._rejectPromise(`The initial parent "${this._initialParent.getName()}" was destroyed or disabled before the first half of the transition could complete.`); + } + else { // Never was an initial parent, so just finish the transition. + this._resolvePromise(); + } + }, false); + return; + } + // If we're over the half-way point, remove the setParent controller and adjust the frame of the initial position. + if (Date.now() / 1000.0 - this._transitionStart >= this._transitionTime / 2.0 || initialParent === finalParent) { + // Remove the setParent controller. + this.getEntity().removeController(setParentController); + // Change the initial position to be in the frame of the final parent. + if (initialParent !== finalParent && initialParent !== null && finalParent !== null) { + initialParent.getPositionRelativeToEntity(this._initialPosition, this._initialPosition, finalParent); + } + } + // We're before the half-way point and at a different parent, so switch to the initial parent. + else { + this.getEntity().setParent(initialParent); + } + } + + // Get the final position and orientation. + const finalPosition = this.getEntity().getPosition(); + const finalOrientation = this.getEntity().getOrientation(); + + // Do the transition. + let u = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((Date.now() / 1000.0 - this._transitionStart) / this._transitionTime); + if (Number.isNaN(u)) { + u = 1.0; + } + this._transitionFunction(this.getEntity(), this._initialPosition, finalPosition, this._initialOrientation, finalOrientation, u); + + // If we've passed the transition time, clean it all up. + if (Date.now() / 1000.0 - this._transitionStart >= this._transitionTime) { + this.getEntity().getScene().getEngine().addCallback(() => { + this._transitionTime = 0; + this.getEntity().removeController(this); + this._resolvePromise(); + }, false); + } + } + + /** + * A default function that lerps between positions and slerps between orientations. + * @param {Entity} entity + * @param {Vector3} initialPosition + * @param {Vector3} finalPosition + * @param {Quaternion} initialOrientation + * @param {Quaternion} finalOrientation + * @param {number} u + */ + _lerpTransitionFunction(entity, initialPosition, finalPosition, initialOrientation, finalOrientation, u) { + const position = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + position.lerp(initialPosition, finalPosition, u); + orientation.slerp(initialOrientation, finalOrientation, u); + + // Set the new position and orientation. + entity.setPosition(position); + entity.setOrientation(orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/translate_controller.js": +/*!***********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/translate_controller.js ***! + \***********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TranslateController": function() { return /* binding */ TranslateController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A controller that translates the position of the entity. + */ +class TranslateController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The translation. + * @type {Vector3} + * @private + */ + this._translation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 0); + this._translation.freeze(); + + /** + * Whether the translation is relative to the orientation. + * @type {boolean} + * @private + */ + this._relativeToOrientation = false; + + // Let the base controller know that this changes the position. + this.addModifiedState('position'); + } + + /** + * Gets the translation. Defaults to Vector3(0, 0, 0). + * @returns {Vector3} + */ + getTranslation() { + return this._translation; + } + + /** + * Sets the translation. + * @param {Vector3} translation + */ + setTranslation(translation) { + this._translation.thaw(); + this._translation.copy(translation); + this._translation.freeze(); + } + + /** + * Sets whether the translation is relative to the orientation. + * @param {boolean} relativeToOrientation + */ + setRelativeToOrientation(relativeToOrientation) { + this._relativeToOrientation = relativeToOrientation; + } + + /** + * Updates a position for the given time. + * @param {Vector3} position + * @param {number} time + * @override + * @internal + */ + __updatePositionAtTime(position, time) { + const newPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (this._relativeToOrientation) { + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + this.getEntity().getOrientationAtTime(orientation, time); + newPosition.rotate(orientation, this._translation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + } + else { + newPosition.copy(this._translation); + } + position.add(newPosition, position); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition); + } + + /** + * Updates the controller. + * @override + * @internal + */ + __update() { + const newPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (this._relativeToOrientation) { + newPosition.rotate(this.getEntity().getOrientation(), this._translation); + } + else { + newPosition.copy(this._translation); + } + newPosition.add(newPosition, this.getEntity().getPosition()); + this.getEntity().setPosition(newPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/controllers/zoom_controller.js": +/*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/zoom_controller.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ZoomController": function() { return /* binding */ ZoomController; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A zoom camera controller. + */ +class ZoomController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + // The sensitivity for zooming. + this._zoomSensitivity = 0.05; + + /** + * The smoothness of the zooming. Zero means no smoothness. + * @type {number} + * @private + */ + this._zoomSmoothness = 0.8; + + /** + * The current value applied every frame to the movement. + * @type {number} + * @private + */ + this._zoomSmoothedValue = 1.0; + + /** + * The distance that it will be clamped to. + * @type {Interval} + * @private + */ + this._distanceClamp = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(0.001, Number.POSITIVE_INFINITY); + this._distanceClamp.freeze(); + + /** + * If true, it will use the distance to the radius of the spheroid instead of the entity position distance. + * @type {boolean} + * @private + */ + this._useSpheroidRadiusForDistance = false; + + // Let the base controller know that this changes the position. + this.addModifiedState('position'); + } + + /** + * Gets the zoom sensitivity. Defaults to 0.01. + * @returns {number} + */ + getZoomSensitivity() { + return this._zoomSensitivity; + } + + /** + * Sets the zoom sensitivity. + * @param {number} zoomSensitivity + */ + setZoomSensitivity(zoomSensitivity) { + this._zoomSensitivity = zoomSensitivity; + } + + /** + * Gets the zoom smoothness. Defaults to 0.8. + * @returns {number} + */ + getZoomSmoothness() { + return this._zoomSmoothness; + } + + /** + * Sets the zoom smoothness, between 0 and 1. + * @param {number} zoomSmoothness + */ + setZoomSmoothness(zoomSmoothness) { + this._zoomSmoothness = zoomSmoothness; + } + + /** + * Gets the interval to which it will be clamped (frozen). + * @returns {Interval} + */ + getDistanceClamp() { + return this._distanceClamp; + } + + /** + * Sets the distance that it will be clamped to. + * @param {Interval} distanceClamp - the value to set + */ + setDistanceClamp(distanceClamp) { + this._distanceClamp.thaw(); + this._distanceClamp.copy(distanceClamp); + this._distanceClamp.freeze(); + } + + /** + * Returns true if it will use the distance to the radius of the spheroid instead of the entity position distance. + * @returns {boolean} + */ + getUseSpheroidRadiusForDistance() { + return this._useSpheroidRadiusForDistance; + } + + /** + * Sets if it will use the distance to the radius of the spheroid instead of the entity position distance. + * @param {boolean} enabled + */ + setUseSpheroidRadiusForDistance(enabled) { + this._useSpheroidRadiusForDistance = enabled; + } + + /** + * Takes input and updates the target distance. Then updates the entity's position. + * @override + * @internal + */ + __update() { + const input = this.getEntity().getScene().getEngine().getInput(); + + // Update the target distance. + let zoomChange = 1.0; + const viewport = input.getActiveViewport(); + if (viewport !== null) { + const camera = viewport.getCamera(); + if (camera !== null && camera.getEntity() === this.getEntity()) { + let zoomMultiplier = 1; + if (input.isKeyPressed('x')) { + zoomMultiplier = 0.05; + } + if (input.isShiftPressed()) { + zoomMultiplier = 5; + } + + // Do zoom/scroll movement. + const zoomOffset = input.getZoomedOffset(); + if (zoomOffset !== 0) { + zoomChange *= Math.pow(2, zoomOffset * this._zoomSensitivity * zoomMultiplier); + } + + // Do key movement. + if (input.isKeyPressed('w')) { + zoomChange /= Math.pow(2, this._zoomSensitivity * zoomMultiplier); + } + if (input.isKeyPressed('s')) { + zoomChange *= Math.pow(2, this._zoomSensitivity * zoomMultiplier); + } + zoomChange *= Math.pow(2, this._zoomSensitivity * zoomMultiplier * cameraOrbitParameters.zoom); + } + } + + // Apply smoothing. + this._zoomSmoothedValue = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(zoomChange, this._zoomSmoothedValue, this._zoomSmoothness), 0.8, 1.25); + if (Math.abs(1.0 - this._zoomSmoothedValue) < 0.0000001) { + this._zoomSmoothedValue = 1.0; + } + + // Get the current distance from the position. + let currentDistance = 1; + const lla = _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + if (this._useSpheroidRadiusForDistance && this.getEntity().getParent() !== null) { + const spheroid = /** @type {SpheroidComponent} */(this.getEntity().getParent().getComponentByType('spheroid')); + if (spheroid !== null) { + const positionOriented = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + positionOriented.rotateInverse(this.getEntity().getParent().getOrientation(), this.getEntity().getPosition()); + spheroid.llaFromXYZ(lla, positionOriented); + currentDistance = lla.alt; + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionOriented); + } + else { + currentDistance = this.getEntity().getPosition().magnitude() - this.getEntity().getParent().getOcclusionRadius(); + } + } + else { + currentDistance = this.getEntity().getPosition().magnitude(); + } + if (Number.isNaN(currentDistance)) { + currentDistance = 1; + } + + // Update the current distance and apply clamping. + currentDistance *= this._zoomSmoothedValue; + if (currentDistance < this._distanceClamp.min) { + currentDistance = this._distanceClamp.min; + this._zoomSmoothedValue = 1.0; + } + if (currentDistance > this._distanceClamp.max) { + currentDistance = this._distanceClamp.max; + this._zoomSmoothedValue = 1.0; + } + + // Set the position from the current distance. + const newPosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + let newMagnitude = currentDistance; + if (this._useSpheroidRadiusForDistance && this.getEntity().getParent() !== null) { + const spheroid = /** @type {SpheroidComponent} */(this.getEntity().getParent().getComponentByType('spheroid')); + if (spheroid !== null) { + lla.alt = currentDistance; + spheroid.xyzFromLLA(newPosition, lla); + newMagnitude = newPosition.magnitude(); + } + else { + newMagnitude = currentDistance + this.getEntity().getParent().getOcclusionRadius(); + } + } + newPosition.normalize(this.getEntity().getPosition()); + newPosition.mult(newPosition, newMagnitude); + this.getEntity().setPosition(newPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition); + _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/entity.js": +/*!*********************************************!*\ + !*** ../pioneer/engine/src/scene/entity.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Entity": function() { return /* binding */ Entity; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The main class that defines an object in space. It has position, orientation, components, controllers, and size. + * @extends {CollectionItem} + */ +class Entity extends _internal__WEBPACK_IMPORTED_MODULE_0__.CollectionItem { + /** + * Constructor. + * @param {string} type - the type of the entity (always 'entity'); + * @param {string} name - the name of the entity + * @param {Scene} scene - the scene + */ + constructor(type, name, scene) { + super(type, name, scene); + + /** + * Flag that the user can use to enable or disable the entity (and its children). + * @type {boolean} + * @private + */ + this._enabled = true; + + /** + * The flag that says whether any ancestor is disabled, making this disabled. + * @type {boolean} + * @private + */ + this._disabledByAncestor = false; + + /** + * Flag that indicates whether the entity has been destroyed. + * @type {boolean} + * @private + */ + this._destroyed = false; + + /** + * The parent of the entity. + * @type {Entity} + * @private + */ + this._parent = null; + + /** + * The parent of the entity at the beginning of the last frame. + * @type {Entity} + * @private + */ + this._lastParent = null; + + /** + * The children of the entity. + * @type {Entity[]} + * @private + */ + this._children = []; + + /** + * The time starts for parents as `[start time, parent name]`, sorted by start times. + * @type {[number, string][]} + * @private + */ + this._parentingTable = []; + + /** + * A list of callbacks to call when the parent changes. + * @type {((entity: Entity, oldParent: Entity, newParent: Entity) => void)[]} + * @private + */ + this._parentChangedCallbacks = []; + + /** + * A list of callbacks to call when the child changes. + * @type {((entity: Entity, child: Entity, added: boolean) => void)[]} + * @private + */ + this._childChangedCallbacks = []; + + /** + * The entity state. + * @type {EntityState} + * @private + */ + this._state = new EntityState(); + + /** + * The entity state from the previous frame. + * @type {EntityState} + * @private + */ + this._lastState = new EntityState(); + + /** + * The position of the entity relative to the camera's position. + * @type {FastMap} + * @private + */ + this._cameraSpacePosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The position of the entity in normal-space. + * @type {FastMap} + * @private + */ + this._normalSpacePosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The position of the entity in pixel-space. + * @type {FastMap} + * @private + */ + this._pixelSpacePosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The normal-space extents radius of the entity. + * @type {FastMap} + * @private + */ + this._normalSpaceExtentsRadius = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The pixel-space extents radius of the entity. + * @type {FastMap} + * @private + */ + this._pixelSpaceExtentsRadius = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The greatest pixel-space extents radius of the entity in any camera. + * @type {number} + * @private + */ + this._greatestPixelSpaceExtentsRadius = 0.0; + + /** + * The collection of components. + * @type {Collection} + * @private + */ + this._components = new _internal__WEBPACK_IMPORTED_MODULE_0__.Collection(this, _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Components); + + /** + * The collection of controllers. + * @type {Collection} + * @private + */ + this._controllers = new _internal__WEBPACK_IMPORTED_MODULE_0__.Collection(this, _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Controllers); + + /** + * The radius of the entity. + * @type {number} + * @private + */ + this._occlusionRadius = 0; + + /** + * The radius of the entity. + * @type {number} + * @private + */ + this._extentsRadius = 0; + + /** + * A user-set flag that determines whether things like labels get hidden behind the entity. + * @type {boolean} + * @private + */ + this._canOcclude = true; + + /** + * The position coverage of the controllers. + * @type {Interval} + * @private + */ + this._positionCoverage = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); + this._positionCoverage.freeze(); + + /** + * The orientation coverage of the controllers. + * @type {Interval} + * @private + */ + this._orientationCoverage = new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); + this._orientationCoverage.freeze(); + + /** + * A flag that is true if the entity's position coverage contains the current time. + * @type {boolean} + * @private + */ + this._isInPositionCoverage = false; + + /** + * A flag that is true if the entity's orientation coverage contains the current time. + * @type {boolean} + * @private + */ + this._isInOrientationCoverage = false; + } + + // NAME, SCENE, ENABLED, VISIBILITY + + /** + * Returns the scene. + * @returns {Scene} + */ + getScene() { + return this.__getCollectionParent(); + } + + /** + * Returns true if the entity is enabled. + * @returns {boolean} + */ + isEnabled() { + return this._enabled && !this._disabledByAncestor; + } + + /** + * Gets the flag that says whether any ancestor is disabled, making this disabled. + * @returns {boolean} + */ + isDisabledByAncestor() { + return this._disabledByAncestor; + } + + /** + * Sets whether the entity is enabled or not. Affects visibility and updating + * of all components and controllers. Does not include children. + * @param {boolean} enabled + */ + setEnabled(enabled) { + // If the flag has changed. + if (this._enabled !== enabled) { + // Update the flag. + this._enabled = enabled; + // Update the components and children's disabledByAncestor flags. + this._updateEnabled(); + } + } + + /** + * Updates the enabled flag after its been set. + * @private + */ + _updateEnabled() { + // Update the component load states, which depends on the entity's enabled flag. + for (let i = 0; i < this._components.size; i++) { + this._components.get(i).__updateLoadState(); + } + // Update the children. + for (let i = 0, l = this._children.length; i < l; i++) { + this._children[i]._updateDisabledByAncestor(); + } + } + + /** + * Updates the disabledByAncestor flag. + * @private + */ + _updateDisabledByAncestor() { + // Check if any ancestor is disabled. + let newDisabledByAncestor = false; + let ancestor = this._parent; + while (ancestor !== null) { + if (!ancestor._enabled || ancestor._disabledByAncestor) { + newDisabledByAncestor = true; + break; + } + ancestor = ancestor._parent; + } + // If the disabledByAncestor flag has changed, update it and its children. + if (this._disabledByAncestor !== newDisabledByAncestor) { + // Update the flag. + this._disabledByAncestor = newDisabledByAncestor; + // Update the components and children's disabledByAncestor flags. + this._updateEnabled(); + } + } + + /** + * Checks if the entity item has been destroyed. + * @returns {boolean} + */ + isDestroyed() { + return this._destroyed; + } + + // POSITION, ORIENTATION, ETC + + /** + * Gets the position (frozen). + * @returns {Vector3} + */ + getPosition() { + return this._state.position; + } + + /** + * Sets the position. Called by controllers when they set the position of the entity. + * @param {Vector3} position - the value to set + */ + setPosition(position) { + this._state.position.thaw(); + this._state.position.copy(position); + this._state.position.freeze(); + } + + /** + * Gets the velocity (frozen). + * @returns {Vector3} + */ + getVelocity() { + return this._state.velocity; + } + + /** + * Sets the velocity. Called by controllers when they set the velocity of the entity. + * @param {Vector3} velocity - the value to set + */ + setVelocity(velocity) { + this._state.velocity.thaw(); + this._state.velocity.copy(velocity); + this._state.velocity.freeze(); + } + + /** + * Gets the orientation (frozen). + * @returns {Quaternion} + */ + getOrientation() { + return this._state.orientation; + } + + /** + * Sets the orientation. Called by controllers when they set the orientation of the entity. + * @param {Quaternion} orientation - the value to set + */ + setOrientation(orientation) { + this._state.orientation.thaw(); + this._state.orientation.copy(orientation); + this._state.orientation.freeze(); + } + + /** + * Gets the rotational velocity (frozen). + * @returns {Vector3} + */ + getAngularVelocity() { + return this._state.angularVelocity; + } + + /** + * Sets the rotational velocity. Called by controllers when they set the rotational velocity of the entity. + * @param {Vector3} angularVelocity - the value to set + */ + setAngularVelocity(angularVelocity) { + this._state.angularVelocity.thaw(); + this._state.angularVelocity.copy(angularVelocity); + this._state.angularVelocity.freeze(); + } + + /** + * Gets the position on the previous frame. + * @returns {Vector3} + */ + getLastPosition() { + return this._lastState.position; + } + + /** + * Gets the velocity on the previous frame. + * @returns {Vector3} + */ + getLastVelocity() { + return this._lastState.velocity; + } + + /** + * Gets the orientation on the previous frame. + * @returns {Quaternion} + */ + getLastOrientation() { + return this._lastState.orientation; + } + + /** + * Gets the angular velocity on the previous frame. + * @returns {Vector3} + */ + getLastAngularVelocity() { + return this._lastState.angularVelocity; + } + + /** + * Gets the position given in this frame relative to the given entity. + * @param {Vector3} outPosition - the result + * @param {Vector3} positionInThisFrame - the position in this frame + * @param {Entity} entity - the entity. If null, defaults to the root. + * @param {number} [time] - an optional time to use. + */ + getPositionRelativeToEntity(outPosition, positionInThisFrame, entity, time) { + /** + * @type {Entity} + */ + let e = this; + outPosition.copy(positionInThisFrame); + if (time === undefined) { + const lca = this.getLowestCommonAncestor(entity); + if (lca === null) { + outPosition.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + outPosition.add(outPosition, e.getPosition()); + while (e !== lca) { + e = e.getParent(); + outPosition.add(outPosition, e.getPosition()); + } + if (entity !== null) { + e = entity; + outPosition.sub(outPosition, e.getPosition()); + while (e !== lca) { + e = e.getParent(); + outPosition.sub(outPosition, e.getPosition()); + } + } + } + else { // A specific time was requested. + const scene = this.getScene(); + const ePosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const lca = this.getLowestCommonAncestorAtTime(entity, time); + if (lca !== null) { + e.getPositionAtTime(ePosition, time); + outPosition.add(outPosition, ePosition); + while (e !== lca) { + const eName = e.getParentAtTime(time); + e = scene.getEntity(eName); + if (e === null) { + outPosition.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + e.getPositionAtTime(ePosition, time); + outPosition.add(outPosition, ePosition); + } + if (entity !== null) { + e = entity; + e.getPositionAtTime(ePosition, time); + outPosition.sub(outPosition, ePosition); + while (e !== lca) { + const eName = e.getParentAtTime(time); + e = scene.getEntity(eName); + if (e === null) { + outPosition.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + e.getPositionAtTime(ePosition, time); + outPosition.sub(outPosition, ePosition); + } + } + } + else { + outPosition.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(ePosition); + } + } + + /** + * Gets the velocity given in this frame relative to the given entity. + * @param {Vector3} outVelocity - the result + * @param {Vector3} velocityInThisFrame - the velocity in this frame + * @param {Entity} entity - the entity. If null, defaults to the root. + * @param {number} [time] - an optional time to use. + */ + getVelocityRelativeToEntity(outVelocity, velocityInThisFrame, entity, time) { + /** + * @type {Entity} + */ + let e = this; + outVelocity.copy(velocityInThisFrame); + if (time === undefined) { + const lca = this.getLowestCommonAncestor(entity); + if (lca === null) { + outVelocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + outVelocity.add(outVelocity, e.getVelocity()); + while (e !== lca) { + e = e.getParent(); + outVelocity.add(outVelocity, e.getVelocity()); + } + if (entity !== null) { + e = entity; + outVelocity.sub(outVelocity, e.getVelocity()); + while (e !== lca) { + e = e.getParent(); + outVelocity.sub(outVelocity, e.getVelocity()); + } + } + } + else { // A specific time was requested. + const scene = this.getScene(); + const eVelocity = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const lca = this.getLowestCommonAncestorAtTime(entity, time); + if (lca !== null) { + e.getVelocityAtTime(eVelocity, time); + outVelocity.add(outVelocity, eVelocity); + while (e !== lca) { + const eName = e.getParentAtTime(time); + e = scene.getEntity(eName); + if (e === null) { + outVelocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + e.getVelocityAtTime(eVelocity, time); + outVelocity.add(outVelocity, eVelocity); + } + if (entity !== null) { + e = entity; + e.getVelocityAtTime(eVelocity, time); + outVelocity.sub(outVelocity, eVelocity); + while (e !== lca) { + const eName = e.getParentAtTime(time); + e = scene.getEntity(eName); + if (e === null) { + outVelocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + e.getVelocityAtTime(eVelocity, time); + outVelocity.sub(outVelocity, eVelocity); + } + } + } + else { + outVelocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(eVelocity); + } + } + + /** + * Sets outPosition to the entity position at the given time. If the time is omitted, the current time is used. + * @param {Vector3} outPosition + * @param {number} [time] + */ + getPositionAtTime(outPosition, time) { + if (!this.isEnabled()) { + outPosition.set(Number.NaN, Number.NaN, Number.NaN); + } + else { + if (time === undefined || this._controllers.size === 0) { + outPosition.copy(this._state.position); + } + else { + outPosition.set(Number.NaN, Number.NaN, Number.NaN); + } + for (let i = 0; i < this._controllers.size; i++) { + const controller = this._controllers.get(i); + if (controller.hasModifiedState('position') && controller.getCoverage().contains(time) && controller.isEnabled()) { + controller.__updatePositionAtTime(outPosition, time); + } + } + } + } + + /** + * Sets outVelocity to the entity velocity at the given time. If the time is omitted, the current time is used. + * @param {Vector3} outVelocity + * @param {number} [time] + */ + getVelocityAtTime(outVelocity, time) { + if (!this.isEnabled()) { + outVelocity.set(Number.NaN, Number.NaN, Number.NaN); + } + else { + if (time === undefined || this._controllers.size === 0) { + outVelocity.copy(this._state.velocity); + } + else { + outVelocity.set(Number.NaN, Number.NaN, Number.NaN); + } + for (let i = 0; i < this._controllers.size; i++) { + const controller = this._controllers.get(i); + if (controller.hasModifiedState('velocity') && controller.getCoverage().contains(time) && controller.isEnabled()) { + controller.__updateVelocityAtTime(outVelocity, time); + } + } + } + } + + /** + * Sets outOrientation to the entity orientation at the given time. If the time is omitted, the current time is used. + * @param {Quaternion} outOrientation - the orientation to be set + * @param {number} [time] - the time to check + */ + getOrientationAtTime(outOrientation, time) { + if (!this.isEnabled()) { + outOrientation.set(Number.NaN, Number.NaN, Number.NaN, Number.NaN); + } + else { + if (time === undefined || this._controllers.size === 0) { + outOrientation.copy(this._state.orientation); + } + else { + outOrientation.set(Number.NaN, Number.NaN, Number.NaN, Number.NaN); + } + for (let i = 0; i < this._controllers.size; i++) { + const controller = this._controllers.get(i); + if (controller.hasModifiedState('orientation') && controller.getCoverage().contains(time) && controller.isEnabled()) { + controller.__updateOrientationAtTime(outOrientation, time); + } + } + } + } + + // RADII + + /** + * Gets the occlusion radius of the entity. For non-spherical entities, this is a rough approximation of the bulk of the entity. + * @returns {number} + */ + getOcclusionRadius() { + return this._occlusionRadius; + } + + /** + * Gets the extents radius of the entity. For non-spherical entities, this is how far any part of the entity extends. + * @returns {number} + */ + getExtentsRadius() { + return this._extentsRadius; + } + + /** + * Sets the radius of the entity. For non-spherical entities, this is a rough approximation of the bulk of the entity. + * @param {number} radius - the value to set + */ + setOcclusionRadius(radius) { + this._occlusionRadius = radius; + } + + /** + * Sets the radius of the entity. For non-spherical entities, this is how far any part of the entity extends. + * @param {number} radius - the value to set + */ + setExtentsRadius(radius) { + this._extentsRadius = radius; + } + + // COVERAGE + + /** + * Gets the position coverage of the entity's controllers. If there are no position coverages, it returns an infinite coverage. + * @returns {Interval} + */ + getPositionCoverage() { + return this._positionCoverage; + } + + /** + * Gets the orientation coverage of the entity's controllers. If there are no orientation coverages, it returns an infinite coverage. + * @returns {Interval} + */ + getOrientationCoverage() { + return this._orientationCoverage; + } + + /** + * Gets the flag that is true if the entity's position coverage contains the current time. + * @returns {boolean} + */ + isInPositionCoverage() { + return this._isInPositionCoverage; + } + + /** + * Gets flag that is true if the entity's orientation coverage contains the current time. + * @returns {boolean} + */ + isInOrientationCoverage() { + return this._isInOrientationCoverage; + } + + /** + * Copies the current state to the last state. + * @internal + */ + __updateLastState() { + this._lastState.position.thaw(); + this._lastState.position.copy(this._state.position); + this._lastState.position.freeze(); + + this._lastState.velocity.thaw(); + this._lastState.velocity.copy(this._state.velocity); + this._lastState.velocity.freeze(); + + this._lastState.orientation.thaw(); + this._lastState.orientation.copy(this._state.orientation); + this._lastState.orientation.freeze(); + + this._lastState.angularVelocity.thaw(); + this._lastState.angularVelocity.copy(this._state.angularVelocity); + this._lastState.angularVelocity.freeze(); + } + + /** + * Updates the position and orientation coverage of the entity from the controllers. + * @internal + */ + __updateCoverage() { + + // Thaw the coverages. + this._positionCoverage.thaw(); + this._orientationCoverage.thaw(); + + // Initially set them to be no coverage. + this._positionCoverage.set(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY); + this._orientationCoverage.set(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY); + + // Go through each controller and union the coverages for position and orientation. + let numPositionControllers = 0; + let numOrientationControllers = 0; + for (let i = 0; i < this._controllers.size; i++) { + const controller = this._controllers.get(i); + if (controller.isEnabled()) { + if (controller.hasModifiedState('position')) { + this._positionCoverage.union(this._positionCoverage, controller.getCoverage()); + numPositionControllers++; + } + if (controller.hasModifiedState('orientation')) { + this._orientationCoverage.union(this._orientationCoverage, controller.getCoverage()); + numOrientationControllers++; + } + } + } + + // If there are no coverages, set them to infinity. + if (numPositionControllers === 0) { + this._positionCoverage.set(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); + } + if (numOrientationControllers === 0) { + this._orientationCoverage.set(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); + } + + // Also limit to the position coverage parenting table coverages. + if (this._parentingTable.length > 0) { + const firstEntry = this._parentingTable[0]; + const lastEntry = this._parentingTable[this._parentingTable.length - 1]; + this._positionCoverage.min = Math.max(this._positionCoverage.min, firstEntry[1] !== '' ? firstEntry[0] : Number.POSITIVE_INFINITY); + this._positionCoverage.max = Math.min(this._positionCoverage.max, lastEntry[1] !== '' ? Number.POSITIVE_INFINITY : lastEntry[0]); + } + + // Refreeze the coverages. + this._positionCoverage.freeze(); + this._orientationCoverage.freeze(); + } + + // OCCLUSION + + /** + * Returns whether the entity can occlude objects in the occlusion system. Returns true by default. + * @returns {boolean} + */ + canOcclude() { + return this._canOcclude; + } + + /** + * Sets whether the entity can occlude objects in the occlusion system. + * @param {boolean} canOcclude + */ + setCanOcclude(canOcclude) { + this._canOcclude = canOcclude; + } + + /** + * Returns true if the entity is occluding the camera-space position. + * @param {CameraComponent} camera + * @param {Vector3} cameraSpacePosition + * @returns {boolean} + */ + isOccludingPosition(camera, cameraSpacePosition) { + if (!this._canOcclude || !this.isInPositionCoverage()) { + return false; + } + const occludingRadius = Math.min(this._occlusionRadius, this.getCameraSpacePosition(camera).magnitude()); + const interval = _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get(); + _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLineSphereIntersectionWithLineStartAtOrigin(interval, cameraSpacePosition, this.getCameraSpacePosition(camera), occludingRadius); + const occluding = interval.min < interval.max && (0 <= interval.min + interval.max) && (interval.min + interval.max < 2); + _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(interval); + return occluding; + } + + // PARENTING + + /** + * Gets the parent of the entity. + * If the parent has been set but is not yet in the scene, it returns null. + * @returns {Entity} + */ + getParent() { + return this._parent; + } + + /** + * Gets the parent name of the entity at the given time. + * @param {number} time + * @returns {string} + */ + getParentAtTime(time) { + const index = _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._parentingTable, isStartTimeLessThanTime); + if (index < this._parentingTable.length && time === this._parentingTable[index][0]) { + return this._parentingTable[index][1]; + } + else if (index > 0) { + return this._parentingTable[index - 1][1]; + } + else { + if (this._parentingTable.length > 0) { + return ''; + } + else { // There's no parenting table, so just choose the current parent, or '' if there's none. + return this._parent !== null ? this._parent.getName() : ''; + } + } + } + + /** + * Sets the parent of the entity. + * @param {Entity} parent - the new parent or its name + */ + setParent(parent) { + // If it already set, just return. + if (parent === this._parent) { + return; + } + + // Make sure the position stays the same relative to the new parent. + const position = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.getPositionRelativeToEntity(position, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, parent); + if (!position.isNaN()) { + this.setPosition(position); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + + // Remove the old parent's child link. + if (this._parent !== null) { + for (let i = 0; i < this._parent._children.length; i++) { + const child = this._parent._children[i]; + if (child === this) { + this._parent._children.splice(i, 1); + } + } + } + + // Change to the new parent, saving the old parent for the callbacks. + const oldParent = this._parent; + this._parent = parent; + + // Add the new parent's child link. + if (this._parent !== null) { + this._parent._children.push(this); + } + + // Clear the camera references of the entity and all of its descendants components, + // since with a new parent, it might have a new set of connected cameras. + // The prepareForRender and setCameraDependentVariables functions will enable them again in any connected camera. + this._clearCameraReferences(); + + // Update the disabledByAncestors flag. + this._updateDisabledByAncestor(); + + // Call any parent changed callbacks. + for (let i = 0, l = this._parentChangedCallbacks.length; i < l; i++) { + this._parentChangedCallbacks[i](this, oldParent, this._parent); + } + + // Call any child changed callbacks for the old and new parents. + if (oldParent !== null) { + for (let i = 0, l = oldParent._childChangedCallbacks.length; i < l; i++) { + oldParent._childChangedCallbacks[i](oldParent, this, false); + } + } + if (this._parent !== null) { + for (let i = 0, l = this._parent._childChangedCallbacks.length; i < l; i++) { + this._parent._childChangedCallbacks[i](this._parent, this, true); + } + } + } + + /** + * Clears the camera references for when an entity changes its parent and may be visible in a new camera or no camera. + * The variables will repopulate with any camera that calls the prepareForRender and updateCameraVariables functions. + * @private + */ + _clearCameraReferences() { + // Clear all of the camera dependent variables to be repopulated again. + this._cameraSpacePosition.clear(); + this._normalSpacePosition.clear(); + this._pixelSpacePosition.clear(); + this._normalSpaceExtentsRadius.clear(); + this._pixelSpaceExtentsRadius.clear(); + + // Do the same for components, and also make them invisible until a camera tries to render them again in prepareForRender. + for (let i = 0, l = this._components.size; i < l; i++) { + const component = this._components.get(i); + component.__clearCameraDependentsBase(); + } + + // Do this for all of the descendants as well. + for (let i = 0, l = this._children.length; i < l; i++) { + this._children[i]._clearCameraReferences(); + } + } + + /** + * Gets the number of child entities. Good for iterating over child entities. + * @return {number} + */ + getNumChildren() { + return this._children.length; + } + + /** + * Gets the child entity at index i. Good for iterating over child entities. + * @param {number} i - the index + * @returns {Entity} + */ + getChild(i) { + return this._children[i]; + } + + /** + * Gets the lowest common ancestor between this and another entity. + * @param {Entity} entity + * @returns {Entity} + */ + getLowestCommonAncestor(entity) { + if (entity === null) { + return null; + } + let entityThis = /** @type {Entity} */(this); + let entityOther = entity; + let levelThis = 0; + let levelOther = 0; + // Get the levels of the two entities relative to the root. + while (entityThis.getParent() !== null) { + levelThis += 1; + entityThis = entityThis.getParent(); + } + while (entityOther.getParent() !== null) { + levelOther += 1; + entityOther = entityOther.getParent(); + } + // Whichever has the greatest level depth, move up to have the same level as the least level depth. + entityThis = this; + entityOther = entity; + while (levelThis > levelOther) { + levelThis -= 1; + entityThis = entityThis.getParent(); + } + while (levelOther > levelThis) { + levelOther -= 1; + entityOther = entityOther.getParent(); + } + // Move up the ancestors for both until a common ancestor is found. + while (entityThis !== entityOther && entityThis !== null) { + entityThis = entityThis.getParent(); + entityOther = entityOther.getParent(); + } + return entityThis; // If they didn't have a common ancestor, this will correctly be null. + } + + /** + * Gets the lowest common ancestor between this and another entity at a given time. + * @param {Entity} entity + * @param {number} time + * @returns {Entity} + */ + getLowestCommonAncestorAtTime(entity, time) { + if (entity === null) { + return null; + } + let entityThis = /** @type {Entity} */(this); + let entityOther = entity; + let levelThis = 0; + let levelOther = 0; + const scene = this.getScene(); + // Get the levels of the two entities relative to the root. + while (true) { + const parentName = entityThis.getParentAtTime(time); + if (parentName === '') { + break; + } + const parent = scene.getEntity(parentName); + if (parent === null) { + return null; + } + levelThis += 1; + entityThis = parent; + } + while (true) { + const parentName = entityOther.getParentAtTime(time); + if (parentName === '') { + break; + } + const parent = scene.getEntity(parentName); + if (parent === null) { + return null; + } + levelOther += 1; + entityOther = parent; + } + // Whichever has the greatest level depth, move up to have the same level as the least level depth. + entityThis = this; + entityOther = entity; + while (levelThis > levelOther) { + levelThis -= 1; + const parentName = entityThis.getParentAtTime(time); + const parent = scene.getEntity(parentName); + if (parent === null) { + return null; + } + entityThis = parent; + } + while (levelOther > levelThis) { + levelOther -= 1; + const parentName = entityOther.getParentAtTime(time); + const parent = scene.getEntity(parentName); + if (parent === null) { + return null; + } + entityOther = parent; + } + // Move up the ancestors for both until a common ancestor is found. + while (entityThis !== entityOther && entityThis !== null) { + const parentThisName = entityThis.getParentAtTime(time); + const parentThis = scene.getEntity(parentThisName); + if (parentThis === null) { + return null; + } + entityThis = parentThis; + const parentOtherName = entityOther.getParentAtTime(time); + const parentOther = scene.getEntity(parentOtherName); + if (parentOther === null) { + return null; + } + entityOther = parentOther; + } + return entityThis; // If they didn't have a common ancestor, this will correctly be null. + } + + /** + * Gets the number of parenting table entries. Can be used for a `for` loop. + * @returns {number} + */ + getNumParentingTableEntries() { + return this._parentingTable.length; + } + + /** + * Gets a parenting table entry. + * @param {number} index + * @returns {readonly [number, string]} + */ + getParentingTableEntry(index) { + return this._parentingTable[index]; + } + + /** + * Adds an entry to the parenting table. + * @param {number} startTime - The starting time of the interval. The next entry will denote the ending time. + * @param {string} parentName - The name of the parent for the interval. + */ + addParentingTableEntry(startTime, parentName) { + _internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add([startTime, parentName], this._parentingTable, isStartTimeLess, isStartTimeEqual); + this.__updateCoverage(); + } + + /** + * Removes an entry from the parenting table. + * @param {number} index + */ + removeParentingTableEntry(index) { + this._parentingTable.splice(index); + this.__updateCoverage(); + } + + /** + * Clears all entries from the parenting table. + */ + clearParentingTableEntries() { + this._parentingTable = []; + this.__updateCoverage(); + } + + /** + * Adds a parent changed callback. + * @param {(entity: Entity, oldParent: Entity, newParent: Entity) => void} callback + */ + addParentChangedCallback(callback) { + this._parentChangedCallbacks.push(callback); + } + + /** + * Removes a parent changed callback. + * @param {(entity: Entity, oldParent: Entity, newParent: Entity) => void} callback + */ + removeParentChangedCallback(callback) { + const index = this._parentChangedCallbacks.indexOf(callback); + if (index !== -1) { + this._parentChangedCallbacks.splice(index, 1); + } + } + + /** + * Adds a child changed callback. + * @param {(entity: Entity, child: Entity, added: boolean) => void} callback + */ + addChildChangedCallback(callback) { + this._childChangedCallbacks.push(callback); + } + + /** + * Removes a child changed callback. + * @param {(entity: Entity, child: Entity, added: boolean) => void} callback + */ + removeChildChangedCallback(callback) { + const index = this._childChangedCallbacks.indexOf(callback); + if (index !== -1) { + this._childChangedCallbacks.splice(index, 1); + } + } + + // COMPONENTS + + /** + * Gets the number of components. + * @returns {number} + */ + getNumComponents() { + return this._components.size; + } + + /** + * Gets the component from either the name or the index. It returns null if the component is not found. + * @param {string|number} nameOrIndex + * @returns {BaseComponent | null} + */ + getComponent(nameOrIndex) { + return this._components.get(nameOrIndex); + } + + /** + * Gets the index'th component of the given type. The index is base 0. Returns null if none is found. + * @param {string} type + * @param {number} [index=0] + * @returns {BaseComponent | null} + */ + getComponentByType(type, index = 0) { + return this._components.getByType(type, index); + } + + /** + * Gets the index'th component of the given type. The index is base 0. Returns null if none is found. + * @template {BaseComponent} Class + * @param {import('../utils/collection').TypeConstructor} ComponentClass + * @param {number} [index=0] + * @returns {Class | null} + */ + getComponentByClass(ComponentClass, index = 0) { + return this._components.getByClass(ComponentClass, index); + } + + /** + * Adds a component. + * @param {string} type - type of the component + * @param {string} [name=''] - name of the component (optional) + * @param {BaseComponent} [beforeComponent=undefined] - insert before this component (optional) + * @returns {BaseComponent} + */ + addComponent(type, name, beforeComponent) { + return this._components.add(type, name, beforeComponent); + } + + /** + * Create an item using with the given name and return it. + * @template {BaseComponent} Class + * @param {import('../utils/collection').TypeConstructor} ClassConstructor + * @param {string} [name=''] - the name of the item to be created + * @param {BaseComponent} [beforeComponent] - insert the item before this item + * @returns {Class} + */ + addComponentByClass(ClassConstructor, name, beforeComponent) { + return this._components.addByClass(ClassConstructor, name, beforeComponent); + } + + /** + * Removes a component. + * @param {BaseComponent|string|number} componentOrNameOrIndex - the component, name, or index to remove. + */ + removeComponent(componentOrNameOrIndex) { + this._components.remove(componentOrNameOrIndex); + } + + /** + * Removes all components. + */ + clearComponents() { + this._components.clear(); + } + + // CONTROLLERS + + /** + * Gets the number of controllers. + * @returns {number} + */ + getNumControllers() { + return this._controllers.size; + } + + /** + * Gets the controller from either the name or the index. It returns null if the controller is not found. + * @param {string|number} nameOrIndex + * @returns {BaseController | null} + */ + getController(nameOrIndex) { + return this._controllers.get(nameOrIndex); + } + + /** + * Gets the index'th controller of the given type. The index is base 0. Returns null if none is found. + * @param {string} type + * @param {number} [index=0] + * @returns {BaseController | null} + */ + getControllerByType(type, index = 0) { + return this._controllers.getByType(type, index); + } + + /** + * Gets the index'th controller of the given type. The index is base 0. Returns null if none is found. + * @template {BaseController} Class + * @param {import('../utils/collection').TypeConstructor} ControllerClass + * @param {number} [index=0] + * @returns {Class | null} + */ + getControllerByClass(ControllerClass, index = 0) { + return this._controllers.getByClass(ControllerClass, index); + } + + /** + * Adds a controller. + * @param {string} type - type of the controller + * @param {string} [name=''] - name of the controller (optional) + * @param {BaseController} [beforeController=undefined] - insert before this controller (optional) + * @returns {BaseController} + */ + addController(type, name, beforeController) { + const controller = this._controllers.add(type, name, beforeController); + this.__updateCoverage(); + return controller; + } + + /** + * Create an item using with the given name and return it. + * @template {BaseController} Class + * @param {import('../utils/collection').TypeConstructor} ClassConstructor + * @param {string} [name=''] - the name of the item to be created + * @param {BaseController} [beforeController] - insert the item before this item + * @returns {Class} + */ + addControllerByClass(ClassConstructor, name, beforeController) { + return this._controllers.addByClass(ClassConstructor, name, beforeController); + } + + /** + * Removes a controller. + * @param {BaseController|string|number} controllerOrNameOrIndex - the controller, name, or index to remove. + */ + removeController(controllerOrNameOrIndex) { + this._controllers.remove(controllerOrNameOrIndex); + this.__updateCoverage(); + } + + /** + * Removes all controllers. + */ + clearControllers() { + this._controllers.clear(); + this.__updateCoverage(); + } + + // CAMERA DEPENDENT POSITION AND RADII + + /** + * Gets the camera-space position relative to the camera (frozen). Returns Vector.NaN if there is no position for that camera. + * @param {CameraComponent} camera + * @returns {Vector3} + */ + getCameraSpacePosition(camera) { + const pos = this._cameraSpacePosition.get(camera); + if (pos !== undefined) { + return pos; + } + return _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]; + } + + /** + * Gets the normal-space position relative to the camera (frozen). Returns Vector.NaN if there is no position for that camera. + * @param {CameraComponent} camera + * @returns {Vector3} + */ + getNormalSpacePosition(camera) { + const pos = this._normalSpacePosition.get(camera); + if (pos !== undefined) { + return pos; + } + return _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]; + } + + /** + * Gets the pixel-space position (frozen). Returns Vector.NaN if there is no position for that camera. + * @param {CameraComponent} camera + * @returns {Vector2} + */ + getPixelSpacePosition(camera) { + const pos = this._pixelSpacePosition.get(camera); + if (pos !== undefined) { + return pos; + } + return _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2[NaN]; + } + + /** + * Gets the normal-space occlusion radius. Returns Number.NaN if there is no occlusion radius for that camera. + * @param {CameraComponent} camera + * @returns {number} + */ + getNormalSpaceOcclusionRadius(camera) { + if (this._extentsRadius !== 0) { + // Since normal-space radii are proportional to entity-space radii, + // we can just use the normal-space extents radius and multiply the factor. + return this.getNormalSpaceExtentsRadius(camera) * this._occlusionRadius / this._extentsRadius; + } + else { + return 0; + } + } + + /** + * Gets the normal-space extents radius. Returns Number.NaN if there is no extents radius for that camera. + * @param {CameraComponent} camera + * @returns {number} + */ + getNormalSpaceExtentsRadius(camera) { + const radius = this._normalSpaceExtentsRadius.get(camera); + if (radius !== undefined) { + return radius; + } + else { + return Number.NaN; + } + } + + /** + * Gets the pixel-space occlusion radius. Returns Number.NaN if there is no occlusion radius for that camera. + * @param {CameraComponent} camera + * @returns {number} + */ + getPixelSpaceOcclusionRadius(camera) { + if (this._extentsRadius !== 0) { + // Since pixel-space radii are proportional to entity-space radii, + // we can just use the pixel-space extents radius and multiply the factor. + return this.getPixelSpaceExtentsRadius(camera) * this._occlusionRadius / this._extentsRadius; + } + else { + return 0; + } + } + + /** + * Gets the pixel-space extents radius. Returns Number.NaN if there is no extents radius for that camera. + * @param {CameraComponent} camera + * @returns {number} + */ + getPixelSpaceExtentsRadius(camera) { + const radius = this._pixelSpaceExtentsRadius.get(camera); + if (radius !== undefined) { + return radius; + } + else { + return Number.NaN; + } + } + + /** + * Gets the greatest pixel-space occlusion radius in all cameras. + * @returns {number} + */ + getGreatestPixelSpaceOcclusionRadius() { + if (this._extentsRadius !== 0) { + // Since pixel-space radii are proportional to entity-space radii, + // we can just use the pixel-space extents radius and multiply the factor. + return this.getGreatestPixelSpaceExtentsRadius() * this._occlusionRadius / this._extentsRadius; + } + else { + return 0; + } + } + + /** + * Gets the greatest pixel-space extents radius in all cameras. + * @returns {number} + */ + getGreatestPixelSpaceExtentsRadius() { + return this._greatestPixelSpaceExtentsRadius; + } + + /** + * Sets the camera dependent variables. + * @param {CameraComponent} camera + * @param {Vector3} newCameraSpacePosition + * @internal + */ + __setCameraDependentVariables(camera, newCameraSpacePosition) { + // Get the viewport using the camera, and if none, do nothing. + const viewport = camera.getViewport(); + if (viewport === null) { + return; + } + + // Do the camera-space position. + let cameraSpacePosition = this._cameraSpacePosition.get(camera); + if (cameraSpacePosition === undefined) { + cameraSpacePosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._cameraSpacePosition.set(camera, cameraSpacePosition); + } + else { + cameraSpacePosition.thaw(); + } + cameraSpacePosition.copy(newCameraSpacePosition); + cameraSpacePosition.freeze(); + + // Do the normal-space position. + let normalSpacePosition = this._normalSpacePosition.get(camera); + if (normalSpacePosition === undefined) { + normalSpacePosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + this._normalSpacePosition.set(camera, normalSpacePosition); + } + else { + normalSpacePosition.thaw(); + } + camera.getNormalSpacePositionFromCameraSpacePosition(normalSpacePosition, cameraSpacePosition); + normalSpacePosition.freeze(); + + // Do the pixel-space position. + let pixelSpacePosition = this._pixelSpacePosition.get(camera); + if (pixelSpacePosition === undefined) { + pixelSpacePosition = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + this._pixelSpacePosition.set(camera, pixelSpacePosition); + } + else { + pixelSpacePosition.thaw(); + } + viewport.getPixelSpacePositionFromNormalSpacePosition(pixelSpacePosition, normalSpacePosition); + pixelSpacePosition.freeze(); + + // Do the normal-space extents radius. + const normalSpaceExtentsRadius = camera.getNormalSpaceRadiusFromRadius(this._extentsRadius, cameraSpacePosition.magnitude()); + this._normalSpaceExtentsRadius.set(camera, normalSpaceExtentsRadius); + + // Do the pixel-space extents radius. + const pixelSpaceExtentsRadius = viewport.getPixelSpaceRadiusFromNormalSpaceRadius(normalSpaceExtentsRadius); + this._pixelSpaceExtentsRadius.set(camera, pixelSpaceExtentsRadius); + } + + /** + * Removes the camera from any camera-dependent variables. Called during camera clean up. + * @param {CameraComponent} camera + * @internal */ + __removeCameraDependents(camera) { + this._cameraSpacePosition.delete(camera); + this._normalSpacePosition.delete(camera); + this._pixelSpacePosition.delete(camera); + this._normalSpaceExtentsRadius.delete(camera); + this._pixelSpaceExtentsRadius.delete(camera); + for (let i = 0; i < this._components.size; i++) { + this._components.get(i).__removeCameraDependentsBase(camera); + } + } + + // GET + + /** + * Gets the component or controller described in the parameters. It is a shortcut function to make things easier on the user. It returns undefined if it is not found. + * @param {string} componentOrControllerType - the type of the component or controller [optional] + * @param {number} [componentOrControllerTypeIndex=0] - the index of the type, in case there are more than one of the same type [optional] + * @returns {BaseComponent|BaseController} + */ + get(componentOrControllerType, componentOrControllerTypeIndex = 0) { + const component = this._components.getByType(componentOrControllerType, componentOrControllerTypeIndex); + if (component !== null) { + return component; + } + else { + return this._controllers.getByType(componentOrControllerType, componentOrControllerTypeIndex); + } + } + + // LOADING + + /** + * Returns a new promise that resolves when every component is loaded. + * @returns {Promise} + */ + getLoadedPromise() { + const promises = []; + if (this.isEnabled()) { + for (let i = 0; i < this._controllers.size; i++) { + promises.push(this._controllers.get(i).getLoadedPromise()); + } + for (let i = 0; i < this._components.size; i++) { + promises.push(this._components.get(i).getLoadedPromise()); + } + } + return Promise.all(promises).then(); + } + + /** + * Converts the entity to a nice string. + * @override + * @returns {string} + */ + toString() { + return this.getName(); + } + + // CLEANUP + + /** + * Destroys the entity resources. + * @override + * @internal + */ + __destroy() { + // Set the destroyed flag to true. + this._destroyed = true; + + // Call super. + super.__destroy(); + + // Disconnect all of the children from this. + for (let i = 0; i < this._children.length; i++) { + this._children[i].setParent(null); + } + // Disconnect this from its parent. + if (this._parent !== null) { + this.setParent(null); + } + // Destroy the controllers. + this._controllers.__destroy(); + // Destroy the components. + this._components.__destroy(); + } + + // MAIN LOOP FUNCTIONS + + /** + * Updates the parents of the entity via the controllers. + * @param {number} currentTime + * @internal + */ + __updateParent(currentTime) { + const parentName = this.getParentAtTime(currentTime); + if (parentName !== '') { + const parent = this.getScene().getEntity(parentName); + if (parent !== this._parent) { + this.setParent(parent); + } + } + else if (this._parent !== null) { + this.setParent(null); + } + + if (this._parent !== this._lastParent) { + // Notify the controller dependency graph that it needs resorting. + this.getScene().getControllerDependencyGraph().needsSorting(); + this._lastParent = this._parent; + } + } + + /** + * Updates the flags that are true if the entity's coverages contain the current time. + * @param {number} currentTime + * @internal + */ + __updateIsInCoverages(currentTime) { + this._isInPositionCoverage = this._positionCoverage.contains(currentTime); + this._isInOrientationCoverage = this._orientationCoverage.contains(currentTime); + + // Update the component load states, which depends on the position and orientation coverage. + for (let i = 0; i < this._components.size; i++) { + this._components.get(i).__updateLoadState(); + } + } + + /** + * Updates the greatest pixel-space radii and the camera-non-specific parts of the components. + * @internal + */ + __updateVisuals() { + // Update the greatest pixel extents radius for use by components and controllers. + this._greatestPixelSpaceExtentsRadius = 0.0; + for (let i = 0, l = this._pixelSpaceExtentsRadius.size; i < l; i++) { + const pixelSpaceExtentsRadius = this._pixelSpaceExtentsRadius.getAt(i).value; + if (this._greatestPixelSpaceExtentsRadius < pixelSpaceExtentsRadius) { + this._greatestPixelSpaceExtentsRadius = pixelSpaceExtentsRadius; + } + } + + // Updates the camera-independent parts of the components. + for (let i = 0, l = this._components.size; i < l; i++) { + const component = this._components.get(i); + if (component.isEnabled()) { + component.__updateBase(); + } + } + } + + /** + * It traverses the scene graph, starting with the camera, setting the camera-space positions, and updating the occlusion. + * @param {CameraComponent} camera - the camera we're rendering + * @param {Entity} comingFrom - the entity we just came from + * @param {boolean} comingFromChild - true if comingFrom is a child of this + * @internal + */ + __updateCameraVariables(camera, comingFrom, comingFromChild) { + if (this.isEnabled()) { + // Update this camera-space position relative to the child that we're coming from. + const cameraSpacePosition = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (this === camera.getEntity()) { + // We're the camera, so we're always at the camera-space origin. + cameraSpacePosition.set(0, 0, 0); + } + else if (comingFromChild) { + // We're moving up the scene graph toward the root, so we get the child's world position and add the negative position. + cameraSpacePosition.sub(comingFrom.getCameraSpacePosition(camera), comingFrom.getPosition()); + } + else { + // We're moving down the scene graph, so we just add on the local to the parent world position. + cameraSpacePosition.add(comingFrom.getCameraSpacePosition(camera), this._state.position); + } + this.__setCameraDependentVariables(camera, cameraSpacePosition); + + // Add the entity to the occluding entities if its radius is large enough. + if (this._canOcclude && this.getPixelSpaceOcclusionRadius(camera) >= 1) { + camera.__addToOccludingEntities(this); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraSpacePosition); + + // Updates the camera-dependent parts of the components. + for (let i = 0, l = this._components.size; i < l; i++) { + const component = this._components.get(i); + if (component !== camera && component.isEnabled()) { + component.__updateCameraVariablesBase(camera); + } + } + } + + // Update the parent if we're still going up. Update the parent position. + if (this._parent !== null && (comingFromChild || this === camera.getEntity())) { + this._parent.__updateCameraVariables(camera, this, true); + } + + // Update the children. + for (let i = 0, l = this._children.length; i < l; i++) { + const child = this._children[i]; + if (child === comingFrom) { + continue; // don't go back down a child that we've already updated. + } + child.__updateCameraVariables(camera, this, false); + } + } + + /** + * Prepares all of its components for rendering. + * @param {CameraComponent} camera - the camera we're rendering + * @internal + */ + __prepareForRender(camera) { + // Prepare the components for render. + for (let i = 0, l = this._components.size; i < l; i++) { + const component = this._components.get(i); + if (!('__render' in component)) { + component.__prepareForRenderBase(camera); + } + } + } +} + +class EntityState { + constructor() { + /** + * The position of the entity relative to its parent's position. + * @type {Vector3} + */ + this.position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(Number.NaN, Number.NaN, Number.NaN); + this.position.freeze(); + + /** + * The velocity of the entity. + * @type {Vector3} + */ + this.velocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(Number.NaN, Number.NaN, Number.NaN); + this.velocity.freeze(); + + /** + * The orientation of the entity. Not relative to parent. + * @type {Quaternion} + */ + this.orientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(Number.NaN, Number.NaN, Number.NaN, Number.NaN); + this.orientation.freeze(); + + /** + * The rotational velocity of the entity. Not relative to parent. + * @type {Vector3} + */ + this.angularVelocity = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(Number.NaN, Number.NaN, Number.NaN); + this.angularVelocity.freeze(); + } +} + +// Functions for the start time to parent list sorting. + +/** + * Returns true if a < b. + * @param {[number, string]} a + * @param {[number, string]} b + */ +function isStartTimeLess(a, b) { + return a[0] < b[0]; +} + +/** + * Returns true if a === b. + * @param {[number, string]} a + * @param {[number, string]} b + */ +function isStartTimeEqual(a, b) { + return a[0] === b[0]; +} + +/** + * Returns true if a < b. + * @param {[number, string]} a + * @param {number} b + */ +function isStartTimeLessThanTime(a, b) { + return a[0] < b; +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/entity_item.js": +/*!**************************************************!*\ + !*** ../pioneer/engine/src/scene/entity_item.js ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "EntityItem": function() { return /* binding */ EntityItem; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The base class for all components and controllers. + * @extends {CollectionItem} + */ +class EntityItem extends _internal__WEBPACK_IMPORTED_MODULE_0__.CollectionItem { + /** + * Constructor. + * @param {string} type - The type of the entity item. + * @param {string} name - The name of the entity item. + * @param {Entity} entity - The containing entity. + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * Flag that indicates whether the entity item is enabled or disabled. + * @type {boolean} + * @private + */ + this._enabled = true; + + /** + * Flag that indicates whether the item has been destroyed. + * @type {boolean} + * @private + */ + this._destroyed = false; + } + + /** + * Returns the entity that contains the entity item. + * @returns {Entity} + */ + getEntity() { + return this.__getCollectionParent(); + } + + /** + * Checks if the entity item has been destroyed. + * @returns {boolean} + */ + isDestroyed() { + return this._destroyed; + } + + /** + * Destroys the entity item's resources. + * @override + * @abstract + */ + __destroy() { + this._destroyed = true; + super.__destroy(); + } + + /** + * Returns true if the entity item is enabled. + * @returns {boolean} + */ + isEnabled() { + return this._enabled; + } + + /** + * Sets whether the entity item is enabled. + * @param {boolean} enabled + */ + setEnabled(enabled) { + this._enabled = enabled; + } + + /** + * Returns a new promise that resolves when the component is loaded. + * @returns {Promise} + */ + getLoadedPromise() { + return Promise.resolve(); + } + + /** + * Updates the entity item. + * @abstract + */ + __update() { + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/scene.js": +/*!********************************************!*\ + !*** ../pioneer/engine/src/scene/scene.js ***! + \********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Scene": function() { return /* binding */ Scene; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The scene which contains all entities. + * @extends {CollectionItem} + */ +class Scene extends _internal__WEBPACK_IMPORTED_MODULE_0__.CollectionItem { + /** + * Constructs the scene. + * @param {string} type - the type of the scene (always 'scene'); + * @param {string} name - the name of the scene + * @param {Engine} engine - the Pioneer engine + */ + constructor(type, name, engine) { + super(type, name, engine); + + /** + * The collection of entities. + * @type {Collection} + * @private + */ + this._entities = new _internal__WEBPACK_IMPORTED_MODULE_0__.Collection(this, new Map([['entity', _internal__WEBPACK_IMPORTED_MODULE_0__.Entity]])); + + /** + * The controller dependency graph. + * @type {DependencyGraph} + * @private + */ + this._controllerDependencyGraph = new _internal__WEBPACK_IMPORTED_MODULE_0__.DependencyGraph(); + + /** + * The ambient light color. The amount of light when there are no light sources. + * @type {Color} + * @private + */ + this._ambientLightColor = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0.02, 0.02, 0.02); + this._ambientLightColor.freeze(); + + /** + * The list of light sources. + * @type {Array>} + * @private + */ + this._lightSources = []; + + /** + * The ThreeJS scene. + * @type {THREE.Scene} + * @private + */ + this._threeJsScene = null; + + // Initialize Three.JS + this._threeJsScene = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Scene(); + + // Setup the controller dependency graph functions. + this._controllerDependencyGraph.setUpdateItemCallback((controller) => { + if (controller.getEntity().isEnabled() && controller.getCoverage().contains(controller.getEntity().getScene().getEngine().getTime()) && controller.isEnabled()) { + controller.__update(); + } + }); + this._controllerDependencyGraph.setCompareItemCallback((a, b) => { + if (a === b) { + return false; + } + if (!a.getEntity().isEnabled() || !b.getEntity().isEnabled() || !a.isEnabled() || !b.isEnabled()) { + return false; + } + const time = a.getEntity().getScene().getEngine().getTime(); + if (!a.getCoverage().contains(time) || !b.getCoverage().contains(time)) { + return false; + } + + // Ensure that later controllers in an entity are dependent on earlier controllers. + if (a.getEntity() === b.getEntity()) { + const entity = a.getEntity(); + for (let i = 0, l = entity.getNumControllers(); i < l; i++) { + const controller = entity.getController(i); + if (b === controller) { + return true; + } + if (a === controller) { + break; + } + } + } + + // Children's controllers are dependent on parent's controllers for position and velocity. + if (a.getEntity().getParent() === b.getEntity()) { + if ((a.hasModifiedState('position') && b.hasModifiedState('position')) || (a.hasModifiedState('velocity') && b.hasModifiedState('velocity'))) { + return true; + } + // A special case for 'parent' as a shortcut to whatever the parent is, since it happens so often. + for (const modifiedState of b.__modifiedStates) { + if (a.hasDependentState('parent', modifiedState)) { + return true; + } + } + } + + // Check if a's dependent states are in b's modified states. + for (const modifiedState of b.__modifiedStates) { + if (a.hasDependentState(b.getEntity().getName(), modifiedState)) { + return true; + } + } + + return false; + }); + } + + /** + * Returns the engine. + * @returns {Engine} + */ + getEngine() { + return this.__getCollectionParent(); + } + + /** + * Gets an entity by name. + * @param {string|number} nameOrIndex - the name or index of the entity + * @returns {Entity} + */ + getEntity(nameOrIndex) { + return this._entities.get(nameOrIndex); + } + + /** + * Gets the number of entities. + * @returns {number} + */ + getNumEntities() { + return this._entities.size; + } + + /** + * Adds an entity. + * @param {string} name - the name of the entity to be added + * @returns {Entity} + */ + addEntity(name) { + return this._entities.add('entity', name); + } + + /** + * Removes an entity. + * @param {Entity|string|number} entityOrNameOrIndex - the entity, name, or index to be removed + */ + removeEntity(entityOrNameOrIndex) { + this._entities.remove(entityOrNameOrIndex); + } + + /** + * Moves an entity to another scene. + * @param {Entity|string|number} entityOrNameOrIndex - the entity, name, or index to be moved + * @param {Scene} scene - the other scene to which the entity will be moved + */ + moveEntity(entityOrNameOrIndex, scene) { + const entity = this._entities.get(entityOrNameOrIndex); + this._entities.move(entityOrNameOrIndex, scene._entities); + // Update the controller dependency graph for both. + for (let i = 0, l = entity.getNumControllers(); i < l; i++) { + this._controllerDependencyGraph.removeItem(entity.getController(i)); + scene._controllerDependencyGraph.addItem(entity.getController(i)); + } + // Update any light sources. + for (let i = 0, l = entity.getNumComponents(); i < l; i++) { + const component = entity.getComponent(i); + if (component.getType() === 'lightSource' && component.getLoadState() === 'loaded') { + for (let j = 0, k = this._lightSources.length; j < k; j++) { + if (this._lightSources[j].getEntityName() === entity.getName() + && this._lightSources[j].getComponentTypeIndex() === component.getTypeIndex()) { + this.__removeLightSource(entity.getName(), component.getTypeIndex()); + this.__addLightSource(entity.getName(), component.getTypeIndex()); + break; + } + } + } + } + } + + /** + * Gets the entity, component, or controller described in the parameters. If the component/controller type is omitted, it will return the entity. It is a shortcut function to make things easier on the user. It returns undefined if it is not found. + * @param {string} entityNameOrIndex - the name or index of the entity + * @param {string?} componentOrControllerType - the type of the component or controller [optional] + * @param {number?} componentOrControllerTypeIndex - the index of the type, in case there are more than one of the same type [optional] + * @returns {Entity|BaseComponent|BaseController} + */ + get(entityNameOrIndex, componentOrControllerType = undefined, componentOrControllerTypeIndex = 0) { + const entity = this._entities.get(entityNameOrIndex); + if (componentOrControllerType === undefined || entity === null) { + return entity; + } + return entity.get(componentOrControllerType, componentOrControllerTypeIndex); + } + + /** + * Gets the controller dependency graph. + * @returns {DependencyGraph} + */ + getControllerDependencyGraph() { + return this._controllerDependencyGraph; + } + + /** + * Gets the ambient light color. Defaults to RGB(0.02, 0.02, 0.02). + * @returns {Color} + */ + getAmbientLightColor() { + return this._ambientLightColor; + } + + /** + * Sets the ambient light color. + * @param {Color} color + */ + setAmbientLightColor(color) { + this._ambientLightColor.thaw(); + this._ambientLightColor.copy(color); + this._ambientLightColor.freeze(); + } + + /** + * Adds a light source. Does nothing if it already is added. It should only be called by the LightSourceComponent. + * @param {string} entityName - The name of the entity that has the light source. + * @param {number} typeIndex - If there is more than one light source component on an entity, this specifies which one. + * @internal + */ + __addLightSource(entityName, typeIndex = 0) { + // If there is already a light source of the given entity name and type index, do nothing. + for (let i = 0, l = this._lightSources.length; i < l; i++) { + const otherLightSource = this._lightSources[i]; + if (otherLightSource.getEntityName() === entityName + && otherLightSource.getComponentTypeIndex() === typeIndex) { + throw new Error(`Light source on ${entityName} with type index ${typeIndex} already added.`); + } + } + // Add the new light source. + const lightSource = /** @type {ComponentRef} */(new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this)); + lightSource.setByType(entityName, 'lightSource', typeIndex); + this._lightSources.push(lightSource); + } + + /** + * Removes a light source. Does nothing if it already is removed. It should only be called by the LightSourceComponent. + * @param {string} entityName - The name of the entity that has the light source. + * @param {number} typeIndex - If there is more than one light source component on an entity, this specifies which one. + * @internal + */ + __removeLightSource(entityName, typeIndex = 0) { + for (let i = 0, l = this._lightSources.length; i < l; i++) { + const otherLightSource = this._lightSources[i]; + if (otherLightSource.getEntityName() === entityName + && otherLightSource.getComponentTypeIndex() === typeIndex) { + // Remove the light source. + this._lightSources.splice(i, 1); + return; + } + } + throw new Error(`Light source on ${entityName} with type index ${typeIndex} not found.`); + } + + /** + * Gets the light source at index i. + * @param {number} i + * @returns {LightSourceComponent} + */ + getLightSource(i) { + if (0 <= i && i < this._lightSources.length) { + return this._lightSources[i].get(); + } + return null; + } + + /** + * Gets the number of light sources. + * @returns {number} + */ + getNumLightSources() { + return this._lightSources.length; + } + + /** + * Returns a new promise that resolves when every entity is loaded. + * @returns {Promise} + */ + getLoadedPromise() { + const promises = []; + for (let i = 0, l = this._entities.size; i < l; i++) { + promises.push(this._entities.get(i).getLoadedPromise()); + } + return Promise.all(promises).then(); + } + + /** + * Cleans up the scene. + * @override + * @internal + */ + __destroy() { + super.__destroy(); + + this._entities.__destroy(); + } + + /** + * Returns the ThreeJS scene so that components can use it. + * @returns {THREE.Scene} + */ + getThreeJsScene() { + return this._threeJsScene; + } + + /** + * Updates the scene. Updates parents, is-in-coverages, and calls update on all entities' controllers using the dependency graph. + * @internal + */ + __update() { + const currentTime = this.getEngine().getTime(); + for (let i = this._entities.size - 1; i >= 0; i--) { + const entity = this._entities.get(i); + entity.__updateLastState(); + entity.__updateParent(currentTime); + entity.__updateIsInCoverages(currentTime); + } + + this._controllerDependencyGraph.update(); + } + + /** + * Updates the camera-non-specific visual parts of the entities. + * @internal + */ + __updateVisuals() { + for (let i = this._entities.size - 1; i >= 0; i--) { + const entity = this._entities.get(i); + if (entity.isInPositionCoverage() && entity.isEnabled()) { + this._entities.get(i).__updateVisuals(); + } + } + } + + /** + * Removes the camera from any camera-dependent variables. Called by camera on clean up. + * @param {CameraComponent} camera + * @internal */ + __removeCameraDependents(camera) { + for (let i = this._entities.size - 1; i >= 0; i--) { + this._entities.get(i).__removeCameraDependents(camera); + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/scene/types.js": +/*!********************************************!*\ + !*** ../pioneer/engine/src/scene/types.js ***! + \********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Types": function() { return /* binding */ Types; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The class that holds the different mappings from component and controller names to their corresponding constructors. + */ +class Types { +} + +/** + * @typedef {typeof Pioneer.BaseComponent} BaseComponentType + */ + +/** + * The mapping of component type names to component constructors. + * @type {Map} + * @internal + */ +Types.Components = new Map(); +Types.Components.set('atmosphere', _internal__WEBPACK_IMPORTED_MODULE_0__.AtmosphereComponent); +Types.Components.set('camera', _internal__WEBPACK_IMPORTED_MODULE_0__.CameraComponent); +Types.Components.set('cmts', _internal__WEBPACK_IMPORTED_MODULE_0__.CMTSComponent); +Types.Components.set('cometTail', _internal__WEBPACK_IMPORTED_MODULE_0__.CometTailComponent); +Types.Components.set('connectedSprite', _internal__WEBPACK_IMPORTED_MODULE_0__.ConnectedSpriteComponent); +Types.Components.set('div', _internal__WEBPACK_IMPORTED_MODULE_0__.DivComponent); +Types.Components.set('dynEnvMap', _internal__WEBPACK_IMPORTED_MODULE_0__.DynamicEnvironmentMapComponent); +Types.Components.set('gizmo', _internal__WEBPACK_IMPORTED_MODULE_0__.GizmoComponent); +Types.Components.set('label', _internal__WEBPACK_IMPORTED_MODULE_0__.LabelComponent); +Types.Components.set('lightSource', _internal__WEBPACK_IMPORTED_MODULE_0__.LightSourceComponent); +Types.Components.set('model', _internal__WEBPACK_IMPORTED_MODULE_0__.ModelComponent); +Types.Components.set('orbitalParticles', _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalParticlesComponent); +Types.Components.set('particleSpray', _internal__WEBPACK_IMPORTED_MODULE_0__.ParticleSprayComponent); +Types.Components.set('rings', _internal__WEBPACK_IMPORTED_MODULE_0__.RingsComponent); +Types.Components.set('skybox', _internal__WEBPACK_IMPORTED_MODULE_0__.SkyboxComponent); +Types.Components.set('spheroid', _internal__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent); +Types.Components.set('spheroidLOD', _internal__WEBPACK_IMPORTED_MODULE_0__.SpheroidLODComponent); +Types.Components.set('spout', _internal__WEBPACK_IMPORTED_MODULE_0__.SpoutComponent); +Types.Components.set('sprite', _internal__WEBPACK_IMPORTED_MODULE_0__.SpriteComponent); +Types.Components.set('starfield', _internal__WEBPACK_IMPORTED_MODULE_0__.StarfieldComponent); +Types.Components.set('trail', _internal__WEBPACK_IMPORTED_MODULE_0__.TrailComponent); + +/** + * @typedef {typeof Pioneer.BaseController} BaseControllerType + */ + +/** + * The mapping of controller type names to controller constructors. + * @type {Map} + * @internal + */ +Types.Controllers = new Map(); +Types.Controllers.set('align', _internal__WEBPACK_IMPORTED_MODULE_0__.AlignController); +Types.Controllers.set('animdata', _internal__WEBPACK_IMPORTED_MODULE_0__.AnimdataController); +Types.Controllers.set('coverage', _internal__WEBPACK_IMPORTED_MODULE_0__.CoverageController); +Types.Controllers.set('dynamo', _internal__WEBPACK_IMPORTED_MODULE_0__.DynamoController); +Types.Controllers.set('fixed', _internal__WEBPACK_IMPORTED_MODULE_0__.FixedController); +Types.Controllers.set('fixedToParent', _internal__WEBPACK_IMPORTED_MODULE_0__.FixedToParentController); +Types.Controllers.set('freeFly', _internal__WEBPACK_IMPORTED_MODULE_0__.FreeFlyController); +Types.Controllers.set('groundClamp', _internal__WEBPACK_IMPORTED_MODULE_0__.GroundClampController); +Types.Controllers.set('keyframe', _internal__WEBPACK_IMPORTED_MODULE_0__.KeyframeController); +Types.Controllers.set('look', _internal__WEBPACK_IMPORTED_MODULE_0__.LookController); +Types.Controllers.set('modelAnimate', _internal__WEBPACK_IMPORTED_MODULE_0__.ModelAnimateController); +Types.Controllers.set('orbit', _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitController); +Types.Controllers.set('orbitKeyframe', _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitKeyframeController); +Types.Controllers.set('orbitalElements', _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalElementsController); +Types.Controllers.set('pick', _internal__WEBPACK_IMPORTED_MODULE_0__.PickController); +Types.Controllers.set('roll', _internal__WEBPACK_IMPORTED_MODULE_0__.RollController); +Types.Controllers.set('rotate', _internal__WEBPACK_IMPORTED_MODULE_0__.RotateController); +Types.Controllers.set('rotateByEntityOrientation', _internal__WEBPACK_IMPORTED_MODULE_0__.RotateByEntityOrientationController); +Types.Controllers.set('scale', _internal__WEBPACK_IMPORTED_MODULE_0__.ScaleController); +Types.Controllers.set('select', _internal__WEBPACK_IMPORTED_MODULE_0__.SelectController); +Types.Controllers.set('setParent', _internal__WEBPACK_IMPORTED_MODULE_0__.SetParentController); +Types.Controllers.set('spin', _internal__WEBPACK_IMPORTED_MODULE_0__.SpinController); +Types.Controllers.set('tap', _internal__WEBPACK_IMPORTED_MODULE_0__.TapController); +Types.Controllers.set('transition', _internal__WEBPACK_IMPORTED_MODULE_0__.TransitionController); +Types.Controllers.set('translate', _internal__WEBPACK_IMPORTED_MODULE_0__.TranslateController); +Types.Controllers.set('zoom', _internal__WEBPACK_IMPORTED_MODULE_0__.ZoomController); + + + + +/***/ }), + +/***/ "../pioneer/engine/src/shaders/basic.js": +/*!**********************************************!*\ + !*** ../pioneer/engine/src/shaders/basic.js ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "BasicShader": function() { return /* binding */ BasicShader; } +/* harmony export */ }); +/* harmony import */ var _log_depth__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./log_depth */ "../pioneer/engine/src/shaders/log_depth.js"); + + +const BasicShader = { + uniforms: { + modelViewMatrix: 'mat4', + projectionMatrix: 'highp mat4', + + color: 'vec4', + + ..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms + }, + properties: {}, + vertex: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + attribute vec3 position; + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + ` + }, + fragment: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + precision highp float; + + uniform vec4 color; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main() { + gl_FragColor = color; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + ` + } +}; + + +/***/ }), + +/***/ "../pioneer/engine/src/shaders/basic_alpha.js": +/*!****************************************************!*\ + !*** ../pioneer/engine/src/shaders/basic_alpha.js ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "BasicAlphaShader": function() { return /* binding */ BasicAlphaShader; } +/* harmony export */ }); +/* harmony import */ var _log_depth__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./log_depth */ "../pioneer/engine/src/shaders/log_depth.js"); + + +const BasicAlphaShader = { + uniforms: { + modelViewMatrix: 'mat4', + projectionMatrix: 'highp mat4', + + color: 'vec4', + + ..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms + }, + properties: { + transparent: true, + depthWrite: false, + side: 'double', + blending: 'normal' + }, + vertex: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + attribute vec3 position; + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + ` + }, + fragment: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + precision highp float; + + uniform vec4 color; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main() { + gl_FragColor = color; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + ` + } +}; + + +/***/ }), + +/***/ "../pioneer/engine/src/shaders/connected_sprite.js": +/*!*********************************************************!*\ + !*** ../pioneer/engine/src/shaders/connected_sprite.js ***! + \*********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ConnectedSpriteShader": function() { return /* binding */ ConnectedSpriteShader; } +/* harmony export */ }); +/* harmony import */ var _log_depth__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./log_depth */ "../pioneer/engine/src/shaders/log_depth.js"); + + +const ConnectedSpriteShader = { + uniforms: { + projectionMatrix: 'highp mat4', + vAxis: 'vec3', + color: 'vec4', + colorTexture: 'sampler2D', + width1: 'float', + width2: 'float', + textureYOffset: 'float', + repeatAmount: 'float', + + ..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms + }, + properties: { + side: 'double', + transparent: true, + depthWrite: false, + blending: 'normal' + }, + vertex: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + attribute vec2 position; + + uniform mat4 modelMatrix; + uniform mat4 viewMatrix; + uniform mat4 projectionMatrix; + + uniform vec3 vAxis; + uniform float width1; + uniform float width2; + + varying vec2 vPosition; + varying float vU; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + + // Get the horizontal axis. + float width = mix(width1, width2, position.y); + vec3 viewVAxis = (viewMatrix * vec4(vAxis, 0)).xyz; + vec2 viewHAxisXZ = normalize(cross(vec3(0, 1, 0), viewVAxis)).xz; + vec4 viewHAxis = vec4(viewHAxisXZ.x, 0, viewHAxisXZ.y, 0); + + // Get the view position. + vec4 modelPosition = modelMatrix * vec4(0, 0, 0, 1) + vec4(vAxis, 0) * position.y; + vec4 viewPosition = viewMatrix * modelPosition; + + // Set the final projected position. + gl_Position = projectionMatrix * viewPosition + projectionMatrix * viewHAxis * width * position.x; + + // Setup a vPosition and vU for use in the fragment shader. + vPosition = vec2(0.5 * (position.x + 1.0), position.y); + #ifdef PIXEL_BASED + vPosition.y *= abs(gl_Position.w); + #endif + vU = position.y; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }` + }, + fragment: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + precision highp float; + + uniform vec4 color; + uniform sampler2D colorTexture; + uniform float width1; + uniform float width2; + uniform float textureYOffset; + uniform float repeatAmount; + + varying vec2 vPosition; + varying float vU; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main() { + + // If we're using pixel-based, we need to undo the perspective divide that happened. + #ifdef PIXEL_BASED + vec2 uv = vec2(vPosition.x, vPosition.y * gl_FragCoord.w); + #else + vec2 uv = vPosition; + #endif + + // Get a correct use that uses the repeat amount and y offset. + // There's a complicated formula, because the widths may be different and the shape of the sprite may be a trapezoid. + float f = width2 * vU / (width1 * (1.0 - vU) + width2 * vU); + float uFactor = step(vU, uv.x); + uv.x = (1.0 - uFactor) * uv.x * f / vU + uFactor * (1.0 + (uv.x - 1.0) * (1.0 - f) / (1.0 - vU)); + uv.y = uv.y * repeatAmount + textureYOffset; + + // Apply the texture and color. + gl_FragColor = color * texture2D(colorTexture, uv); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }` + } +}; + + +/***/ }), + +/***/ "../pioneer/engine/src/shaders/line.js": +/*!*********************************************!*\ + !*** ../pioneer/engine/src/shaders/line.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LineShader": function() { return /* binding */ LineShader; } +/* harmony export */ }); +/* harmony import */ var _log_depth__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./log_depth */ "../pioneer/engine/src/shaders/log_depth.js"); + + +const LineShader = { + uniforms: { + modelViewMatrix: 'mat4', + projectionMatrix: 'highp mat4', + + pixelSize: 'vec2', + alphaMultiplier: 'float', + dashLength: 'float', + dashGapLength: 'float', + glowWidth: 'float', + + ..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms + }, + properties: { + transparent: true, + depthWrite: false, + side: 'double', + blending: 'additive' + }, + vertex: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + attribute vec3 position; + attribute vec3 positionPrev; + attribute vec3 positionNext; + attribute vec4 color; + attribute float width; + attribute float dashOffset; + + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + uniform vec2 pixelSize; + uniform float glowWidth; + + varying vec4 fColor; + varying float fDashOffset; + varying float fWidth; + varying float fOffsetScalar; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + // Get the line vertices into pixel space. + vec4 view_center = modelViewMatrix * vec4(position, 1.0); + vec4 view_prev = modelViewMatrix * vec4(positionPrev, 1.0); + vec4 view_next = modelViewMatrix * vec4(positionNext, 1.0); + vec4 projected_center = projectionMatrix * view_center; + vec4 projected_prev = projectionMatrix * view_prev; + vec4 projected_next = projectionMatrix * view_next; + vec2 ndc_center = projected_center.xy / view_center.y; + vec2 ndc_prev = projected_prev.xy / view_prev.y; + vec2 ndc_next = projected_next.xy / view_next.y; + vec2 pixel_center = (ndc_center.xy + 1.0) / 2.0 * pixelSize; + vec2 pixel_prev = (ndc_prev.xy + 1.0) / 2.0 * pixelSize; + vec2 pixel_next = (ndc_next.xy + 1.0) / 2.0 * pixelSize; + + // Get the offset of the part perpendicular to the lines. + vec2 l0 = normalize(pixel_center - pixel_prev); + vec2 l1 = normalize(pixel_next - pixel_center); + float offsetScalar = sign(width) * (abs(width) / 2.0 + glowWidth); + vec2 offset = vec2(offsetScalar, offsetScalar); + if (pixel_center == pixel_prev) { + if (pixel_center == pixel_next) { + offset = vec2(0.0, 0.0); + } + else { + offset *= vec2(-l1.y, l1.x); + } + } + else if (pixel_center == pixel_next) { + offset *= vec2(-l0.y, l0.x); + } + else { + offset *= normalize(vec2(-l0.y - l1.y, l0.x + l1.x)); + offset /= max(0.25, sqrt((1.0 + dot(l0, l1)) / 2.0)); + } + + // Re-add the perpendicular part to the center as the final vertex. + ndc_center = (pixel_center + offset) / pixelSize * 2.0 - 1.0; + gl_Position = vec4(ndc_center * view_center.y, projected_center.z, projected_center.w); + + // Set the varyings. + fColor = color; + fDashOffset = dashOffset; + fWidth = width; + fOffsetScalar = offsetScalar; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + ` + }, + fragment: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + precision highp float; + + uniform float alphaMultiplier; + uniform float dashLength; + uniform float dashGapLength; + uniform float glowWidth; + + varying vec4 fColor; + varying float fDashOffset; + varying float fWidth; + varying float fOffsetScalar; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + float line_dash_func() { + float u = mod(fDashOffset, dashLength + dashGapLength); + return float(u < dashLength); + } + + float edgeGlow() { + if (glowWidth > 0.0) { + float value = clamp((fWidth / 2.0 + glowWidth - abs(fOffsetScalar)) / glowWidth, 0.0, 1.0); + if (value < 1.0) { + value *= 0.75; + } + return value; + } + return 1.0; + } + + void main() { + gl_FragColor = fColor; + gl_FragColor.a *= alphaMultiplier * edgeGlow() * line_dash_func(); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + ` + } +}; + + +/***/ }), + +/***/ "../pioneer/engine/src/shaders/log_depth.js": +/*!**************************************************!*\ + !*** ../pioneer/engine/src/shaders/log_depth.js ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ShaderChunkLogDepth": function() { return /* binding */ ShaderChunkLogDepth; } +/* harmony export */ }); +/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ "../pioneer/engine/node_modules/three/build/three.module.js"); + + +class ShaderChunkLogDepth { + /** Uniforms for the built-in shaders. */ + static Uniforms = { + invertDepth: 'float', + nearDistance: 'float', + midDistance: 'float' + }; + + /** Code for the header of the vertex shader. */ + static VertexHead = ` + #ifdef L_EXT_frag_depth + varying float depth; + #else + uniform float nearDistance; + uniform float midDistance; + #endif + `; + + /** Code for the end of the vertex shader main() function. */ + static Vertex = ` + #ifdef L_EXT_frag_depth + depth = gl_Position.w; + #else + float z = gl_Position.w; + if (z < midDistance) { + gl_Position.z = nearDistance * (z - midDistance) / (midDistance - nearDistance); + } + else { + float logFactor = 0.01254291648; // 1 / log2(1e24 - midDistance + 1.0) + gl_Position.z = log2(z - midDistance + 1.0) * logFactor; + gl_Position.z *= gl_Position.w; + } + #endif + `; + + /** Code for the header of the fragment shader. */ + static FragmentHead = ` + #ifdef L_EXT_frag_depth + uniform float invertDepth; + uniform float nearDistance; + uniform float midDistance; + varying float depth; + #endif + `; + + /** Code for the end of the fragment shader main() function. */ + static Fragment = ` + #ifdef L_EXT_frag_depth + float logFactor = 0.01254291648; // 1 / log2(1 + 1e24) + float nearFactor = 0.5 * (depth - nearDistance) / (midDistance - nearDistance); + float farFactor = 0.5 * (1.0 + log2(1.0 + depth - midDistance) * logFactor); + gl_FragDepthEXT = (1.0 - 2.0 * invertDepth) * (depth >= midDistance ? farFactor : nearFactor) + invertDepth; + #endif + `; + + /** Three.js uniform variables for custom materials. + * Eventually I'd like to remove the need for this by having every material be in the shaders folder. */ + static ThreeUniforms = { + invertDepth: new three__WEBPACK_IMPORTED_MODULE_0__.Uniform(0), + nearDistance: new three__WEBPACK_IMPORTED_MODULE_0__.Uniform(0), + midDistance: new three__WEBPACK_IMPORTED_MODULE_0__.Uniform(0) + }; +}; + + +/***/ }), + +/***/ "../pioneer/engine/src/shaders/plumes.js": +/*!***********************************************!*\ + !*** ../pioneer/engine/src/shaders/plumes.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "PlumesShader": function() { return /* binding */ PlumesShader; } +/* harmony export */ }); +/* harmony import */ var _log_depth__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./log_depth */ "../pioneer/engine/src/shaders/log_depth.js"); + + +const PlumesShader = { + uniforms: { + modelViewMatrix: 'mat4', + projectionMatrix: 'highp mat4', + + colorTexture: 'sampler2D', + colorMultiplier: 'vec4', + speed: 'float', + time: 'float', + + ..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms + }, + properties: { + transparent: true, + depthWrite: false, + side: 'double', + blending: 'normal' + }, + vertex: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + attribute vec3 position; + attribute vec2 uv; + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + varying vec2 vUV; + + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + vUV = uv; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + ` + }, + fragment: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + precision highp float; + + uniform sampler2D colorTexture; + uniform vec4 colorMultiplier; + uniform float speed; + uniform float time; + varying vec2 vUV; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + vec2 v2_construct_func(float x, float y) { + return vec2(x, y); + } + float s_mult_func(float s1, float s2) { + return s1 * s2; + } + float s_mod_func(float s1, float s2) { + return mod(s1, s2); + } + vec2 v2s_mult_func(vec2 v, float s) { + return v * s; + } + vec2 v2_add_func(vec2 v1, vec2 v2) { + return v1 + v2; + } + vec4 texture_func(sampler2D tex, vec2 uv) { + return texture2D(tex, uv); + } + vec4 v4v4_mult_func(vec4 v1, vec4 v2) { + return v1 * v2; + } + float s_sub_func(float s1, float s2) { + return s1 - s2; + } + vec4 alpha_mult_func(vec4 color, float alpha) { + return vec4(color.rgb, color.a * alpha); + } + void main() { + vec2 yAxis = v2_construct_func(0.0, 1.0); + float yMultiplier = s_mult_func(time, speed); + float yMultiplierMod = s_mod_func(yMultiplier, 1.0); + vec2 uvOffset = v2s_mult_func(yAxis, yMultiplierMod); + vec2 finalUV = v2_add_func(vUV, uvOffset); + vec4 textureOffset = texture_func(colorTexture, finalUV); + vec4 color = v4v4_mult_func(textureOffset, colorMultiplier); + float fade = s_sub_func(1.0, vUV.y); + vec4 color_with_fade = alpha_mult_func(color, fade); + gl_FragColor = color_with_fade; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + ` + } +}; + + +/***/ }), + +/***/ "../pioneer/engine/src/shaders/sprite.js": +/*!***********************************************!*\ + !*** ../pioneer/engine/src/shaders/sprite.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SpriteShader": function() { return /* binding */ SpriteShader; } +/* harmony export */ }); +/* harmony import */ var _log_depth__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./log_depth */ "../pioneer/engine/src/shaders/log_depth.js"); + + +const SpriteShader = { + uniforms: { + modelViewMatrix: 'mat4', + projectionMatrix: 'highp mat4', + + pixelBased: 'float', + color: 'vec4', + colorTexture: 'sampler2D', + + ..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms + }, + properties: { + transparent: true, + depthWrite: false, + side: 'double', + blending: 'normal' + }, + vertex: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + attribute vec3 position; + attribute vec2 uv; + + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + uniform float pixelBased; + + varying vec2 vUV; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + if (pixelBased != 0.0) { + gl_Position /= abs(gl_Position.w); + } + vUV = uv; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + ` + }, + fragment: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + precision highp float; + + uniform vec4 color; + uniform sampler2D colorTexture; + + varying vec2 vUV; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main() { + gl_FragColor = texture2D(colorTexture, vUV) * color; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + ` + } +}; + + +/***/ }), + +/***/ "../pioneer/engine/src/shaders/sprite_particles.js": +/*!*********************************************************!*\ + !*** ../pioneer/engine/src/shaders/sprite_particles.js ***! + \*********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SpriteParticlesShader": function() { return /* binding */ SpriteParticlesShader; } +/* harmony export */ }); +/* harmony import */ var _log_depth__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./log_depth */ "../pioneer/engine/src/shaders/log_depth.js"); + + +const SpriteParticlesShader = { + uniforms: { + modelViewMatrix: 'mat4', + projectionMatrix: 'highp mat4', + + ..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms + }, + properties: { + transparent: true, + depthWrite: false, + side: 'double', + blending: 'additive' + }, + vertex: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + attribute vec3 position; + attribute vec4 color; + attribute vec3 offset; + attribute float scale; + + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + varying vec4 fColor; + varying vec2 fPosition; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + vec4 viewPosition = modelViewMatrix * vec4(offset, 1.0) + vec4(position, 0.0) * scale; + gl_Position = projectionMatrix * viewPosition; + fColor = color; + fPosition = position.xz; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + ` + }, + fragment: { + extensions: [ + 'EXT_frag_depth' + ], + code: ` + precision highp float; + + varying vec4 fColor; + varying vec2 fPosition; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main() { + gl_FragColor = fColor * (1.0 - length(fPosition)); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + ` + } +}; + + +/***/ }), + +/***/ "../pioneer/engine/src/shaders/trail.js": +/*!**********************************************!*\ + !*** ../pioneer/engine/src/shaders/trail.js ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TrailShader": function() { return /* binding */ TrailShader; } +/* harmony export */ }); +/* harmony import */ var _log_depth__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./log_depth */ "../pioneer/engine/src/shaders/log_depth.js"); + + +const TrailShader = { + uniforms: { + modelViewMatrix: 'mat4', + projectionMatrix: 'highp mat4', + + pixelSize: 'vec2', + alphaMultiplier: 'float', + dashLength: 'float', + dashGapLength: 'float', + glowWidth: 'float', + indexStart: 'float', + indexCount: 'float', + indexLength: 'float', + color: 'vec4', + alphaFade: 'float', + widthMin: 'float', + widthMax: 'float', + + ..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms + }, + properties: { + transparent: true, + depthWrite: false, + side: 'double', + blending: 'additive' + }, + vertex: { + extensions: ['EXT_frag_depth'], + code: ` + attribute vec3 positionCurr; + attribute vec3 positionPrev; + attribute vec3 positionNext; + attribute float side; + attribute float index; + attribute float dashOffset; + + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + uniform vec2 pixelSize; + uniform float glowWidth; + uniform float indexStart; + uniform float indexCount; + uniform float indexLength; + uniform float widthMin; + uniform float widthMax; + + varying vec4 fColor; + varying float fDashOffset; + varying float fWidth; + varying float fOffsetScalar; + varying float fIndexU; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + // Get the width depending on the length. + float indexU = mod(index - indexStart + indexLength, indexLength) / (indexCount - 1.0); + float width = mix(widthMin, widthMax, indexU); + + // Get the line vertices into pixel space. + vec4 viewCenter = modelViewMatrix * vec4(positionCurr, 1.0); + vec4 viewPrev = modelViewMatrix * vec4(positionPrev, 1.0); + vec4 viewNext = modelViewMatrix * vec4(positionNext, 1.0); + vec4 projectedCenter = projectionMatrix * viewCenter; + vec4 projected_prev = projectionMatrix * viewPrev; + vec4 projected_next = projectionMatrix * viewNext; + vec2 ndcCenter = projectedCenter.xy / viewCenter.y; + vec2 ndcPrev = projected_prev.xy / viewPrev.y; + vec2 ndcNext = projected_next.xy / viewNext.y; + vec2 pixelCenter = (ndcCenter.xy + 1.0) / 2.0 * pixelSize; + vec2 pixelPrev = (ndcPrev.xy + 1.0) / 2.0 * pixelSize; + vec2 pixelNext = (ndcNext.xy + 1.0) / 2.0 * pixelSize; + + // Get the offset of the part perpendicular to the lines. + vec2 l0 = normalize(pixelCenter - pixelPrev); + vec2 l1 = normalize(pixelNext - pixelCenter); + float offsetScalar = side * (width / 2.0 + glowWidth); + vec2 offset = vec2(offsetScalar, offsetScalar); + if (pixelCenter == pixelPrev) { + if (pixelCenter == pixelNext) { + offset = vec2(0.0, 0.0); + } + else { + offset *= vec2(-l1.y, l1.x); + } + } + else if (pixelCenter == pixelNext) { + offset *= vec2(-l0.y, l0.x); + } + else { + offset *= normalize(vec2(-l0.y - l1.y, l0.x + l1.x)); + offset /= sqrt((1.0 + max(0.0, dot(l0, l1))) / 2.0); + } + + // Re-add the perpendicular part to the center as the final vertex. + ndcCenter = (pixelCenter + offset) / pixelSize * 2.0 - 1.0; + gl_Position = vec4(ndcCenter * viewCenter.y, projectedCenter.z, projectedCenter.w); + + // Set the varyings. + fIndexU = indexU; + fDashOffset = dashOffset; + fWidth = width; + fOffsetScalar = offsetScalar; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + ` + }, + fragment: { + extensions: ['EXT_frag_depth'], + code: ` + precision highp float; + + uniform vec4 color; + uniform float alphaMultiplier; + uniform float alphaFade; + uniform float dashLength; + uniform float dashGapLength; + uniform float glowWidth; + + varying float fIndexU; + varying float fDashOffset; + varying float fWidth; + varying float fOffsetScalar; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + float lineDash() { + float u = mod(fDashOffset, dashLength + dashGapLength); + return float(u < dashLength); + } + + float edgeGlow() { + if (glowWidth > 0.0) { + float value = clamp((fWidth / 2.0 + glowWidth - abs(fOffsetScalar)) / glowWidth, 0.0, 1.0); + if (value < 1.0) { + value *= 0.75; + } + return value; + } + return 1.0; + } + + void main() { + gl_FragColor = color; + gl_FragColor.a *= alphaMultiplier * edgeGlow() * lineDash() * mix(alphaFade, 1.0, fIndexU); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + ` + } +}; + + +/***/ }), + +/***/ "../pioneer/engine/src/texture_loader.js": +/*!***********************************************!*\ + !*** ../pioneer/engine/src/texture_loader.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TextureLoader": function() { return /* binding */ TextureLoader; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The texture loader. Responsible for loading all textures. + * If `useCompression` is used for any of the functions, the appropriate extension is retrieved from Capabilities, + * and it plus the '.ktx' extension replace the extension of the original url. See {@link Capabilities} for more detail. + */ +class TextureLoader extends _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Loader { + /** + * Constructor. + * @param {Downloader} downloader - The download manager. + * @param {THREE.WebGLRenderer} renderer + */ + constructor(downloader, renderer) { + super(); + + /** + * The downloader. + * @type {Downloader} + * @protected + */ + this._downloader = downloader; + + /** + * The threejs renderer. + * @type {THREE.WebGLRenderer} + * @protected + */ + this._renderer = renderer; + + /** + * The cross origin attribute value use in loads. + * @type {string} + * @protected + */ + this._crossOrigin = 'anonymous'; + + /** + * The path value used in loads. + * @type {string} + * @protected + */ + this._path = undefined; + + /** + * A pre-loaded 1x1 white texture. + * @type {THREE.Texture} + * @protected + */ + this._white = null; + + /** + * A pre-loaded 1x1 black texture. + * @type {THREE.Texture} + * @protected + */ + this._black = null; + + /** + * A pre-loaded 1x1 clear texture. + * @type {THREE.Texture} + * @protected + */ + this._clear = null; + + /** + * A pre-loaded 1x1 pink texture. + * @type {THREE.Texture} + * @protected + */ + this._pink = null; + + /** + * A pre-loaded 1x1 gray texture. + * @type {THREE.Texture} + * @protected + */ + this._gray = null; + + /** + * A ThreeJs texture loader for use by the load function. + * @type {THREE.TextureLoader} + * @protected + */ + this._threeJsTextureLoader = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.TextureLoader(); + + // Configure the loaders. + this._threeJsTextureLoader.setCrossOrigin(this._crossOrigin); + this._threeJsTextureLoader.setPath(this._path); + + // Setup the static pre-loaded textures. + this._white = TextureLoader._newTexture(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1)); + this._black = TextureLoader._newTexture(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0, 0, 0, 1)); + this._clear = TextureLoader._newTexture(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0, 0, 0, 0)); + this._pink = TextureLoader._newTexture(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1, 105 / 255, 180 / 255, 1)); + this._gray = TextureLoader._newTexture(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0.4, 0.4, 0.4, 1)); + + // Add this texture loader to the ThreeJs url handler. Complex loaders like GLTFLoader will use this. + _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DefaultLoadingManager.addHandler(/.$/i, this); + } + + /** + * Returns a promise that resolves when the texture is loaded into the uniform and rejects if there is an error. + * @param {THREE.IUniform} uniform - The uniform into which to load the texture. + * @param {string} url - The url of the texture to load. + * @param {boolean} useMipMaps - Whether or not to use mipmap textures. If true, only power-of-two textures are allowed. + * @returns {Promise} + */ + async loadIntoUniform(uniform, url, useMipMaps) { + return this.loadTexture(url, useMipMaps).then((texture) => { + if (uniform.value !== null) { + uniform.value.dispose(); + } + uniform.value = texture; + }); + } + + /** + * Returns a promise that resolves when the cube texture is loaded and rejects if there is an error. + * @param {string} url - The url of the texture to load. Every instance of $FACE is replaced by one of ['posx', 'negx', 'posy', 'negy', 'posz', 'negz']. + * @param {boolean} useMipMaps - Whether or not to use mipmap textures. If true, only power-of-two textures are allowed. + * @returns {Promise} + */ + async loadCubeTexture(url, useMipMaps) { + const cubeTexture = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CubeTexture(); + const promises = []; + for (let i = 0; i < 6; i++) { + const newUrl = url.replace('$FACE', _cubeFaceNames[i]); + promises.push(new Promise((resolve) => { + this.loadTexture(newUrl, useMipMaps).then((texture) => { + cubeTexture.images[i] = texture.image; + resolve(); + }); + })); + } + return Promise.all(promises).then(() => { + cubeTexture.needsUpdate = true; + return cubeTexture; + }); + } + + /** + * Returns a promise that resolves with a texture and rejects with an error. + * @param {string} url - The url of the texture to load. + * @param {boolean} useMipMaps - Whether or not to use mipmap textures. If true, only power-of-two textures are allowed. + * @returns {Promise} + */ + async loadTexture(url, useMipMaps) { + return new Promise((resolve, reject) => { + this.load(url, (texture) => { + resolve(texture); + }, undefined, (message) => { + reject(new Error(`Failed to load ${url}: ${message}`)); + }, useMipMaps); + }); + } + + /** + * Generates an environment map with proper cube UV. + * @param {THREE.Texture|THREE.CubeTexture} texture + * @returns {THREE.Texture} + */ + generateEnvMap(texture) { + let cubemap = texture; + // Transforms equirectangular texture to cubemap texture if it is not already a cubemap + if (!(texture instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CubeTexture)) { + const options = { + depthBuffer: false, + stencilBuffer: false, + generateMipmaps: true, + minFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearMipMapLinearFilter, + magFilter: _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter + }; + cubemap = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLCubeRenderTarget(512, options).fromEquirectangularTexture(this._renderer, texture).texture; + } + + const pmremGenerator = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.PMREMGenerator(this._renderer); + pmremGenerator.compileEquirectangularShader(); + const envMap = pmremGenerator.fromEquirectangular(cubemap).texture; + + return envMap; + } + + /** + * Loads a texture and calls the callbacks when it is done. The signature is to be compatible with THREE.TextureLoader. + * @param {string} url - The url of the texture to load. + * @param {(texture: THREE.Texture) => any} onLoad - The callback that is called when the texture is loaded. + * @param {(event: ProgressEvent, request: XMLHttpRequest) => any} _onProgress - The callback that is called when there is progress loading the texture. It is currently unused. + * @param {(message: string) => any} onError - The callback that is called when there is an error loading the texture. + * @param {boolean} [useMipMaps] - Whether or not to use mipmap textures. If true, only power-of-two textures are allowed. + * @returns {THREE.Texture} + */ + load(url, onLoad, _onProgress, onError, useMipMaps) { + // Process the URL + url = this._downloader.processUrl(url); + + // Handle preloaded cases + let texture = /** @type {THREE.Texture} */(null); + if (url === 'white') { + texture = this._white; + } + else if (url === 'black') { + texture = this._black; + } + else if (url === 'clear') { + texture = this._clear; + } + else if (url === 'pink') { + texture = this._pink; + } + else if (url === 'gray') { + texture = this._gray; + } + if (texture !== null) { + onLoad(texture); + } + else { + // Detect video types from url + if (url.includes('.mp4')) { + // Controls through videoTexture.image + const videoElement = document.createElement('video'); + videoElement.src = url; + videoElement.muted = true; + videoElement.playsInline = true; + videoElement.loop = false; + videoElement.crossOrigin = 'anonymous'; + + texture = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.VideoTexture(videoElement); + texture.format = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RGBAFormat; + texture.flipY = false; + texture.needsUpdate = true; + + this._downloader.download(url, true).then((download) => { + videoElement.src = URL.createObjectURL(new Blob([download.content], { type: 'video/mp4' })); + videoElement.onerror = (event) => { + onError(event.toString()); + }; + videoElement.oncanplaythrough = () => { + onLoad(texture); + }; + videoElement.load(); + }); + } + else { + // Load the texture. + this._threeJsTextureLoader.load(url, (texture) => { + texture.flipY = false; + if (useMipMaps === false) { + texture.minFilter = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter; + texture.generateMipmaps = false; + } + texture.needsUpdate = true; + onLoad(texture); + }, undefined, (event) => { + onError(event.message); + }); + } + } + + return texture; + } + + /** + * Gets the cross origin attribute value used in loads. Present to be compatible with THREE.TextureLoader. + * @returns {string} + * @internal + */ + // @ts-ignore + get crossOrigin() { + return this._crossOrigin; + } + + /** + * Sets the cross origin attribute value used in loads. Present to be compatible with THREE.TextureLoader. + * @param {string} crossOrigin - The cross origin attribute value. + * @override + * @internal + */ + set crossOrigin(crossOrigin) { + this._crossOrigin = crossOrigin; + if (this._threeJsTextureLoader) { + this._threeJsTextureLoader.setCrossOrigin(this._crossOrigin); + } + } + + /** + * Set method for the cross origin attribute. Present to be compatible with THREE.TextureLoader. + * @param {string} crossOrigin - The cross origin attribute value. + * @returns {this} + * @override + * @internal + */ + setCrossOrigin(crossOrigin) { + this.crossOrigin = crossOrigin; + return this; + } + + /** + * Gets the path value used in loads. Present to be compatible with THREE.TextureLoader. + * @returns {string} + * @internal + */ + // @ts-ignore + get path() { + return this._path; + } + + /** + * Sets the path value used in loads. Present to be compatible with THREE.TextureLoader. + * @param {string} path - The path value. + * @override + * @internal + */ + set path(path) { + this._path = path; + if (this._threeJsTextureLoader) { + this._threeJsTextureLoader.setPath(this._path); + } + } + + /** + * Set method for the path value. Present to be compatible with THREE.TextureLoader. + * @param {string} path - The path value. + * @returns {this} + * @override + * @internal + */ + setPath(path) { + this.path = path; + return this; + } + + /** + * Returns a new 1x1 pixel THREE.Texture from the color. + * @param {Color} color - The color of the single pixel. + * @returns {THREE.Texture} + * @protected + */ + static _newTexture(color) { + const canvas = document.createElement('canvas'); + canvas.width = 1; + canvas.height = 1; + const context = canvas.getContext('2d'); + context.fillStyle = 'rgba(' + (color.r * 255) + ',' + (color.g * 255) + ',' + (color.b * 255) + ',' + (color.a * 255) + ')'; + context.fillRect(0, 0, 1, 1); + return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CanvasTexture(canvas); + } +} + +/** + * The cube face names for cube map texture loading. + * @type {string[]} + */ +const _cubeFaceNames = [ + 'posx', + 'negx', + 'posy', + 'negy', + 'posz', + 'negz']; + + +/***/ }), + +/***/ "../pioneer/engine/src/texture_loader_compressed.js": +/*!**********************************************************!*\ + !*** ../pioneer/engine/src/texture_loader_compressed.js ***! + \**********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TextureLoaderCompressed": function() { return /* binding */ TextureLoaderCompressed; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * The texture loader. Responsible for loading all textures. + * If `useCompression` is used for any of the functions, the appropriate extension is retrieved from Capabilities, + * and it plus the '.ktx' extension replace the extension of the original url. See {@link Capabilities} for more detail. + */ +class TextureLoaderCompressed extends _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLoader { + /** + * Constructor. + * @param {Downloader} downloader - The download manager. + * @param {Config} config - The config manager. + * @param {THREE.WebGLRenderer} renderer + */ + constructor(downloader, config, renderer) { + super(downloader, renderer); + + /** + * The config. + * @type {Config} + * @private + */ + this._config = config; + + /** + * A ThreeJs texture loader for use by the load function. + * @type {ThreeJsKTXLoader} + * @private + */ + this._threeJsKTXLoader = new _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsKTXLoader(); + + // Configure the loaders. + this._threeJsKTXLoader.setCrossOrigin(this._crossOrigin); + this._threeJsKTXLoader.setPath(this._path); + } + + /** + * Loads a texture and calls the callbacks when it is done. The signature is to be compatible with THREE.TextureLoader. + * @param {string} url - The url of the texture to load. + * @param {(texture: THREE.Texture) => any} onLoad - The callback that is called when the texture is loaded. + * @param {(event: ProgressEvent, request: XMLHttpRequest) => any} onProgress - The callback that is called when there is progress loading the texture. + * @param {(message: string) => any} onError - The callback that is called when there is an error loading the texture. + * @param {boolean} [useMipMaps] - Whether or not to use mipmap textures. If true, only power-of-two textures are allowed. + * @returns {THREE.Texture} + * @override + */ + load(url, onLoad, onProgress, onError, useMipMaps) { + // If it's a normal, just do regular texture. + if (url.match(/_n\.[^.]+$/) !== null) { + return super.load(url, onLoad, onProgress, onError, useMipMaps); + } + + // Process the URL + url = this._downloader.processUrl(url); + + // Handle preloaded cases + let texture = null; + if (url === 'white') { + texture = this._white; + } + else if (url === 'black') { + texture = this._black; + } + else if (url === 'clear') { + texture = this._clear; + } + else if (url === 'pink') { + texture = this._pink; + } + if (texture !== null) { + onLoad(texture); + } + else { + // Replace the url with the .ktx version. + url = url.replace(/\.(\w+)$/, '-' + _internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.__getCompressedTextureExtension() + '.ktx'); + // Load the texture. + this._threeJsKTXLoader.load(url, (texture) => { + texture.flipY = false; + texture.needsUpdate = true; + if (useMipMaps === false) { // If undefined or true, it'll use mipmaps. + texture.minFilter = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter; + texture.generateMipmaps = false; + } + // @ts-ignore + texture.ktxFormat = texture.format; // This is needed because GLTFLoader forces the texture format to RGB/A. See https://github.com/mrdoob/three.js/issues/15763 + onLoad(texture); + }, undefined, (event) => { + onError(event.message); + }); + } + + return texture; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/aer.js": +/*!******************************************!*\ + !*** ../pioneer/engine/src/utils/aer.js ***! + \******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AER": function() { return /* binding */ AER; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** An azimuth, elevation, and range. */ +class AER extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable { + /** + * Pool for temporary variables. + * @returns {Pool} + */ + static get pool() { + return _pool; + } + + /** + * Constructor. + * @param {number} azimuth + * @param {number} elevation + * @param {number} range + */ + constructor(azimuth = 0, elevation = 0, range = 0) { + super(); + + /** + * azimuth + * @type {number} + * @private + */ + this._azimuth = azimuth; + /** + * elevation + * @type {number} + * @private + */ + this._elevation = elevation; + /** + * range + * @type {number} + * @private + */ + this._range = range; + } + + /** + * Gets the azimuth. + * @returns {number} + */ + get azimuth() { + return this._azimuth; + } + + /** + * Sets the azimuth. + * @param {number} azimuth + */ + set azimuth(azimuth) { + this.throwIfFrozen(); + this._azimuth = azimuth; + } + + /** + * Gets the elevation. + * @returns {number} + */ + get elevation() { + return this._elevation; + } + + /** + * Sets the elevation. + * @param {number} elevation + */ + set elevation(elevation) { + this.throwIfFrozen(); + this._elevation = elevation; + } + + /** + * Gets the range. + * @returns {number} + */ + get range() { + return this._range; + } + + /** + * Sets the range. + * @param {number} range + */ + set range(range) { + this.throwIfFrozen(); + this._range = range; + } + + /** + * Returns a nicely formed string. + * @param {boolean} deg - whether or not to print in degrees or radians. + * @returns {string} + * @override + */ + toString(deg = false) { + if (deg) { + return '[' + _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.radToDeg(this._azimuth) + ', ' + _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.radToDeg(this._elevation) + ', ' + this._range + ']'; + } + else { + return '[' + this._azimuth + ', ' + this._elevation + ', ' + this._range + ']'; + } + } + + /** + * Sets this to a. + * @param {AER} a + */ + copy(a) { + this.throwIfFrozen(); + this._azimuth = a._azimuth; + this._elevation = a._elevation; + this._range = a._range; + } + + /** + * Sets this to the parameters. + * @param {number} azimuth + * @param {number} elevation + * @param {number} range + */ + set(azimuth, elevation, range) { + this.throwIfFrozen(); + this._azimuth = azimuth; + this._elevation = elevation; + this._range = range; + } + + /** + * Sets this from the xyz equivalent of azimuth (rotation about z-axis starting from x-axis), elevation (from x-y plane), and range. + * @param {Vector3} xyz + */ + setFromVector(xyz) { + this.throwIfFrozen(); + this._range = xyz.magnitude(); + this._elevation = Math.asin(xyz.z / this._range); + this._azimuth = Math.atan2(xyz.y, xyz.x); + } +} + +/** @type {Pool} */ +const _pool = new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(AER); + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/base_ref.js": +/*!***********************************************!*\ + !*** ../pioneer/engine/src/utils/base_ref.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "BaseRef": function() { return /* binding */ BaseRef; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * @typedef RefAble + * @property {function(): boolean} isEnabled + * @property {function(): boolean} isDestroyed + */ + +/** + * A reference to an object. + * @template {RefAble} Type + */ +class BaseRef { + /** + * Constructor. + * @param {Scene} scene + */ + constructor(scene) { + /** + * The scene where this reference will search. + * @type {Scene} + * @protected + */ + this._scene = scene; + + /** + * The entity. + * @type {Type | null} + * @protected + */ + this._ref = null; + + /** + * The callback to be called when the reference changes. + * @type {((oldRef: Type | null, newRef: Type | null) => any) | null} + * @private + */ + this._refChangedCallback = null; + } + + /** + * Gets the reference. + * @returns {Type | null} + */ + get() { + this.update(); + return this._ref; + } + + /** + * Sets a callback to be called when the reference changes. + * @param {((oldRef: Type | null, newRef: Type | null) => any) | null} refChangedCallback + */ + setRefChangedCallback(refChangedCallback) { + this._refChangedCallback = refChangedCallback; + } + + /** + * Updates the reference. + * @abstract + */ + update() { + } + + /** + * Updates the ref, calling the callback if necessary. + * @param {Type | null} newRef + * @protected + */ + _setRef(newRef) { + // Make sure the new ref is enabled, otherwise discard it. + if (newRef !== null && !newRef.isEnabled()) { + newRef = null; + } + // If they are different, + if (this._ref !== newRef) { + const oldRef = this._ref; + // Set the ref. + this._ref = newRef; + // Call the callback. + if (this._refChangedCallback !== null) { + this._refChangedCallback(oldRef, this._ref); + } + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/cache.js": +/*!********************************************!*\ + !*** ../pioneer/engine/src/utils/cache.js ***! + \********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Cache": function() { return /* binding */ Cache; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A generic cache. + * @template Type + * @extends {FastIterable} + */ +class Cache extends _internal__WEBPACK_IMPORTED_MODULE_0__.FastIterable { + /** + * Constructor. + * @param {(key: string) => Type} itemConstructor + * @param {(item: Type) => any} itemDestructor + */ + constructor(itemConstructor = null, itemDestructor = null) { + super(); + + /** + * The keys to entries. + * @type {FastMap} + * @private + */ + this._keysToEntries = new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The items to keys. + * @type {Map} + * @private + */ + this._itemToKeys = new Map(); + + /** + * The item constructor. + * @type {(key: string) => Type} + * @private + */ + this._itemConstructor = itemConstructor; + + /** + * The item destructor. + * @type {(item: Type) => any} + * @private + */ + this._itemDestructor = itemDestructor; + } + + /** + * Gets the item with the key. If it doesn't yet exist, it creates it. + * @param {string} key + * @returns {Type} + */ + get(key) { + const entry = this._keysToEntries.get(key); + if (entry === undefined) { + const newEntry = { + item: this._itemConstructor(key), + count: 1 + }; + this._keysToEntries.set(key, newEntry); + this._itemToKeys.set(newEntry.item, key); + return newEntry.item; + } + else { + entry.count += 1; + return entry.item; + } + } + + /** + * Releases the item after a call to get. + * @param {Type} item + */ + release(item) { + const key = this._itemToKeys.get(item); + if (key !== undefined) { + const entry = this._keysToEntries.get(key); + entry.count -= 1; + if (entry.count === 0) { + this._itemDestructor(entry.item); + this._keysToEntries.delete(key); + this._itemToKeys.delete(item); + } + } + } + + /** + * Gets the item of the given index. + * @param {number} index + * @returns {Type} + * @override + */ + getAt(index) { + return this._keysToEntries.getAt(index).value.item; + } + + /** + * Gets the number of key-value pairs. + * @returns {number} + * @override + */ + get size() { + return this._keysToEntries.size; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/collection.js": +/*!*************************************************!*\ + !*** ../pioneer/engine/src/utils/collection.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CollectionItem": function() { return /* binding */ CollectionItem; }, +/* harmony export */ "Collection": function() { return /* binding */ Collection; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * A item within the Collection. This is meant to be subclassed. + * @template CollectionParentType + * @abstract + */ +class CollectionItem { + /** + * Constructs an item. + * @constructor + * @param {string} type - the type of the item + * @param {string} name - the name of the item + * @param {CollectionParentType} collectionParent - the object that contains the collection + */ + constructor(type, name, collectionParent) { + /** + * The type of the item. + * @type {string} + * @private + */ + this._type = type; + + /** + * The index of the item. + * @type {number} + * @private + */ + this._index = 0; + + /** + * The type index of the item. + * @type {number} + * @private + */ + this._typeIndex = 0; + + /** + * The name of the item. + * @type {string} + * @private + */ + this._name = name; + + /** + * The object that contains the collection. + * @type {CollectionParentType} + * @private + */ + this._collectionParent = collectionParent; + } + + /** + * Gets the type. + * @returns {string} + */ + getType() { + return this._type; + } + + /** + * Gets the index. + * @returns {number} + */ + getIndex() { + return this._index; + } + + /** + * Sets the index. Only to be used internally by Collection. + * @param {number} index + * @internal + */ + __setIndex(index) { + this._index = index; + } + + /** + * Gets the type index. + * @returns {number} + */ + getTypeIndex() { + return this._typeIndex; + } + + /** + * Sets the type index. Only to be used internally by Collection. + * @param {number} typeIndex + * @internal + */ + __setTypeIndex(typeIndex) { + this._typeIndex = typeIndex; + } + + /** + * Gets the name. + * @returns {string} + */ + getName() { + return this._name; + } + + /** + * Gets the object that contains the collection. Only to be used internally by the class that contains this. + * @returns {CollectionParentType} + */ + __getCollectionParent() { + return this._collectionParent; + } + + /** + * Sets the object that contains the collection. Only to be used internally by the class that contains this. + * @param {CollectionParentType} collectionParent + */ + __setCollectionParent(collectionParent) { + this._collectionParent = collectionParent; + } + + /** + * Does whatever is necessary to clean up the resources used by the item. + * @abstract + */ + __destroy() { + } +} + +/** + * The type constructor that takes a type, name, and its parent. + * @template {CollectionItem} ItemType + * @template CollectionParentType + * @typedef {new (type: string, name: string, parent: CollectionParentType) => ItemType} TypeConstructor + */ + +/** + * An ordered and named list of items. Every item constructor must be of the form Type(name, parent). + * @template {CollectionItem} ItemType + * @template CollectionParentType + */ +class Collection { + /** + * Constructs the collection. + * @constructor + * @param {CollectionParentType} parent - the object that contains this collection + * @param {Map>} types - the mapping from type names to type constructors + */ + constructor(parent, types) { + /** + * The parent of this collection that the items can refer to. + * @type {CollectionParentType} + * @private + */ + this._parent = parent; + + /** + * The mapping from type names to type constructors. + * @type {Map>} + * @private + */ + this._types = types; + + /** + * The array of items to manage. + * @type {ItemType[]} + * @private + */ + this._items = []; + + /** + * The mapping from names to items. + * @type {Map} + * @private + */ + this._itemsByName = new Map(); + + /** + * The mapping from type constructors to items in arrays. + * @type {Map, ItemType[]>} + * @private + */ + this._itemsByType = new Map(); + } + + /** + * Gets the item from either the item, name, or an index. It returns null if the item is not found. + * @param {ItemType|string|number} itemOrNameOrIndex - the item, its name, or its index to get + * @returns {ItemType | null} + */ + get(itemOrNameOrIndex) { + const index = this._getByItemOrNameOrIndex(itemOrNameOrIndex); + return index !== undefined ? this._items[index] : null; + } + + /** + * Gets the index'th item of the given type. The index is base 0. Returns null if none is found. + * @param {string} typeName + * @param {number} [index=0] + * @returns {ItemType | null} + */ + getByType(typeName, index = 0) { + const type = this._types.get(typeName); + if (type === undefined) { + return null; + } + const itemsOfType = this._itemsByType.get(type); + if (itemsOfType === undefined) { + return null; + } + if (index < 0 || index >= itemsOfType.length) { + return null; + } + return itemsOfType[index]; + } + + /** + * Gets the index'th item of the given type. The index is base 0. Returns null if none is found. + * @template {ItemType} Class + * @param {TypeConstructor} ClassConstructor + * @param {number} [index=0] + * @returns {Class | null} + */ + getByClass(ClassConstructor, index = 0) { + const typesList = this._itemsByType.get(ClassConstructor); + if (typesList !== undefined && index >= 0 && index < typesList.length) { + return /** @type {Class | null} */(typesList[index]); + } + return null; + } + + /** + * Create an item using with the given name and return it. + * @param {string} type - the type of the item to be created + * @param {string} [name=''] - the name of the item to be created + * @param {ItemType} [beforeItem] - insert the item before this item + * @returns {ItemType} + */ + add(type, name = '', beforeItem) { + // Check if the name already exists in the scene. + if (name !== '' && this._itemsByName.has(name)) { + throw new Error(`Already added "${name}".`); + } + const TypeConstructor = this._types.get(type); + if (type === undefined) { + throw new Error(`Type "${type}" not found.`); + } + let item; + try { + item = new TypeConstructor(type, name, this._parent); + } + catch (error) { + if (error instanceof Error) { + error.message = `While adding "${name}" of type "${type}": ${error.message}`; + } + throw error; + } + // Add the item to the lists. + this._addToLists(name, item, beforeItem); + // Return the newly created item. + return item; + } + + /** + * Create an item using with the given name and return it. + * @template {ItemType} Class + * @param {TypeConstructor} ClassConstructor + * @param {string} [name=''] - the name of the item to be created + * @param {ItemType} [beforeItem] - insert the item before this item + * @returns {Class} + */ + addByClass(ClassConstructor, name = '', beforeItem) { + // Check if the name already exists in the scene. + if (name !== '' && this._itemsByName.has(name)) { + throw new Error(`Already added "${name}".`); + } + try { + // Get the string type associated with the class, if there is one. + let type = ''; + for (const entry of this._types.entries()) { + if (entry[1] === ClassConstructor) { + type = entry[0]; + break; + } + } + // Create the new item. + const item = new ClassConstructor(type, name, this._parent); + // Add the item to the lists. + this._addToLists(name, item, beforeItem); + // Return the newly created item. + return item; + } + catch (error) { + if (error instanceof Error) { + error.message = `While adding "${name}": ${error.message}`; + } + throw error; + } + } + + /** + * Moves an item to another collection of the same type. + * @param {ItemType|string|number} itemOrNameOrIndex - the item, its name, or its index to be moved + * @param {Collection} newCollection + * @param {ItemType} [beforeItem] - insert the item before this item in the new scene. + */ + move(itemOrNameOrIndex, newCollection, beforeItem) { + // Get the index of the item. + const index = this._getByItemOrNameOrIndex(itemOrNameOrIndex); + // If the item isn't found, do nothing. + if (index === undefined) { + throw new Error('While moving item, the item is not found.'); + } + // Get the item and name. + const item = this._items[index]; + const name = item.getName(); + // Check if the name already exists in the new scene. + if (name !== '' && newCollection._itemsByName.has(name)) { + throw new Error(`Already added "${name}".`); + } + // Remove the item from this list. + this._removeFromLists(index, name, item); + // Add the item to the new list. + newCollection._addToLists(name, item, beforeItem); + // Update the parent. + item.__setCollectionParent(newCollection._parent); + } + + /** + * Remove and destroy an item. + * @param {ItemType|string|number} itemOrNameOrIndex - the item, its name, or its index to be removed + */ + remove(itemOrNameOrIndex) { + // Get the index of the item. + const index = this._getByItemOrNameOrIndex(itemOrNameOrIndex); + // If the item isn't found, do nothing. + if (index === undefined) { + return; + } + // Get the item and name. + const item = this._items[index]; + const name = item.getName(); + // Remove the item from the lists. + this._removeFromLists(index, name, item); + // Call the destroy function. + item.__destroy(); + } + + /** + * Removes and destroys all of the items. + */ + clear() { + for (let i = this._items.length - 1; i >= 0; i--) { + this._items[i].__destroy(); + } + this._items = []; + this._itemsByName.clear(); + this._itemsByType.clear(); + } + + /** + * Gets the number of items. + * @returns {number} + */ + get size() { + return this._items.length; + } + + /** + * Adds an item to the lists. + * @param {string} name + * @param {ItemType} item + * @param {ItemType | undefined} beforeItem + * @private + */ + _addToLists(name, item, beforeItem) { + // Add the item to the lists. + const index = beforeItem !== undefined ? beforeItem.getIndex() : this._items.length; + this._items.splice(index, 0, item); + if (name !== '') { + this._itemsByName.set(name, item); + } + this._updateIndices(index, item); + } + + /** + * Removes an item from the lists. + * @param {number} index + * @param {string} name + * @param {ItemType} item + * @private + */ + _removeFromLists(index, name, item) { + // Remove the item from the lists. + this._items.splice(index, 1); + if (name !== '') { + this._itemsByName.delete(name); + } + this._updateIndices(index, item); + } + + /** + * Update indices and type indices. + * @param {number} startingIndex + * @param {ItemType} item + * @private + */ + _updateIndices(startingIndex, item) { + // Update the indices. + for (let i = startingIndex; i < this._items.length; i++) { + this._items[i].__setIndex(i); + } + // Update the type indices for this type. + const type = /** @type {TypeConstructor} */(item.constructor); + const typesList = this._itemsByType.set(type, []).get(type); + let typeIndex = item.getTypeIndex(); + for (let i = 0; i < this._items.length; i++) { + if (this._items[i].constructor === type) { + this._items[i].__setTypeIndex(typeIndex); + typesList.push(this._items[i]); + typeIndex += 1; + } + } + if (typesList.length === 0) { + this._itemsByType.delete(type); + } + } + + __destroy() { + for (let i = this._items.length - 1; i >= 0; i--) { + this._items[i].__destroy(); + } + } + + /** + * Gets the index of an item by item, name, or index. + * @param {ItemType|string|number} itemOrNameOrIndex + * @returns {number | undefined} + * @private + */ + _getByItemOrNameOrIndex(itemOrNameOrIndex) { + if (typeof itemOrNameOrIndex === 'number') { + if (itemOrNameOrIndex >= 0 && itemOrNameOrIndex < this._items.length) { + return itemOrNameOrIndex; + } + } + else { // item or name + let item; + if (typeof itemOrNameOrIndex === 'string') { + item = this._itemsByName.get(itemOrNameOrIndex); + } + else { + item = itemOrNameOrIndex; + } + for (let i = this._items.length - 1; i >= 0; i--) { + if (this._items[i] === item) { + return i; + } + } + } + return undefined; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/color.js": +/*!********************************************!*\ + !*** ../pioneer/engine/src/utils/color.js ***! + \********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Color": function() { return /* binding */ Color; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** An RGBA color. All values are from 0 to 1. */ +class Color extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable { + /** + * Pool for temporary variables. + * @returns {Pool} + */ + static get pool() { + return _pool; + } + + /** + * Black vector + * @returns {Color} + */ + static get Black() { + return _black; + } + + /** + * Clear vector + * @returns {Color} + */ + static get Clear() { + return _clear; + } + + /** + * Constructor. Defaults to white. Can use just RGB. + * @param {number} r - red component [0 to 1] + * @param {number} g - green component [0 to 1] + * @param {number} b - blue component [0 to 1] + * @param {number} a - alpha component [0 to 1] + */ + constructor(r = 1, g = 1, b = 1, a = 1) { + super(); + + /** + * red + * @type {number} + * @private + */ + this._r = r; + + /** + * green + * @type {number} + * @private + */ + this._g = g; + + /** + * blue + * @type {number} + * @private + */ + this._b = b; + + /** + * alpha + * @type {number} + * @private + */ + this._a = a; + } + + /** + * Gets the red component. + * @returns {number} + */ + get r() { + return this._r; + } + + /** + * Sets the red component. + * @param {number} r + */ + set r(r) { + this.throwIfFrozen(); + this._r = r; + } + + /** + * Gets the green component. + * @returns {number} + */ + get g() { + return this._g; + } + + /** + * Sets the green component. + * @param {number} g + */ + set g(g) { + this.throwIfFrozen(); + this._g = g; + } + + /** + * Gets the blue component. + * @returns {number} + */ + get b() { + return this._b; + } + + /** + * Sets the blue component. + * @param {number} b + */ + set b(b) { + this.throwIfFrozen(); + this._b = b; + } + + /** + * Gets the alpha component. + * @returns {number} + */ + get a() { + return this._a; + } + + /** + * Sets the alpha component. + * @param {number} a + */ + set a(a) { + this.throwIfFrozen(); + this._a = a; + } + + /** + * Returns a nicely formed string. + * @override + * @returns {string} + */ + toString() { + return '[' + this._r + ', ' + this._g + ', ' + this._b + ', ' + this._a + ']'; + } + + /** + * Sets this to a. + * @param {Color} a - the source color + */ + copy(a) { + this.throwIfFrozen(); + this._r = a._r; + this._g = a._g; + this._b = a._b; + this._a = a._a; + } + + /** + * Sets this to the parameters. Can use just RGB. + * @param {number} r - red component [0 to 1] + * @param {number} g - green component [0 to 1] + * @param {number} b - blue component [0 to 1] + * @param {number} a - alpha component [0 to 1] + */ + set(r, g, b, a = 1) { + this.throwIfFrozen(); + this._r = r; + this._g = g; + this._b = b; + this._a = a; + } + + /** + * Sets this to a + b. + * @param {Color} a + * @param {Color} b + */ + add(a, b) { + this.throwIfFrozen(); + this._r = a._r + b._r; + this._g = a._g + b._g; + this._b = a._b + b._b; + this._a = a._a + b._a; + } + + /** + * Sets this to a - b. + * @param {Color} a + * @param {Color} b + */ + sub(a, b) { + this.throwIfFrozen(); + this._r = a._r - b._r; + this._g = a._g - b._g; + this._b = a._b - b._b; + this._a = a._a - b._a; + } + + /** + * Sets this to a * b, where b is a number. + * @param {Color} a + * @param {number} b + */ + mult(a, b) { + this.throwIfFrozen(); + this._r = a._r * b; + this._g = a._g * b; + this._b = a._b * b; + this._a = a._a * b; + } + + /** + * Sets this to a + b * c, where c is a number. + * @param {Color} a + * @param {Color} b + * @param {number} c + */ + addMult(a, b, c) { + this.throwIfFrozen(); + this._r = a._r + b._r * c; + this._g = a._g + b._g * c; + this._b = a._b + b._b * c; + this._a = a._a + b._a * c; + } + + /** + * Sets this to a / b, where b is a number. + * @param {Color} a + * @param {number} b + */ + div(a, b) { + this.throwIfFrozen(); + this._r = a._r / b; + this._g = a._g / b; + this._b = a._b / b; + this._a = a._a / b; + } + + /** + * Sets this to a * b, component-wise multiplication. + * @param {Color} a + * @param {Color} b + */ + scale(a, b) { + this.throwIfFrozen(); + this._r = a._r * b._r; + this._g = a._g * b._g; + this._b = a._b * b._b; + this._a = a._a * b._a; + } + + /** + * Returns the value (average of r, g, b components). + * @returns {number} + */ + value() { + return (this._r + this._g + this._b) / 3.0; + } + + /** + * Returns the value of the least component (only r, g, b). + * @returns {number} + */ + min() { + return Math.min(this._r, this._g, this._b); + } + + /** + * Returns the value of the greatest component (only r, g, b). + * @returns {number} + */ + max() { + return Math.max(this._r, this._g, this._b); + } + + /** + * Sets this to the lerp between a and b. + * @param {Color} a - the color when u = 0 + * @param {Color} b - the color when u = 1 + * @param {number} u - the lerp parameter + */ + lerp(a, b, u) { + this.throwIfFrozen(); + this._r = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._r, b._r, u); + this._g = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._g, b._g, u); + this._b = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._b, b._b, u); + this._a = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._a, b._a, u); + } +} + +/** + * @type {Pool} + */ +const _pool = new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Color); + +const _black = new Color(0, 0, 0, 1); +_black.freeze(); + +const _clear = new Color(0, 0, 0, 1); +_clear.freeze(); + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/component_ref.js": +/*!****************************************************!*\ + !*** ../pioneer/engine/src/utils/component_ref.js ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ComponentRef": function() { return /* binding */ ComponentRef; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A reference to a component. + * @template {BaseComponent} Type + * @extends BaseRef + */ +class ComponentRef extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseRef { + /** + * Constructor. + * @param {Scene} scene + */ + constructor(scene) { + super(scene); + + /** + * The name of the entity. + * @type {string} + * @private + */ + this._entityName = ''; + + /** + * The name of the component. + * @type {string} + * @private + */ + this._componentName = ''; + + /** + * The type of the component. + * @type {string} + * @private + */ + this._componentType = ''; + + /** + * The index of the type of the component. + * @type {number} + * @private + */ + this._componentTypeIndex = 0; + } + + /** + * Gets the entity name. + * @returns {string} + */ + getEntityName() { + return this._entityName; + } + + /** + * Gets the component name, if used. + * @returns {string} + */ + getComponentName() { + return this._componentName; + } + + /** + * Gets the component type, if used. + * @returns {string} + */ + getComponentType() { + return this._componentType; + } + + /** + * Gets the component type index, if the component type is used. + * @returns {number} + */ + getComponentTypeIndex() { + return this._componentTypeIndex; + } + + /** + * Sets the name of the reference component. + * @param {string} entityName + * @param {string} componentName + */ + setByName(entityName, componentName) { + this._entityName = entityName; + this._componentName = componentName; + this._componentType = ''; + } + + /** + * Sets the type and index of the reference component. + * @param {string} entityName + * @param {string} componentType + * @param {number} [componentTypeIndex] + */ + setByType(entityName, componentType, componentTypeIndex = 0) { + this._entityName = entityName; + this._componentType = componentType; + this._componentTypeIndex = componentTypeIndex; + this._componentName = ''; + } + + /** + * Updates the reference. + * @override + */ + update() { + // If there's no entity name or componentName/Type set, make sure the ref is null. + if (this._entityName === '' || (this._componentName === '' && this._componentType === '')) { + this._setRef(null); + } + // If there is an entity name and a componentName set, make sure the ref is valid and correct. + else if (this._componentName !== '') { + // Make sure the entity is correct. + const entity = this._scene.getEntity(this._entityName); + if (entity !== null && entity.isEnabled()) { + // Make sure the component is correct. + const ref = /** @type {Type} */(entity.getComponent(this._componentName)); + // Set the ref. + this._setRef(ref); + } + else { + this._setRef(null); + } + } + // If there is an entity name and a componentType set, make sure the ref is valid and correct. + else { + // Make sure the entity is correct. + const entity = this._scene.getEntity(this._entityName); + if (entity !== null && entity.isEnabled()) { + // Make sure the component is correct. + const ref = /** @type {Type} */(entity.getComponentByType(this._componentType, this._componentTypeIndex)); + // Set the ref. + this._setRef(ref); + } + else { + this._setRef(null); + } + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/controller_ref.js": +/*!*****************************************************!*\ + !*** ../pioneer/engine/src/utils/controller_ref.js ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ControllerRef": function() { return /* binding */ ControllerRef; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A reference to a controller. + * @template {BaseController} Type + * @extends BaseRef + */ +class ControllerRef extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseRef { + /** + * Constructor. + * @param {Scene} scene + */ + constructor(scene) { + super(scene); + + /** + * The name of the entity. + * @type {string} + * @private + */ + this._entityName = ''; + + /** + * The name of the controller. + * @type {string} + * @private + */ + this._controllerName = ''; + + /** + * The type of the controller. + * @type {string} + * @private + */ + this._controllerType = ''; + + /** + * The index of the type of the controller. + * @type {number} + * @private + */ + this._controllerTypeIndex = 0; + } + + /** + * Gets the entity name. + * @returns {string} + */ + getEntityName() { + return this._entityName; + } + + /** + * Gets the controller name, if used. + * @returns {string} + */ + getControllerName() { + return this._controllerName; + } + + /** + * Gets the controller type, if used. + * @returns {string} + */ + getControllerType() { + return this._controllerType; + } + + /** + * Gets the controller type index, if the controller type is used. + * @returns {number} + */ + getControllerTypeIndex() { + return this._controllerTypeIndex; + } + + /** + * Sets the name of the reference controller. + * @param {string} entityName + * @param {string} controllerName + */ + setByName(entityName, controllerName) { + this._entityName = entityName; + this._controllerName = controllerName; + this._controllerType = ''; + } + + /** + * Sets the type and index of the reference controller. + * @param {string} entityName + * @param {string} controllerType + * @param {number} [controllerTypeIndex] + */ + setByType(entityName, controllerType, controllerTypeIndex = 0) { + this._entityName = entityName; + this._controllerType = controllerType; + this._controllerTypeIndex = controllerTypeIndex; + this._controllerName = ''; + } + + /** + * Updates the reference. + * @override + */ + update() { + // If there's no entity name or controllerName/Type set, make sure the ref is null. + if (this._entityName === '' || (this._controllerName === '' && this._controllerType === '')) { + this._setRef(null); + } + // If there is an entity name and a controllerName set, make sure the ref is valid and correct. + else if (this._controllerName !== '') { + // Make sure the entity is correct. + const entity = this._scene.getEntity(this._entityName); + if (entity !== null && entity.isEnabled()) { + // Make sure the controller is correct. + const ref = /** @type {Type} */(entity.getController(this._controllerName)); + // Set the ref. + this._setRef(ref); + } + else { + this._setRef(null); + } + } + // If there is an entity name and a controllerType set, make sure the ref is valid and correct. + else { + // Make sure the entity is correct. + const entity = this._scene.getEntity(this._entityName); + if (entity !== null && entity.isEnabled()) { + // Make sure the controller is correct. + const ref = /** @type {Type} */(entity.getControllerByType(this._controllerType, this._controllerTypeIndex)); + // Set the ref. + this._setRef(ref); + } + else { + this._setRef(null); + } + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/cube_map.js": +/*!***********************************************!*\ + !*** ../pioneer/engine/src/utils/cube_map.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CubeMap": function() { return /* binding */ CubeMap; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +class CubeMap { + /** + * Converts an xyz vector to a uvFace vector. An array of cube map vectors may be passed in. + * @param {Vector3} outUVFace + * @param {Vector3} xyz + * @param {Vector3[][]} [cubeMapFaceFrames] + */ + static xyzToUVFace(outUVFace, xyz, cubeMapFaceFrames = this._defaultCubeMapFaceFrames) { + /** @type {Vector3[]} */ + let basis; + for (let i = 0; i < 6; i++) { + const cubeMapFaceFrame = cubeMapFaceFrames[i]; + const outVector = cubeMapFaceFrame[2]; + let value0 = 0; + let value1 = 0; + let value2 = 0; + let neg = false; + if (outVector === _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis || outVector === _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg) { + value0 = xyz.x; + value1 = xyz.y; + value2 = xyz.z; + neg = (outVector === _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg); + } + else if (outVector === _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis || outVector === _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg) { + value0 = xyz.y; + value1 = xyz.z; + value2 = xyz.x; + neg = (outVector === _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg); + } + else { + value0 = xyz.z; + value1 = xyz.x; + value2 = xyz.y; + neg = (outVector === _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxisNeg); + } + if (Math.abs(value0) >= Math.abs(value1) && Math.abs(value0) >= Math.abs(value2)) { + if ((value0 >= 0.0 && !neg) || (value0 < 0.0 && neg)) { + basis = cubeMapFaceFrame; + outUVFace.z = i; + } + } + } + if (basis === undefined) { + outUVFace.set(NaN, NaN, NaN); + return; + } + + // Convert into the uv basis from the xyz basis. + let z = basis[2].x * xyz.x + basis[2].y * xyz.y + basis[2].z * xyz.z; + if (z < 0.0) { + z = 1.0; + } + outUVFace.x = (basis[0].x * xyz.x + basis[0].y * xyz.y + basis[0].z * xyz.z) / z; + outUVFace.y = (basis[1].x * xyz.x + basis[1].y * xyz.y + basis[1].z * xyz.z) / z; + + // Convert from -1 to +1, to 0 to 1. + outUVFace.x = 0.5 * (outUVFace.x + 1.0); + outUVFace.y = 0.5 * (outUVFace.y + 1.0); + } +} + +/** + * The default vectors used for a cube map face frame orientation. The first dimension is 0-5 for each face and the second dimension are the +u, +v, and out vectors, respectively. + * @type {Vector3[][]} + */ +CubeMap._defaultCubeMapFaceFrames = [ + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis], + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis], + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg], + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg], + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis], + [_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxisNeg] +]; + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/dependency_graph.js": +/*!*******************************************************!*\ + !*** ../pioneer/engine/src/utils/dependency_graph.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "DependencyGraph": function() { return /* binding */ DependencyGraph; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * A dependency graph. The nodes are the items and the arrows are determined by the comparison function. + * @template ItemType + */ +class DependencyGraph { + constructor() { + /** + * The callback to be called for each item in the dependency graph. + * @type {(item: ItemType) => any} + * @private + */ + this._updateItemCallback = null; + + /** + * The callback to ber called when comparing items. True means item a is dependent on item b. + * @type {(a: ItemType, b: ItemType) => boolean} + * @private + */ + this._compareItemCallback = null; + + /** + * The list of items in the dependency graph. + * @type {Map>} + * @private + */ + this._nodes = new Map(); + + /** + * The sorted nodes. + * @type {Array>} + * @private + */ + this._sortedNodes = []; + + /** + * A boolean flag that determines of the dependency graph needs sorting. + * @type {boolean} + * @private + */ + this._needsSorting = false; + } + + /** + * Sets the callback to be called for each item in the dependency graph. + * @param {(item: ItemType) => any} updateItemCallback + */ + setUpdateItemCallback(updateItemCallback) { + this._updateItemCallback = updateItemCallback; + } + + /** + * Sets the callback to be called for each item in the dependency graph. + * @param {(a: ItemType, b: ItemType) => boolean} compareItemCallback + */ + setCompareItemCallback(compareItemCallback) { + this._compareItemCallback = compareItemCallback; + } + + /** + * Adds an item. + * @param {ItemType} item + */ + addItem(item) { + /** @type {Node} */ + const node = new Node(item); + this._nodes.set(item, node); + this._needsSorting = true; + } + + /** + * Removes an item. + * @param {ItemType} item + */ + removeItem(item) { + if (this._nodes.delete(item)) { + this._needsSorting = true; + } + } + + /** + * Signals that the graph needs sorting. + */ + needsSorting() { + this._needsSorting = true; + } + + /** + * Sorts the dependency graph and then iterates through through the dependency graph, calling the callback on each item. + */ + update() { + // Do the sorting if we need to do it. + if (this._needsSorting) { + // Reset all of the marks. + for (const node of this._nodes.values()) { + node.permanentMark = false; + node.temporaryMark = false; + } + this._sortedNodes = []; + + // Sort the items using the depth-first algorithm. + const iterator = this._nodes.values(); + do { + const result = iterator.next(); + if (result.done) { + break; + } + const keepGoing = this._visit(result.value); + if (!keepGoing) { + break; + } + } while (true); + + // It's sorted! + this._needsSorting = false; + } + + // Do the update on the items. + for (let i = 0, l = this._sortedNodes.length; i < l; i++) { + this._updateItemCallback(this._sortedNodes[i].item); + } + } + + /** + * The visit function in the depth-first sort algorithm. + * @param {Node} node + * @returns {boolean} + * @private + */ + _visit(node) { + if (node.permanentMark) { + return true; + } + if (node.temporaryMark) { + throw new Error('Dependency cycle in graph: ' + node.item); + } + node.temporaryMark = true; + for (const aNode of this._nodes.values()) { + let nodeDependsOn = false; + if (this._compareItemCallback) { + nodeDependsOn = this._compareItemCallback(node.item, aNode.item); + } + if (nodeDependsOn) { + try { + this._visit(aNode); + } + catch (error) { + if (error instanceof Error) { + error.message = `${error.message} ← ${node.item}`; + } + throw error; + } + } + } + node.temporaryMark = false; + node.permanentMark = true; + this._sortedNodes.push(node); + return true; + } +} + +/** + * The node in the graph. + * @template ItemType + * @private + */ +class Node { + /** + * Constructor. + * @param {ItemType} item + */ + constructor(item) { + /** + * The item. + * @type {ItemType} + */ + this.item = item; + + /** + * A mark to help with depth-first topological sorting algorithm. + * @type {boolean} + */ + this.permanentMark = false; + + /** + * A mark to help with depth-first topological sorting algorithm. + * @type {boolean} + */ + this.temporaryMark = false; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/entity_ref.js": +/*!*************************************************!*\ + !*** ../pioneer/engine/src/utils/entity_ref.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "EntityRef": function() { return /* binding */ EntityRef; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A reference to an entity. + * @extends {BaseRef} + */ +class EntityRef extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseRef { + /** + * Constructor. + * @param {Scene} scene + * @param {string} [name] + */ + constructor(scene, name) { + super(scene); + + /** + * The name of the entity to reference. + * @type {string} + * @private + */ + this._name = name !== undefined ? name : ''; + } + + /** + * Gets the name of the reference. + * @returns {string} + */ + getName() { + return this._name; + } + + /** + * Sets the name of the reference. + * @param {string} name + */ + setName(name) { + this._name = name; + } + + /** + * Updates the reference. + * @override + */ + update() { + // If there's no name set, make sure the ref is null. + if (this._name === '') { + if (this._ref !== null) { + this._setRef(null); + } + } + // If there is a name, make sure the ref is valid and correct. + else { + if (this._ref === null || this._ref.isDestroyed() || !this._ref.isEnabled() || this._ref.getName() !== this._name) { + // Get the new ref. + const ref = this._scene.getEntity(this._name); + // Set the ref. + this._setRef(ref); + } + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/fast_iterable.js": +/*!****************************************************!*\ + !*** ../pioneer/engine/src/utils/fast_iterable.js ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FastIterable": function() { return /* binding */ FastIterable; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * A set of values, with the same functions as the standard Set object, except for iteration. + * It has getAt(index) and size for iteration. + * It's O(n) and garbage for removes, O(1) and no garbage for adds and iteration. + * @template ValueType + */ +class FastIterable { + /** + * Gets the value of the given index. + * @param {number} _index + * @returns {ValueType} + */ + getAt(_index) { + throw new Error(); + } + + /** + * Gets the number of values. + * @returns {number} + */ + get size() { + throw new Error(); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/fast_map.js": +/*!***********************************************!*\ + !*** ../pioneer/engine/src/utils/fast_map.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FastMapEntry": function() { return /* binding */ FastMapEntry; }, +/* harmony export */ "FastMap": function() { return /* binding */ FastMap; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * An entry in the map. + * @template KeyType + * @template ValueType + */ +class FastMapEntry { + /** + * Constructor. + * @param {KeyType} key + * @param {ValueType} value + */ + constructor(key, value) { + /** + * The key. + * @type {KeyType} + */ + this.key = key; + + /** + * The value. + * @type {ValueType} + */ + this.value = value; + } +} + +/** + * A map of key-value pairs with the same functions as the standard Map object, except for iteration. + * It has getAt(index) and size for iteration. + * It's O(n) and garbage for removes, O(1) and no garbage for adds, gets, sets, and iteration. + * @template KeyType + * @template ValueType + * @extends {FastIterable>} + */ +class FastMap extends _internal__WEBPACK_IMPORTED_MODULE_0__.FastIterable { + /** + * Constructor. + * @param {Iterable>} [iterable] + */ + constructor(iterable) { + super(); + + /** + * The list of key-value pairs. + * @type {Array>} + * @private + */ + this._entries = []; + + /** + * A mapping from keys to indices. + * @type {Map} + * @private + */ + this._keyMap = new Map(); + + // Apply the iterable if it is supplied. + if (iterable !== undefined) { + for (const entry of iterable) { + this._entries.push(new FastMapEntry(entry.key, entry.value)); + this._keyMap.set(entry.key, this._entries.length - 1); + } + } + } + + /** + * Returns true if the key is in the map. + * @param {KeyType} key + * @returns {boolean} + */ + has(key) { + return this._keyMap.has(key); + } + + /** + * Gets the value given a key. + * @param {KeyType} key + * @returns {ValueType} + */ + get(key) { + const index = this._keyMap.get(key); + if (index !== undefined) { + return this._entries[index].value; + } + return undefined; + } + + /** + * Sets the value for the given key. + * @param {KeyType} key + * @param {ValueType} value + */ + set(key, value) { + const index = this._keyMap.get(key); + if (index !== undefined) { + this._entries[index].value = value; + } + else { + this._entries.push(new FastMapEntry(key, value)); + this._keyMap.set(key, this._entries.length - 1); + } + } + + /** + * Deletes the value for the given key. Returns true if the key existed. + * @param {KeyType} key + * @returns {boolean} + */ + delete(key) { + const index = this._keyMap.get(key); + if (index !== undefined) { + this._entries.splice(index, 1); + this._keyMap.delete(key); + // Every index higher than the one deleted gets decremented by one. O(n) and generates garbage. + for (const pair of this._keyMap) { + if (pair[1] > index) { + this._keyMap.set(pair[0], pair[1] - 1); + } + } + return true; + } + else { + return false; + } + } + + /** + * Deletes all of the key-value pairs. + */ + clear() { + this._entries = []; + this._keyMap.clear(); + } + + /** + * Gets the key-value pair of the given index. + * @param {number} index + * @returns {FastMapEntry} + * @override + */ + getAt(index) { + return this._entries[index]; + } + + /** + * Gets the number of key-value pairs. + * @returns {number} + * @override + */ + get size() { + return this._entries.length; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/fast_set.js": +/*!***********************************************!*\ + !*** ../pioneer/engine/src/utils/fast_set.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FastSet": function() { return /* binding */ FastSet; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A set of values, with the same functions as the standard Set object, except for iteration. + * It has getAt(index) and size for iteration. + * It's O(n) and garbage for removes, O(1) and no garbage for adds and iteration. + * @template ValueType + * @extends {FastIterable} + */ +class FastSet extends _internal__WEBPACK_IMPORTED_MODULE_0__.FastIterable { + /** + * Constructor. + * @param {Iterable} [iterable] + */ + constructor(iterable) { + super(); + + /** + * The list of values. + * @type {Array} + * @private + */ + this._values = []; + + /** + * A mapping from values to indices. + * @type {Map} + * @private + */ + this._valueMap = new Map(); + + // Apply the iterable if it is supplied. + if (iterable !== undefined) { + for (const key of iterable) { + this._values.push(key); + this._valueMap.set(key, this._values.length - 1); + } + } + } + + /** + * Returns true if the value is in the set. + * @param {ValueType} value + * @returns {boolean} + */ + has(value) { + return this._valueMap.has(value); + } + + /** + * Adds the value. + * @param {ValueType} value + * @returns {FastSet} + */ + add(value) { + const index = this._valueMap.get(value); + if (index === undefined) { + this._values.push(value); + this._valueMap.set(value, this._values.length - 1); + } + return this; + } + + /** + * Deletes the value. Returns true if the value existed. + * @param {ValueType} value + * @returns {boolean} + */ + delete(value) { + const index = this._valueMap.get(value); + if (index !== undefined) { + this._values.splice(index, 1); + this._valueMap.delete(value); + // Every index higher than the one deleted gets decremented by one. O(n) and generates garbage. + for (const pair of this._valueMap) { + if (pair[1] > index) { + this._valueMap.set(pair[0], pair[1] - 1); + } + } + return true; + } + else { + return false; + } + } + + /** + * Deletes all of the keys. + */ + clear() { + this._values = []; + this._valueMap.clear(); + } + + /** + * Gets the value of the given index. + * @param {number} index + * @returns {ValueType} + * @override + */ + getAt(index) { + return this._values[index]; + } + + /** + * Gets the number of values. + * @returns {number} + * @override + */ + get size() { + return this._values.length; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/fps.js": +/*!******************************************!*\ + !*** ../pioneer/engine/src/utils/fps.js ***! + \******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "FPS": function() { return /* binding */ FPS; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * An FPS calculator. All you need to do is run update() every frame, and it will produce an FPS. + */ +class FPS { + constructor() { + /** + * The number of samples to take when calculating the FPS. + * @type {number} + * @private + */ + this._numberOfSamples = 100; + + /** + * The buffer of samples. + * @type {Array} + * @private + */ + this._samples = new Array(this._numberOfSamples); + + /** + * The current index in the buffer of samples. + * @type {number} + * @private + */ + this._index = 0; + } + + /** + * Gets the number of samples to take when calculating the FPS. + * @returns {number} + */ + getNumberOfSamples() { + return this._numberOfSamples; + } + + /** + * Sets the number of samples to take when calculating the FPS. This will reset the sample buffer. The default is 100. + * @param {number} numberOfSamples - The number of samples in the buffer. + */ + setNumberOfSamples(numberOfSamples) { + this._numberOfSamples = numberOfSamples; + this._samples = new Array(this._numberOfSamples); + } + + /** + * Gets the FPS given the current samples. + * @returns {number} + */ + getFPS() { + let samplesTotal = 0; + for (let i = 0; i < this._samples.length; i++) { + samplesTotal += this._samples[i]; + } + return this._samples.length / samplesTotal; + } + + /** + * Updates the samples with the latest delta time. + * @param {number} deltaTime - The change in time between two frames. + */ + update(deltaTime) { + this._samples[this._index] = deltaTime; // Used for frame-rate smoothing. + this._index = (this._index + 1) % this._samples.length; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/freezable.js": +/*!************************************************!*\ + !*** ../pioneer/engine/src/utils/freezable.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Freezable": function() { return /* binding */ Freezable; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * This is a class that dynamically makes an object frozen or thawed. + * When it is frozen, it cannot be modified. + * To use this, an object must extend this and then for every method that modifies the object, call throwIfFrozen(). + */ +class Freezable { + /** + * Constructor. Starts out thawed. + */ + constructor() { + this._frozen = false; + } + + /** + * Throws a TypeError if it is frozen. + */ + throwIfFrozen() { + if (this._frozen) { + throw new TypeError('The object is frozen.'); + } + } + + /** + * Returns true if it is frozen. + * @returns {boolean} + */ + isFrozen() { + return this._frozen; + } + + /** + * Freezes the object. + */ + freeze() { + this._frozen = true; + } + + /** + * Thaws (unfreezes) the object. + */ + thaw() { + this._frozen = false; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/geometry.js": +/*!***********************************************!*\ + !*** ../pioneer/engine/src/utils/geometry.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Geometry": function() { return /* binding */ Geometry; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A class of geometry routines + * @hideconstructor */ +class Geometry { + /** + * Given a line segment starting at p and going in the direction l (not unit), and a sphere of radius r at the origin, return the least lerp value such that 0 is at p and 1 is at p + l, that represents the an intersection between the line and the sphere. If there is no intersection NaN is returned. + * @param {Vector3} p - The starting point of the segment (returning 0 = p). + * @param {Vector3} l - The offset from the starting point (returning 1 = p + l). + * @param {number} r - The radius of the sphere at the origin. + * @returns {number} + */ + static getLineSphereIntersectionWithSphereAtOrigin(p, l, r) { + const pp = p.dot(p); + const pl = p.dot(l); + const ll = l.dot(l); + const underSquareRoot = pl * pl + (r * r - pp) * ll; + if (underSquareRoot < 0) { + return Number.NaN; + } + else { + return (-pl - Math.sqrt(underSquareRoot)) / ll; + } + } + + /** + * Given a line segment starting at the origin and going toward l, and a sphere of radius r with its center at c, return the least lerp value such that 0 is at the origin and 1 is at l, that represents the an intersection between the line segment and the sphere. If there is no intersection NaN is returned. + * @param {Interval} out - The interval representing the near and far points of intersection. + * @param {Vector3} l - The end point of the line segment. + * @param {Vector3} c - The center of the sphere. + * @param {number} r - The radius of the sphere. + */ + static getLineSphereIntersectionWithLineStartAtOrigin(out, l, c, r) { + const ll = l.dot(l); + const lc = l.dot(c); + const cc = c.dot(c); + const underSquareRoot = lc * lc + (r * r - cc) * ll; + if (underSquareRoot < 0) { + out.min = out.max = Number.NaN; + } + else { + const sqrt = Math.sqrt(underSquareRoot); + out.min = (lc - sqrt) / ll; + out.max = (lc + sqrt) / ll; + } + } + + /** + * Takes an XYZ and sets out to the equivalent LLA on a sphere. + * @param {LatLonAlt} outLLA - the LLA vector to be set + * @param {Vector3} xyz - the XYZ vector to convert + * @param {number} radius - the radius of the sphere + */ + static getLLAFromXYZOnSphere(outLLA, xyz, radius) { + const xyLength = xyz.magnitudeXY(); + outLLA.lon = Math.atan2(xyz.y, xyz.x); + outLLA.lat = Math.atan(xyz.z / xyLength); + outLLA.alt = xyz.magnitude() - radius; + } + + /** + * Takes an LLA and sets out to the equivalent XYZ on a sphere. + * @param {Vector3} outXYZ - the XYZ vector to be set + * @param {LatLonAlt} lla - the LLA vector to convert + * @param {number} radius - the radius of the sphere + */ + static getXYZFromLLAOnSphere(outXYZ, lla, radius) { + outXYZ.x = (radius + lla.alt) * Math.cos(lla.lat) * Math.cos(lla.lon); + outXYZ.y = (radius + lla.alt) * Math.cos(lla.lat) * Math.sin(lla.lon); + outXYZ.z = (radius + lla.alt) * Math.sin(lla.lat); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/interval.js": +/*!***********************************************!*\ + !*** ../pioneer/engine/src/utils/interval.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Interval": function() { return /* binding */ Interval; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** An interval with a minimum and maximum. */ +class Interval extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable { + /** + * Pool for temporary variables. + * @returns {Pool} + */ + static get pool() { + return _pool; + } + + /** + * Infinite Interval + * @returns {Interval} + */ + static get Infinite() { + return _infinite; + } + + /** + * Constructor. + * @param {number} min - the minimum of the interval + * @param {number} max - the maximum of the interval + */ + constructor(min = 0, max = 0) { + super(); + + /** + * minumum + * @type {number} + * @private + */ + this._min = min; + + /** + * maximum + * @type {number} + * @private + */ + this._max = max; + } + + /** + * Gets the minimum. + * @returns {number} + */ + get min() { + return this._min; + } + + /** + * Sets the minimum. + * @param {number} min + */ + set min(min) { + this.throwIfFrozen(); + this._min = min; + } + + /** + * Gets the maximum. + * @returns {number} + */ + get max() { + return this._max; + } + + /** + * Sets the maximum + * @param {number} max + */ + set max(max) { + this.throwIfFrozen(); + this._max = max; + } + + /** + * Returns a nicely formed string. + * @returns {string} + * @override + */ + toString() { + return '[' + this._min + ', ' + this._max + ']'; + } + + /** + * Sets this to a. + * @param {Interval} a - the source interval + */ + copy(a) { + this.throwIfFrozen(); + this._min = a._min; + this._max = a._max; + } + + /** + * Sets this to the parameters. + * @param {number} min - the minimum to set + * @param {number} max - the maximum to set + */ + set(min, max) { + this.throwIfFrozen(); + this._min = min; + this._max = max; + } + + /** + * Returns the length (max - min). If this represents a integer interval, you'll need to add one. + * @returns {number} + */ + length() { + return this._max - this._min; + } + + /** + * Returns the value clamped to within this. + * @param {number} value - the value to clamp + * @returns {number} + */ + clamp(value) { + return Math.min(Math.max(this._min, value), this._max); + } + + /** + * Expands this to contain the value. + * @param {number} value + */ + expandTo(value) { + this.throwIfFrozen(); + this._min = Math.min(this._min, value); + this._max = Math.max(this._max, value); + } + + /** + * Returns true if value is within this. + * @param {number} value - the value to check + * @returns {boolean} + */ + contains(value) { + return this._min <= value && value < this._max; + } + + /** + * Returns true if this intersects (not just touches) the other interval. + * @param {Interval} interval - the interval to check + * @returns {boolean} + */ + intersects(interval) { + return this._min < interval._max && interval._min < this._max; + } + + /** + * Sets this to the intersection of intervals a and b. + * @param {Interval} a + * @param {Interval} b + */ + intersection(a, b) { + this.throwIfFrozen(); + this._min = Math.max(a._min, b._min); + this._max = Math.min(a._max, b._max); + if (this._max < this._min) { + this._max = this._min; + } + } + + /** + * Sets this to the union of intervals a and b. + * @param {Interval} a + * @param {Interval} b + */ + union(a, b) { + this.throwIfFrozen(); + this._min = Math.min(a._min, b._min); + this._max = Math.max(a._max, b._max); + } +} + +/** + * @type {Pool} + */ +const _pool = new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Interval); + +/** + * Infinite Interval + * @type {Interval} + */ +const _infinite = new Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY); +_infinite.freeze(); + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/lat_lon_alt.js": +/*!**************************************************!*\ + !*** ../pioneer/engine/src/utils/lat_lon_alt.js ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LatLonAlt": function() { return /* binding */ LatLonAlt; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A latitude, longitude, and altitude */ +class LatLonAlt extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable { + /** + * Pool for temporary variables. + * @returns {Pool} + */ + static get pool() { + return _pool; + } + + /** + * Constructor. + * @param {number} lat - Latitude + * @param {number} lon - Longitude + * @param {number} alt - Altitude + */ + constructor(lat = 0, lon = 0, alt = 0) { + super(); + + /** + * Latitude + * @type {number} + * @private + */ + this._lat = lat; + + /** + * Longitude + * @type {number} + * @private + */ + this._lon = lon; + + /** + * Altitude + * @type {number} + * @private + */ + this._alt = alt; + } + + /** + * Gets the latitude. + * @returns {number} + */ + get lat() { + return this._lat; + } + + /** + * Sets the latitude. + * @param {number} lat + */ + set lat(lat) { + this.throwIfFrozen(); + this._lat = lat; + } + + /** + * Gets the longitude. + * @returns {number} + */ + get lon() { + return this._lon; + } + + /** + * Sets the longitude. + * @param {number} lon + */ + set lon(lon) { + this.throwIfFrozen(); + this._lon = lon; + } + + /** + * Gets the altitude. + * @returns {number} + */ + get alt() { + return this._alt; + } + + /** + * Sets the altitude. + * @param {number} alt + */ + set alt(alt) { + this.throwIfFrozen(); + this._alt = alt; + } + + /** + * Returns a nicely formed string. + * @param {boolean} deg - whether or not to print in degrees or radians. + * @returns {string} + * @override + */ + toString(deg = false) { + if (deg) { + return '[' + _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.radToDeg(this._lat) + ', ' + _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.radToDeg(this._lon) + ', ' + this._alt + ']'; + } + else { + return '[' + this._lat + ', ' + this._lon + ', ' + this._alt + ']'; + } + } + + /** + * Sets this to a. + * @param {LatLonAlt} a + */ + copy(a) { + this.throwIfFrozen(); + this._lat = a._lat; + this._lon = a._lon; + this._alt = a._alt; + } + + /** + * Sets this to the parameters. + * @param {number} lat + * @param {number} lon + * @param {number} alt + */ + set(lat, lon, alt) { + this.throwIfFrozen(); + this._lat = lat; + this._lon = lon; + this._alt = alt; + } +} + +/** + * @type {Pool} + */ +const _pool = new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(LatLonAlt); + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/line_mesh.js": +/*!************************************************!*\ + !*** ../pioneer/engine/src/utils/line_mesh.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LineMesh": function() { return /* binding */ LineMesh; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A helper class for drawing lines. It creates the objects and materials, but they are 'owned' by the component. + */ +class LineMesh { + /** + * Constructor. + * @param {BaseComponent} component + */ + constructor(component) { + /** + * The component that uses this. + * @type {BaseComponent} + * @private + */ + this._component = component; + + /** + * A global multiplier for the alpha channel. + * @type {number} + * @private + */ + this._alphaMultiplier = 1.0; + + /** + * The position that the line points are relative to. + * @type {Vector3} + * @private + */ + this._position = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + /** + * The orientation that the line points are relative to. + * @type {Quaternion} + * @private + */ + this._orientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + + /** + * The scale that all points are multiplied by. + * @type {number} + * @private + */ + this._scale = 1; + + /** + * The line dash gap length. + * @type {number} + * @private + */ + this._dashGapLength = 0; + + /** + * The line dash length. + * @type {number} + * @private + */ + this._dashLength = 1; + + /** + * The width of the glow from full to clear along the edge of the lines. + * @type {number} + * @private + */ + this._glowWidth = 0; + + /** + * The Three.js objects. There needs to be a copy here since there may be multiple line meshes in the component. + * @type {Array>} + * @private + */ + this._threeJsObjects = []; + + /** + * The Three.js material. + * @type {THREE.ShaderMaterial} + * @private + */ + this._threeJsMaterial = null; + + // Create the material. + this._threeJsMaterial = component.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('line'); + component.getThreeJsMaterials().push(this._threeJsMaterial); + this._threeJsMaterial.uniforms['alphaMultiplier'].value = this._alphaMultiplier; + this._threeJsMaterial.uniforms['dashLength'].value = this._dashLength; + this._threeJsMaterial.uniforms['dashGapLength'].value = this._dashGapLength; + this._threeJsMaterial.uniforms['glowWidth'].value = this._glowWidth; + } + + /** + * Sets the positions. Each two positions is a line segment. + * @param {Vector3[]} positions + */ + setPositions(positions) { + if (positions.length % 2 !== 0) { + throw new Error('Number of positions in the LineMesh must be even.'); + } + // Adjust the number of vertices. * 2 is because the line has width. + this._adjustVerticesInGeometries(positions.length * 2); + const positionPrev = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const positionNext = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const tangent = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const normal = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const segment = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + // Go through each geometry, setting the vertices. Each object holds up to _verticesPerGeometry vertices. + let dashOffset = 0; + for (let objectIndex = 0; objectIndex < this._threeJsObjects.length; objectIndex++) { + const attribute = /** @type {THREE.InterleavedBufferAttribute} */(this._threeJsObjects[objectIndex].geometry.getAttribute('position')); + const array = attribute.array; + for (let i = 0; i < array.length / (2 * LineMesh._floatsPerVertex); i++) { + const offset = i + objectIndex * (LineMesh._verticesPerGeometry / 2); + array[i * 2 * LineMesh._floatsPerVertex + 0] = positions[offset].x; + array[i * 2 * LineMesh._floatsPerVertex + 1] = positions[offset].y; + array[i * 2 * LineMesh._floatsPerVertex + 2] = positions[offset].z; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 0] = positions[offset].x; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 1] = positions[offset].y; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 2] = positions[offset].z; + // Get the positionPrev and positionNext. + if (offset % 2 === 0) { + if (positions[offset].equals(positions[_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(offset - 1, 0, positions.length)])) { + positionPrev.copy(positions[_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(offset - 2, 0, positions.length)]); + positionNext.copy(positions[offset + 1]); + } + else { // Disconnected segments, so just use the current position as the previous position. + positionPrev.copy(positions[offset]); + positionNext.copy(positions[offset + 1]); + dashOffset = 0; + } + } + else if (offset % 2 === 1) { + if (positions[offset].equals(positions[_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(offset + 1, 0, positions.length)])) { + positionPrev.copy(positions[offset - 1]); + positionNext.copy(positions[_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(offset + 2, 0, positions.length)]); + } + else { // Disconnected segments, so just use the current position as the next position. + positionPrev.copy(positions[offset - 1]); + positionNext.copy(positions[offset]); + } + segment.sub(positions[offset], positions[offset - 1]); + dashOffset += segment.magnitude(); + } + array[i * 2 * LineMesh._floatsPerVertex + 3] = positionPrev.x; + array[i * 2 * LineMesh._floatsPerVertex + 4] = positionPrev.y; + array[i * 2 * LineMesh._floatsPerVertex + 5] = positionPrev.z; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 3] = positionPrev.x; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 4] = positionPrev.y; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 5] = positionPrev.z; + array[i * 2 * LineMesh._floatsPerVertex + 6] = positionNext.x; + array[i * 2 * LineMesh._floatsPerVertex + 7] = positionNext.y; + array[i * 2 * LineMesh._floatsPerVertex + 8] = positionNext.z; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 6] = positionNext.x; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 7] = positionNext.y; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 8] = positionNext.z; + + array[i * 2 * LineMesh._floatsPerVertex + 14] = dashOffset; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 14] = dashOffset; + } + attribute.data.needsUpdate = true; + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(tangent); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(normal); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionPrev); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionNext); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(segment); + } + + /** + * Sets the colors. Each two colors is a line segment. + * @param {Color[]} colors + */ + setColors(colors) { + if (colors.length % 2 !== 0) { + throw new Error('Number of colors in the LineMesh must be even.'); + } + // Adjust the number of vertices. * 2 is because the line has width. + this._adjustVerticesInGeometries(colors.length * 2); + for (let objectIndex = 0; objectIndex < this._threeJsObjects.length; objectIndex++) { + const attribute = /** @type {THREE.InterleavedBufferAttribute} */(this._threeJsObjects[objectIndex].geometry.getAttribute('color')); + const array = attribute.array; + for (let i = 0; i < array.length / (2 * LineMesh._floatsPerVertex); i++) { + const offset = i + objectIndex * (LineMesh._verticesPerGeometry / 2); + array[i * 2 * LineMesh._floatsPerVertex + 9] = colors[offset].r; + array[i * 2 * LineMesh._floatsPerVertex + 10] = colors[offset].g; + array[i * 2 * LineMesh._floatsPerVertex + 11] = colors[offset].b; + array[i * 2 * LineMesh._floatsPerVertex + 12] = colors[offset].a; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 9] = colors[offset].r; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 10] = colors[offset].g; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 11] = colors[offset].b; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 12] = colors[offset].a; + } + attribute.data.needsUpdate = true; + } + } + + /** + * Sets the positions. Each two positions is a line segment. + * @param {number[]|number} widths + */ + setWidths(widths) { + if (typeof widths === 'number') { + for (let objectIndex = 0; objectIndex < this._threeJsObjects.length; objectIndex++) { + const attribute = /** @type {THREE.InterleavedBufferAttribute} */(this._threeJsObjects[objectIndex].geometry.getAttribute('width')); + const array = attribute.array; + for (let i = 0; i < array.length / (2 * LineMesh._floatsPerVertex); i++) { + array[i * 2 * LineMesh._floatsPerVertex + 13] = widths; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 13] = -widths; + } + attribute.data.needsUpdate = true; + } + } + else { + if (widths.length % 2 !== 0) { + throw new Error('Number of widths in the LineMesh must be even.'); + } + // Adjust the number of vertices. * 2 is because the line has width. + this._adjustVerticesInGeometries(widths.length * 2); + for (let objectIndex = 0; objectIndex < this._threeJsObjects.length; objectIndex++) { + const attribute = /** @type {THREE.InterleavedBufferAttribute} */(this._threeJsObjects[objectIndex].geometry.getAttribute('width')); + const array = attribute.array; + for (let i = 0; i < array.length / (2 * LineMesh._floatsPerVertex); i++) { + const offset = i + objectIndex * (LineMesh._verticesPerGeometry / 2); + array[i * 2 * LineMesh._floatsPerVertex + 13] = widths[offset]; + array[(i * 2 + 1) * LineMesh._floatsPerVertex + 13] = -widths[offset]; + } + attribute.data.needsUpdate = true; + } + } + } + + /** + * Sets the line dash and gap length. + * @param {number} dashLength + * @param {number} dashGapLength + */ + setDashLength(dashLength, dashGapLength) { + this._dashLength = dashLength; + this._dashGapLength = dashGapLength; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this._threeJsMaterial, 'dashLength', this._dashLength); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this._threeJsMaterial, 'dashGapLength', this._dashGapLength); + } + + /** + * Set the width of the glow from full to clear along the edge of the lines. + * @param {number} glowWidth + */ + setGlowWidth(glowWidth) { + this._glowWidth = glowWidth; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this._threeJsMaterial, 'glowWidth', this._glowWidth); + } + + /** + * Sets the scale. + * @param {number} scale + */ + setScale(scale) { + this._scale = scale; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setScale(this._threeJsObjects, scale); + } + + /** + * Gets the alpha multiplier. This value is multiplied into all line segments as an additional alpha control. + * @returns {number} + */ + getAlphaMultiplier() { + return this._alphaMultiplier; + } + + /** + * Sets the alpha multiplier. This value is multiplied into all line segments as an additional alpha control. + * @param {number} alphaMultiplier - from 0 to 1 + */ + setAlphaMultiplier(alphaMultiplier) { + this._alphaMultiplier = alphaMultiplier; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this._threeJsMaterial, 'alphaMultiplier', this._alphaMultiplier); + } + + /** + * Prepares the line mesh for rendering. It should be called by every component that uses it. + * @param {CameraComponent} camera + */ + prepareForRender(camera) { + const pixelSize = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + + // If the camera is a Spout camera, make the lines thicker and use Spout for the render size. + if (camera.getType() === 'spout') { + const spoutComponent = /** @type {SpoutComponent} */(camera); + pixelSize.set(spoutComponent.getRenderWidth() * 0.1, spoutComponent.getRenderWidth() * 0.5 * 0.1); + } + // Otherwise use the viewport size. + else { + pixelSize.copy(camera.getViewport().getBounds().size); + } + + // Set the pixel render size. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this._threeJsMaterial, 'pixelSize', pixelSize); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelSize); + } + + /** + * Updates the number of Three.js objects and vertices if they have changed. + * @param {number} numVertices + * @private + */ + _adjustVerticesInGeometries(numVertices) { + // The number of objects and meshes we'll be needing. + // Each object can hold up to _verticesPerGeometry vertices, + // due to WebGL 1.0 limitations on the the bit size of index buffers (max 16 bits). + const numThreeJsObjects = Math.ceil(numVertices / LineMesh._verticesPerGeometry); + // Remove any excess objects that are no longer needed because there are now less vertices than before. + while (this._threeJsObjects.length > numThreeJsObjects) { + const objectToRemove = this._threeJsObjects[this._threeJsObjects.length - 1]; + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyObject(objectToRemove); + this._threeJsObjects.splice(this._threeJsObjects.length - 1, 1); + // Remove it from the base component's list. + for (let i = 0, l = this._component.getThreeJsObjects().length; i < l; i++) { + if (this._component.getThreeJsObjects()[i] === objectToRemove) { + this._component.getThreeJsObjects().splice(i, 1); + break; + } + } + } + // Add any new objects that are needed. + if (this._threeJsObjects.length < numThreeJsObjects) { + // Update the current last geometry to have full vertices. + if (this._threeJsObjects.length > 0) { + this._setupThreeJsGeometry(this._threeJsObjects[this._threeJsObjects.length - 1].geometry, LineMesh._verticesPerGeometry); + } + // Add the new objects. + for (let i = this._threeJsObjects.length; i < numThreeJsObjects; i++) { + const objectToAdd = _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this._component, this._threeJsMaterial, [], false); + this._threeJsObjects.push(objectToAdd); + this._component.getThreeJsObjects().push(objectToAdd); + const numVerticesInGeometry = Math.min(numVertices - i * LineMesh._verticesPerGeometry, LineMesh._verticesPerGeometry); + this._setupThreeJsGeometry(objectToAdd.geometry, numVerticesInGeometry); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPosition(objectToAdd, this._position); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(objectToAdd, this._orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setScale(objectToAdd, this._scale); + objectToAdd.frustumCulled = false; + } + } + // There were no new objects needed, so just adjust the vertices of the last mesh. + else if (numThreeJsObjects > 0) { + // If we've got a different number of vertices, we need to update the Three.js geometry. + const geometry = this._threeJsObjects[numThreeJsObjects - 1].geometry; + const numVerticesInLastGeometry = numVertices - (numThreeJsObjects - 1) * LineMesh._verticesPerGeometry; + if (geometry.getAttribute('position').array.length !== numVerticesInLastGeometry * LineMesh._floatsPerVertex) { + this._setupThreeJsGeometry(geometry, numVerticesInLastGeometry); + } + } + } + + /** + * A helper function to setup the Three.js geometry when a new object is created. + * @param {THREE.BufferGeometry} geometry + * @param {number} numVertices - The number of vertices to create. + * @private + */ + _setupThreeJsGeometry(geometry, numVertices) { + // Setup the interleaved vertex buffer. + const vertices = new Float32Array(numVertices * LineMesh._floatsPerVertex); + const buffer = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBuffer(vertices, LineMesh._floatsPerVertex); + geometry.setAttribute('position', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 3, 0, false)); + geometry.setAttribute('positionPrev', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 3, 3, false)); + geometry.setAttribute('positionNext', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 3, 6, false)); + geometry.setAttribute('color', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 4, 9, false)); + geometry.setAttribute('width', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 1, 13, false)); + geometry.setAttribute('dashOffset', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer, 1, 14, false)); + + // Setup the index buffer. + const meshIndices = new Uint16Array(numVertices * 6 / 4); + for (let j = 0; j < numVertices / 4; j++) { + meshIndices[j * 6 + 0] = j * 4; + meshIndices[j * 6 + 1] = j * 4 + 2; + meshIndices[j * 6 + 2] = j * 4 + 3; + meshIndices[j * 6 + 3] = j * 4; + meshIndices[j * 6 + 4] = j * 4 + 3; + meshIndices[j * 6 + 5] = j * 4 + 1; + } + geometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(meshIndices, 1)); + } +} + +LineMesh._floatsPerVertex = 3 + 3 + 3 + 4 + 1 + 1; +LineMesh._verticesPerGeometry = 65536; + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/material_utils.js": +/*!*****************************************************!*\ + !*** ../pioneer/engine/src/utils/material_utils.js ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "MaterialUtils": function() { return /* binding */ MaterialUtils; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** Material utilities. */ +class MaterialUtils { + /** + * Sets the light source uniforms. lightPosition is in camera-space. + * @param {THREE.ShaderMaterial[]} materials + * @param {Entity} entity + * @param {CameraComponent} camera + */ + static setLightSourceUniforms(materials, entity, camera) { + const scene = entity.getScene(); + const lightSourceColor = _internal__WEBPACK_IMPORTED_MODULE_0__.Color.pool.get(); + let lightSourceCount = 0; + for (let i = 0, l = scene.getNumLightSources(); i < Math.min(l, 5); i++) { + // Set the lightPosition and lightColor uniform. + const lightSource = scene.getLightSource(i); + if (lightSource !== null && lightSource !== entity.getComponentByType('lightSource')) { + // Position + const lightSourcePosition = lightSource.getEntity().getCameraSpacePosition(camera); + // Flux + // const lightSourcePositionRelEntity = Vector3.pool.get(); + // lightSource.getEntity().getPositionRelativeToEntity(lightSourcePositionRelEntity, Vector3.Zero, entity); + // const flux = 4.0 * Math.pow(2.51188643151, 46.4205043102 - lightSource.getAbsoluteMagnitude()) / lightSourcePositionRelEntity.magnitudeSqr(); + // Vector3.pool.release(lightSourcePositionRelEntity); + const flux = 1.0; // Note: The above accurately calculates the flux, but farther planets are too dark. Just setting it to one for now. + // Color + lightSourceColor.mult(lightSource.getColor(), flux); + // Radius. Make the radius for the camera light infinite so that it doesn't cast any shadows. + const lightRadius = lightSource.getEntity().getComponentByType('camera') === null + ? lightSource.getEntity().getOcclusionRadius() + : -1.0; + for (let j = 0, m = materials.length; j < m; j++) { + if (materials[j].uniforms['lightPositions'] !== undefined) { + materials[j].uniforms['lightPositions'].value[lightSourceCount].set(lightSourcePosition.x, lightSourcePosition.y, lightSourcePosition.z); + materials[j].uniforms['lightColors'].value[lightSourceCount].set(lightSourceColor.r, lightSourceColor.g, lightSourceColor.b); + materials[j].uniforms['lightRadii'].value[lightSourceCount] = lightRadius; + } + } + lightSourceCount += 1; + } + } + for (let j = 0, m = materials.length; j < m; j++) { + if (materials[j].uniforms['numLights'] !== undefined) { + materials[j].uniforms['numLights'].value = lightSourceCount; + } + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Color.pool.release(lightSourceColor); + } + + /** + * Sets the materials' uniforms from the camera, entity, and light source. + * @param {THREE.ShaderMaterial[]} materials + * @param {CameraComponent} camera + * @param {Entity} entity + * @param {EntityRef[]} shadowEntities + * @param {AtmosphereComponent} atmosphere + * @param {boolean} isSpheroid + */ + static setUniforms(materials, camera, entity, shadowEntities, atmosphere, isSpheroid) { + // Get the time. + const time = entity.getScene().getEngine().getTime(); + + // Get the ambient color. + const ambientLightColor = entity.getScene().getAmbientLightColor(); + + // Set the lightPosition and lightColor uniform. + MaterialUtils.setLightSourceUniforms(materials, entity, camera); + + for (let i = 0, l = materials.length; i < l; i++) { + /** @type {THREE.ShaderMaterial} */ + const material = materials[i]; + const uniforms = material.uniforms; + + if (material instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RawShaderMaterial) { + if (uniforms['time'] !== undefined) { + // Wrap it to the nearest hour, since the full time can't fit into a GLSL float variable. + uniforms['time'].value = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(time, 0.0, 3600.0); + } + } + else { // Regular ShaderMaterial from the MaterialUtils. + // Set the entity position uniform. + const position = entity.getCameraSpacePosition(camera); + uniforms['entityPos'].value.set(position.x, position.y, position.z); + + // Set the uniforms that don't depend on a light source. + uniforms['ambientLightColor'].value.setRGB(ambientLightColor.r, ambientLightColor.g, ambientLightColor.b); + + // For each shadow entity, apply the params. + if (shadowEntities !== undefined && shadowEntities.length > 0) { + let validShadowEntities = 0; + for (let j = 0; j < shadowEntities.length; j++) { + const shadowEntity = shadowEntities[j].get(); + if (shadowEntity !== null) { + const position = shadowEntity.getCameraSpacePosition(camera); + uniforms['shadowEntityPositions'].value[validShadowEntities].set(position.x, position.y, position.z); + uniforms['shadowEntityRadii'].value[validShadowEntities] = shadowEntity.getOcclusionRadius(); + + const atmosphereComponent = /** @type {AtmosphereComponent} */(shadowEntity.get('atmosphere')); + if (atmosphereComponent !== null) { + const sunsetColor = atmosphereComponent.getSunsetColor(); + uniforms['shadowEntitySunsetColors'].value[validShadowEntities].set(sunsetColor.r, sunsetColor.g, sunsetColor.b); + uniforms['shadowEntitySunsetIntensity'].value[validShadowEntities] = atmosphereComponent.getSunsetIntensity(); + } + else { + uniforms['shadowEntitySunsetIntensity'].value[validShadowEntities] = 0.0; + } + validShadowEntities += 1; + } + else { + uniforms['shadowEntityRadii'].value[validShadowEntities] = 0; + uniforms['shadowEntitySunsetIntensity'].value[validShadowEntities] = 0.0; + } + } + + uniforms['numShadowEntities'].value = validShadowEntities; + } + + if (materials[i].defines['shadowRings']) { + const ringsComponent = /** @type {RingsComponent} */(entity.get('rings')); + if (ringsComponent !== null) { + const normal = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + entity.getOrientation().getAxis(normal, 2); + uniforms['shadowRingsInnerRadius'].value = ringsComponent.getInnerRadius(); + uniforms['shadowRingsOuterRadius'].value = ringsComponent.getOuterRadius(); + uniforms['shadowRingsTexture'].value = ringsComponent.getTopTexture(); + uniforms['shadowRingsNormal'].value.set(normal.x, normal.y, normal.z); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(normal); + } + } + } + + // Atmospheres + if (atmosphere !== null && atmosphere.getLoadState() === 'loaded' && !atmosphere.isExcludedFromCamera(camera) && uniforms['atmospherePosition'] !== undefined) { + const spheroid = atmosphere.getSpheroid(); + const atmospherePosition = atmosphere.getEntity().getCameraSpacePosition(camera); + const atmosphereOrientation = atmosphere.getEntity().getOrientation(); + const atmosphereColor = atmosphere.getColor(); + const atmosphereSunsetColor = atmosphere.getSunsetColor(); + uniforms['atmospherePosition'].value.set(atmospherePosition.x, atmospherePosition.y, atmospherePosition.z); + uniforms['atmosphereOrientation'].value.set(atmosphereOrientation.x, atmosphereOrientation.y, atmosphereOrientation.z, atmosphereOrientation.w); + if (spheroid !== null) { + uniforms['atmosphereEquatorialRadius'].value = spheroid.getEquatorialRadius(); + uniforms['atmospherePolarRadius'].value = spheroid.getPolarRadius(); + } + else { + uniforms['atmosphereEquatorialRadius'].value = 0; + uniforms['atmospherePolarRadius'].value = 0; + } + uniforms['atmosphereDensity'].value = atmosphere.getDensity(); + uniforms['atmosphereScaleHeight'].value = atmosphere.getScaleHeight(); + uniforms['atmosphereEmissivity'].value = atmosphere.getEmissivity(); + uniforms['atmosphereColor'].value.set(atmosphereColor.r, atmosphereColor.g, atmosphereColor.b); + uniforms['atmosphereSunsetColor'].value.set(atmosphereSunsetColor.r, atmosphereSunsetColor.g, atmosphereSunsetColor.b); + uniforms['atmosphereSunsetIntensity'].value = atmosphere.getSunsetIntensity(); + uniforms['atmosphereGroundIsSpheroid'].value = isSpheroid ? 1 : 0; + if (material.defines['atmosphere'] === undefined) { + material.defines['atmosphere'] = true; + material.needsUpdate = true; + } + } + else if (material.defines['atmosphere'] === true) { + delete material.defines['atmosphere']; + material.needsUpdate = true; + } + } + } +} + +/** + * Returns a specular/phong material. + * @returns {THREE.ShaderMaterial} + */ +MaterialUtils.get = _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtilsPhong.get; + +/** + * Returns a PBR material. + * @returns {THREE.ShaderMaterial} + */ +MaterialUtils.getPBR = _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtilsStandard.get; + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/material_utils_phong.js": +/*!***********************************************************!*\ + !*** ../pioneer/engine/src/utils/material_utils_phong.js ***! + \***********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "MaterialUtilsPhong": function() { return /* binding */ MaterialUtilsPhong; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** Material utilities. */ +class MaterialUtilsPhong { + /** Gets a Phong ShaderMaterial. + * @returns {THREE.ShaderMaterial} + */ + static get() { + if (MaterialUtilsPhong._material === null) { + MaterialUtilsPhong._material = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ShaderMaterial({ + uniforms: { + // External lighting and camera. + entityPos: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()), + + // Lights + ambientLightColor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Color()), + lightPositions: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0)]), + lightColors: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0)]), + lightRadii: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0, 0, 0, 0, 0]), + numLights: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + + // Shading. + color: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Color(1, 1, 1)), + specularColor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Color(1, 1, 1)), + specularIntensity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + specularHardness: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(50.0), + + // Textures. + colorTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + normalTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + specularTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + nightTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + decalTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + + normalScale: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2()), + + // Shadow Entities + numShadowEntities: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + shadowEntityPositions: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()]), + shadowEntityRadii: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0, 0, 0, 0, 0]), + shadowEntitySunsetIntensity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0, 0, 0, 0, 0]), + shadowEntitySunsetColors: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()]), + + // Shadow Rings + shadowRingsInnerRadius: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + shadowRingsOuterRadius: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + shadowRingsTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + shadowRingsNormal: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()), + + // Atmosphere + atmospherePosition: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0)), + atmosphereOrientation: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4(1, 0, 0, 0)), + atmosphereEquatorialRadius: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1), + atmospherePolarRadius: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1), + atmosphereDensity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + atmosphereScaleHeight: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1), + atmosphereEmissivity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + atmosphereColor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0)), + atmosphereSunBrightness: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1), + atmosphereSunsetColor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0)), + atmosphereSunsetIntensity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + atmosphereGroundIsSpheroid: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + + ..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms + }, + vertexShader: ` + #ifdef normalMap + attribute vec4 tangent; + varying vec4 viewTangent; + #endif + #ifdef normalUVs + attribute vec2 normalUV; + varying vec2 vNormalUV; + #endif + #ifdef specularUVs + attribute vec2 specularUV; + varying vec2 vSpecularUV; + #endif + #ifdef nightUVs + attribute vec2 nightUV; + varying vec2 vNightUV; + #endif + #ifdef decalUVs + attribute vec2 decalUV; + varying vec2 vDecalUV; + #endif + varying vec2 vColorUV; + varying vec3 cameraSpacePosition; + varying vec3 cameraSpaceNormal; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + #ifdef normalMap + viewTangent = vec4((modelMatrix * vec4(tangent.xyz, 0.0)).xyz, tangent.w); + #endif + vColorUV = uv; + #ifdef normalUVs + vNormalUV = normalUV; + #endif + #ifdef specularUVs + vSpecularUV = specularUV; + #endif + #ifdef nightUVs + vNightUV = nightUV; + #endif + #ifdef decalUVs + vDecalUV = decalUV; + #endif + cameraSpacePosition = (modelMatrix * vec4(position, 1.)).xyz; + cameraSpaceNormal = (modelMatrix * vec4(normal, 0.)).xyz; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.); + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`, + fragmentShader: ` + precision highp float; + + #ifndef saturate + #define saturate(a) clamp(a, 0.0, 1.0) + #endif + uniform mat3 normalMatrix; + + // External lighting and camera. + uniform vec3 entityPos; + + // Lights + uniform vec3 ambientLightColor; + uniform vec3 lightPositions[5]; + uniform vec3 lightColors[5]; + uniform float lightRadii[5]; + uniform int numLights; + + // Shading. + uniform vec3 color; + uniform vec3 specularColor; + uniform float specularIntensity; + uniform float specularHardness; + + // Shadow Entities. + #ifdef shadowEntities + uniform int numShadowEntities; + uniform vec3 shadowEntityPositions[5]; + uniform float shadowEntityRadii[5]; + uniform float shadowEntitySunsetIntensity[5]; + uniform vec3 shadowEntitySunsetColors[5]; + #endif + + #ifdef shadowRings + uniform float shadowRingsInnerRadius; + uniform float shadowRingsOuterRadius; + uniform sampler2D shadowRingsTexture; + uniform vec3 shadowRingsNormal; + #endif + + // Textures. + uniform sampler2D colorTexture; + #ifdef normalMap + uniform sampler2D normalTexture; + #endif + #ifdef specularMap + uniform sampler2D specularTexture; + #endif + #ifdef nightMap + uniform sampler2D nightTexture; + #endif + #ifdef decalMap + uniform sampler2D decalTexture; + #endif + + // Modifications on the textures. + #ifdef normalMap + uniform vec2 normalScale; + #endif + + // The varying attributes. + #ifdef normalMap + varying vec4 viewTangent; + #endif + #ifdef normalUVs + varying vec2 vNormalUV; + #endif + #ifdef specularUVs + varying vec2 vSpecularUV; + #endif + #ifdef nightUVs + varying vec2 vNightUV; + #endif + #ifdef decalUVs + varying vec2 vDecalUV; + #endif + varying vec2 vColorUV; + varying vec3 cameraSpacePosition; + varying vec3 cameraSpaceNormal; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + #ifdef normalMap + vec3 getNormalFromMap() { + vec3 normal = normalize(cameraSpaceNormal); + vec3 tangent = normalize(viewTangent.xyz); + vec3 bitangent = normalize(cross(normal, tangent)); + if (viewTangent.w < 0.0) { + bitangent *= -1.0; + } + mat3 transform = mat3(tangent, bitangent, normal); + #ifdef normalUVs + vec2 uv = vNormalUV; + #else + vec2 uv = vColorUV; + #endif + vec3 normalFromMap = texture2D(normalTexture, uv).rgb * 2.0 - 1.0; + normalFromMap.xy *= vec2(1, -1); + normalFromMap.xy *= normalScale; + return normalize(transform * normalFromMap); + } + #endif + + #ifdef colorTextureEnvironment + vec4 getColorFromEnvironmentMap(sampler2D environmentTexture, vec3 positionDir, vec3 normal) { + vec3 r = reflect(positionDir, normal); + float m = 2. * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.) * (r.z + 1.)); + vec2 uv = r.xy / m + .5; + return vec4(texture2D(environmentTexture, uv).rgb, 1.); + } + #endif + + #ifdef shadowEntities + vec3 applyRayleighScattering(vec3 color, float amount) { + float value = (color.r + color.g + color.b); + if (value > 0.0) { + float rFactor = 1.0; // 6.3^-4 / 6.3^-4 + float gFactor = 1.602; // 5.6^-4 / 6.3^-4 + float bFactor = 3.228; // 4.7^-4 / 6.3^-4 + color.r *= pow(rFactor, -amount); + color.g *= pow(gFactor, -amount); + color.b *= pow(bFactor, -amount); + } + return color; + } + + vec3 getLightColorFromShadowEntities(vec3 lightColor, vec3 lightDir, vec3 lightPosition, float lightRadius, vec3 normal) { + vec3 color = lightColor; + for (int i = 0; i < 5; i++) { + if (i >= numShadowEntities || lightRadius < 0.0) { + break; + } + vec3 origin = cameraSpacePosition - shadowEntityPositions[i]; + vec3 axis = normalize(shadowEntityPositions[i] - lightPosition); + float sd = dot(origin, axis); + if (sd > 0.0) { + float e = length(origin - sd * axis); + float ld = dot(cameraSpacePosition - lightPosition, axis); + float lr = lightRadius; + float sr = shadowEntityRadii[i]; + float e0 = (ld * sr - sd * lr) / (ld - sd); + float e1 = (ld * sr + sd * lr) / (ld - sd); + float lightLevel = 0.0; + if (e1 < 0.0 || sd < 0.0) { // light in front of shadow entity + lightLevel = 1.0; + } + else if (e0 < e1) { + e0 /= max(1.0, shadowEntitySunsetIntensity[i] * 2.0); + lightLevel = (e - e0) / (e1 - e0); + } + else { + lightLevel = e < e0 ? 0.0 : 1.0; // 0 radius light. + } + color = saturate(lightLevel) * applyRayleighScattering(color, saturate(1.5 - lightLevel) * saturate(shadowEntitySunsetIntensity[i])); + } + } + return color; + } + #endif + + #ifdef shadowRings + vec3 getLightColorFromShadowRings(vec3 lightColor, vec3 lightDir) { + vec3 position = cameraSpacePosition - entityPos; + float d = dot(position, shadowRingsNormal) / dot(lightDir, shadowRingsNormal); + highp vec3 pointOnDisc = -d * lightDir + position; + float lengthOnDisc = length(pointOnDisc - dot(pointOnDisc, shadowRingsNormal) * shadowRingsNormal); + float u = (lengthOnDisc - shadowRingsInnerRadius) / (shadowRingsOuterRadius - shadowRingsInnerRadius); + float shadow = 1.0 - texture2D(shadowRingsTexture, vec2(u, 0.0), 0.0).a; + if (shadowRingsInnerRadius <= lengthOnDisc && lengthOnDisc <= shadowRingsOuterRadius && d > 0.0) { + return lightColor * saturate(shadow); + } + else { + return lightColor; + } + } + #endif + + // ATMOSPHERE + + #ifdef atmosphere + uniform vec3 atmospherePosition; + uniform vec4 atmosphereOrientation; + uniform float atmosphereEquatorialRadius; + uniform float atmospherePolarRadius; + uniform float atmosphereDensity; + uniform float atmosphereScaleHeight; + uniform vec3 atmosphereColor; + uniform float atmosphereEmissivity; + uniform float atmosphereSunBrightness; + uniform vec3 atmosphereSunsetColor; + uniform float atmosphereSunsetIntensity; + uniform float atmosphereGroundIsSpheroid; + + const int atmosphereNumIterations = 5; + + // Inverse rotate a vector by a quaternion. + vec3 quatRotInv(vec4 q, vec3 v) { + float tx = q.w * v.x - q.y * v.z + q.z * v.y; + float ty = q.w * v.y - q.z * v.x + q.x * v.z; + float tz = q.w * v.z - q.x * v.y + q.y * v.x; + float tw = q.x * v.x + q.y * v.y + q.z * v.z; + float x = tx * q.w + tw * q.x + ty * q.z - tz * q.y; + float y = ty * q.w + tw * q.y + tz * q.x - tx * q.z; + float z = tz * q.w + tw * q.z + tx * q.y - ty * q.x; + return vec3(x, y, z); + } + + // Given an origin and direction, computes the sampling start and end as distance from the origin in the direction. + void getStartEndSamples(out float start, out float end, vec3 origin, vec3 direction, float maxDistance, float groundRadius, float atmosphereScaleHeight) { + // Get the along the ray perpendicular to the sphere. + float perpD = -dot(origin, direction); + vec3 perp = origin + direction * perpD; + + // Figure out the sample distance. + float atmosphereRadius = groundRadius + atmosphereScaleHeight * 6.0; + float chordHalfLength = sqrt(max(0.0, atmosphereRadius * atmosphereRadius - dot(perp, perp))); + + // Figure out starting and ending sample points. + start = max(0.0, perpD - chordHalfLength); + end = min(maxDistance, perpD + chordHalfLength); + } + + // Gets the density of the atmosphere at a given position. + float getDensity(vec3 position, float radius, float density, float atmosphereScaleHeight) { + return density * exp((radius - length(position)) / atmosphereScaleHeight); + } + + // Returns 0 if the ray does not intersect and 1.0 if the ray very intersects (with a gradient inbetween). + float getDayLevel(vec3 origin, vec3 direction, float radius, float scaleHeight) { + float blendHeight = scaleHeight * radius / 200.0; + float perpD = -dot(origin, direction); + float depth = radius - sqrt(dot(origin, origin) - sign(perpD) * perpD * perpD); + if (depth < 0.0) { // day + return 1.0 - max(0.0, 0.25 * depth / blendHeight + 0.25); + } + else { // night + return 1.0 - min(1.0, 0.75 * depth / blendHeight + 0.25); + } + } + + // Adjusts the color if one of the RGB values is greater than 1.0. + vec3 adjustOverbrightness(vec3 color) { + float maxColor = max(color.r, max(color.g, color.b)); + if (maxColor > 1.0) { + float f = (maxColor - 1.0) / maxColor; + color.r = min(1.0, pow(color.r / maxColor, 1.0 / maxColor)); + color.g = min(1.0, pow(color.g / maxColor, 1.0 / maxColor)); + color.b = min(1.0, pow(color.b / maxColor, 1.0 / maxColor)); + } + return color; + } + + float easeInOut(float x, float sharpness) { + float b = sharpness; + if (x < 0.5) { + return max(0.0, (pow(b, 2.0 * x) - 1.0) / (2.0 * (b - 1.0))); + } + else { + return min(1.0, 1.0 - (pow(b, 2.0 * (1.0 - x)) - 1.0) / (2.0 * (b - 1.0))); + } + } + + // Calculates a glow around the light direction. + float glow(float spread, float amount, float lightDotCamera) { + return amount * spread / (1.0 + spread - lightDotCamera); + } + + struct AtmosphereInfo { + float spheroidRatio; + highp vec3 position; + highp vec3 cameraPosition; + highp vec3 cameraToPosition; + float cameraToPositionDist; + highp vec3 cameraToPositionUnit; + float start; + float end; + float totalDensity; + }; + + // Get atmosphere info that is independent of any light. + AtmosphereInfo getAtmosphereInfo() { + + AtmosphereInfo atmosphereInfo; + + // Get position and camera in the atmosphere frame. + atmosphereInfo.position = quatRotInv(atmosphereOrientation, cameraSpacePosition - atmospherePosition); + atmosphereInfo.cameraPosition = quatRotInv(atmosphereOrientation, -atmospherePosition); + + // Convert everything into a sphere frame. + atmosphereInfo.spheroidRatio = atmosphereEquatorialRadius / atmospherePolarRadius; + atmosphereInfo.position.z *= atmosphereInfo.spheroidRatio; + atmosphereInfo.cameraPosition.z *= atmosphereInfo.spheroidRatio; + + // Make sure the position is right on the ground. + atmosphereInfo.position = normalize(atmosphereInfo.position / 1.0e8) * atmosphereEquatorialRadius; + + // Get some shortcut vectors. + atmosphereInfo.cameraToPosition = atmosphereInfo.position - atmosphereInfo.cameraPosition; + atmosphereInfo.cameraToPositionDist = length(atmosphereInfo.cameraToPosition / 1.0e8) * 1.0e8; + atmosphereInfo.cameraToPositionUnit = atmosphereInfo.cameraToPosition / atmosphereInfo.cameraToPositionDist; + + // Get the start and end of the sampling from the camera to the position. + getStartEndSamples(atmosphereInfo.start, atmosphereInfo.end, atmosphereInfo.cameraPosition, atmosphereInfo.cameraToPositionUnit, atmosphereInfo.cameraToPositionDist, atmosphereEquatorialRadius, atmosphereScaleHeight); + float step = 1.0 / float(atmosphereNumIterations - 1); + float stepDist = step * (atmosphereInfo.end - atmosphereInfo.start); + + // Do the sampling. + atmosphereInfo.totalDensity = 0.0; + float segmentStart = atmosphereInfo.start; + for (int j = 0; j < atmosphereNumIterations; j++) { + // Get the distance that this segment covers. + float segDist = stepDist; + if (j == 0 || j == atmosphereNumIterations - 1) { + segDist *= 0.5; + } + + // Get the segment start that we're looking at. + vec3 p = atmosphereInfo.cameraPosition + segmentStart * atmosphereInfo.cameraToPositionUnit; + + // Get the density at that segment start. It'll be the density for the whole segment. + float densityAtP = getDensity(p, atmosphereEquatorialRadius, atmosphereDensity, atmosphereScaleHeight); + + // Add it to the total density. + atmosphereInfo.totalDensity += densityAtP * segDist; + + // Next step. + segmentStart += stepDist; + } + + return atmosphereInfo; + } + + vec4 getAtmosphereEmissiveColor(AtmosphereInfo atmosphereInfo, vec3 color, float emissivity) { + + // Scale the total density with the emissivity. + atmosphereInfo.totalDensity *= emissivity; + + // Apply the total density to the transparency of the atmosphere. + vec4 outColor = vec4(0.0); + outColor.a = clamp(pow(3.0 * atmosphereInfo.totalDensity, 0.3), 0.0, 1.0); + + // Multiply it all together with the source light color. + outColor.rgb = emissivity * color * clamp(pow(15.0 * atmosphereInfo.totalDensity / (atmosphereDensity * atmosphereEquatorialRadius), 0.2), 0.75, 1.0); + + // Make it more opaque when lower down. + outColor.a *= 1.0 + 0.5 * getDensity(atmosphereInfo.cameraPosition, atmosphereEquatorialRadius, 1.0, atmosphereScaleHeight); + + // Clamp it to make it clean. + outColor.a = clamp(outColor.a, 0.0, 1.0); + + // Return the color. + return outColor; + } + + // Adjust the incoming light for the atmosphere. + vec4 getAtmosphereColor(AtmosphereInfo atmosphereInfo, vec3 incomingLight, vec3 lightPosition) { + + // The color starts out in full brightness (as if emissivity was 1.0). + vec4 outColor = getAtmosphereEmissiveColor(atmosphereInfo, incomingLight * atmosphereColor, 1.0); + + // Get the light position in the sphere entity-space. + lightPosition = quatRotInv(atmosphereOrientation, lightPosition); + lightPosition.z *= atmosphereInfo.spheroidRatio; + highp vec3 lightToPosition = atmosphereInfo.position - lightPosition; + highp vec3 lightToPositionUnit = normalize(lightToPosition / 1.0e8); + + // Get the day level, from 0 to 1, and apply it to the alpha. + float ambientLightIntensity = min(1.0, length(ambientLightColor)); + vec3 dayRefUp = normalize(atmosphereInfo.cameraPosition + atmosphereInfo.end * atmosphereInfo.cameraToPositionUnit); + float dayLevel = -dot(lightToPositionUnit, dayRefUp); + float lightIntensity = mix(dayLevel, 0.0, ambientLightIntensity); + outColor.a *= easeInOut(0.25 * 700.0 * atmosphereDensity + 1.0 * lightIntensity, 2.0); + + // Add broader sun glare. + float lightDotCamera = max(0.0, -dot(lightToPositionUnit, atmosphereInfo.cameraToPositionUnit)); + outColor.rgb *= incomingLight * (1.0 + atmosphereSunBrightness * outColor.a * glow(0.04, 0.125, lightDotCamera)); + + // Apply the sunset. + float sunsetAmount = mix(atmosphereSunsetIntensity * easeInOut(0.5 * (1.0 - abs(dayLevel)), 4.0), 0.0, ambientLightIntensity); + outColor.rgb *= mix(vec3(1.0), atmosphereSunsetColor, clamp(sunsetAmount, 0.0, 1.0)); + + // Adjust for values that are greater than one. + outColor.rgb = adjustOverbrightness(outColor.rgb); + + return outColor; + } + #endif + + void main(void) { + // Get the camera direction to the position. + vec3 positionDir = normalize(cameraSpacePosition); + + // Calculate the normal. + #ifdef normalMap + vec3 normal = getNormalFromMap(); + #else + vec3 normal = normalize(cameraSpaceNormal); + #endif + + // The diffuse light. + vec3 diffuseLight = ambientLightColor; + vec3 specularLight = vec3(0, 0, 0); + + // Atmosphere emissive shading. + #ifdef atmosphere + AtmosphereInfo atmosphereInfo = getAtmosphereInfo(); + vec4 atmosphereColor = getAtmosphereEmissiveColor(atmosphereInfo, atmosphereColor, atmosphereEmissivity); + #endif + + // For each light, + for (int i = 0; i < 5; i++) { + if (i >= numLights) { + break; + } + + // Get lighting angles. + vec3 lightDir = normalize(cameraSpacePosition - lightPositions[i]); + float lightCosAngle = -dot(lightDir, normal); + + // Make the shadows a bit sharper, depending on atmospheres. + float sharpness = 3.0; + #ifdef atmosphere + sharpness /= 1.0 + 700.0 * atmosphereDensity; + #endif + lightCosAngle = 2.0 * (1.0 + exp(-sharpness)) / (1.0 + exp(-sharpness * lightCosAngle)) - 1.0; + + // Get the incoming light after shadows. + vec3 incomingLight = lightColors[i]; + #if !defined(colorMapEmmissive) | !defined(nightMapEmmissive) | !defined(decalMapEmmissive) + #ifdef shadowEntities + incomingLight = getLightColorFromShadowEntities(incomingLight, lightDir, lightPositions[i], lightRadii[i], normal); + #endif + #ifdef shadowRings + incomingLight = getLightColorFromShadowRings(incomingLight, lightDir); + #endif + #endif + + // Diffuse shading. + diffuseLight += incomingLight * saturate(lightCosAngle); + + // Specular shading. + vec3 reflectedLightDir = reflect(lightDir, normal); + vec3 halfVector = normalize(-lightDir - positionDir); + float phongHighlight = 0.25 * pow(saturate(-dot(reflectedLightDir, positionDir)), specularHardness / 2.0); + float blinnHighlight = 4.0 * pow(saturate(dot(halfVector, normal)), specularHardness); + float specularAngle = phongHighlight + pow(1.0 - saturate(-dot(positionDir, normal)), specularHardness / 12.0) * blinnHighlight; + specularLight += saturate(lightCosAngle * 20.0) * specularAngle * incomingLight; + + // Atmosphere shading. + #ifdef atmosphere + if (length(lightPositions[i]) > 0.0) { // don't use a camera light + atmosphereColor += getAtmosphereColor(atmosphereInfo, incomingLight, lightPositions[i]); + } + #endif + } + diffuseLight = saturate(diffuseLight); + + // If there's ambience, remove the direct light components. + specularLight *= vec3(1, 1, 1) - ambientLightColor; + + // Main Color map. + vec4 colorPixel = vec4(1, 0, 1, 1); + #ifdef colorTextureEnvironment + colorPixel = getColorFromEnvironmentMap(colorTexture, positionDir, normal); + #else + colorPixel = texture2D(colorTexture, vColorUV) * vec4(color, 1); + #endif + #ifdef baseColor + colorPixel = vec4(color, 1); + #endif + + // Apply diffuse shading. + #ifndef colorMapEmmissive + colorPixel *= vec4(diffuseLight, 1.0); + #endif + gl_FragColor = colorPixel; + + // Specular Map + vec3 specularPixel = specularColor * specularIntensity; + #ifdef specularMap + #ifdef specularUVs + vec2 specularUV = vSpecularUV; + #else + vec2 specularUV = vColorUV; + #endif + specularPixel = specularColor * texture2D(specularTexture, specularUV).r; + #endif + + // Apply specular Shading + gl_FragColor.rgb += specularLight * specularPixel; + + // Night-Side Map + #ifdef nightMap + float ambientLightIntensity = min(1.0, length(ambientLightColor)); + #ifdef nightUVs + vec2 nightUV = vNightUV; + #else + vec2 nightUV = vColorUV; + #endif + vec4 nightPixel = texture2D(nightTexture, nightUV); + #ifndef nightMapEmmissive + nightPixel *= vec4(diffuseLight, 1.0); + #endif + gl_FragColor = mix(gl_FragColor, nightPixel, 1.0 - min(1.0, length(ambientLightColor + diffuseLight)));//(1.0 - ambientLightIntensity) * saturate(0.5 - length(diffuseLight))); + #endif + + // Decal Map + #ifdef decalMap + #ifdef decalUVs + vec2 decalUV = vDecalUV; + #else + vec2 decalUV = vColorUV; + #endif + vec4 decalPixel = texture2D(decalTexture, decalUV); + #ifndef decalMapEmmissive + decalPixel *= vec4(diffuseLight, 1.0); + #endif + gl_FragColor.rgb = mix(gl_FragColor.rgb, decalPixel.rgb, decalPixel.a); + #endif + + // Atmosphere + #ifdef atmosphere + gl_FragColor.rgb = mix(gl_FragColor.rgb, atmosphereColor.rgb, clamp(atmosphereColor.a, 0.0, 1.0)); + #endif + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }` + }); + } + const newMaterial = MaterialUtilsPhong._material.clone(); + for (let i = 0; i < newMaterial.uniforms['shadowEntityPositions'].value.length; i++) { + newMaterial.uniforms['shadowEntityPositions'].value[i] = MaterialUtilsPhong._material.uniforms['shadowEntityPositions'].value[i].clone(); + } + for (let i = 0; i < newMaterial.uniforms['shadowEntitySunsetColors'].value.length; i++) { + newMaterial.uniforms['shadowEntitySunsetColors'].value[i] = MaterialUtilsPhong._material.uniforms['shadowEntitySunsetColors'].value[i].clone(); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupLogDepthBuffering(newMaterial); + newMaterial.extensions.derivatives = true; + newMaterial.needsUpdate = true; + return newMaterial; + } +} + +/** + * @type {THREE.ShaderMaterial} +*/ +MaterialUtilsPhong._material = null; + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/material_utils_standard.js": +/*!**************************************************************!*\ + !*** ../pioneer/engine/src/utils/material_utils_standard.js ***! + \**************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "MaterialUtilsStandard": function() { return /* binding */ MaterialUtilsStandard; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +class MaterialUtilsStandard { + /** Gets a PBR ShaderMaterial. + * @returns {THREE.ShaderMaterial} + */ + static get() { + if (MaterialUtilsStandard._material === null) { + MaterialUtilsStandard._material = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ShaderMaterial({ + uniforms: { + // Lights + ambientLightColor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Color()), + lightPositions: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1, 0, 0)]), + lightColors: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0, 0, 0)]), + lightRadii: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0, 0, 0, 0, 0]), + numLights: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + environmentIntensity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1.0), + gammaCorrectionFactor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1.0), + + // External lighting and camera. + entityPos: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()), + + // Shading. + color: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Color(1, 1, 1)), + metalness: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0.0), + roughness: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0.0), + emissiveColor: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Color(0, 0, 0)), + alphaMultiplier: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1.0), + + // Textures + colorTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + roughnessTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + metalnessTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + normalTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + emissiveTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + + // Shadow Entities + numShadowEntities: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + shadowEntityPositions: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()]), + shadowEntityRadii: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0, 0, 0, 0, 0]), + shadowEntitySunsetIntensity: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0, 0, 0, 0, 0]), + shadowEntitySunsetColors: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(), new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()]), + + // Environmental cubemap + envTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + maxMipLevel: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + + // Dynamic environment map + dynEnvTexture: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null), + dynEnvFaceSize: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0), + + normalScale: new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2()), + + ..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms + }, + vertexShader: ` + #ifdef normalMap + attribute vec4 tangent; + varying vec4 localTangent; + varying vec3 localNormal; + #else + varying vec3 modelNormal; + #endif + #if defined(normalMap) || defined(colorMap) || defined(roughnessMap) || defined(metalnessMap) || defined(emissiveMap) + varying vec2 localUV; + #endif + varying vec3 cameraSpacePosition; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + #ifdef normalMap + localTangent = tangent; + localNormal = normal; + #else + modelNormal = normalize((modelMatrix * vec4(normal, 0.)).xyz); + #endif + #if defined(normalMap) || defined(colorMap) || defined(roughnessMap) || defined(metalnessMap) || defined(emissiveMap) + localUV = uv; + #endif + cameraSpacePosition = (modelMatrix * vec4(position, 1.)).xyz; + vec4 viewPosition = modelViewMatrix * vec4(position, 1.); + gl_Position = projectionMatrix * viewPosition; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`, + fragmentShader: ` + precision highp float; + + #define DEFAULT_SPECULAR_COEFFICIENT 0.04 + #define EPSILON 1e-6 + #define PI 3.14159265359 + #define RECIPROCAL_PI 0.31830988618 + #define RECIPROCAL_PI2 0.15915494 + #ifndef saturate + #define saturate(a) clamp( a, 0.0, 1.0 ) + #endif + + float pow2( float x ) { return x*x; } + + uniform mat4 modelMatrix; + + // Lights + uniform vec3 ambientLightColor; + uniform vec3 lightPositions[5]; + uniform vec3 lightColors[5]; + uniform float lightRadii[5]; + uniform int numLights; + uniform float environmentIntensity; + uniform float gammaCorrectionFactor; + + // External lighting and camera. + uniform vec3 entityPos; + + // Textures. + uniform sampler2D colorTexture; + uniform sampler2D roughnessTexture; + uniform sampler2D metalnessTexture; + #ifdef normalMap + uniform sampler2D normalTexture; + #endif + #ifdef emissiveMap + uniform sampler2D emissiveTexture; + #endif + #ifdef dynEnvMap + uniform sampler2D dynEnvTexture; + uniform float dynEnvFaceSize; + #elif defined( envMap ) + #ifdef envIsCube + uniform samplerCube envTexture; + #else + uniform sampler2D envTexture; + #endif + #endif + + #ifdef normalMap + uniform vec2 normalScale; + #endif + + // Shadow Entities. + #ifdef shadowEntities + uniform int numShadowEntities; + uniform vec3 shadowEntityPositions[5]; + uniform float shadowEntityRadii[5]; + uniform float shadowEntitySunsetIntensity[5]; + uniform vec3 shadowEntitySunsetColors[5]; + #endif + + // Scalars + uniform vec3 color; + uniform float roughness; + uniform float metalness; + uniform vec3 emissiveColor; + uniform float alphaMultiplier; + + // The varying attributes. + #ifdef normalMap + varying vec4 localTangent; + varying vec3 localNormal; + #else + varying vec3 modelNormal; + #endif + #if defined(normalMap) || defined(colorMap) || defined(roughnessMap) || defined(metalnessMap) || defined(emissiveMap) + varying vec2 localUV; + #endif + varying vec3 cameraSpacePosition; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + struct PhysicalMaterial { + vec3 diffuseColor; + vec3 specularColor; + float specularRoughness; + }; + struct IncidentLight { + vec3 color; + vec3 direction; + }; + + struct ReflectedLight { + vec3 directDiffuse; + vec3 directSpecular; + vec3 indirectDiffuse; + vec3 indirectSpecular; + }; + + struct GeometricContext { + vec3 normal; + vec3 viewDir; + }; + + #ifdef normalMap + vec3 getNormalFromMap() { + vec3 normal = normalize(localNormal); + vec3 tangent = normalize(localTangent.xyz); + vec3 bitangent = normalize(cross(normal, tangent)); + if (localTangent.w < 0.0) { + bitangent *= -1.0; + } + mat3 transform = mat3(tangent, bitangent, normal); + vec3 normalFromMap = texture2D(normalTexture, localUV).rgb * 2.0 - 1.0; + normalFromMap.xy *= vec2(1, -1); + normalFromMap.xy *= normalScale; + return normalize(transform * normalFromMap); + } + #endif + + #ifdef shadowEntities + vec3 applyRayleighScattering(vec3 color, float amount) { + float value = (color.r + color.g + color.b); + if (value > 0.0) { + float rFactor = 1.0; // 6.3^-4 / 6.3^-4 + float gFactor = 1.602; // 5.6^-4 / 6.3^-4 + float bFactor = 3.228; // 4.7^-4 / 6.3^-4 + color.r *= pow(rFactor, -amount); + color.g *= pow(gFactor, -amount); + color.b *= pow(bFactor, -amount); + color = value * color / (color.r + color.g + color.b); + } + return color; + } + + vec3 getLightColorFromShadowEntities(vec3 lightColor, vec3 lightDir, vec3 lightPosition, float lightRadius, vec3 normal) { + vec3 color = lightColor; + for (int i = 0; i < 5; i++) { + if (i >= numShadowEntities || lightRadius < 0.0) { + break; + } + vec3 origin = cameraSpacePosition - shadowEntityPositions[i]; + vec3 axis = normalize(shadowEntityPositions[i] - lightPosition); + float sd = dot(origin, axis); + if (sd > 0.0) { + float e = length(origin - sd * axis); + float ld = dot(cameraSpacePosition - lightPosition, axis); + float lr = lightRadius; + float sr = shadowEntityRadii[i]; + float e0 = (ld * sr - sd * lr) / (ld - sd); + float e1 = (ld * sr + sd * lr) / (ld - sd); + float lightLevel = 0.0; + if (e1 < 0.0 || sd < 0.0) { // light in front of shadow entity + lightLevel = 1.0; + } + else if (e0 < e1) { + e0 -= (e1 - e0) * saturate(shadowEntitySunsetIntensity[i] / 3.0); + lightLevel = pow(saturate((e - e0) / (e1 - e0)), 0.5); // soft light + } + else { + lightLevel = e < e0 ? 0.0 : 1.0; // 0 radius light. + } + color = lightLevel * mix(color, shadowEntitySunsetColors[i], (1.0 - lightLevel) * saturate(shadowEntitySunsetIntensity[i])); + } + } + return color; + } + #endif + + vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) { + return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); + } + + // These use optimizations found in https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf. + + // The Smith-method geometry function. Calculates the ratio of incident light that is blocked by the microfacets to never reach the viewer. + // alpha is the roughness^2 + // dotNL is the normal · the light vector. + // dotNV is the normal · the view vector. + float G_GGX_SmithCorrelated( float alpha, float dotNL, float dotNV ) { + float a2 = pow2( alpha ); + // Get the light direction part of the geometry function. + float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); + // Get the view direction part of the geometry function. + float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); + // It would normally be be gv * gl, but this is using an optimization by Heitz (2014), + // including the BRDF denominator, simplifying the results. + return 0.5 / max( gv + gl, EPSILON ); + } + + // The Trowbridge-Reitz normal distribution function. Calculates the relative surface area microfacets exactly aligned to the halfway vector, how "smooth" the surface is. + // alpha is the roughness^2. + // dotNH is the normal · the halfway vector. + float D_GGX( float alpha, float dotNH ) { + float a2 = pow2( alpha ); + float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; + return RECIPROCAL_PI * a2 / pow2( denom ); + } + + // The Schlick approximation for the Fresnel equation. + // Since metallic and non-metallic surfaces have different equations, this function combines the two by approximation. + // specularColor is the specular color at normal incidence. + // dotLH is the light direction · the halfway vector. + vec3 F_Schlick( vec3 specularColor, float dotLH ) { + float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH ); + return ( 1.0 - specularColor ) * fresnel + specularColor; + } + + // The specular part of the main BRDF function that describes the weighting function for the sum of every incoming light. + // It uses the Cook-Torrance model. + vec3 BRDF_Specular_GGX( IncidentLight incidentLight, GeometricContext geometry, vec3 specularColor, float roughness ) { + float alpha = pow2( roughness ); + vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); + float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); + float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); + float dotNH = saturate( dot( geometry.normal, halfDir ) ); + float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); + vec3 F = F_Schlick( specularColor, dotLH ); + float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV ); + float D = D_GGX( alpha, dotNH ); + return F * ( G * D ); + } + + // The diffuse part of the main BRDF function. + vec3 BRDF_Diffuse_Lambert( vec3 diffuseColor ) { + return RECIPROCAL_PI * diffuseColor; + } + + float BlinnExponentToGGXRoughness( float blinnExponent ) { + return sqrt( 2.0 / ( blinnExponent + 2.0 ) ); + } + + float GGXRoughnessToBlinnExponent( float ggxRoughness ) { + return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 ); + } + + vec2 integrateSpecularBRDF( float dotNV, float roughness ) { + const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); + const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); + vec4 r = roughness * c0 + c1; + float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; + return vec2( -1.04, 1.04 ) * a004 + r.zw; + } + + vec3 BRDF_Specular_GGX_Environment( GeometricContext geometry, vec3 specularColor, float roughness ) { + float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); + vec2 brdf = integrateSpecularBRDF( dotNV, roughness ); + return specularColor * brdf.x + brdf.y; + } + + void BRDF_Specular_Multiscattering_Environment( GeometricContext geometry, vec3 specularColor, float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) { + float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); + vec3 F = F_Schlick( specularColor, dotNV ); + vec2 brdf = integrateSpecularBRDF( dotNV, roughness ); + vec3 FssEss = F * brdf.x + brdf.y; + float Ess = brdf.x + brdf.y; + float Ems = 1.0 - Ess; + vec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg ); + singleScatter += FssEss; + multiScatter += Fms * Ems; + } + + float opacity = 1.0; + + uniform float reflectivity; + uniform int maxMipLevel; + + // Returns the radiance: the incoming light * the cos(light angle to the normal) + vec3 getIncomingLight( IncidentLight directLight, GeometricContext geometry) { + float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); + return (dotNL * directLight.color); + } + + float getSpecularMIPLevel( float blinnShininessExponent, int maxMIPLevel ) { + float maxMIPLevelScalar = float( maxMIPLevel ); + float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 ); + return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar ); + } + + #ifdef envIsCubeUV + // These defines must match with PMREMGenerator + #define cubeUV_maxMipLevel 8.0 + #define cubeUV_minMipLevel 4.0 + #define cubeUV_maxTileSize 256.0 + #define cubeUV_minTileSize 16.0 + // These shader functions convert between the UV coordinates of a single face of + // a cubemap, the 0-5 integer index of a cube face, and the direction vector for + // sampling a textureCube (not generally normalized ). + float getFace( vec3 direction ) { + vec3 absDirection = abs( direction ); + float face = - 1.0; + if ( absDirection.x > absDirection.z ) { + if ( absDirection.x > absDirection.y ) + face = direction.x > 0.0 ? 0.0 : 3.0; + else + face = direction.y > 0.0 ? 1.0 : 4.0; + } else { + if ( absDirection.z > absDirection.y ) + face = direction.z > 0.0 ? 2.0 : 5.0; + else + face = direction.y > 0.0 ? 1.0 : 4.0; + } + return face; + } + // RH coordinate system; PMREM face-indexing convention + vec2 getUV( vec3 direction, float face ) { + vec2 uv; + if ( face == 0.0 ) { + uv = vec2( direction.z, direction.y ) / abs( direction.x ); // pos x + } else if ( face == 1.0 ) { + uv = vec2( - direction.x, - direction.z ) / abs( direction.y ); // pos y + } else if ( face == 2.0 ) { + uv = vec2( - direction.x, direction.y ) / abs( direction.z ); // pos z + } else if ( face == 3.0 ) { + uv = vec2( - direction.z, direction.y ) / abs( direction.x ); // neg x + } else if ( face == 4.0 ) { + uv = vec2( - direction.x, direction.z ) / abs( direction.y ); // neg y + } else { + uv = vec2( direction.x, direction.y ) / abs( direction.z ); // neg z + } + return 0.5 * ( uv + 1.0 ); + } + vec3 bilinearCubeUV( sampler2D environmentMap, vec3 direction, float mipInt ) { + float face = getFace( direction ); + float filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 ); + mipInt = max( mipInt, cubeUV_minMipLevel ); + float faceSize = exp2( mipInt ); + float texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize ); + vec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ); + vec2 f = fract( uv ); + uv += 0.5 - f; + if ( face > 2.0 ) { + uv.y += faceSize; + face -= 3.0; + } + uv.x += face * faceSize; + if ( mipInt < cubeUV_maxMipLevel ) { + uv.y += 2.0 * cubeUV_maxTileSize; + } + uv.y += filterInt * 2.0 * cubeUV_minTileSize; + uv.x += 3.0 * max( 0.0, cubeUV_maxTileSize - 2.0 * faceSize ); + uv *= texelSize; + vec3 tl = texture2D( environmentMap, uv ).rgb; + uv.x += texelSize; + vec3 tr = texture2D( environmentMap, uv ).rgb; + uv.y += texelSize; + vec3 br = texture2D( environmentMap, uv ).rgb; + uv.x -= texelSize; + vec3 bl = texture2D( environmentMap, uv ).rgb; + vec3 tm = mix( tl, tr, f.x ); + vec3 bm = mix( bl, br, f.x ); + return mix( tm, bm, f.y ); + } + #define r0 1.0 + #define v0 0.339 + #define m0 - 2.0 + #define r1 0.8 + #define v1 0.276 + #define m1 - 1.0 + #define r4 0.4 + #define v4 0.046 + #define m4 2.0 + #define r5 0.305 + #define v5 0.016 + #define m5 3.0 + #define r6 0.21 + #define v6 0.0038 + #define m6 4.0 + float roughnessToMip( float roughness ) { + float mip = 0.0; + if ( roughness >= r1 ) { + mip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0; + } else if ( roughness >= r4 ) { + mip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1; + } else if ( roughness >= r5 ) { + mip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4; + } else if ( roughness >= r6 ) { + mip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5; + } else { + mip = - 2.0 * log2( 1.16 * roughness ); // 1.16 = 1.79^0.25 + } + return mip; + } + vec4 textureCubeUV( sampler2D environmentMap, vec3 sampleDir, float roughness ) { + float mip = clamp( roughnessToMip( roughness ), m0, cubeUV_maxMipLevel ); + float mipF = fract( mip ); + float mipInt = floor( mip ); + vec3 color0 = bilinearCubeUV( environmentMap, sampleDir, mipInt ); + if ( mipF == 0.0 ) { + return vec4( color0, 1.0 ); + } else { + vec3 color1 = bilinearCubeUV( environmentMap, sampleDir, mipInt + 1.0 ); + return vec4( mix( color0, color1, mipF ), 1.0 ); + } + } + #endif + + #ifdef dynEnvMap + // Converts an XY in cylindrical space to a face (z) with coordinates within that face (xy). + vec3 xyzToUvFace(vec3 xyz, float pixelSize) { + // Figure out which basis we're using. + vec3 basis[3]; + float face; + if (xyz.x * xyz.x >= xyz.y * xyz.y && xyz.x * xyz.x >= xyz.z * xyz.z) { + if (xyz.x >= 0.0) { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(1, 0, 0); + face = 0.0; + } + else { + basis[0] = vec3(0, -1, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(-1, 0, 0); + face = 2.0; + } + } + else if (xyz.y * xyz.y >= xyz.x * xyz.x && xyz.y * xyz.y >= xyz.z * xyz.z) { + if (xyz.y >= 0.0) { + basis[0] = vec3(-1, 0, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(0, 1, 0); + face = 1.0; + } + else { + basis[0] = vec3(1, 0, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(0, -1, 0); + face = 3.0; + } + } + else { + if (xyz.z >= 0.0) { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(-1, 0, 0); basis[2] = vec3(0, 0, 1); + face = 4.0; + } + else { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(1, 0, 0); basis[2] = vec3(0, 0, -1); + face = 5.0; + } + } + + // Convert into the uv basis from the xyz basis. + float z = basis[2].x * xyz.x + basis[2].y * xyz.y + basis[2].z * xyz.z; + if (z < 0.0) { + z = 1.0; + } + vec2 uv = vec2( + (basis[0].x * xyz.x + basis[0].y * xyz.y + basis[0].z * xyz.z) / z, + (basis[1].x * xyz.x + basis[1].y * xyz.y + basis[1].z * xyz.z) / z); + + // Convert from -1 to +1, to 0 to 1. + uv = 0.5 * (uv + vec2(1.0)); + + // Convert to pixel-space. + uv *= pixelSize; + + // Shrink to ignore 1 pixel borders. + uv.x = (pixelSize - 2.0) / pixelSize * uv.x + 1.0; + uv.y = (pixelSize - 2.0) / pixelSize * uv.y + 1.0; + + // Convert back to unit-space. + uv /= pixelSize; + + return vec3(uv, face); + } + + // Gets the dynamic environmental lighting given the outward direction. + vec3 getEnvLight(vec3 direction, float roughness) { + // Get the mip levels. + float mipLevel = pow(roughness, 0.25) * (log2(dynEnvFaceSize) - 2.0); + float mipLevel0 = floor(mipLevel); + float mipLevel1 = floor(mipLevel) + 1.0; + float mipLevelU = mipLevel - mipLevel0; + float mipSizeX0 = pow(2.0, -mipLevel0); + float mipOffsetY0 = 1.0 - pow(2.0, -mipLevel0); + float mipSizeX1 = pow(2.0, -mipLevel1); + float mipOffsetY1 = 1.0 - pow(2.0, -mipLevel1); + // Get UV within a mip of cube faces. + vec3 uvFace0 = xyzToUvFace(direction, dynEnvFaceSize * mipSizeX0); + vec3 uvFace1 = xyzToUvFace(direction, dynEnvFaceSize * mipSizeX1); + vec2 faceOffset = vec2(mod(uvFace0.z, 3.0) / 3.0, floor(uvFace0.z / 3.0) / 2.0); + vec2 uvInMip0 = vec2(faceOffset.x + uvFace0.x / 3.0, faceOffset.y + uvFace0.y / 2.0); + vec2 uvInMip1 = vec2(faceOffset.x + uvFace1.x / 3.0, faceOffset.y + uvFace1.y / 2.0); + // Get the UVs within the textures. + vec2 uv0 = vec2(uvInMip0.x * mipSizeX0 * 0.75, 0.5 * uvInMip0.y * mipSizeX0 + mipOffsetY0); + vec2 uv1 = vec2(uvInMip1.x * mipSizeX1 * 0.75, 0.5 * uvInMip1.y * mipSizeX1 + mipOffsetY1); + vec3 color0 = texture2D(dynEnvTexture, uv0).rgb; + vec3 color1 = texture2D(dynEnvTexture, uv1).rgb; + return mix(color0, color1, mipLevelU) * environmentIntensity * ((PI - 1.0) * roughness + 1.0); + } + #endif + + vec3 getLightProbeIndirectRadiance( GeometricContext geometry, float blinnShininessExponent, int maxMIPLevel ) { + vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal ); + #if defined( envMap ) + reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); + float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel ); + vec3 queryReflectVec = vec3( reflectVec.x, reflectVec.yz ); + #ifdef envIsCube + #ifdef TEXTURE_LOD_EXT + vec4 envMapColor = textureCubeLodEXT( envTexture, queryReflectVec, specularMIPLevel ); + #else + vec4 envMapColor = textureCube( envTexture, queryReflectVec, specularMIPLevel ); + #endif + #elif defined( envIsCubeUV ) + vec4 envMapColor = textureCubeUV( envTexture, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent )); + #else + vec2 sampleUV; + sampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; + sampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5; + #ifdef TEXTURE_LOD_EXT + vec4 envMapColor = texture2DLodEXT( envTexture, sampleUV, specularMIPLevel ); + #else + vec4 envMapColor = texture2D( envTexture, sampleUV, specularMIPLevel ); + #endif + #endif + return envMapColor.rgb * environmentIntensity; + #else + return vec3(0, 0, 0); + #endif + } + + // Given the directLight, accumulates onto the reflectedLight the irradiance as the BRDF function. + void RE_Direct_Physical( IncidentLight directLight, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight ) { + vec3 irradiance = getIncomingLight( directLight, geometry ); + irradiance *= PI; + float clearCoatDHR = 0.0; + reflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness ); + reflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); + } + + void RE_IndirectDiffuse_Physical( vec3 irradiance, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight ) { + reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); + } + + void RE_IndirectSpecular_Physical( vec3 radiance, vec3 irradiance, vec3 clearCoatRadiance, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight) { + float clearCoatDHR = 0.0; + float clearCoatInv = 1.0 - clearCoatDHR; + reflectedLight.indirectSpecular += clearCoatInv * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness ); + } + + #define RE_Direct RE_Direct_Physical + #define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness ) + #define RE_IndirectDiffuse RE_IndirectDiffuse_Physical + #define RE_IndirectSpecular RE_IndirectSpecular_Physical + + void main(void) { + vec4 diffuseColor = vec4( color, 1.0 ); + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + + #ifdef colorMap + vec4 texelColor = texture2D(colorTexture, localUV); + diffuseColor *= texelColor; + opacity = texelColor.a; + #endif + + // PBR variables + float roughnessFactor; + float metalnessFactor; + + roughnessFactor = roughness; + #ifdef roughnessMap + roughnessFactor *= texture2D( roughnessTexture, localUV ).g; + #endif + + metalnessFactor = metalness; + #ifdef metalnessMap + metalnessFactor *= texture2D( metalnessTexture, localUV ).b; + #endif + + PhysicalMaterial material; + material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); + material.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 ); + material.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor ); + + GeometricContext geometry; + geometry.viewDir = -normalize(cameraSpacePosition); + #ifdef normalMap + geometry.normal = normalize((modelMatrix * vec4(getNormalFromMap(), 0.)).xyz); + #else + geometry.normal = modelNormal; + #endif + + // Env Light + vec3 irradiance = ambientLightColor; + #ifdef dynEnvMap + irradiance += getEnvLight(geometry.normal, 1.0); + #endif + vec3 radiance = ambientLightColor / 2.0; + #ifdef dynEnvMap + radiance += getEnvLight(reflect(-geometry.viewDir, geometry.normal), material.specularRoughness); + #endif + + // Add emissivity. + vec3 totalEmissiveRadiance = emissiveColor; + #ifdef emissiveMap + totalEmissiveRadiance *= texture2D(emissiveTexture, localUV).rgb; + #endif + + // Add direct radiance. + vec3 totalDirectIrradiance = ambientLightColor / 2.0; + #ifdef dynEnvMap + totalDirectIrradiance += getEnvLight(reflect(-geometry.viewDir, geometry.normal), material.specularRoughness); + #endif + + // For each light, + for (int i = 0; i < 5; i++) { + if (i >= numLights) { + break; + } + + IncidentLight directLight; + directLight.color = lightColors[i]; + directLight.direction = -normalize(cameraSpacePosition - lightPositions[i]); + #ifdef shadowEntities + directLight.color = getLightColorFromShadowEntities(directLight.color, directLight.direction, lightPositions[i], lightRadii[i], geometry.normal); + #endif + + RE_Direct(directLight, geometry, material, reflectedLight); + + radiance += getLightProbeIndirectRadiance(geometry, Material_BlinnShininessExponent(material), maxMipLevel); + RE_IndirectDiffuse(irradiance, geometry, material, reflectedLight); + RE_IndirectSpecular(radiance, irradiance, vec3(0.0), geometry, material, reflectedLight); + + // Modify env light by total incoming light. + totalDirectIrradiance += getIncomingLight(directLight, geometry); + } + + // Multiply in the direct irradiance. + reflectedLight.indirectSpecular *= totalDirectIrradiance; + + // If there's ambience, remove the direct light components. + reflectedLight.directDiffuse *= vec3(1, 1, 1) - ambientLightColor; + reflectedLight.directSpecular *= vec3(1, 1, 1) - ambientLightColor; + + // Add the reflected light to the outgoing light. + vec3 outgoingLight = totalEmissiveRadiance + reflectedLight.directDiffuse + reflectedLight.directSpecular + reflectedLight.indirectDiffuse + reflectedLight.indirectSpecular; + + // Set the frag color based on the total outgoing light. + gl_FragColor = vec4( outgoingLight, opacity ); + + // Gamma correction + gl_FragColor = vec4( pow( abs(gl_FragColor.rgb), vec3( 1.0 / gammaCorrectionFactor ) ), gl_FragColor.a ); + + // Convert to sRGB. + gl_FragColor = LinearTosRGB(gl_FragColor); + + // Multiply the alphaMultiplier. + gl_FragColor.a *= alphaMultiplier; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }` + }); + } + const newMaterial = MaterialUtilsStandard._material.clone(); + for (let i = 0; i < newMaterial.uniforms['shadowEntityPositions'].value.length; i++) { + newMaterial.uniforms['shadowEntityPositions'].value[i] = MaterialUtilsStandard._material.uniforms['shadowEntityPositions'].value[i].clone(); + } + for (let i = 0; i < newMaterial.uniforms['shadowEntitySunsetColors'].value.length; i++) { + newMaterial.uniforms['shadowEntitySunsetColors'].value[i] = MaterialUtilsStandard._material.uniforms['shadowEntitySunsetColors'].value[i].clone(); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupLogDepthBuffering(newMaterial); + if (_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasGLExtension('EXT_shader_texture_lod')) { + newMaterial.extensions.shaderTextureLOD = true; + } + newMaterial.extensions.derivatives = true; + newMaterial.needsUpdate = true; + return newMaterial; + } +} + +/** @type {THREE.ShaderMaterial} */ +MaterialUtilsStandard._material = null; + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/math_utils.js": +/*!*************************************************!*\ + !*** ../pioneer/engine/src/utils/math_utils.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "MathUtils": function() { return /* binding */ MathUtils; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * A class of math routines to augment the built-in Math class. + * @hideconstructor + */ +class MathUtils { + /** + * Returns PI. + * @returns {number} + */ + static get pi() { + return 3.141592653589793; + } + + /** + * Returns PI * 2. + * @returns {number} + */ + static get twoPi() { + return 6.283185307179586; + } + + /** + * Returns PI / 2. + * @returns {number} + */ + static get halfPi() { + return 1.5707963267948966; + } + + /** + * Returns the nearest angle between a0 and a1. + * @param {number} a0 + * @param {number} a1 + * @returns {number} + */ + static angle(a0, a1) { + a0 = this.wrap(a0, 0, 2 * Math.PI); + a1 = this.wrap(a1, 0, 2 * Math.PI); + if (a1 - a0 > Math.PI) { + return a0 - a1 + 2 * Math.PI; + } + if (a0 - a1 > Math.PI) { + return a1 - a0 + 2 * Math.PI; + } + return Math.abs(a1 - a0); + } + + /** + * Clamps a between a0 and a1. + * @param {number} a - the value to clamp + * @param {number} a0 - the minimum + * @param {number} a1 - the maximum + * @returns {number} + */ + static clamp(a, a0, a1) { + return Math.min(Math.max(a0, a), a1); + } + + /** + * Clamps a between 0 and 1. + * @param {number} a - the value to clamp + * @returns {number} + */ + static clamp01(a) { + return Math.min(Math.max(0, a), 1); + } + + /** + * Returns the point a between a0 and a1 as if they were a cycle. + * @param {number} a - the value to wrap + * @param {number} a0 - the start of the cycle + * @param {number} a1 - the end of the cycle + * @returns {number} + */ + static wrap(a, a0, a1) { + let phase = (a - a0) % (a1 - a0) + a0; + if (phase < a0) { + phase += a1 - a0; + } + return phase; + } + + /** + * Linearly interpolates between a0 and a1. + * @param {number} a0 - the value when u = 0 + * @param {number} a1 - the value when u = 1 + * @param {number} u - the lerp factor + * @returns {number} + */ + static lerp(a0, a1, u) { + return (1.0 - u) * a0 + u * a1; + } + + /** + * Linearly interpolates between two angles in radians a0 and a1. + * @param {number} a0 - the value when u = 0 + * @param {number} a1 - the value when u = 1 + * @param {number} u - the lerp factor + * @returns {number} + */ + static lerpAngle(a0, a1, u) { + a0 = this.wrap(a0, -Math.PI, +Math.PI); + a1 = this.wrap(a1, -Math.PI, +Math.PI); + if (a1 - a0 > Math.PI) { + a0 += 2 * Math.PI; + } + if (a0 - a1 > Math.PI) { + a1 += 2 * Math.PI; + } + return this.wrap(this.lerp(a0, a1, u), -Math.PI, +Math.PI); + } + + /** + * Converts radians to degrees. + * @param {number} a - the value in radians + * @returns {number} + */ + static radToDeg(a) { + return a * 57.29577951308232; + } + + /** + * Converts degrees to radians. + * @param {number} a - the value in degrees + * @returns {number} + */ + static degToRad(a) { + return a * 0.01745329251994329; + } + + /** + * Returns the next higher power of two, or a if it is a power of 2. + * @param {number} a - the value to use + * @returns {number} + */ + static ceilPow2(a) { + return Math.pow(2, Math.ceil(Math.log(a) / Math.log(2))); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/orbital_elements.js": +/*!*******************************************************!*\ + !*** ../pioneer/engine/src/utils/orbital_elements.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "OrbitalElements": function() { return /* binding */ OrbitalElements; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +class OrbitalElements { + constructor() { + /** + * The epoch. + * @type {number} + */ + this.epoch = 0; + + /** + * The eccentricity. + * @type {number} + */ + this.eccentricity = 0; + + /** + * The semi-major axis. + * @type {number} + */ + this.semiMajorAxis = 0; + + /** + * The mean angular motion. + * @type {number} + */ + this.meanAngularMotion = 0; + + /** + * The mean anomaly at the epoch. + * @type {number} + */ + this.meanAnomalyAtEpoch = 0; + + /** + * The orbit's oriention. + * The x-axis is along the eccentricity vector (periapsis) and the z-axis is along the angular momentum vector. + * @type {Quaternion} + */ + this.orbitOrientation = new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + } + + /** + * Copies an other orbital elements to this. + * @param {OrbitalElements} other + */ + copy(other) { + this.epoch = other.epoch; + this.eccentricity = other.eccentricity; + this.semiMajorAxis = other.semiMajorAxis; + this.meanAnomalyAtEpoch = other.meanAnomalyAtEpoch; + this.meanAngularMotion = other.meanAngularMotion; + this.orbitOrientation.copy(other.orbitOrientation); + } + + /** + * Projects a position and velocity based on the orbital elements. + * @param {Vector3} outPosition + * @param {Vector3} outVelocity + * @param {number} meanAnomaly + */ + projectFromMeanAnomaly(outPosition, outVelocity, meanAnomaly) { + if (this.eccentricity < 1.0) { + // Get the eccentric anomaly. + const eccentricAnomaly = this.getEccentricAnomalyFromMeanAnomaly(meanAnomaly); + + // Set the position and rotate it by the orbit orientation. + const radius = this.semiMajorAxis * (1.0 - this.eccentricity * Math.cos(eccentricAnomaly)); + const velocityFactor = this.meanAngularMotion * this.semiMajorAxis * this.semiMajorAxis / radius; + outPosition.x = this.semiMajorAxis * (Math.cos(eccentricAnomaly) - this.eccentricity); + outPosition.y = this.semiMajorAxis * Math.sqrt(1.0 - this.eccentricity * this.eccentricity) * Math.sin(eccentricAnomaly); + outVelocity.x = -velocityFactor * Math.sin(eccentricAnomaly); + outVelocity.y = velocityFactor * Math.sqrt(1.0 - this.eccentricity * this.eccentricity) * Math.cos(eccentricAnomaly); + } + else { + // Get the hyperbolic anomaly. + const hyperbolicAnomaly = this.getEccentricAnomalyFromMeanAnomaly(meanAnomaly); + + // Set the position and rotate it by the orbit orientation. + const radius = -this.semiMajorAxis * (1.0 - this.eccentricity * Math.cosh(hyperbolicAnomaly)); + const velocityFactor = this.meanAngularMotion * this.semiMajorAxis * this.semiMajorAxis / radius; + outPosition.x = this.semiMajorAxis * (this.eccentricity - Math.cosh(hyperbolicAnomaly)); + outPosition.y = this.semiMajorAxis * Math.sqrt(this.eccentricity * this.eccentricity - 1.0) * Math.sinh(hyperbolicAnomaly); + outVelocity.x = -velocityFactor * Math.sinh(hyperbolicAnomaly); + outVelocity.y = velocityFactor * Math.sqrt(this.eccentricity * this.eccentricity - 1.0) * Math.cosh(hyperbolicAnomaly); + } + outPosition.z = 0.0; + outVelocity.z = 0.0; + + // Rotate the vectors by the orbit orientation. + outPosition.rotate(this.orbitOrientation, outPosition); + outVelocity.rotate(this.orbitOrientation, outVelocity); + } + + /** + * Projects a position and velocity based on the orbital elements. + * @param {Vector3} outPosition + * @param {Vector3} outVelocity + * @param {number} time + */ + project(outPosition, outVelocity, time) { + // Get the mean anomaly for the time. + let meanAnomaly = this.meanAnomalyAtEpoch + this.meanAngularMotion * (time - this.epoch); + if (this.eccentricity < 1.0) { + meanAnomaly = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(meanAnomaly, -_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi, +_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi); + } + this.projectFromMeanAnomaly(outPosition, outVelocity, meanAnomaly); + } + + /** + * Gets the true anomaly given a position. + * @param {Vector3} position + * @returns {number} + */ + getTrueAnomalyFromPosition(position) { + const positionInPlane = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + positionInPlane.rotateInverse(this.orbitOrientation, position); + const trueAnomaly = Math.atan2(positionInPlane.y, positionInPlane.x); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionInPlane); + return trueAnomaly; + } + + /** + * Gets the mean anomaly from the true anomaly. + * @param {number} trueAnomaly + * @returns {number} + */ + getMeanAnomalyFromTrueAnomaly(trueAnomaly) { + // The eccentric anomaly, mean anomaly, and mean angular motion from the true anomaly, for either ellipses or hyperbolas. + let eccentricAnomaly = 0.0; + let meanAnomaly = 0.0; + if (this.eccentricity < 1.0) { + eccentricAnomaly = 2.0 * Math.atan(Math.tan(trueAnomaly / 2.0) * Math.sqrt((1 - this.eccentricity) / (1 + this.eccentricity))); + meanAnomaly = eccentricAnomaly - this.eccentricity * Math.sin(eccentricAnomaly); + } + else { + eccentricAnomaly = 2.0 * Math.atanh(Math.tan(trueAnomaly / 2.0) * Math.sqrt((this.eccentricity - 1) / (1 + this.eccentricity))); + meanAnomaly = this.eccentricity * Math.sinh(eccentricAnomaly) - eccentricAnomaly; + } + return meanAnomaly; + } + + /** + * Gets the eccentric/hyperbolic anomaly from the mean anomaly. + * @param {number} meanAnomaly + * @returns {number} + */ + getEccentricAnomalyFromMeanAnomaly(meanAnomaly) { + if (this.eccentricity < 1.0) { + // Use Newton's method to find the eccentric anomaly. + let eccentricAnomaly = meanAnomaly; + if (this.eccentricity >= 0.8) { + eccentricAnomaly = Math.sign(meanAnomaly) * _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi; // use a more optimal start point for near parabolic orbits + } + for (let i = 0; i < 20; i++) { + const difference = (eccentricAnomaly - this.eccentricity * Math.sin(eccentricAnomaly) - meanAnomaly) / (this.eccentricity * Math.cos(eccentricAnomaly) - 1.0); + eccentricAnomaly += difference; + if (Math.abs(difference) < 0.00174532925) { // .1 degrees + break; + } + } + return eccentricAnomaly; + } + else { + // Use Newton's method to find the hyperbolic anomaly. + let hyperbolicAnomaly = Math.log(2.0 * Math.abs(meanAnomaly) / Math.E + 1.8); + if (this.eccentricity <= 1.2) { + hyperbolicAnomaly = Math.log(2.0 * Math.abs(meanAnomaly) / Math.E + 1.8); // use a more optimal start point for near parabolic orbits + } + if (meanAnomaly < 0.0) { + hyperbolicAnomaly *= -1; + } + for (let i = 0; i < 20; i++) { + const difference = (hyperbolicAnomaly - this.eccentricity * Math.sinh(hyperbolicAnomaly) + meanAnomaly) / (this.eccentricity * Math.cosh(hyperbolicAnomaly) - 1.0); + hyperbolicAnomaly += difference; + if (Math.abs(difference) < 0.00174532925) { // .1 degrees + break; + } + } + return hyperbolicAnomaly; + } + } + + /** + * Gets the mean anomaly from the eccentric or hyperbolic anomaly. + * @param {number} eccentricAnomaly + * @returns {number} + */ + getMeanAnomalyFromEccentricAnomaly(eccentricAnomaly) { + if (this.eccentricity < 1.0) { + const meanAnomaly = eccentricAnomaly - this.eccentricity * Math.sin(eccentricAnomaly); + return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(meanAnomaly, -Math.PI, +Math.PI); + } + else { + return this.eccentricity * Math.sinh(eccentricAnomaly) - eccentricAnomaly; + } + } + + /** + * Gets the true anomaly from the eccentric or hyperbolic anomaly. + * @param {number} eccentricAnomaly + * @returns {number} + */ + getTrueAnomalyFromEccentricAnomaly(eccentricAnomaly) { + if (this.eccentricity < 1.0) { + return 2.0 * Math.atan(Math.sqrt((1 + this.eccentricity) / (1 - this.eccentricity)) * Math.tan(eccentricAnomaly / 2.0)); + } + else { + return 2.0 * Math.atan(Math.sqrt((1 + this.eccentricity) / (this.eccentricity - 1)) * Math.tanh(eccentricAnomaly / 2.0)); + } + } + + /** + * Gets the eccentric/hyperbolic anomaly from the true anomaly. + * @param {number} trueAnomaly + * @returns {number} + */ + getEccentricAnomalyFromTrueAnomaly(trueAnomaly) { + // The eccentric anomaly, mean anomaly, and mean angular motion from the true anomaly, for either ellipses or hyperbolas. + if (this.eccentricity < 1.0) { + const eccentricAnomaly = 2.0 * Math.atan2(Math.tan(trueAnomaly / 2.0), Math.sqrt((1 + this.eccentricity) / (1 - this.eccentricity))); + return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(eccentricAnomaly, -Math.PI, +Math.PI); + } + else { + return 2.0 * Math.atanh(Math.sqrt((this.eccentricity - 1.0) / (this.eccentricity + 1.0)) * Math.tan(trueAnomaly / 2.0)); + } + } + + /** + * Gets the inclination in radians. + * @returns {number} + */ + getInclination() { + const h = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + // Get the angular momentum. + this.orbitOrientation.getAxis(h, 2); + // Get the inclination as angle between angular momentum and z-axis. + const inclination = h.angle(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(h); + return inclination; + } + + /** + * Gets the longitude of the ascending node in radians. + * @returns {number} + */ + getLongitudeOfAscendingNode() { + const h = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + // Get the angular momentum. + this.orbitOrientation.getAxis(h, 2); + // Get the longitude of ascending node as perpendicular to the angular momentum projected onto the x-y plane. + const longitudeOfAscendingNode = Math.atan2(h.x, -h.y); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(h); + return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(longitudeOfAscendingNode, 0, _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi); + } + + /** + * Gets the argument of the periapsis in radians. + * @returns {number} + */ + getArgumentOfPeriapsis() { + const h = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const e = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + // Get the angular momentum. + this.orbitOrientation.getAxis(h, 2); + // Get the ascending node. + h.set(-h.y, h.x, 0); + // Get the eccentricity vector. + this.orbitOrientation.getAxis(e, 0); + const argumentOfPeriapsis = h.angle(e); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(e); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(h); + return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(argumentOfPeriapsis, 0, _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi); + } + + /** + * Gets the period in seconds. + * @returns {number} + */ + getPeriod() { + return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi / this.meanAngularMotion; + } + + /** + * Gets the periapsis. + * @returns {number} + */ + getPeriapsis() { + return this.semiMajorAxis * (1 - this.eccentricity); + } + + /** + * Gets the apoapsis. + * @returns {number} + */ + getApoapsis() { + return this.semiMajorAxis * (1 + this.eccentricity); + } + + /** + * Given an inclination, longitude of ascending node, and argument of periapsis, all in radians, + * get the orbit orientation as a quaternion. + * @param {number} inclination + * @param {number} longitudeOfAscendingNode + * @param {number} argumentOfPeriapsis + */ + setOrbitOrientationFromElements(inclination, longitudeOfAscendingNode, argumentOfPeriapsis) { + const n = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const h = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const periapsisRotation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + n.set(Math.cos(longitudeOfAscendingNode), Math.sin(longitudeOfAscendingNode), 0); + h.set(Math.sin(longitudeOfAscendingNode) * Math.sin(inclination), -Math.cos(longitudeOfAscendingNode) * Math.sin(inclination), Math.cos(inclination)); + this.orbitOrientation.setFromAxes(n, undefined, h); + periapsisRotation.setFromAxisAngle(h, argumentOfPeriapsis); + this.orbitOrientation.mult(periapsisRotation, this.orbitOrientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(periapsisRotation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(h); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(n); + } + + /** + * Sets orbital elements from a position, velocity, time, and a gravitational constant GM. + * @param {Vector3} position + * @param {Vector3} velocity + * @param {number} time + * @param {number} gm + */ + setFromPositionAndVelocity(position, velocity, time, gm) { + const gmInv = 1 / gm; + + // Set the epoch. + this.epoch = time; + + // Get the specific angular momentum. + const specificAngularMomentum = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + specificAngularMomentum.cross(position, velocity); + + // Get the eccentricity vector and eccentricity. + const eccentricityVec = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const positionNormalized = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + positionNormalized.normalize(position); + eccentricityVec.cross(velocity, specificAngularMomentum); + eccentricityVec.mult(eccentricityVec, gmInv); + eccentricityVec.sub(eccentricityVec, positionNormalized); + this.eccentricity = eccentricityVec.magnitude(); + + // The semi-major axis. + const semiLatusRectum = specificAngularMomentum.dot(specificAngularMomentum) * gmInv; + this.semiMajorAxis = semiLatusRectum / (1 - this.eccentricity * this.eccentricity); + if (this.eccentricity > 1) { + this.semiMajorAxis *= -1; + } + + // The true anomaly. + let trueAnomaly = Math.acos(_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(eccentricityVec.dot(positionNormalized) / this.eccentricity, -1, 1)); + if (position.dot(velocity) < 0) { + trueAnomaly *= -1; + } + if (trueAnomaly < -Math.PI) { + trueAnomaly += _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + } + if (trueAnomaly >= Math.PI) { + trueAnomaly -= _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + } + + // The orbit orientation quaternion. + eccentricityVec.normalize(eccentricityVec); + specificAngularMomentum.normalize(specificAngularMomentum); + this.orbitOrientation.setFromAxes(eccentricityVec, undefined, specificAngularMomentum); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionNormalized); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(specificAngularMomentum); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(eccentricityVec); + + // The eccentric anomaly, mean anomaly, and mean angular motion from the true anomaly, for either ellipses or hyperbolas. + const eccentricAnomaly = this.getEccentricAnomalyFromTrueAnomaly(trueAnomaly); + this.meanAnomalyAtEpoch = this.getMeanAnomalyFromEccentricAnomaly(eccentricAnomaly); + this.meanAngularMotion = Math.sqrt(gm / (this.semiMajorAxis * this.semiMajorAxis * this.semiMajorAxis)); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/pool.js": +/*!*******************************************!*\ + !*** ../pioneer/engine/src/utils/pool.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Pool": function() { return /* binding */ Pool; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A pool for generic objects. Great for minimizing garbage collection. For every get call you must call release. + * @template Type + * @extends FastIterable + */ +class Pool extends _internal__WEBPACK_IMPORTED_MODULE_0__.FastIterable { + /** + * @typedef PoolData + * @property {number} _poolIndex - The index in the pool. + * @property {boolean} _poolUsed - If true, the item is in the pool. + */ + + /** + * @typedef {PoolData & Type} PoolItem + */ + + /** + * The constructor. + * @param {new () => Type} type - The class that will be instantiated when a new object needs to be allocated. It must be default constructable. + */ + constructor(type) { + super(); + + /** + * The class type for when new objects are needed. + * @type {new () => Type} + * @private + */ + this._type = type; + + /** + * List of objects, free and used. + * @type {Array} + * @private + */ + this._objects = []; + + /** + * List of which objects are free in the objects list. It acts like a stack of indices into the objects list. + * @type {number[]} + * @private + */ + this._free = []; + + /** + * Since the free list only grows, this says how long the array is. + * @type {number} + * @private + */ + this._freeLength = 0; + + /** + * A constructor function that is called when a new object needs to be created. + * @type {function():Type} + * @private + */ + this._constructorFunction = () => { + return new this._type(); + }; + + /** + * A destructor function that is called when an object needs to be destroyed. + * @type {() => void} + * @private + */ + this._destructorFunction = () => { + }; + } + + /** + * Sets a constructor function that is called when a new object needs to be created. + * @param {() => Type} constructorFunction + */ + setConstructorFunction(constructorFunction) { + this._constructorFunction = constructorFunction; + } + + /** + * Sets a destructor function that is called when an object needs to be destroyed. + * @param {() => void} destructorFunction + */ + setDestructorFunction(destructorFunction) { + this._destructorFunction = destructorFunction; + } + + /** + * Gets an object from the pool. + * @returns {Type} + */ + get() { + /** @type {PoolItem} */ + let objectToGet = null; + if (this._freeLength > 0) { + objectToGet = this._objects[this._free[this._freeLength - 1]]; + this._freeLength -= 1; + } + else { + // @ts-ignore - Ignoring conversion from Type to PoolItem. + const poolIndex = this._objects.push(this._constructorFunction()) - 1; + this._objects[poolIndex]._poolIndex = poolIndex; + objectToGet = this._objects[poolIndex]; + } + objectToGet._poolUsed = true; + // @ts-ignore - Ignoring conversion from PoolItem to Type. + return objectToGet; + } + + /** + * Releases an object back into the pool. + * @param {Type} o - The object to release. + */ + release(o) { + /** @type {PoolItem} */ + // @ts-ignore - Ignoring conversion from Type to PoolItem. + const poolItem = o; + if (poolItem._poolIndex !== undefined) { + if (this._freeLength >= this._free.length) { + this._free.push(poolItem._poolIndex); + } + else { + this._free[this._freeLength] = poolItem._poolIndex; + } + this._freeLength += 1; + poolItem._poolUsed = false; + } + } + + /** + * Cleans up memory, removing all unused objects. If the threshold is a number and is greater or equal than the number of used / total, + * it will be cleaned. + * @param {number} [threshold] + */ + clean(threshold) { + if (threshold === undefined || threshold >= (this._objects.length - this._freeLength) / this._objects.length) { + for (let freeI = 0; freeI < this._freeLength; freeI++) { + const indexToRemove = this._free[freeI]; + // @ts-ignore - Ignoring conversion from PoolItem to Type. + this._destructorFunction(this._objects[indexToRemove]); + this._objects.splice(indexToRemove, 1); + for (let i = indexToRemove, l = this._objects.length; i < l; i++) { + this._objects[i]._poolIndex -= 1; + } + for (let i = freeI + 1, l = this._freeLength; i < l; i++) { + if (this._free[i] > indexToRemove) { + this._free[i] -= 1; + } + } + } + this._free = []; + this._freeLength = 0; + } + } + + /** + * Returns the whole pool as an array. + * @returns {Type[]} + */ + getAsArray() { + // @ts-ignore - Ignoring conversion from PoolItem to Type. + return this._objects; + } + + /** + * Returns true if the object is in the pool and used. + * @param {any} o + * @returns {boolean} + */ + isUsed(o) { + return o._poolUsed; + } + + /** + * Returns true if there are any objects used. This is good for debugging to see if there are any get calls without release calls. + * @returns {boolean} + */ + areAnyUsed() { + return this._freeLength < this._objects.length; + } + + /** + * Gets the value of the given index. + * @param {number} index + * @returns {Type} + * @override + */ + getAt(index) { + return this._objects[index]; + } + + /** + * Gets the number of values. + * @returns {number} + * @override + */ + get size() { + return this._objects.length; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/quaternion.js": +/*!*************************************************!*\ + !*** ../pioneer/engine/src/utils/quaternion.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Quaternion": function() { return /* binding */ Quaternion; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A mathematical quaternion */ +class Quaternion extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable { + /** + * Pool for temporary variables. + * @returns {Pool} + */ + static get pool() { + return _pool; + } + + /** + * NaN quaternion + * @returns {Quaternion} + */ + static get NaN() { + return _nan; + } + + /** + * Returns the identity quaternion. + * @returns {Quaternion} + */ + static get Identity() { + return _identity; + } + + /** + * Returns a quaternion from the angle-axis rotation. + * @param {Vector3} axis - must be normalized + * @param {number} angle - in radians + * @returns {Quaternion} + */ + static fromAxisAngle(axis, angle) { + const q = new Quaternion(); + q.setFromAxisAngle(axis, angle); + return q; + } + + /** + * Returns a quaternion representing a rotate frame from the given at least two axes, the other being undefined. The given axes must be orthonormal. + * @param {Vector3|undefined} xAxis + * @param {Vector3|undefined} yAxis + * @param {Vector3|undefined} zAxis + * @returns {Quaternion} + */ + static fromAxes(xAxis, yAxis, zAxis) { + const q = new Quaternion(); + q.setFromAxes(xAxis, yAxis, zAxis); + return q; + } + + /** + * Returns a quaternion from Euler angles. + * @param {number} pitch - the angle around the +x axis to rotate + * @param {number} roll - the angle around the +y axis to rotate + * @param {number} yaw - the angle around the +z axis to rotate + * @returns {Quaternion} + */ + static fromEuler(pitch, roll, yaw) { + const q = new Quaternion(); + q.setFromEuler(pitch, roll, yaw); + return q; + } + + /** + * Returns a quaternion rotation that would rotate the fromVector to the toVector. The two vectors must be normalized. + * @param {Vector3} fromVector + * @param {Vector3} toVector + * @returns {Quaternion} + */ + static fromVectorFromTo(fromVector, toVector) { + const q = new Quaternion(); + q.setFromVectorFromTo(fromVector, toVector); + return q; + } + + /** + * Returns a quaternion rotation with the given z axis, and arbitrary x and y axes. + * @param {Vector3} axis - the axis to set + * @param {number} which - the index of the axis in the quaternion: 0 for x, 1 for y, 2 for z + * @returns {Quaternion} + */ + static fromFromAxis(axis, which) { + const q = new Quaternion(); + q.setFromAxis(axis, which); + return q; + } + + /** + * Constructor. Defaults to identity. + * @param {number} w + * @param {number} x + * @param {number} y + * @param {number} z + */ + constructor(w = 1, x = 0, y = 0, z = 0) { + super(); + + /** + * @type {number} + * @private + */ + this._w = w; + /** + * @type {number} + * @private + */ + this._x = x; + /** + * @type {number} + * @private + */ + this._y = y; + /** + * @type {number} + * @private + */ + this._z = z; + } + + /** + * Gets the w component. + * @returns {number} + */ + get w() { + return this._w; + } + + /** + * Sets the w component. + * @param {number} w + */ + set w(w) { + this.throwIfFrozen(); + this._w = w; + } + + /** + * Gets the x component. + * @returns {number} + */ + get x() { + return this._x; + } + + /** + * Sets the x component. + * @param {number} x + */ + set x(x) { + this.throwIfFrozen(); + this._x = x; + } + + /** + * Gets the y component. + * @returns {number} + */ + get y() { + return this._y; + } + + /** + * Sets the y component. + * @param {number} y + */ + set y(y) { + this.throwIfFrozen(); + this._y = y; + } + + /** + * Gets the z component. + * @returns {number} + */ + get z() { + return this._z; + } + + /** + * Sets the z component. + * @param {number} z + */ + set z(z) { + this.throwIfFrozen(); + this._z = z; + } + + /** + * Gets the rotation angle. + * @returns {number} + */ + getAngle() { + return Math.acos(this._w) * 2.0; + } + + /** + * Sets this to a. + * @param {Quaternion} a - the source quaternion + */ + copy(a) { + this.throwIfFrozen(); + this._w = a._w; + this._x = a._x; + this._y = a._y; + this._z = a._z; + } + + /** + * Sets this to a as a ThreeJs quaternion. + * @param {THREE.Quaternion} a + */ + copyFromThreeJs(a) { + this.throwIfFrozen(); + this._w = a.w; + this._x = a.x; + this._y = a.y; + this._z = a.z; + } + + /** + * Sets this to the parameters. + * @param {number} w + * @param {number} x + * @param {number} y + * @param {number} z + */ + set(w, x, y, z) { + this.throwIfFrozen(); + this._w = w; + this._x = x; + this._y = y; + this._z = z; + } + + /** + * Sets this to the angle-axis rotation. + * @param {Vector3} axis - must be normalized + * @param {number} angle - in radians + */ + setFromAxisAngle(axis, angle) { + this.throwIfFrozen(); + const sinHalfAngle = Math.sin(angle / 2.0); + this._w = Math.cos(angle / 2.0); + this._x = sinHalfAngle * axis.x; + this._y = sinHalfAngle * axis.y; + this._z = sinHalfAngle * axis.z; + } + + /** + * Sets this to a quaternion representing a rotate frame from the given at least two axes, the other being undefined. The given axes must be orthonormal. + * @param {Vector3|undefined} xAxis + * @param {Vector3|undefined} yAxis + * @param {Vector3|undefined} zAxis + */ + setFromAxes(xAxis, yAxis, zAxis) { + this.throwIfFrozen(); + let missingAxis; + if (xAxis === undefined) { + xAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + missingAxis = xAxis; + xAxis.cross(yAxis, zAxis); + } + else if (yAxis === undefined) { + yAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + missingAxis = yAxis; + yAxis.cross(zAxis, xAxis); + } + else if (zAxis === undefined) { + zAxis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + missingAxis = zAxis; + zAxis.cross(xAxis, yAxis); + } + const tr = xAxis.x + yAxis.y + zAxis.z; + if (tr > 0) { + const S = Math.sqrt(tr + 1.0) * 2; // S = 4 * this._w + this._w = 0.25 * S; + this._x = (yAxis.z - zAxis.y) / S; + this._y = (zAxis.x - xAxis.z) / S; + this._z = (xAxis.y - yAxis.x) / S; + } + else if ((xAxis.x > yAxis.y) && (xAxis.x > zAxis.z)) { + const S = Math.sqrt(1.0 + xAxis.x - yAxis.y - zAxis.z) * 2; // S = 4 * this._x + this._w = (yAxis.z - zAxis.y) / S; + this._x = 0.25 * S; + this._y = (yAxis.x + xAxis.y) / S; + this._z = (zAxis.x + xAxis.z) / S; + } + else if (yAxis.y > zAxis.z) { + const S = Math.sqrt(1.0 + yAxis.y - zAxis.z - xAxis.x) * 2; // S = 4 * this._y + this._w = (zAxis.x - xAxis.z) / S; + this._x = (yAxis.x + xAxis.y) / S; + this._y = 0.25 * S; + this._z = (zAxis.y + yAxis.z) / S; + } + else { + const S = Math.sqrt(1.0 + zAxis.z - xAxis.x - yAxis.y) * 2; // S = 4 * this._z + this._w = (xAxis.y - yAxis.x) / S; + this._x = (zAxis.x + xAxis.z) / S; + this._y = (zAxis.y + yAxis.z) / S; + this._z = 0.25 * S; + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(missingAxis); + } + + /** + * Sets this to the euler angles. Use right-hand rule for rotation directions. + * @param {number} pitch - the angle around the +x axis to rotate + * @param {number} roll - the angle around the +y axis to rotate + * @param {number} yaw - the angle around the +z axis to rotate + */ + setFromEuler(pitch, roll, yaw) { + this.throwIfFrozen(); + const halfX = pitch * 0.5; + const halfY = roll * 0.5; + const halfZ = yaw * 0.5; + const cosHalfX = Math.cos(halfX); + const sinHalfX = Math.sin(halfX); + const cosHalfY = Math.cos(halfY); + const sinHalfY = Math.sin(halfY); + const cosHalfZ = Math.cos(halfZ); + const sinHalfZ = Math.sin(halfZ); + this._w = cosHalfX * cosHalfY * cosHalfZ + sinHalfX * sinHalfY * sinHalfZ; + this._x = sinHalfX * cosHalfY * cosHalfZ - cosHalfX * sinHalfY * sinHalfZ; + this._y = cosHalfX * sinHalfY * cosHalfZ + sinHalfX * cosHalfY * sinHalfZ; + this._z = cosHalfX * cosHalfY * sinHalfZ - sinHalfX * sinHalfY * cosHalfZ; + } + + /** + * Sets this to the quaternion rotation that would rotate the fromVector to the toVector. The two vectors must be normalized. + * @param {Vector3} fromVector + * @param {Vector3} toVector + */ + setFromVectorFromTo(fromVector, toVector) { + const axis = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const dot = fromVector.dot(toVector); + if (dot >= 1.0) { + this.set(1, 0, 0, 0); + } + else if (dot <= -1.0) { + this.set(0, 1, 0, 0); + } + else { + axis.cross(fromVector, toVector); + axis.normalize(axis); + const angle = Math.acos(dot); + this.setFromAxisAngle(axis, angle); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(axis); + } + + /** + * Sets this to a quaternion rotation with the given z axis, and arbitrary x and y axes. + * @param {Vector3} axis - the axis to set + * @param {number} which - the index of the axis in the quaternion: 0 for x, 1 for y, 2 for z + */ + setFromAxis(axis, which) { + const axis0 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const axis1 = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + axis0.normalize(axis); + axis1.cross(axis0, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis); + if (axis1.isZero()) { + axis1.cross(axis0, _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis); + } + axis1.normalize(axis1); + if (which === 0) { + this.setFromAxes(axis0, axis1, undefined); + } + else if (which === 1) { + this.setFromAxes(undefined, axis0, axis1); + } + else if (which === 2) { + this.setFromAxes(axis1, undefined, axis0); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(axis0); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(axis1); + } + + /** + * Returns a nicely formed string. + * @override + * @returns {string} + */ + toString() { + return '[' + this._w + ', ' + this._x + ', ' + this._y + ', ' + this._z + ']'; + } + + /** + * Returns true if the quaternion is NaN (just checks w component). + * @returns {boolean} + */ + isNaN() { + return (!(this._w <= 0) && !(this._w > 0)); + } + + /** + * Returns the magnitude of the quaternion. It should be 1 if you're using it right. + * @returns {number} + */ + magnitude() { + return Math.sqrt(this._w * this._w + this._x * this._x + this._y * this._y + this._z * this._z); + } + + /** + * Sets this to a with a magnitude of 1.0. + * @param {Quaternion} a + */ + normalize(a) { + this.throwIfFrozen(); + const magnitude = a.magnitude(); + if (magnitude > 0) { + this._w = a._w / magnitude; + this._x = a._x / magnitude; + this._y = a._y / magnitude; + this._z = a._z / magnitude; + } + } + + /** + * Sets this to the inverse of quaternion a. + * @param {Quaternion} a + */ + inverse(a) { + this.throwIfFrozen(); + this._w = a._w; + this._x = -a._x; + this._y = -a._y; + this._z = -a._z; + } + + /** + * Sets this to quaternion a * quaternion b. + * @param {Quaternion} a + * @param {Quaternion} b + */ + mult(a, b) { + this.throwIfFrozen(); + const r = Quaternion.pool.get(); + r._w = a._w * b._w - a._x * b._x - a._y * b._y - a._z * b._z; + r._x = a._w * b._x + a._x * b._w + a._y * b._z - a._z * b._y; + r._y = a._w * b._y - a._x * b._z + a._y * b._w + a._z * b._x; + r._z = a._w * b._z + a._x * b._y - a._y * b._x + a._z * b._w; + this.copy(r); + Quaternion.pool.release(r); + } + + /** + * Sets this to (the inverse of quaternion a) * quaternion b. + * @param {Quaternion} a + * @param {Quaternion} b + */ + multInverseL(a, b) { + this.throwIfFrozen(); + const r = Quaternion.pool.get(); + r._w = a._w * b._w + a._x * b._x + a._y * b._y + a._z * b._z; + r._x = a._w * b._x - a._x * b._w - a._y * b._z + a._z * b._y; + r._y = a._w * b._y + a._x * b._z - a._y * b._w - a._z * b._x; + r._z = a._w * b._z - a._x * b._y + a._y * b._x - a._z * b._w; + this.copy(r); + Quaternion.pool.release(r); + } + + /** + * Sets this to quaternion a * (the inverse of quaternion b). + * @param {Quaternion} a + * @param {Quaternion} b + */ + multInverseR(a, b) { + this.throwIfFrozen(); + const r = Quaternion.pool.get(); + r._w = +a._w * b._w + a._x * b._x + a._y * b._y + a._z * b._z; + r._x = -a._w * b._x + a._x * b._w - a._y * b._z + a._z * b._y; + r._y = -a._w * b._y + a._x * b._z + a._y * b._w - a._z * b._x; + r._z = -a._w * b._z - a._x * b._y + a._y * b._x + a._z * b._w; + this.copy(r); + Quaternion.pool.release(r); + } + + /** + * Sets this to quaternion a, with its rotation angle multiplied by b. + * @param {Quaternion} a + * @param {number} b + */ + scaleAngle(a, b) { + this.throwIfFrozen(); + const halfAngle = Math.acos(a._w); + const sinHalfAngle = Math.sin(halfAngle); + if (sinHalfAngle === 0) { + this.copy(a); + return; + } + const sinHalfAngleB = Math.sin(halfAngle * b); + this._w = Math.cos(halfAngle * b); + this._x = a._x / sinHalfAngle * sinHalfAngleB; + this._y = a._y / sinHalfAngle * sinHalfAngleB; + this._z = a._z / sinHalfAngle * sinHalfAngleB; + } + + /** + * Returns the angle in radians between this and quaternion a. + * @param {Quaternion} a + * @returns {number} + */ + angle(a) { + return Math.acos(this._w * a._w + this._x * a._x + this._y * a._y + this._z * a._z) * 2.0; + } + + /** + * Sets this to be spherically interpolated between a and b by the factor u. The parameter u is not clamped. + * @param {Quaternion} a - the quaternion when u = 0 + * @param {Quaternion} b - the quaternion when u = 1 + * @param {number} u - the lerp parameter + */ + slerp(a, b, u) { + this.throwIfFrozen(); + let dot = a._w * b._w + a._x * b._x + a._y * b._y + a._z * b._z; + let f = 1; + if (dot < 0.0) { + f = -1; + dot = -dot; + } + if (dot <= 0.9995) { + const angle = Math.acos(dot); + const A = f * Math.sin((1.0 - u) * angle) / Math.sin(angle); + const B = Math.sin(u * angle) / Math.sin(angle); + this._w = A * a._w + B * b._w; + this._x = A * a._x + B * b._x; + this._y = A * a._y + B * b._y; + this._z = A * a._z + B * b._z; + } + else { // too small, so lerp + const A = f * (1.0 - u); + const B = u; + this._w = A * a._w + B * b._w; + this._x = A * a._x + B * b._x; + this._y = A * a._y + B * b._y; + this._z = A * a._z + B * b._z; + this.normalize(this); + } + } + + /** + * Sets Vector3 outAxis to an axis (x = 0, y = 1, z = 2) of the quaternion. If the axis is undefined, it returns the axis of rotation. + * @param {Vector3} outAxis + * @param {number} axis + */ + getAxis(outAxis, axis) { + if (axis === undefined) { + outAxis.set(this._x, this._y, this._z); + outAxis.normalize(outAxis); + } + else if (axis === 0) { + outAxis.x = this._w * this._w + this._x * this._x - this._y * this._y - this._z * this._z; + outAxis.y = 2.0 * this._w * this._z + 2.0 * this._x * this._y; + outAxis.z = 2.0 * this._x * this._z - 2.0 * this._w * this._y; + } + else if (axis === 1) { + outAxis.x = 2.0 * this._y * this._x - 2.0 * this._w * this._z; + outAxis.y = this._w * this._w - this._x * this._x + this._y * this._y - this._z * this._z; + outAxis.z = 2.0 * this._x * this._w + 2.0 * this._y * this._z; + } + else if (axis === 2) { + outAxis.x = 2.0 * this._y * this._w + 2.0 * this._z * this._x; + outAxis.y = 2.0 * this._z * this._y - 2.0 * this._w * this._x; + outAxis.z = this._w * this._w - this._x * this._x - this._y * this._y + this._z * this._z; + } + } +} + +/** + * @type {Pool} + */ +const _pool = new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Quaternion); + +const _identity = new Quaternion(); +_identity.freeze(); + +const _nan = new Quaternion(Number.NaN, Number.NaN, Number.NaN, Number.NaN); +_nan.freeze(); + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/reader.js": +/*!*********************************************!*\ + !*** ../pioneer/engine/src/utils/reader.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Reader": function() { return /* binding */ Reader; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * A binary data reader. + */ +class Reader { + /** + * Constructor. + * @param {ArrayBuffer | SharedArrayBuffer} data + */ + constructor(data) { + this._dataView = new DataView(data); + this._offset = 0; + } + + /** + * Returns true if the offset is at the end of the data. + * @returns {boolean} + */ + isAtEnd() { + return this._offset >= this._dataView.byteLength; + } + + /** + * Reads an 8-bit unsigned integer. + * @returns {number} + */ + readByte() { + const result = this._dataView.getUint8(this._offset); + this._offset += 1; + return result; + } + + /** + * Reads a 32-bit floating-point number. + * @returns {number} + */ + readFloat32() { + const result = this._dataView.getFloat32(this._offset, true); + this._offset += 4; + return result; + } + + /** + * Reads a 64-bit floating-point number. + * @returns {number} + */ + readFloat64() { + const result = this._dataView.getFloat64(this._offset, true); + this._offset += 8; + return result; + } + + /** + * Reads a 8-bit unsigned integer. + * @returns {number} + */ + readUInt8() { + const result = this._dataView.getUint8(this._offset); + this._offset += 1; + return result; + } + + /** + * Reads a 16-bit unsigned integer. + * @returns {number} + */ + readUInt16() { + const result = this._dataView.getUint16(this._offset, true); + this._offset += 2; + return result; + } + + /** + * Reads a 32-bit unsigned integer. + * @returns {number} + */ + readUInt32() { + const result = this._dataView.getUint32(this._offset, true); + this._offset += 4; + return result; + } + + /** + * Reads a 64-bit unsigned integer. + * @returns {number} + */ + readUInt64() { + const result = Number(this._dataView.getBigUint64(this._offset, true)); + this._offset += 8; + return Number.isSafeInteger(result) ? result : NaN; + } + + /** + * Reads a 8-bit integer. + * @returns {number} + */ + readInt8() { + const result = this._dataView.getInt8(this._offset); + this._offset += 1; + return result; + } + + /** + * Reads a 16-bit integer. + * @returns {number} + */ + readInt16() { + const result = this._dataView.getInt16(this._offset, true); + this._offset += 2; + return result; + } + + /** + * Reads a 32-bit integer. + * @returns {number} + */ + readInt32() { + const result = this._dataView.getInt32(this._offset, true); + this._offset += 4; + return result; + } + + /** + * Reads a 64-bit integer. + * @returns {number} + */ + readInt64() { + const result = Number(this._dataView.getBigInt64(this._offset, true)); + this._offset += 8; + return Number.isSafeInteger(result) ? result : NaN; + } + + /** + * Reads a single line of text, ending with '\n'. + * @returns {string} + */ + readLine() { + const byteArray = []; + while (true) { + const byte = this.readByte(); + const byteAsString = String.fromCharCode(byte); + if (byteAsString === '\r') { + continue; + } + if (byteAsString === '\n') { + break; + } + byteArray.push(byte); + } + if (typeof TextEncoder !== 'undefined') { + const utf8Decoder = new TextDecoder(); + const array = new Uint8Array(byteArray); + return utf8Decoder.decode(array); + } + else { + return this._utf8ArrayToStr(byteArray); + } + } + + /** + * Reads a null terminated UTF-8 string or a given number of bytes as a string. + * @param {number} [numBytes] + * @returns {string} + */ + readString(numBytes) { + const byteArray = []; + while (true) { + const byte = this.readByte(); + if (numBytes === undefined && byte === 0) { + break; + } + byteArray.push(byte); + if (numBytes !== undefined && byteArray.length === numBytes) { + break; + } + } + if (typeof TextEncoder !== 'undefined') { + const utf8Decoder = new TextDecoder(); + const array = new Uint8Array(byteArray); + return utf8Decoder.decode(array); + } + else { + return this._utf8ArrayToStr(byteArray); + } + } + + /** + * Converts a UTF-8 array to a string. Taken, verified, and formatted from https://stackoverflow.com/a/59339612. + * @param {number[]} byteArray + * @returns {string} + */ + _utf8ArrayToStr(byteArray) { + let c0 = 0; + let c1 = 0; + let c2 = 0; + let c3 = 0; + let out = ''; + let i = 0; + const len = byteArray.length; + while (i < len) { + c0 = byteArray[i]; + i += 1; + switch (c0 >> 4) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + // 0xxxxxxx + out += String.fromCharCode(c0); + break; + case 12: case 13: + // 110xxxxx 10xxxxxx + c1 = byteArray[i] | 0; + i += 1; + out += String.fromCharCode(((c0 & 0x1F) << 6) | (c1 & 0x3F)); + break; + case 14: + // 1110xxxx 10xxxxxx 10xxxxxx + c1 = byteArray[i] | 0; + i += 1; + c2 = byteArray[i] | 0; + i += 1; + out += String.fromCharCode(((c0 & 0x0F) << 12) + | ((c1 & 0x3F) << 6) + | ((c2 & 0x3F) << 0)); + break; + case 15: + // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + c1 = byteArray[i] | 0; + i += 1; + c2 = byteArray[i] | 0; + i += 1; + c3 = byteArray[i] | 0; + i += 1; + out += String.fromCharCode(((c0 & 0x07) << 18) + | ((c1 & 0x3F) << 12) + | ((c2 & 0x3F) << 6) + | ((c3 & 0x3F) << 0)); + break; + } + } + + return out; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/rect.js": +/*!*******************************************!*\ + !*** ../pioneer/engine/src/utils/rect.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Rect": function() { return /* binding */ Rect; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A class for handling an axis-aligned rectangle. */ +class Rect extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable { + /** + * Pool for temporary variables. + * @returns {Pool} + */ + static get pool() { + return _pool; + } + + /** + * Constructor. + * @param {number} x - origin x + * @param {number} y - origin y + * @param {number} w - size x + * @param {number} h - size y + */ + constructor(x = 0, y = 0, w = 0, h = 0) { + super(); + + /** + * origin + * @type {Vector2} + * @private + */ + this._origin = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(x, y); + + /** + * size + * @type {Vector2} + * @private + */ + this._size = new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(w, h); + } + + /** + * Freezes the object. + * @override + */ + freeze() { + this._origin.freeze(); + this._size.freeze(); + } + + /** + * Thaws (unfreezes) the object. + * @override + */ + thaw() { + this._origin.thaw(); + this._size.thaw(); + } + + /** + * Gets the origin. + * @returns {Vector2} + */ + get origin() { + return this._origin; + } + + /** + * Gets the size. + * @returns {Vector2} + */ + get size() { + return this._size; + } + + /** + * Returns a nicely formed string. + * @override + * @returns {string} + */ + toString() { + return '[Origin: (' + this._origin.x + ', ' + this._origin.y + '), Size: (' + this._size.x + ', ' + this._size.y + ')]'; + } + + /** + * Sets this to a. + * @param {Rect} a + */ + copy(a) { + this._origin.copy(a._origin); + this._size.copy(a._size); + } + + /** + * Sets this to the parameters. + * @param {number} x - origin x + * @param {number} y - origin y + * @param {number} w - size x + * @param {number} h - size y */ + set(x, y, w, h) { + this._origin.set(x, y); + this._size.set(w, h); + } + + /** + * Returns true if the position is within this. + * @param {Vector2} position + * @returns {boolean} + */ + contains(position) { + return this._origin.x <= position.x && position.x < this._origin.x + this._size.x && this._origin.y <= position.y && position.y < this._origin.y + this._size.y; + } + + /** + * Returns true if the rect intersects with this. + * @param {Rect} rect + * @returns {boolean} + */ + intersects(rect) { + return this._origin.x + this._size.x > rect._origin.x && rect._origin.x + rect._size.x > this._origin.x + && this._origin.y + this._size.y > rect._origin.y && rect._origin.y + rect._size.y > this._origin.y; + } +} + +/** + * @type {Pool} + */ +const _pool = new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Rect); + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/shader_fix.js": +/*!*************************************************!*\ + !*** ../pioneer/engine/src/utils/shader_fix.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ShaderFix": function() { return /* binding */ ShaderFix; } +/* harmony export */ }); +/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ "../pioneer/engine/node_modules/three/build/three.module.js"); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + + +class ShaderFix { + /** + * Fixes up shader code. + * Also converts shader code from GLSL 1 to 3, if WebGL is being used. + * @param {THREE.RawShaderMaterial} rawShaderMaterial + * */ + static fix(rawShaderMaterial) { + const webGL2 = _internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.isWebGL2(); + const fragDepth = _internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasFragDepth(); + let prependVertex = ''; + let prependFragment = ''; + if (webGL2) { + prependVertex += ` + #define attribute in + #define varying out + #define texture2D texture + precision highp float; + precision highp int; + #define L_EXT_frag_depth true + `; + prependFragment += ` + #define varying in + out highp vec4 pc_fragColor; + #define gl_FragColor pc_fragColor + #define gl_FragDepthEXT gl_FragDepth + #define texture2D texture + #define textureCube texture + #define texture2DProj textureProj + #define texture2DLodEXT textureLod + #define texture2DProjLodEXT textureProjLod + #define textureCubeLodEXT textureLod + #define texture2DGradEXT textureGrad + #define texture2DProjGradEXT textureProjGrad + #define textureCubeGradEXT textureGrad + #define L_EXT_frag_depth true + precision highp float; + precision highp int; + `; + rawShaderMaterial.glslVersion = three__WEBPACK_IMPORTED_MODULE_1__.GLSL3; + } + else { + if (fragDepth) { + prependVertex += ` + #extension GL_EXT_frag_depth : enable + #define L_EXT_frag_depth true + `; + prependFragment += ` + #extension GL_EXT_frag_depth : enable + #define L_EXT_frag_depth true + `; + } + prependVertex += ` + precision highp float; + precision highp int; + `; + prependFragment += ` + precision highp float; + precision highp int; + `; + rawShaderMaterial.glslVersion = three__WEBPACK_IMPORTED_MODULE_1__.GLSL1; + } + rawShaderMaterial.vertexShader = prependVertex + rawShaderMaterial.vertexShader; + rawShaderMaterial.fragmentShader = prependFragment + rawShaderMaterial.fragmentShader; + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/sort.js": +/*!*******************************************!*\ + !*** ../pioneer/engine/src/utils/sort.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Sort": function() { return /* binding */ Sort; } +/* harmony export */ }); +/** @module pioneer */ + +class Sort { + /** + * Gets the least index whose value is greater than or equal to the value. + * 1.5 on [0, 1, 2, 3] will return 2, 5.5 will return 4, and -4 will return 0. + * O(log n). + * @template ArrayType + * @template ValueType + * @param {ValueType} value + * @param {ArrayType[]} array + * @param {CompareFunction} [isLess] + * @returns {number} + */ + static getIndex(value, array, isLess) { + let low = 0; + let high = array.length; + if (isLess === undefined) { + while (low < high) { + const mid = (low + high) >>> 1; + // @ts-ignore + if (array[mid] < value) { + low = mid + 1; + } + else { + high = mid; + } + } + } + else { + while (low < high) { + const mid = (low + high) >>> 1; + if (isLess(array[mid], value)) { + low = mid + 1; + } + else { + high = mid; + } + } + } + return low; + } + + /** + * Adds the value into a sorted array. + * @template ArrayType + * @param {ArrayType} value + * @param {ArrayType[]} array + * @param {CompareFunction} [isLess] + * @param {CompareFunction} [isEqual] + */ + static add(value, array, isLess, isEqual) { + let index = this.getIndex(value, array, isLess); + if (isEqual === undefined) { + while (index < array.length && array[index] === value) { + index += 1; + } + } + else { + while (index < array.length && isEqual(array[index], value)) { + index += 1; + } + } + array.splice(index, 0, value); + } + + /** + * Removes the value from a sorted array. Returns true if the value was found. + * @template ArrayType + * @template ValueType + * @param {ValueType} value + * @param {ArrayType[]} array + * @param {CompareFunction} [isLess] + * @param {CompareFunction} [isEqual] + */ + static remove(value, array, isLess, isEqual) { + const index = this.getIndex(value, array, isLess); + let isFound = false; + if (index < array.length) { + // @ts-ignore + if (isEqual === undefined && array[index] === value) { + isFound = true; + } + else if (isEqual !== undefined && isEqual(array[index], value)) { + isFound = true; + } + } + if (isFound) { + array.splice(index, 1); + } + return isFound; + } +} + +/** + * An compare function that uses two types. + * @template LHSType + * @template RHSType + * @callback CompareFunction + * @param {LHSType} a + * @param {RHSType} b + * @returns {boolean} + */ + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/sprite_particles.js": +/*!*******************************************************!*\ + !*** ../pioneer/engine/src/utils/sprite_particles.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SpriteParticles": function() { return /* binding */ SpriteParticles; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A basic sprite particle system with position, color, and scale attributes. + */ +class SpriteParticles { + /** + * The constructor. + * @param {BaseComponent} component + */ + constructor(component) { + /** + * The component that contains this. + * @type {BaseComponent} + * @private + */ + this._component = component; + + /** + * Whether or not the particles are relative to the orientation of the entity. + * @type {boolean} + * @private + */ + this._relativeToEntityOrientation = true; + + /** + * The positions of the particles. + * @type {Float32Array} + * @private + */ + this._offsetArray = new Float32Array(0); + + /** + * The colors of the particles. + * @type {Float32Array} + * @private + */ + this._colorArray = new Float32Array(0); + + /** + * The scales of the particles. + * @type {Float32Array} + * @private + */ + this._scaleArray = new Float32Array(0); + + /** + * The ThreeJs instanced geometry. + * @type {THREE.InstancedBufferGeometry} + * @private + */ + this._threeJsGeometry = null; + + /** + * The ThreeJs material. + * @type {THREE.RawShaderMaterial} + * @private + */ + this._threeJsMaterial = null; + + /** + * The ThreeJs object. + * @type {THREE.Mesh} + * @private + */ + this._threeJsObject = null; + + // Setup the Three.js geometry. + this._threeJsGeometry = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferGeometry(); + this._threeJsGeometry.setAttribute('position', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Float32Array([-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1]), 3)); + this._threeJsGeometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Uint16Array([0, 1, 2, 2, 3, 0]), 1)); + this._threeJsGeometry.setAttribute('offset', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(this._offsetArray, 3)); + this._threeJsGeometry.setAttribute('color', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(this._colorArray, 4)); + this._threeJsGeometry.setAttribute('scale', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(this._scaleArray, 1)); + + // Setup the Three.js material. + this._threeJsMaterial = this._component.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('sprite_particles'); + + // Setup the Three.js object. + this._threeJsObject = /** @type {THREE.Mesh} */ (_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObjectGivenGeometry(component, this._threeJsMaterial, this._threeJsGeometry)); + } + + /** + * Gets the Three.js object. + * @returns {THREE.Mesh} + */ + getThreeJsObject() { + return this._threeJsObject; + } + + /** + * Gets the Three.js object. + * @returns {THREE.ShaderMaterial} + */ + getThreeJsMaterial() { + return this._threeJsMaterial; + } + + /** + * Sets the positions of the particles. + * @param {Float32Array} particleOffsets + */ + setParticleOffsets(particleOffsets) { + this._setAttribute('offset', particleOffsets, 3); + } + + /** + * Sets the colors of the particles. + * @param {Float32Array} particleColors + */ + setParticleColors(particleColors) { + this._setAttribute('color', particleColors, 4); + } + + /** + * Sets the scales of the particles. + * @param {Float32Array} particleScales + */ + setParticleScales(particleScales) { + this._setAttribute('scale', particleScales, 1); + } + + /** + * Gets whether or not the particles are relative to the orientation of the entity. Defaults to true. + * @returns {boolean} + */ + getRelativeToEntityOrientation() { + return this._relativeToEntityOrientation; + } + + /** + * Sets whether or not the particles are relative to the orientation of the entity. + * @param {boolean} relativeToEntityOrientation + */ + setRelativeToEntityOrientation(relativeToEntityOrientation) { + this._relativeToEntityOrientation = relativeToEntityOrientation; + } + + /** + * Prepares the sprite particles for rendering. + * @param {CameraComponent} camera + */ + prepareForRender(camera) { + // Set the position of the ThreeJs object. + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this._threeJsObject, this._component.getEntity(), camera); + + // Set the orientation of the ThreeJs object if it is relative to the entity orientation. + if (this._relativeToEntityOrientation) { + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this._threeJsObject, this._component.getEntity()); + } + } + + /** + * Sets the values of an attribute, and adjusts the number of particles if needed. + * @param {string} name + * @param {Float32Array} array + * @param {number} itemSize + * @private + */ + _setAttribute(name, array, itemSize) { + let attribute = this._threeJsGeometry.getAttribute(name); + if (attribute instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute) { + if (attribute.count !== array.length / itemSize) { + this._offsetArray = new Float32Array(array.length / itemSize * 3); + this._colorArray = new Float32Array(array.length / itemSize * 4); + this._scaleArray = new Float32Array(array.length / itemSize * 1); + this._threeJsGeometry.instanceCount = array.length / itemSize; + this._threeJsGeometry.setAttribute('offset', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(this._offsetArray, 3)); + this._threeJsGeometry.setAttribute('color', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(this._colorArray, 4)); + this._threeJsGeometry.setAttribute('scale', new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(this._scaleArray, 1)); + } + } + attribute = this._threeJsGeometry.getAttribute(name); + if (attribute instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute) { + attribute.copyArray(array); + attribute.needsUpdate = true; + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/texture_lod.js": +/*!**************************************************!*\ + !*** ../pioneer/engine/src/utils/texture_lod.js ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TextureLOD": function() { return /* binding */ TextureLOD; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A texture that downloads different resolution textures depending on the level of detail requested. + * Each texture URL is can use the $SIZE and $FACE replacement strings to specify the different images loaded depending on the LOD and face. + */ +class TextureLOD { + /** + * Constructor. + * @param {BaseComponent} component - the component container + */ + constructor(component) { + /** + * The Pioneer engine. + * @type {Engine} + * @private + */ + this._engine = component.getEntity().getScene().getEngine(); + + /** + * The component container. + * @type {BaseComponent} + * @private + */ + this._component = component; + + /** + * The uniform to be set to the texture. + * @type {THREE.IUniform} + * @private + */ + this._uniform = null; + + /** + * The url to be used. + * @type {string} + * @private + */ + this._url = ''; + + /** + * The array of sizes of textures. + * @type {number[]} + * @private + */ + this._sizes = []; + + /** + * The current size of the texture. + * @type {number} + * @private + */ + this._currentSize = 0; + + /** + * If not undefined, forces the texture to be this size. + * @type {number} + * @private + */ + this._forcedSize = undefined; + + /** + * The flag that if true, uses compressed textures. + * @type {boolean} + * @private + */ + this._useCompressed = false; + + /** + * A promise that resolves when the texture is loaded. Every new texture load creates a new promise. + * @type {Promise} + * @private + */ + this._loadedPromise = Promise.resolve(); + + /** + * A flag that tells whether this is currently loading a texture. + * @type {boolean} + * @private + */ + this._loading = false; + } + + /** + * Gets the url currently being used. + * @returns {string} + */ + getUrl() { + return this._url; + } + + /** + * Sets the url to be used. If can have a $SIZE in the URL to act as replacements for different sizes. + * @param {string} url + */ + setUrl(url) { + this._url = url; + this._currentSize = 0; + } + + /** + * Gets the uniform to be used. + * @returns {THREE.IUniform} + */ + getUniform() { + return this._uniform; + } + + /** + * Sets the uniform to be used, or null for no uniform. + * @param {THREE.IUniform} uniform + */ + setUniform(uniform) { + this._uniform = uniform; + this._currentSize = 0; + } + + /** + * Gets the sizes to be loaded. + * @returns {number[]} + */ + getSizes() { + return this._sizes.slice(); + } + + /** + * Sets the sizes of the textures to be loaded. + * @param {number[]} sizes + */ + setSizes(sizes) { + this._sizes = sizes.slice(); + this._currentSize = 0; + } + + /** + * Gets the size of the current texture. + * @returns {number} + */ + getCurrentSize() { + return this._currentSize; + } + + /** + * Gets the forced texture size, if defined. + * @returns {number} + */ + getForcedSize() { + return this._forcedSize; + } + + /** + * Sets the forced texture size, if defined. + * @param {number} size + */ + setForcedSize(size) { + this._forcedSize = size; + } + + /** + * Gets the flag that if true, uses compressed textures. + * @returns {boolean} + */ + getUseCompression() { + return this._useCompression; + } + + /** + * Sets the flag that if true, uses compressed textures. + * @param {boolean} useCompression + */ + setUseCompression(useCompression) { + this._useCompression = useCompression; + this._currentSize = 0; + } + + /** + * Returns a promise that resolves when the texture for the current target size is loaded. + * @returns {Promise} + */ + getLoadedPromise() { + return this._loadedPromise; + } + + /** + * Starts the downloading of a texture at the current target level. + */ + update() { + // Still loading a texture. + if (this._loading || this._uniform === null) { + return; + } + // No textures to check or load. + if (this._url === '' || this._sizes.length === 0 || (this._component.getLoadState() === 'unloaded' && this._forcedSize === undefined)) { + // Unload any existing texture. + if (this._uniform.value !== null) { + this._uniform.value.dispose(); + this._uniform.value = null; + this._currentSize = 0; + } + return; + } + // Figure out which texture should be loaded. + let targetSize = this._sizes[0]; + if (this._forcedSize !== undefined) { + targetSize = this._forcedSize; + } + else { + targetSize = this._component.getEntity().getGreatestPixelSpaceExtentsRadius(); + } + // Get the index of the least size greater than or equal to the target size. + let sizeIndex = 0; + for (let i = 0, l = this._sizes.length; i < l; i++) { + const size = this._sizes[i]; + if (i === l - 1) { // End of list, so choose the highest one. + sizeIndex = i; + } + const maxTextureSize = this._engine.getConfig().getValue('maxTextureSize'); + if (size >= targetSize // If we've past the target or the maxTextureSize config (without a forced size), choose the this one. + || (typeof maxTextureSize === 'number' && size >= maxTextureSize && this._forcedSize === undefined)) { + sizeIndex = i; + break; + } + } + // If the current size is different than the requested size, load up the new size. + if (this._currentSize !== this._sizes[sizeIndex]) { + this._currentSize = this._sizes[sizeIndex]; + this._loadTexture(this._currentSize); + } + } + + /** + * Loads the texture at the given size. + * This is separate from the update function to avoid garbage generation from the this-bound anonymous function after the download. + * @param {number} size - The size of the texture to load. + * @private + */ + _loadTexture(size) { + const url = this._url.replace('$SIZE', size.toString()); + this._loading = true; + const textureLoader = this._useCompression ? this._engine.getTextureLoaderCompressed() : this._engine.getTextureLoader(); + this._loadedPromise = textureLoader.loadIntoUniform(this._uniform, url, true).then(() => { + this._loading = false; + }).catch((error) => { + throw Error(error); + }); + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/three_js_helper.js": +/*!******************************************************!*\ + !*** ../pioneer/engine/src/utils/three_js_helper.js ***! + \******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ThreeJsHelper": function() { return /* binding */ ThreeJsHelper; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A set of helper functions for Three.js objects and materials. + * `attributes` takes an array of {name: string, dimensions: number} objects. + */ +class ThreeJsHelper { + // CREATE & DESTROY + + /** + * Creates a Three.js Mesh object with BufferGeometry (with given attributes) and a default pink ShaderMaterial, and adds it to the scene. + * @param {Object[]} attributes + * @param {string} attributes[].name + * @param {number} attributes[].dimensions + * @param {boolean} interleavedAttributes + * @returns {THREE.BufferGeometry} + */ + static createGeometry(attributes, interleavedAttributes) { + // Create the Three.js goemetry. + const geometry = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferGeometry(); + + // Setup the attributes. + if (interleavedAttributes) { + // Get stride. + let stride = 0; + for (let i = 0; i < attributes.length; i++) { + stride += attributes[i].dimensions; + } + // Create the buffers. + const interleavedBuffer = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBuffer(new Float32Array(0), stride); + let offset = 0; + for (let i = 0; i < attributes.length; i++) { + geometry.setAttribute(attributes[i].name, new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(interleavedBuffer, attributes[i].dimensions, offset)); + offset += attributes[i].dimensions; + } + } + else { + for (let i = 0; i < attributes.length; i++) { + geometry.setAttribute(attributes[i].name, new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Float32Array(0), attributes[i].dimensions)); + } + } + geometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Uint16Array(0), 1)); + + // Return the geometry. + return geometry; + } + + /** + * Sets up the Three.js objec, assuming it's the root of its hierarchy. + * @param {BaseComponent} component + * @param {THREE.Object3D} object + */ + static setupObject(component, object) { + // Set the name of the object. + object.name = component + '.' + Math.floor(Math.random() * 10000); + + // This turns off recalculating the world matrix every single frame. + object.matrixAutoUpdate = false; + + // Set the object to never be culled by Three.js. + object.frustumCulled = false; + + // Set the object to be initially invisible. + object.visible = false; + + // Add it to the scene. + component.getEntity().getScene().getThreeJsScene().add(object); + } + + /** + * Creates a Three.js Mesh object with BufferGeometry (with given attributes) and a default pink ShaderMaterial, and adds it to the scene. + * @param {BaseComponent} component + * @param {THREE.ShaderMaterial | THREE.ShaderMaterial[]} material + * @param {THREE.BufferGeometry} geometry + * @returns {THREE.Mesh} + */ + static createMeshObjectGivenGeometry(component, material, geometry) { + // Create the Three.js object. + const object = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh(geometry, material); + + // Setup the mesh. + this.setupObject(component, object); + + // Return the mesh. + return object; + } + + /** + * Creates a Three.js Mesh object with BufferGeometry (with given attributes) and a default pink ShaderMaterial, and adds it to the scene. + * @param {BaseComponent} component + * @param {THREE.ShaderMaterial | THREE.ShaderMaterial[]} material + * @param {{ name: string, dimensions: number }[]} attributes + * @param {boolean} interleavedAttributes + * @returns {THREE.Mesh} + */ + static createMeshObject(component, material, attributes, interleavedAttributes) { + // Create the Three.js goemetry. + const geometry = this.createGeometry(attributes, interleavedAttributes); + + // Create the object with no material. + const object = this.createMeshObjectGivenGeometry(component, material, geometry); + + // Return the mesh. + return object; + } + + /** + * Destroys a Three.js geometry. + * @param {THREE.BufferGeometry} geometry + */ + static destroyGeometry(geometry) { + geometry.dispose(); + } + + /** + * Disposes of geometry and removes the object from the Three.js scene. Also applies to children. Does not affect materials. + * @param {THREE.Object3D} object + */ + static destroyObject(object) { + while (object.children.length > 0) { + this.destroyObject(object.children[object.children.length - 1]); + } + if (object.parent !== null) { + object.parent.remove(object); + } + if (object instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh) { + this.destroyGeometry(object.geometry); + } + } + + /** + * Destroys a Three.js material. Disposes of it and any textures. + * @param {THREE.ShaderMaterial} material + */ + static destroyMaterial(material) { + const uniforms = material.uniforms; + for (const uniform in uniforms) { + if (Object.prototype.hasOwnProperty.call(uniforms, uniform) && uniforms[uniform].value !== null && uniforms[uniform].value.dispose !== undefined) { + uniforms[uniform].value.dispose(); + } + } + material.dispose(); + } + + /** + * Destroys all Three.js objects, geometries, materials, and textures in the component. + * @param {BaseComponent} component + */ + static destroyAllObjectsAndMaterials(component) { + const objects = component.getThreeJsObjects(); + const materials = component.getThreeJsMaterials(); + for (let i = 0; i < objects.length; i++) { + this.destroyObject(objects[i]); + } + for (let i = 0; i < materials.length; i++) { + this.destroyMaterial(materials[i]); + } + } + + // POSITION & ORIENTATION + + /** + * Sets the object's position. + * @param {THREE.Object3D | THREE.Object3D[]} objects + * @param {Vector3} position + */ + static setPosition(objects, position) { + if (!objects) { + return; + } + if (Array.isArray(objects)) { + for (let i = 0, l = objects.length; i < l; i++) { + objects[i].position.set(position.x, position.y, position.z); + } + } + else { + objects.position.set(position.x, position.y, position.z); + } + } + + /** + * Sets the object's position to be the entity's camera-space position, along with an optional offset. + * @param {THREE.Object3D | THREE.Object3D[]} objects + * @param {Entity} entity + * @param {CameraComponent} camera + * @param {Vector3} [offset] + * @param {boolean} [offsetIsInEntityFrame] + */ + static setPositionToEntity(objects, entity, camera, offset, offsetIsInEntityFrame) { + if (!objects) { + return; + } + const cameraSpacePosition = entity.getCameraSpacePosition(camera); + this._tempThreeJsVector3.set(cameraSpacePosition.x, cameraSpacePosition.y, cameraSpacePosition.z); + if (offset) { + const newOffset = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (offsetIsInEntityFrame) { + newOffset.rotate(entity.getOrientation(), offset); + } + else { + newOffset.copy(offset); + } + this._tempThreeJsVector3.x += newOffset.x; + this._tempThreeJsVector3.y += newOffset.y; + this._tempThreeJsVector3.z += newOffset.z; + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newOffset); + } + if (Array.isArray(objects)) { + for (let i = 0, l = objects.length; i < l; i++) { + objects[i].position.copy(this._tempThreeJsVector3); + } + } + else { + objects.position.copy(this._tempThreeJsVector3); + } + } + + /** + * Sets the object's scale. + * @param {THREE.Object3D | THREE.Object3D[]} objects + * @param {number|Vector3} scale + */ + static setScale(objects, scale) { + if (!objects) { + return; + } + if (Array.isArray(objects)) { + for (let i = 0, l = objects.length; i < l; i++) { + if (typeof scale === 'number') { + objects[i].scale.set(scale, scale, scale); + } + else { + objects[i].scale.set(scale.x, scale.y, scale.z); + } + } + } + else { + if (typeof scale === 'number') { + objects.scale.set(scale, scale, scale); + } + else { + objects.scale.set(scale.x, scale.y, scale.z); + } + } + } + + /** + * Sets the object's orientation. + * @param {THREE.Object3D | THREE.Object3D[]} objects + * @param {Quaternion} orientation + */ + static setOrientation(objects, orientation) { + if (!objects) { + return; + } + _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent._tempThreeJsQuaternion.set(orientation.x, orientation.y, orientation.z, orientation.w); + if (Array.isArray(objects)) { + for (let i = 0, l = objects.length; i < l; i++) { + objects[i].setRotationFromQuaternion(_internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent._tempThreeJsQuaternion); + } + } + else { + objects.setRotationFromQuaternion(_internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent._tempThreeJsQuaternion); + } + } + + /** + * Sets the object to have its axes so that its z-axis faces the camera, and x-axis is aligned with the camera's right. + * @param {THREE.Object3D | THREE.Object3D[]} objects + * @param {Entity} entity + * @param {CameraComponent} camera + */ + static setOrientationToBillboard(objects, entity, camera) { + if (!objects) { + return; + } + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const forward = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const right = _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + forward.normalize(entity.getCameraSpacePosition(camera)); + camera.getEntity().getOrientation().getAxis(right, 0); + right.setNormalTo(forward, right); + orientation.setFromAxes(right, undefined, forward); + _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent._tempThreeJsQuaternion.set(orientation.x, orientation.y, orientation.z, orientation.w); + if (Array.isArray(objects)) { + for (let i = 0, l = objects.length; i < l; i++) { + objects[i].setRotationFromQuaternion(_internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent._tempThreeJsQuaternion); + } + } + else { + objects.setRotationFromQuaternion(_internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent._tempThreeJsQuaternion); + } + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(forward); + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(right); + } + + /** + * Sets the object's orientation to be the same as the entity, with optional addition rotation applied first. + * @param {THREE.Object3D | THREE.Object3D[]} objects + * @param {Entity} entity + * @param {Quaternion} [rotation] + */ + static setOrientationToEntity(objects, entity, rotation) { + if (!objects) { + return; + } + const entityOrientation = entity.getOrientation(); + if (rotation === undefined) { + _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent._tempThreeJsQuaternion.set(entityOrientation.x, entityOrientation.y, entityOrientation.z, entityOrientation.w); + } + else { + const orientation = _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + orientation.mult(entityOrientation, rotation); + _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent._tempThreeJsQuaternion.set(orientation.x, orientation.y, orientation.z, orientation.w); + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + } + if (Array.isArray(objects)) { + for (let i = 0, l = objects.length; i < l; i++) { + objects[i].setRotationFromQuaternion(_internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent._tempThreeJsQuaternion); + } + } + else { + objects.setRotationFromQuaternion(_internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent._tempThreeJsQuaternion); + } + } + + // OTHER OBJECT PROPERTIES + + /** + * Sets whether or not to use the component in the dynamic environment map. Defaults to false if it isn't used. + * @param {THREE.Object3D} object + * @param {boolean} enable + */ + static useInDynEnvMap(object, enable) { + if (enable) { + object.layers.enable(1); + } + else { + object.layers.disable(1); + } + } + + // GEOMETRY + + /** + * Sets the vertices of the given attribute. + * @param {THREE.BufferGeometry} geometry + * @param {string} name + * @param {Float32Array} vertices + */ + static setVertices(geometry, name, vertices) { + const attribute = geometry.getAttribute(name); + if (attribute instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute) { + if (attribute.array.length === vertices.length) { + attribute.copyArray(vertices); + attribute.needsUpdate = true; + } + else { + geometry.setAttribute(name, new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(vertices, geometry.getAttribute(name).itemSize)); + } + } + } + + /** + * Sets the vertices of the given attribute. + * @param {THREE.BufferGeometry} geometry + * @param {Uint16Array} indices + */ + static setIndices(geometry, indices) { + const attribute = geometry.getIndex(); + if (attribute.array.length === indices.length) { + attribute.copyArray(indices); + attribute.needsUpdate = true; + } + else { + geometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(indices, 1)); + } + } + + /** + * Sets the tangent attribute computed from the normal and uv attributes. + * @param {THREE.BufferGeometry} geometry + */ + static computeTangents(geometry) { + geometry.computeTangents(); + } + + /** + * Sets the render order of the objects. + * @param {THREE.Object3D} object + * @param {number} renderOrder + */ + static setRenderOrder(object, renderOrder) { + if (!object) { + return; + } + object.renderOrder = renderOrder; + } + + // MATERIALS & TEXTURES + + /** + * Sets up log-depth buffering for the material. + * They should already have the proper defines in their vertex and fragment code. + * @param {THREE.ShaderMaterial} material + */ + static setupLogDepthBuffering(material) { + if (_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasFragDepth()) { + material.defines['L_EXT_frag_depth'] = true; + material.extensions.fragDepth = true; + } + else { + delete material.defines['L_EXT_frag_depth']; + } + material.needsUpdate = true; + } + + /** + * Loads a texture. + * @param {BaseComponent} component + * @param {string} url + * @param {boolean} useMipMaps + * @param {boolean} useCompression + * @returns {Promise} + */ + static loadTexture(component, url, useMipMaps, useCompression) { + const engine = component.getEntity().getScene().getEngine(); + const textureLoader = useCompression ? engine.getTextureLoaderCompressed() : engine.getTextureLoader(); + return textureLoader.loadTexture(url, useMipMaps); + } + + /** + * Loads a texture from a canvas element. The canvas needs to be power of 2. + * @param {HTMLCanvasElement} canvas + * @returns {THREE.Texture} + */ + static loadTextureFromCanvas(canvas) { + const texture = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CanvasTexture(canvas); + texture.magFilter = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NearestFilter; + texture.minFilter = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NearestFilter; + texture.flipY = false; + texture.needsUpdate = true; + return texture; + } + + /** + * Loads a texture. + * @param {BaseComponent} component + * @param {THREE.ShaderMaterial} material + * @param {string} uniformName + * @param {string} url + * @param {boolean} useMipMaps + * @param {boolean} useCompression + * @returns {Promise} + */ + static async loadTextureIntoUniform(component, material, uniformName, url, useMipMaps, useCompression) { + if (!material) { + return; + } + const engine = component.getEntity().getScene().getEngine(); + const textureLoader = useCompression ? engine.getTextureLoaderCompressed() : engine.getTextureLoader(); + const texture = await textureLoader.loadTexture(url, useMipMaps); + const materials = component.getThreeJsMaterials(); + if (materials.includes(material)) { // Check if the material is still loaded. + const uniform = material.uniforms[uniformName]; + if (uniform === undefined) { + throw new Error(`Material in ${component} doesn't have uniform name '${uniformName}'.`); + } + if (uniform.value !== null) { + uniform.value.dispose(); + } + uniform.value = texture; + } + else { + texture.dispose(); + } + } + + /** + * Sets whether or not the material is an overlay. If true, it will be rendered on top of the scene with no scene occlusion. + * @param {THREE.ShaderMaterial} material + * @param {boolean} overlay + */ + static setOverlay(material, overlay) { + if (!material) { + return; + } + material.depthFunc = (overlay ? _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.AlwaysDepth : _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LessEqualDepth); + } + + /** + * Sets the uniform on the material. + * @param {THREE.ShaderMaterial} material + * @param {boolean} enabled + */ + static setTransparent(material, enabled) { + if (!material) { + return; + } + material.transparent = enabled; + material.depthWrite = !enabled; + } + + /** + * Sets blending mode. Defaults to 'normal'. + * @param {THREE.ShaderMaterial} material + * @param {string} blending - one of 'normal', 'additive', 'subtractive', 'multliply', 'custom', or 'none' + */ + static setBlending(material, blending) { + if (!material) { + return; + } + switch (blending) { + case 'normal': + material.blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NormalBlending; + break; + case 'additive': + material.blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.AdditiveBlending; + break; + case 'subtractive': + material.blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.SubtractiveBlending; + break; + case 'multiply': + material.blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.MultiplyBlending; + break; + case 'custom': + material.blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CustomBlending; + break; + default: + material.blending = _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NoBlending; + break; + } + material.needsUpdate = true; + } + + /** + * Sets the define on the material. + * @param {THREE.ShaderMaterial} material + * @param {string} name + * @param {boolean} enabled + */ + static setDefine(material, name, enabled) { + if (enabled && !material.defines[name]) { + material.defines[name] = true; + material.needsUpdate = true; + } + else if (!enabled && material.defines[name] === true) { + delete material.defines[name]; + material.needsUpdate = true; + } + } + + // UNIFORMS + + /** + * Sets the uniform on the material. + * @param {THREE.ShaderMaterial} material + * @param {string} name + * @param {number} value + */ + static setUniformNumber(material, name, value) { + if (!material) { + return; + } + material.uniforms[name].value = value; + } + + /** + * Sets the uniform on the material. + * @param {THREE.ShaderMaterial} material + * @param {string} name + * @param {Vector2} value + */ + static setUniformVector2(material, name, value) { + if (!material) { + return; + } + material.uniforms[name].value.set(value.x, value.y); + } + + /** + * Sets the uniform on the material. + * @param {THREE.ShaderMaterial} material + * @param {string} name + * @param {Vector3} value + */ + static setUniformVector3(material, name, value) { + if (!material) { + return; + } + material.uniforms[name].value.set(value.x, value.y, value.z); + } + + /** + * Sets the uniform on the material. + * @param {THREE.ShaderMaterial} material + * @param {string} name + * @param {Color} value + */ + static setUniformColorRGB(material, name, value) { + if (!material) { + return; + } + material.uniforms[name].value.set(value.r, value.g, value.b); + } + + /** + * Sets the uniform on the material. + * The alphaMultipier is multiplied onto the alpha component (defaults to 1). + * @param {THREE.ShaderMaterial} material + * @param {string} name + * @param {Color} value + * @param {number} [alphaMultiplier=1] + */ + static setUniformColorRGBA(material, name, value, alphaMultiplier = 1) { + if (!material) { + return; + } + material.uniforms[name].value.set(value.r, value.g, value.b, value.a * alphaMultiplier); + } + + /** + * Sets the uniform on the material. + * @param {THREE.ShaderMaterial} material + * @param {string} name + * @param {Quaternion} value + */ + static setUniformQuaternion(material, name, value) { + if (!material) { + return; + } + material.uniforms[name].value.set(value.x, value.y, value.z, value.w); + } + + /** + * Sets the uniform on the material. + * @param {THREE.ShaderMaterial} material + * @param {string} uniformName + * @param {THREE.Texture} value + */ + static setUniformTexture(material, uniformName, value) { + if (!material) { + return; + } + if (material.uniforms[uniformName].value !== null) { + material.uniforms[uniformName].value.dispose(); + } + material.uniforms[uniformName].value = value; + } +} + +/** + * A temporary Three.js Vector3. + * @type {THREE.Vector3} + */ +ThreeJsHelper._tempThreeJsVector3 = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(); + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/tile.js": +/*!*******************************************!*\ + !*** ../pioneer/engine/src/utils/tile.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Tile": function() { return /* binding */ Tile; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * A generic multi-level tile class that supports loading, unloading, activating, and deactivating of tiles of a subclass. + * @template {Tile} TileType + * @private + */ +class Tile { + /** + * Constructor. + * @param {TileType | null} parent + */ + constructor(parent) { + /** + * The parent tile. + * @type {TileType | null} + * @private + */ + this._parent = parent; + + /** + * The child tiles. + * @type {TileType[]} + * @private + */ + this._children = []; + + /** + * True if the tile has been activated. + * @type {boolean} + * @private + */ + this._active = false; + + /** + * True if the tile has been loaded. + * @type {boolean} + * @private + */ + this._loaded = false; + + /** + * True if the tile has been destroyed. + * @type {boolean} + * @private + */ + this._destroyed = false; + + /** + * True if this is in a transition (loading, splitting, joining, etc). + * @type {boolean} + * @private + */ + this._transitioning = false; + } + + /** + * Gets the parent tile. + * @returns {TileType | null} + */ + getParent() { + return this._parent; + } + + /** + * Forces a tile to load. Useful for the root node that needs to start the process. + * @returns {Promise} + */ + async forceLoad() { + this._transitioning = true; + if (!this._destroyed) { + await this.load(); + } + this._loaded = true; + if (!this._destroyed) { + await this.activate(); + } + this._active = true; + this._transitioning = false; + } + + /** + * Checks the tile to see if needs to be split or join. Returns true if it is transitioning. + * @returns {boolean} + */ + check() { + if (!this._destroyed && !this._transitioning) { + if (this._children.length === 0 && this.checkSplit()) { + this._split(); + } + else if (this._children.length > 0 && this.checkJoin()) { + this._join(); + } + } + + return this._transitioning; + } + + /** + * Gets the children. + * @returns {TileType[]} + */ + get children() { + return this._children; + } + + /** + * Returns a new Tile or null if the tile could not be created. + * @param {TileType} _parent + * @param {number} _row - 0 or 1 + * @param {number} _col - 0 or 1 + * @returns {TileType} + */ + createNewTile(_parent, _row, _col) { + return null; + } + + /** + * Returns true if this tile should be split. + * @abstract + * @returns {boolean} + */ + checkSplit() { + return false; + } + + /** + * Returns true if this tile should join its children. + * @abstract + * @returns {boolean} + */ + checkJoin() { + return false; + } + + /** + * Asynchronously loads the tile so that it may be used. + * @abstract + * @returns {Promise} + */ + async load() { + } + + /** + * Asynchronously unloads the tile. + * @abstract + * @returns {Promise} + */ + async unload() { + } + + /** + * Asynchronously activates the tile. + * @abstract + * @returns {Promise} + */ + async activate() { + } + + /** + * Asynchronously deactivates the tile. + * @abstract + * @returns {Promise} + */ + async deactivate() { + } + + /** + * Destroys the tile and all of its children. + */ + destroy() { + this._destroyed = true; + for (let i = 0; i < this._children.length; i++) { + this._children[i].destroy(); + } + if (!this._transitioning) { + if (this._active) { + this.deactivate().then(() => { + this.unload(); + }).catch((error) => { + throw error; + }); + } + else if (this._loaded) { + this.unload(); + } + } + } + + /** + * Splits a tile all the way down and only loads the leaf tiles. + * @private + */ + _split() { + /** @type {Array>} */ + const loadedPromises = []; + /** @type {TileType[]} */ + const newTiles = []; + + // Create and load all of the tiles. + this._splitAndLoad(loadedPromises, newTiles); + + // Wait till all of the tiles are loaded, then activate them. + Promise.all(loadedPromises).then(() => { + /** @type {Array>} */ + const activatedPromises = []; + for (let i = 0; i < newTiles.length; i++) { + if (newTiles[i]._loaded && !newTiles[i]._destroyed) { + activatedPromises.push(newTiles[i].activate().then(async () => { + if (this._destroyed) { + return this.deactivate().then(() => { + this.unload(); + }).catch((error) => { + throw error; + }); + } + newTiles[i]._active = true; + newTiles[i]._transitioning = false; + }).catch((error) => { + throw error; + })); + } + else { + newTiles[i]._transitioning = false; + } + } + if (this._active) { + activatedPromises.push(this.deactivate().then(() => { + this._active = false; + }).catch((error) => { + throw error; + })); + } + return activatedPromises; + // Wait till all of the tiles are activated and this is deactivated, then unload this. + }).then(() => { + if (this._loaded) { + this.unload().then(() => { + this._loaded = false; + this._transitioning = false; + }).catch((error) => { + throw error; + }); + } + else { + this._transitioning = false; + } + }).catch((error) => { + throw error; + }); + } + + /** + * Joins a tile, deactivating, unloading, and removing all children. + * @private + */ + _join() { + // First mark all of the descendant tiles as transitioning, + // and if any were already transitioning, we don't do the join. + if (this._checkIfDescendantsAreTransitioning()) { + return; + } + + // Make this and all descendant tiles transitioning. + /** @type {TileType[]} */ + const tilesToUnload = []; + this._transitioning = true; + this._markDescendantsAsTransitioning(tilesToUnload); + + this.load().then(async () => { + if (this._destroyed) { + return this.unload(); + } + this._loaded = true; + }).then(() => { + const promises = []; + for (let i = 0; i < tilesToUnload.length; i++) { + promises.push(tilesToUnload[i].deactivate().then(() => { + tilesToUnload[i]._active = false; + }).catch((error) => { + throw error; + })); + } + if (!this._destroyed) { + promises.push(this.activate().then(async () => { + if (this._destroyed) { + return this.deactivate().then(() => { + this.unload(); + }).catch((error) => { + throw error; + }); + } + this._active = true; + }).catch((error) => { + throw error; + })); + } + return Promise.all(promises); + }).then(() => { + const promises = []; + for (let i = 0; i < tilesToUnload.length; i++) { + promises.push(tilesToUnload[i].unload().then(() => { + tilesToUnload[i]._loaded = false; + }).catch((error) => { + throw error; + })); + } + return Promise.all(promises); + }).then(() => { + this._children = []; + this._transitioning = false; + }).catch((error) => { + throw error; + }); + } + + /** + * Creates and loads all of the required tiles. + * @param {Array>} loadedPromises - the list of tiles that were loaded + * @param {TileType[]} newTiles - the list of tiles that were created (and possibly loaded) + * @private + */ + _splitAndLoad(loadedPromises, newTiles) { + // Create and load all of the tiles. + this._transitioning = true; + for (let row = 0; row < 2; row++) { + for (let col = 0; col < 2; col++) { + // Construct the tile. + // @ts-ignore - because it can't convert 'this' to 'TileType'. + const tile = this.createNewTile(this, row, col); + if (tile !== null) { + this._children.push(tile); + // Check to see if this tile needs to be split as well. + if (tile.checkSplit()) { + tile._splitAndLoad(loadedPromises, newTiles); + } + // Otherwise, load the tile. + else { + tile._transitioning = true; + loadedPromises.push(tile.load().then(async () => { + if (tile._destroyed) { + return tile.unload(); + } + tile._loaded = true; + }).catch((error) => { + throw error; + })); + } + newTiles.push(tile); + } + } + } + } + + /** + * Returns true if any descendant tiles are transitioning. Used by join to ensure that all joined tiles are not already transitioning. + * @returns {boolean} + * @private + */ + _checkIfDescendantsAreTransitioning() { + for (let i = 0; i < this._children.length; i++) { + const tile = this._children[i]; + if (tile._transitioning) { + return true; + } + else { + if (tile._checkIfDescendantsAreTransitioning()) { + return true; + } + } + } + return false; + } + + /** + * Marks all descendant tiles as transitioning. Assumes the _checkIfDescendantsAreTransitioning function has already been called. + * Used by join to ensure that nothing happens to the descendants during the join process. + * Also stores the active tiles for later deactivating and unloading. + * @param {TileType[]} tilesToUnload + * @private + */ + _markDescendantsAsTransitioning(tilesToUnload) { + for (let i = 0; i < this._children.length; i++) { + const tile = this._children[i]; + tile._transitioning = true; + if (tile._active) { + tilesToUnload.push(tile); + } + tile._markDescendantsAsTransitioning(tilesToUnload); + } + } +} + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/time_utils.js": +/*!*************************************************!*\ + !*** ../pioneer/engine/src/utils/time_utils.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TimeUtils": function() { return /* binding */ TimeUtils; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * A class of time routines. + * @hideconstructor + */ +class TimeUtils { + /** + * Returns the ET time right now. + * @returns {number} + */ + static now() { + return TimeUtils.unixToEt(Date.now() / 1000.0); + } + + /** + * Converts an ET time to a Unix time. + * @param {number} et - the ET time to convert + * @returns {number} + */ + static etToUnix(et) { + let leapSecondsOffset = 0; + for (let i = 0; i < _leapSeconds.length; i++) { + if (et + 946727957.816 + leapSecondsOffset >= _leapSeconds[i] + 1) { + leapSecondsOffset -= 1; + } + } + return et + 946727957.816 + leapSecondsOffset; + } + + /** + * Converts a Unix time to an ET time. + * @param {number} unix - the Unix time to convert + * @returns {number} + */ + static unixToEt(unix) { + let leapSecondsOffset = 0; + for (let i = 0; i < _leapSeconds.length; i++) { + if (unix >= _leapSeconds[i] + 1) { + leapSecondsOffset += 1; + } + } + return unix - 946727957.816 + leapSecondsOffset; + } + + /** + * Returns the leap seconds array, which is the list of Unix times in seconds right before the leap second. + * @returns {number[]} + */ + static get leapSeconds() { + return _leapSeconds; + } +} + +/** + * The array of leap seconds, which is the list of Unix times in seconds right before the leap second. + * @type {number[]} + */ +const _leapSeconds = [ + Date.UTC(1972, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(1972, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1973, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1974, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1975, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1976, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1977, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1978, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1979, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1981, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(1982, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(1983, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(1985, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(1987, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1989, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1990, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1992, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(1993, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(1994, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(1995, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(1997, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(1998, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(2005, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(2008, 12 - 1, 31, 23, 59, 59) / 1000.0, + Date.UTC(2012, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(2015, 6 - 1, 30, 23, 59, 59) / 1000.0, + Date.UTC(2016, 12 - 1, 31, 23, 59, 59) / 1000.0 +]; + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/vector2.js": +/*!**********************************************!*\ + !*** ../pioneer/engine/src/utils/vector2.js ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Vector2": function() { return /* binding */ Vector2; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A 2-dimensional vector */ +class Vector2 extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable { + /** + * Pool for temporary variables. + * @returns {Pool} + */ + static get pool() { + return _pool; + } + + /** + * NaN vector + * @returns {Vector2} + */ + static get NaN() { + return _nan; + } + + /** + * Zero vector + * @returns {Vector2} + */ + static get Zero() { + return _zero; + } + + /** + * Unit x-axis vector + * @returns {Vector2} + */ + static get XAxis() { + return _xAxis; + } + + /** + * Unit y-axis vector + * @returns {Vector2} + */ + static get YAxis() { + return _yAxis; + } + + /** + * Constructor. + * @param {number} x + * @param {number} y + */ + constructor(x = 0, y = 0) { + super(); + + /** + * @type {number} + * @private + */ + this._x = x; + /** + * @type {number} + * @private + */ + this._y = y; + } + + /** + * Gets the x component. + * @returns {number} + */ + get x() { + return this._x; + } + + /** + * Sets the x component. + * @param {number} x + */ + set x(x) { + this.throwIfFrozen(); + this._x = x; + } + + /** + * Gets the y component. + * @returns {number} + */ + get y() { + return this._y; + } + + /** + * Sets the y component. + * @param {number} y + */ + set y(y) { + this.throwIfFrozen(); + this._y = y; + } + + /** + * Returns a nicely formed string. + * @override + * @returns {string} + */ + toString() { + return '[' + this._x + ', ' + this._y + ']'; + } + + /** + * Returns true if this equals a. + * @param {Vector2} a + * @returns {boolean} + */ + equals(a) { + return this._x === a._x && this._y === a._y; + } + + /** + * Returns true if all components are zero. + * @returns {boolean} + */ + isZero() { + return this._x === 0 && this._y === 0; + } + + /** + * Returns true if any component of the vector is NaN. + * @returns {boolean} + */ + isNaN() { + return (!(this._x <= 0) && !(this._x > 0)) || (!(this._y <= 0) && !(this._y > 0)); + } + + /** + * Sets this to a. + * @param {Vector2} a + */ + copy(a) { + this.throwIfFrozen(); + this._x = a._x; + this._y = a._y; + } + + /** + * Sets this to a as a ThreeJs vector. + * @param {THREE.Vector2} a + */ + copyFromThreeJs(a) { + this.throwIfFrozen(); + this._x = a.x; + this._y = a.y; + } + + /** + * Sets this to the parameters. + * @param {number} x + * @param {number} y + */ + set(x, y) { + this.throwIfFrozen(); + this._x = x; + this._y = y; + } + + /** + * Sets this to the negative of a. + * @param {Vector2} a + */ + neg(a) { + this.throwIfFrozen(); + this._x = -a._x; + this._y = -a._y; + } + + /** + * Sets this to a + b. + * @param {Vector2} a + * @param {Vector2} b + */ + add(a, b) { + this.throwIfFrozen(); + this._x = a._x + b._x; + this._y = a._y + b._y; + } + + /** + * Sets this to a - b. + * @param {Vector2} a + * @param {Vector2} b + */ + sub(a, b) { + this.throwIfFrozen(); + this._x = a._x - b._x; + this._y = a._y - b._y; + } + + /** + * Sets this to a * b, where b is a number. + * @param {Vector2} a + * @param {number} b + */ + mult(a, b) { + this.throwIfFrozen(); + this._x = a._x * b; + this._y = a._y * b; + } + + /** + * Sets this to a + b * c, where c is a number. + * @param {Vector2} a + * @param {Vector2} b + * @param {number} c + */ + addMult(a, b, c) { + this.throwIfFrozen(); + this._x = a._x + b._x * c; + this._y = a._y + b._y * c; + } + + /** + * Sets this to a / b, where b is a number. + * @param {Vector2} a + * @param {number} b + */ + div(a, b) { + this.throwIfFrozen(); + this._x = a._x / b; + this._y = a._y / b; + } + + /** + * Sets this to a * b, component-wise multiplication. + * @param {Vector2} a + * @param {Vector2} b + */ + scale(a, b) { + this.throwIfFrozen(); + this._x = a._x * b._x; + this._y = a._y * b._y; + } + + /** + * Sets this to a / b, component-wise division. + * @param {Vector2} a + * @param {Vector2} b + */ + scaleInv(a, b) { + this.throwIfFrozen(); + this._x = a._x / b._x; + this._y = a._y / b._y; + } + + /** + * Returns the dot product of this and a. + * @param {Vector2} a + * @returns {number} + */ + dot(a) { + return this._x * a._x + this._y * a._y; + } + + /** + * Returns a 2D cross product, which can be used for signed angles between vectors. + * @param {Vector2} a + */ + cross(a) { + return this._x * a._y - this._y * a._x; + } + + /** + * Returns the squared length of this vector. + * @returns {number} + */ + magnitudeSqr() { + return this._x * this._x + this._y * this._y; + } + + /** + * Returns the length of this vector. + * @returns {number} + */ + magnitude() { + return Math.sqrt(this.magnitudeSqr()); + } + + /** + * Sets this to a with a magnitude of 1.0. + * @param {Vector2} a + */ + normalize(a) { + this.throwIfFrozen(); + const magnitude = a.magnitude(); + if (magnitude > 0) { + this._x = a._x / magnitude; + this._y = a._y / magnitude; + } + } + + /** + * Sets this to a with a given magnitude. + * @param {Vector2} a + * @param {number} magnitude + */ + setMagnitude(a, magnitude) { + this.throwIfFrozen(); + this.normalize(a); + this._x *= magnitude; + this._y *= magnitude; + } + + /** + * Returns the distance between this and a. + * @param {Vector2} a + * @returns {number} + */ + distance(a) { + const x = this._x - a._x; + const y = this._y - a._y; + return Math.sqrt(x * x + y * y); + } + + /** + * Returns the angle in radians between this and a. If this or a are zero, returns NaN. + * @param {Vector2} a + * @returns {number} + */ + angle(a) { + const magnitudes = this.magnitude() * a.magnitude(); + if (magnitudes > 0) { + return Math.acos(_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(this.dot(a) / magnitudes, -1.0, 1.0)); + } + else { + return Number.NaN; + } + } + + /** + * Sets this to a, clamped between min and max, component-wise. + * @param {Vector2} a + * @param {Vector2} min + * @param {Vector2} max + */ + clamp(a, min, max) { + this.throwIfFrozen(); + this._x = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a._x, min._x, max._x); + this._y = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a._y, min._y, max._y); + } + + /** + * Sets this to the lerp between a and b, where u is the lerp parameter, and it may be clamped between a and b. + * @param {Vector2} a - the value when u = 0 + * @param {Vector2} b - the value when u = 1 + * @param {number} u - the lerp factor + */ + lerp(a, b, u) { + this.throwIfFrozen(); + this._x = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._x, b._x, u); + this._y = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._y, b._y, u); + } +} + +/** + * @type {Pool} + */ +const _pool = new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Vector2); + +const _zero = new Vector2(); +_zero.freeze(); + +const _xAxis = new Vector2(1, 0); +_xAxis.freeze(); + +const _yAxis = new Vector2(0, 1); +_yAxis.freeze(); + +const _nan = new Vector2(Number.NaN, Number.NaN); +_nan.freeze(); + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/vector3.js": +/*!**********************************************!*\ + !*** ../pioneer/engine/src/utils/vector3.js ***! + \**********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Vector3": function() { return /* binding */ Vector3; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** A 3-dimensional vector */ +class Vector3 extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable { + /** + * Pool for temporary variables. + * @returns {Pool} + */ + static get pool() { + return _pool; + } + + /** + * NaN vector + * @returns {Vector3} + */ + static get NaN() { + return _nan; + } + + /** + * Zero vector + * @returns {Vector3} + */ + static get Zero() { + return _zero; + } + + /** + * Unit x-axis vector + * @returns {Vector3} + */ + static get XAxis() { + return _xAxis; + } + + /** + * Unit y-axis vector + * @returns {Vector3} + */ + static get YAxis() { + return _yAxis; + } + + /** + * Unit z-axis vector + * @returns {Vector3} + */ + static get ZAxis() { + return _zAxis; + } + + /** + * Unit negative x-axis vector + * @returns {Vector3} + */ + static get XAxisNeg() { + return _xAxisNeg; + } + + /** + * Unit negative y-axis vector + * @returns {Vector3} + */ + static get YAxisNeg() { + return _yAxisNeg; + } + + /** + * Unit negative z-axis vector + * @returns {Vector3} + */ + static get ZAxisNeg() { + return _zAxisNeg; + } + + /** + * Returns the xyz equivalent of azimuth (rotation from x-axis about z-axis), elevation (from x-y plane), and range. + * @param {AER} aer + * @returns {Vector3} + */ + static fromAER(aer) { + const v = new Vector3(); + v.setFromAER(aer); + return v; + } + + /** + * Constructor. + * @param {number} x + * @param {number} y + * @param {number} z + */ + constructor(x = 0, y = 0, z = 0) { + super(); + + /** + * @type {number} + * @private + */ + this._x = x; + /** + * @type {number} + * @private + */ + this._y = y; + /** + * @type {number} + * @private + */ + this._z = z; + } + + /** + * Gets the x component. + * @returns {number} + */ + get x() { + return this._x; + } + + /** + * Sets the x component. + * @param {number} x + */ + set x(x) { + this.throwIfFrozen(); + this._x = x; + } + + /** + * Gets the y component. + * @returns {number} + */ + get y() { + return this._y; + } + + /** + * Sets the y component. + * @param {number} y + */ + set y(y) { + this.throwIfFrozen(); + this._y = y; + } + + /** + * Gets the z component. + * @returns {number} + */ + get z() { + return this._z; + } + + /** + * Sets the z component. + * @param {number} z + */ + set z(z) { + this.throwIfFrozen(); + this._z = z; + } + + /** + * Returns a nicely formed string. + * @override + * @returns {string} + */ + toString() { + return '[' + this._x + ', ' + this._y + ', ' + this._z + ']'; + } + + /** + * Returns true if this equals a. + * @param {Vector3} a + * @returns {boolean} + */ + equals(a) { + return this._x === a._x && this._y === a._y && this._z === a._z; + } + + /** + * Returns true if all components are zero. + * @returns {boolean} + */ + isZero() { + return this._x === 0 && this._y === 0 && this._z === 0; + } + + /** + * Returns true if any component in the vector is NaN. + * @returns {boolean} + */ + isNaN() { + return (!(this._x <= 0) && !(this._x > 0)) || (!(this._y <= 0) && !(this._y > 0)) || (!(this._z <= 0) && !(this._z > 0)); + } + + /** + * Sets this to a. + * @param {Vector3} a + */ + copy(a) { + this.throwIfFrozen(); + this._x = a._x; + this._y = a._y; + this._z = a._z; + } + + /** + * Sets this to a as a ThreeJs vector. + * @param {THREE.Vector3} a + */ + copyFromThreeJs(a) { + this.throwIfFrozen(); + this._x = a.x; + this._y = a.y; + this._z = a.z; + } + + /** + * Sets this to the parameters. + * @param {number} x + * @param {number} y + * @param {number} z + */ + set(x, y, z) { + this.throwIfFrozen(); + this._x = x; + this._y = y; + this._z = z; + } + + /** + * Sets this to the xyz equivalent of azimuth (rotation from x-axis about z-axis), elevation (from x-y plane), and range. + * @param {AER} aer + */ + setFromAER(aer) { + this.throwIfFrozen(); + const cosElevation = Math.cos(aer.elevation); + this._x = aer.range * cosElevation * Math.cos(aer.azimuth); + this._y = aer.range * cosElevation * Math.sin(aer.azimuth); + this._z = aer.range * Math.sin(aer.elevation); + } + + /** + * Sets this to the negative of a. + * @param {Vector3} a + */ + neg(a) { + this.throwIfFrozen(); + this._x = -a._x; + this._y = -a._y; + this._z = -a._z; + } + + /** + * Sets this to a + b. + * @param {Vector3} a + * @param {Vector3} b + */ + add(a, b) { + this.throwIfFrozen(); + this._x = a._x + b._x; + this._y = a._y + b._y; + this._z = a._z + b._z; + } + + /** + * Sets this to a - b. + * @param {Vector3} a + * @param {Vector3} b + */ + sub(a, b) { + this.throwIfFrozen(); + this._x = a._x - b._x; + this._y = a._y - b._y; + this._z = a._z - b._z; + } + + /** + * Sets this to a * b, where b is a number. + * @param {Vector3} a + * @param {number} b + */ + mult(a, b) { + this.throwIfFrozen(); + this._x = a._x * b; + this._y = a._y * b; + this._z = a._z * b; + } + + /** + * Sets this to a + b * c, where c is a number. + * @param {Vector3} a + * @param {Vector3} b + * @param {number} c + */ + addMult(a, b, c) { + this.throwIfFrozen(); + this._x = a._x + b._x * c; + this._y = a._y + b._y * c; + this._z = a._z + b._z * c; + } + + /** + * Sets this to a / b, where b is a number. + * @param {Vector3} a + * @param {number} b + */ + div(a, b) { + this.throwIfFrozen(); + this._x = a._x / b; + this._y = a._y / b; + this._z = a._z / b; + } + + /** + * Sets this to a * b, component-wise multiplication. + * @param {Vector3} a + * @param {Vector3} b + */ + scale(a, b) { + this.throwIfFrozen(); + this._x = a._x * b._x; + this._y = a._y * b._y; + this._z = a._z * b._z; + } + + /** + * Sets this to a / b, component-wise division. + * @param {Vector3} a + * @param {Vector3} b + */ + scaleInv(a, b) { + this.throwIfFrozen(); + this._x = a._x / b._x; + this._y = a._y / b._y; + this._z = a._z / b._z; + } + + /** + * Returns the dot product of this and a. + * @param {Vector3} a + * @returns {number} + */ + dot(a) { + return this._x * a._x + this._y * a._y + this._z * a._z; + } + + /** + * Sets this to the cross product of a and b. + * @param {Vector3} a + * @param {Vector3} b + */ + cross(a, b) { + this.throwIfFrozen(); + const x = a._y * b._z - a._z * b._y; + const y = a._z * b._x - a._x * b._z; + const z = a._x * b._y - a._y * b._x; + this._x = x; + this._y = y; + this._z = z; + } + + /** + * Returns the squared length of this vector. + * @returns {number} + */ + magnitudeSqr() { + return this._x * this._x + this._y * this._y + this._z * this._z; + } + + /** + * Returns the length of this vector. + * @returns {number} + */ + magnitude() { + return Math.sqrt(this.magnitudeSqr()); + } + + /** + * Returns the length of just the x and y components. Useful in calculations involving spheres. + * @returns {number} + */ + magnitudeXY() { + return Math.sqrt(this._x * this._x + this._y * this._y); + } + + /** + * Sets this to a with a magnitude of 1.0. + * @param {Vector3} a + */ + normalize(a) { + this.throwIfFrozen(); + const magnitude = a.magnitude(); + if (magnitude > 0) { + this._x = a._x / magnitude; + this._y = a._y / magnitude; + this._z = a._z / magnitude; + } + else { + this.copy(a); + } + } + + /** + * Sets this to a with a given magnitude. + * @param {Vector3} a + * @param {number} magnitude + */ + setMagnitude(a, magnitude) { + this.throwIfFrozen(); + this.normalize(a); + this._x *= magnitude; + this._y *= magnitude; + this._z *= magnitude; + } + + /** + * Returns the distance between this and a. + * @param {Vector3} a + * @returns {number} + */ + distance(a) { + const x = this._x - a._x; + const y = this._y - a._y; + const z = this._z - a._z; + return Math.sqrt(x * x + y * y + z * z); + } + + /** + * Returns the angle in radians between this and a. If this or a are zero, returns NaN. + * @param {Vector3} a + * @returns {number} + */ + angle(a) { + const magnitudes = this.magnitude() * a.magnitude(); + if (magnitudes > 0) { + return Math.acos(_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(this.dot(a) / magnitudes, -1.0, 1.0)); + } + else { + return Number.NaN; + } + } + + /** + * Returns the angle in radians from this to a if they were projected on the plane formed by axis. It can be plus or minus, based on the right-hand rule rotation around axis. + * @param {Vector3} a + * @param {Vector3} axis + * @returns {number} + */ + angleAroundAxis(a, axis) { + const thisP = Vector3.pool.get(); + const aP = Vector3.pool.get(); + + // Project the vectors. + thisP.addMult(this, axis, -this.dot(axis)); + aP.addMult(a, axis, -a.dot(axis)); + + // Get the angle. + let angle = thisP.angle(aP); + + // Determine the sign of the angle. + thisP.cross(thisP, aP); + if (thisP.dot(axis) < 0) { + angle *= -1; + } + + Vector3.pool.release(thisP); + Vector3.pool.release(aP); + return angle; + } + + /** + * Sets this to a, clamped between min and max, component-wise. + * @param {Vector3} a + * @param {Vector3} min + * @param {Vector3} max + */ + clamp(a, min, max) { + this.throwIfFrozen(); + this._x = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a._x, min._x, max._x); + this._y = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a._y, min._y, max._y); + this._z = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a._z, min._z, max._z); + } + + /** + * Sets this to the lerp between a and b, where u is the lerp parameter, and it may be clamped between a and b. + * @param {Vector3} a - the value when u = 0 + * @param {Vector3} b - the value when u = 1 + * @param {number} u - the lerp factor + */ + lerp(a, b, u) { + this.throwIfFrozen(); + this._x = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._x, b._x, u); + this._y = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._y, b._y, u); + this._z = _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._z, b._z, u); + } + + /** + * Sets this to the slerp between a and b, where u is the lerp parameter, and it may be clamped between a and b. + * @param {Vector3} a - the value when u = 0 + * @param {Vector3} b - the value when u = 1 + * @param {number} u - the lerp factor + */ + slerp(a, b, u) { + this.throwIfFrozen(); + const aMag = a.magnitude(); + const bMag = b.magnitude(); + if (aMag > 0.0 && bMag > 0.0) { + const angle = Math.acos(_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a.dot(b) / (aMag * bMag), -1, +1)); + if (Math.abs(angle) > 0.01745327777) { // If less than one degree, just lerp + const sinAngleInv = 1 / Math.sin(angle); + const aFactor = Math.sin((1 - u) * angle) * sinAngleInv; + const bFactor = Math.sin(u * angle) * sinAngleInv; + this.set(a.x * aFactor / aMag + b.x * bFactor / bMag, a.y * aFactor / aMag + b.y * bFactor / bMag, a.z * aFactor / aMag + b.z * bFactor / bMag); + this.mult(this, (1 - u) * aMag + u * bMag); + } + else { + this.lerp(a, b, u); + } + } + else { + this.lerp(a, b, u); + } + } + + /** + * Sets this to the result of the vector b rotated by the quaternion a. + * @param {Quaternion} a + * @param {Vector3} b + */ + rotate(a, b) { + this.throwIfFrozen(); + const tx = a.w * b._x + a.y * b._z - a.z * b._y; + const ty = a.w * b._y + a.z * b._x - a.x * b._z; + const tz = a.w * b._z + a.x * b._y - a.y * b._x; + const tw = -a.x * b._x - a.y * b._y - a.z * b._z; + this._x = tx * a.w - tw * a.x - ty * a.z + tz * a.y; + this._y = ty * a.w - tw * a.y - tz * a.x + tx * a.z; + this._z = tz * a.w - tw * a.z - tx * a.y + ty * a.x; + } + + /** + * Sets this to the result of the vector b rotated by the inverse of quaternion a. + * @param {Quaternion} a + * @param {Vector3} b + */ + rotateInverse(a, b) { + this.throwIfFrozen(); + const tx = a.w * b._x - a.y * b._z + a.z * b._y; + const ty = a.w * b._y - a.z * b._x + a.x * b._z; + const tz = a.w * b._z - a.x * b._y + a.y * b._x; + const tw = a.x * b._x + a.y * b._y + a.z * b._z; + this._x = tx * a.w + tw * a.x + ty * a.z - tz * a.y; + this._y = ty * a.w + tw * a.y + tz * a.x - tx * a.z; + this._z = tz * a.w + tw * a.z + tx * a.y - ty * a.x; + } + + /** + * Sets this to a vector normal to a, in the plane of 'a cross b', such that 'this dot b' is positive. + * @param {Vector3} a + * @param {Vector3} b + */ + setNormalTo(a, b) { + const x = b._x * (a._y * a._y + a._z * a._z) - a._x * (a._y * b._y + a._z * b._z); + const y = b._y * (a._z * a._z + a._x * a._x) - a._y * (a._z * b._z + a._x * b._x); + const z = b._z * (a._x * a._x + a._y * a._y) - a._z * (a._x * b._x + a._y * b._y); + this._x = x; + this._y = y; + this._z = z; + this.normalize(this); + } +} + +/** + * @type {Pool} + */ +const _pool = new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Vector3); + +const _zero = new Vector3(); +_zero.freeze(); + +const _xAxis = new Vector3(1, 0, 0); +_xAxis.freeze(); + +const _yAxis = new Vector3(0, 1, 0); +_yAxis.freeze(); + +const _zAxis = new Vector3(0, 0, 1); +_zAxis.freeze(); + +const _xAxisNeg = new Vector3(-1, 0, 0); +_xAxis.freeze(); + +const _yAxisNeg = new Vector3(0, -1, 0); +_yAxis.freeze(); + +const _zAxisNeg = new Vector3(0, 0, -1); +_zAxis.freeze(); + +const _nan = new Vector3(Number.NaN, Number.NaN, Number.NaN); +_nan.freeze(); + + +/***/ }), + +/***/ "../pioneer/engine/src/utils/wait_until.js": +/*!*************************************************!*\ + !*** ../pioneer/engine/src/utils/wait_until.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "waitUntil": function() { return /* binding */ waitUntil; } +/* harmony export */ }); +/** @module pioneer */ + +/** + * Waits until the testFunc returns true. + * @param {() => boolean} testFunc - The testing function. Returning true stops the wait. + * @param {number} testInterval - The interval in seconds to wait between tests. + * @param {number} timeout - The time at which point the promise rejects. + */ +async function waitUntil(testFunc, testInterval, timeout) { + return new Promise((resolve, reject) => { + let timeSoFar = 0; + const intervalCheck = setInterval(() => { + // Do the test. + if (testFunc()) { + clearInterval(intervalCheck); + resolve(); + } + // Increase the time we've waited. + timeSoFar += testInterval; + // If we've hit the timeout, reject. + if (timeSoFar >= timeout) { + clearInterval(intervalCheck); + reject(new Error()); + } + }, testInterval * 1000.0); + }); +} + + +/***/ }), + +/***/ "../pioneer/engine/src/version.js": +/*!****************************************!*\ + !*** ../pioneer/engine/src/version.js ***! + \****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Version": function() { return /* binding */ Version; } +/* harmony export */ }); +const Version = '51.0.1'; + + +/***/ }), + +/***/ "../pioneer/engine/src/viewport.js": +/*!*****************************************!*\ + !*** ../pioneer/engine/src/viewport.js ***! + \*****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Viewport": function() { return /* binding */ Viewport; } +/* harmony export */ }); +/* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal */ "../pioneer/engine/src/internal.js"); +/** @module pioneer */ + + +/** + * A viewport is where a scene will be rendered through a camera. + * When it is created, it creates a div element that can be styled, and which is contained in the viewports div. + * @extends {CollectionItem} + */ +class Viewport extends _internal__WEBPACK_IMPORTED_MODULE_0__.CollectionItem { + /** + * Constructs the viewport. Only called by the engine. + * @param {string} type - The type of the viewport (always 'viewport'). + * @param {string} name - The name of the viewport. + * @param {Engine} engine - The engine. + */ + constructor(type, name, engine) { + super(type, name, engine); + + /** + * Flag whether the viewport is enabled or not. + * @type {boolean} + * @private + */ + this._enabled = true; + + /** + * The camera being used to render. + * @type {CameraComponent} + * @private + */ + this._camera = null; + + /** + * The div that this viewport uses for its bounds. + * @type {HTMLDivElement} + * @private + */ + this._div = document.createElement('div'); + + /** + * The bounds of the viewport. Calculated from the div. + * @type {Rect} + * @private + */ + this._bounds = new _internal__WEBPACK_IMPORTED_MODULE_0__.Rect(0, 0, 0, 0); + this._bounds.freeze(); + + /** + * The color of the viewport background. + * @type {Color} + * @private + */ + this._backgroundColor = new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0, 0, 0, 1); + this._backgroundColor.freeze(); + + /** + * A THREE.Color helper so that a new THREE.Color doesn't need to be generated every frame. + * @type {THREE.Color} + * @private + */ + this._threeJsBackgroundColor = new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Color(); + + // Configure and add the div. + this._div.style.position = 'absolute'; + this._div.style.overflow = 'hidden'; + this._div.id = name ?? ''; + this._div.classList.add('viewport'); + if (!this._enabled) { + this._div.style.display = 'none'; + } + this.getEngine().getViewportDiv().appendChild(this._div); + + // Make sure the pixel bounds are valid on startup. + const rootDiv = this.getEngine().getRootDiv(); + this._bounds.thaw(); + this._bounds.set(this._div.offsetLeft - rootDiv.offsetLeft, this._div.offsetTop - rootDiv.offsetTop, this._div.offsetWidth, this._div.offsetHeight); + this._bounds.freeze(); + + // Make this the active viewport if there is none yet. + const input = this.getEngine().getInput(); + if (input.getActiveViewport() === null) { + input.__setActiveViewport(this); + } + } + + /** + * Gets the engine. + * @returns {Engine} + */ + getEngine() { + return this.__getCollectionParent(); + } + + /** + * Gets the div. This can be used to style the viewport. + * @returns {HTMLDivElement} + */ + getDiv() { + return this._div; + } + + /** + * Gets the pixel bounds within which this viewport renders, relative to the root div. + * @returns {Rect} + */ + getBounds() { + return this._bounds; + } + + /** + * Gets the background color. + * @returns {Color} + */ + getBackgroundColor() { + return this._backgroundColor; + } + + /** + * Sets the background color. + * @param {Color} backgroundColor - The color for the background. + */ + setBackgroundColor(backgroundColor) { + this._backgroundColor.thaw(); + this._backgroundColor = backgroundColor; + this._backgroundColor.freeze(); + this._threeJsBackgroundColor.setRGB(this._backgroundColor.r, this._backgroundColor.g, this._backgroundColor.b); + } + + /** + * Returns the camera that will be used by this viewport. + * @returns {CameraComponent} + */ + getCamera() { + return this._camera; + } + + /** + * Sets the camera that will be used by this viewport. + * @param {CameraComponent} camera + */ + setCamera(camera) { + this._camera = camera; + if (this._camera !== null) { + this._camera.__setViewport(this); + } + } + + /** + * Returns true if the viewport is enabled. + * @returns {boolean} + */ + isEnabled() { + return this._enabled; + } + + /** + * Sets whether the viewport is enabled or not. + * @param {boolean} enabled + */ + setEnabled(enabled) { + this._enabled = enabled; + if (!this._enabled) { + this._div.style.display = 'none'; + } + else { + this._div.style.display = 'block'; + } + } + + /** + * Gets a normal-space position from a pixel-space position. Sets the z coordinate to +1, which is equivalent to the near point of the camera. + * @param {Vector3} outNormalSpacePosition + * @param {Vector2} pixelSpacePosition + */ + getNormalSpacePositionFromPixelSpacePosition(outNormalSpacePosition, pixelSpacePosition) { + outNormalSpacePosition.x = 2.0 * (pixelSpacePosition.x - this._bounds.origin.x) / this._bounds.size.x - 1.0; + outNormalSpacePosition.y = 1.0 - 2.0 * (pixelSpacePosition.y - this._bounds.origin.y) / this._bounds.size.y; + outNormalSpacePosition.z = +1; + } + + /** + * Gets a pixel-space position from a normal-space position. Ignores the z coordinate. + * @param {Vector2} outPixelSpacePosition + * @param {Vector3} normalSpacePosition + */ + getPixelSpacePositionFromNormalSpacePosition(outPixelSpacePosition, normalSpacePosition) { + if (-1.0 < normalSpacePosition.z && normalSpacePosition.z < 1.0) { + outPixelSpacePosition.x = this._bounds.size.x * (normalSpacePosition.x + 1.0) / 2.0 + this._bounds.origin.x; + outPixelSpacePosition.y = this._bounds.size.y * (1.0 - normalSpacePosition.y) / 2.0 + this._bounds.origin.y; + } + else { + outPixelSpacePosition.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2[NaN]); + } + } + + /** + * Gets the pixel-space radius from a normal-space radius. + * @param {number} normalSpaceRadius + * @returns {number} + */ + getPixelSpaceRadiusFromNormalSpaceRadius(normalSpaceRadius) { + return normalSpaceRadius * Math.max(this._bounds.size.x, this._bounds.size.y); + } + + /** + * Gets the normal-space radius from a pixel-space radius. + * @param {number} pixelSpaceRadius + * @returns {number} + */ + getNormalSpaceRadiusFromPixelSpaceRadius(pixelSpaceRadius) { + return pixelSpaceRadius / Math.max(this._bounds.size.x, this._bounds.size.y); + } + + /** + * Gets the direction in camera-space of the cursor position, or NaN if the cursor is not over the viewport. + * @param {Vector3} outDirection + */ + getDirectionOfCursor(outDirection) { + const camera = this.getCamera(); + if (camera === null) { + outDirection.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + // Get the picked position in normal space. + const input = this.getEngine().getInput(); + this.getNormalSpacePositionFromPixelSpacePosition(outDirection, input.getCursorPosition()); + if (outDirection.x < -1 || outDirection.x > +1 + || outDirection.y < -1 || outDirection.y > +1 + || outDirection.z < -1 || outDirection.z > +1) { + outDirection.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + return; + } + + // Get the picked position in camera space. + camera.getCameraSpacePositionFromNormalSpacePosition(outDirection, outDirection); + + // Turn it into a ray of length 1, going from the camera. + outDirection.normalize(outDirection); + } + + /** + * Removes the div from the viewports div. + * @override + * @internal + */ + __destroy() { + super.__destroy(); + + // Clean up the div. + this._div.parentNode.removeChild(this._div); + } + + /** + * Prepares the camera-dependent variables and those of its connected entities. + * @internal + */ + __updateViewportVariables() { + if (this._enabled) { + // Update the bounds. + this._bounds.thaw(); + this._bounds.set(this._div.offsetLeft, this._div.offsetTop, this._div.offsetWidth, this._div.offsetHeight); + this._bounds.freeze(); + + // Update the camera variables for the camera. + if (this._camera !== null) { + this._camera.__updateCameraVariablesForConnectedScene(); + } + } + } + + /** + * Renders the camera in the viewport. Called by Engine. + * @internal + */ + __render() { + if (!this._enabled) { + return; + } + + const renderer = this.getEngine().__getThreeJsRenderer(); + + const positionFromBottomLeft = this.getEngine().getRootDiv().offsetHeight - this._div.offsetTop - this._div.offsetHeight; + renderer.setViewport(this._bounds.origin.x, positionFromBottomLeft, this._bounds.size.x, this._bounds.size.y); + renderer.setScissor(this._bounds.origin.x, positionFromBottomLeft, this._bounds.size.x, this._bounds.size.y); + + this._threeJsBackgroundColor.setRGB(this._backgroundColor.r, this._backgroundColor.g, this._backgroundColor.b); + renderer.setClearColor(this._threeJsBackgroundColor, this._backgroundColor.a); + + // Render the camera (which renders its scene). + if (this._camera !== null) { + this._camera.__prepareForRender(); + + this._camera.__render(); + } + else { + this.getEngine().__getThreeJsRenderer().clear(); + } + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/animation.js": +/*!*******************************************!*\ + !*** ../pioneer/scripts/src/animation.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Animation": function() { return /* binding */ Animation; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * Helpful utilities for scenes. + * @hideconstructor + */ +class Animation { + + /** + * Makes an animation that makes visible and invisible a subobjects at different times. + * Each keyframe is a [time, visible] pair. + * @param {Pioneer.ModelComponent} model + * @param {string} subobject + * @param {boolean} visibilityAtNegInf + * @param {[number, boolean][]} keyframes + * @returns {Pioneer.CoverageController} + */ + static makeSubobjectVisibleAnimation(model, subobject, visibilityAtNegInf, keyframes) { + // Sort the keyframes by time, just in case they aren't. + keyframes.sort((a, b) => a[0] - b[0]); + + // Get the coverage controller or create one if it doesn't already exist. + const entity = model.getEntity(); + const coverageController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CoverageController); + coverageController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY)); + coverageController.setUpdateFunction((entity) => { + const time = entity.getScene().getEngine().getTime(); + const index = pioneer__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, keyframes, (a, time) => a[0] < time); + if (index === 0) { // At first keyframe time or before. + model.setHiddenObject(subobject, !visibilityAtNegInf); + } + else { + model.setHiddenObject(subobject, !keyframes[index - 1][1]); + } + }); + + return coverageController; + } + + /** + * Makes an animation that rotates an entity's joints at different times. + * Each keyframe is a [time, rotation] pair. + * @param {Pioneer.ModelComponent} model + * @param {string} joint + * @param {'x' | 'y' | 'z'} axis + * @param {[number, number][]} keyframes + */ + static makeJointRotationAnimation(model, joint, axis, keyframes) { + // Sort the keyframes by time, just in case they aren't. + keyframes.sort((a, b) => a[0] - b[0]); + + // Get the coverage controller or create one if it doesn't already exist. + const entity = model.getEntity(); + const coverageController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CoverageController); + coverageController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY)); + coverageController.setUpdateFunction((entity) => { + const obj = model.getThreeJsObjectByName(joint); + if (obj !== null) { + const time = entity.getScene().getEngine().getTime(); + const index = pioneer__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, keyframes, (a, time) => a[0] < time); + if (index === 0) { // At first keyframe time or before. + obj.rotation[axis] = keyframes[0][1]; + } + else if (index === keyframes.length) { // After last keyframe time. + obj.rotation[axis] = keyframes[keyframes.length - 1][1]; + } + else { + const prevKeyframe = keyframes[index - 1]; + const nextKeyframe = keyframes[index]; + const u = (time - prevKeyframe[0]) / (nextKeyframe[0] - prevKeyframe[0]); + obj.rotation[axis] = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(prevKeyframe[1], nextKeyframe[1], u); + } + } + }); + + return coverageController; + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/cameras.js": +/*!*****************************************!*\ + !*** ../pioneer/scripts/src/cameras.js ***! + \*****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Cameras": function() { return /* binding */ Cameras; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * @callback TransitionFunction + * @param {Pioneer.Entity} entity + * @param {Pioneer.Vector3} initialPosition + * @param {Pioneer.Vector3} finalPosition + * @param {Pioneer.Quaternion} initialOrientation + * @param {Pioneer.Quaternion} finalOrientation + * @param {number} u + */ + +/** + * Helpful functions for viewports and cameras. + * @hideconstructor + */ +class Cameras { + /** + * Creates a full size (100% width and height) viewport and a camera. + * @param {Pioneer.Scene} scene - the scene in which to create the camera + * @param {string} [viewportName = 'main'] - the name of the viewport + * @param {string} [cameraEntityName = 'camera'] - the name of the camera entity + */ + static createFullSizeViewportAndCamera(scene, viewportName = 'main', cameraEntityName = 'camera') { + const viewport = scene.getEngine().addViewport(viewportName); + viewport.getDiv().style.width = '100%'; + viewport.getDiv().style.height = '100%'; + const cameraEntity = scene.addEntity(cameraEntityName); + const camera = cameraEntity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CameraComponent); + viewport.setCamera(camera); + } + + /** Makes the camera align to the focus entity. + * @param {Pioneer.Entity} cameraEntity - the camera entity + * @param {Pioneer.Entity} focusEntity - the entity around which the camera entity will orbit + * @param {Object} options - the options used to setup the camera + * @param {boolean} [options.up = true] - If true, the camera's up will be aligned with the entity. + * @param {boolean} [options.orbiter = false] - If true, the camera's up will be the away from the focus entity's parent, and if false, it will be the z-axis (usually the north pole). + */ + static focusOnEntity(cameraEntity, focusEntity, { up = true, orbiter = false }) { + const alignController = cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.AlignController); + alignController.setPrimaryAlignType('point'); + alignController.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis); + alignController.setPrimaryTargetEntity(focusEntity.getName()); + if (up) { + if (orbiter) { + alignController.setSecondaryAlignType('position'); + alignController.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis); + alignController.setSecondaryTargetEntity(focusEntity.getName()); + } + else { + alignController.setSecondaryAlignType('align'); + alignController.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis); + alignController.setSecondaryTargetEntity(focusEntity.getName()); + alignController.setSecondaryTargetAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis); + } + } + } + + /** + * Makes the camera look at an entity. + * @param {Pioneer.Entity} cameraEntity - the camera entity + * @param {Pioneer.Entity} focusEntity - the entity that the camera entity will look at + * @param {Object} options - the options used to setup the camera + * @param {number} [options.duration = 0.5] - seconds to do the transition + * @param {Pioneer.Vector3} [options.finalUp] - the final up vector, defaults to undefined, which means no up alignment + * @param {Pioneer.Entity} [options.finalUpRelativeEntity] - the final up vector is relative to this entity, defaults to the focus entity + * @param {boolean} [options.finalUpPosition] - true if the final up vector is the position of the finalUpRelativeEntity relative to its parent + */ + static async lookAtEntity(cameraEntity, focusEntity, { duration = 0.5, finalUp = undefined, finalUpRelativeEntity = undefined, finalUpPosition = false }) { + // If the camera isn't yet anywhere, there's nowhere to look. + if (cameraEntity.getPosition().isNaN()) { + return; + } + + // Get the final forward vector. + const forward = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + focusEntity.getPositionRelativeToEntity(forward, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, cameraEntity); + forward.normalize(forward); + + // Remove any other orientation modifying controllers. + for (let i = 0; i < cameraEntity.getNumControllers(); i++) { + if (cameraEntity.getController(i).hasModifiedState('orientation')) { + cameraEntity.removeController(i); + i--; + } + } + + // Add and setup the align controller. + const alignController = cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.AlignController); + alignController.setPrimaryAlignType('point'); + alignController.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis); + alignController.setPrimaryTargetEntity(focusEntity.getName()); + if (finalUp !== undefined) { + if (finalUpRelativeEntity === undefined) { + finalUpRelativeEntity = focusEntity; + } + if (finalUpPosition) { + alignController.setSecondaryAlignType('position'); + alignController.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis); + alignController.setSecondaryTargetEntity(finalUpRelativeEntity.getName()); + } + else { + alignController.setSecondaryAlignType('align'); + alignController.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis); + alignController.setSecondaryTargetEntity(finalUpRelativeEntity.getName()); + alignController.setSecondaryTargetAxis(finalUp); + } + } + + // Add and setup the transition controller. + const transitionController = cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.TransitionController); + transitionController.setTransitionTime(duration); + await transitionController.getEndPromise(); + } + + /** + * Makes the camera go to an object. + * @param {Pioneer.Entity} cameraEntity - the camera entity + * @param {Pioneer.Entity} focusEntity - the entity that the camera will orbit around, starting on the sunny side + * @param {Object} options - the options used to setup the camera + * @param {boolean} [options.up = true] - align the entity to either the north pole of the entity or if it is an orbiter, the position of the orbiter. + * @param {boolean} [options.orbiter = false] - if true, the camera's up will be the away from the focus entity's parent. + * @param {boolean} [options.fixedToParent = false] - if true, the camera will be fixed to the parent and will not drift if the parent rotates. + * @param {number} [options.duration = 0.5] - seconds to do the transition + * @param {number} [options.distance] - how far away from the focus entity the camera should be (default is 5 times focusEntity's radius) + * @param {boolean} [options.zoom = true] - if true, sets a zoom controller + * @param {Pioneer.Vector3} [options.destination] - the location relative to the focus entity to transition to; if undefined it goes to the nearest spot from the camera's current position; this overrides distance + * @param {Pioneer.Vector3} [options.destinationUp] - the up direction that the camera will transition to; if undefined it will use the current up of the camera projected into the forward plane + * @param {boolean} [options.destinationInFocusFrame = false] - if true, the destination and destinationUp are in the orientation frame of the focus entity + * @param {TransitionFunction} [options.transitionFunction] - a manual transition function to use + * @returns {Promise} + */ + static async goToEntity(cameraEntity, focusEntity, { up = true, orbiter = false, fixedToParent = false, duration = 1.0, distance = undefined, zoom = true, destination = undefined, destinationUp = undefined, destinationInFocusFrame = false, transitionFunction = undefined }) { + if (!distance) { + distance = focusEntity.getExtentsRadius() * 5.0; + } + + // If the camera isn't yet anywhere, set it to a nice location. + if (cameraEntity.getPosition().isNaN() || cameraEntity.getOrientation().isNaN()) { + cameraEntity.setParent(focusEntity); + if (destination === undefined) { + cameraEntity.setPosition(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, -distance, 0)); + } + else { + cameraEntity.setPosition(destination); + } + cameraEntity.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + duration = 0; + } + + // Get the destination position for the end of the transition if there was none set. + if (destination === undefined) { + destination = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + cameraEntity.getPositionRelativeToEntity(destination, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, focusEntity); + destination.normalize(destination); + destination.mult(destination, distance); + if (destination.isNaN()) { + destination.set(0, -distance, 0); + } + } + + // Set the destination position for the end of the transition. + cameraEntity.clearControllers(); + const fixedController = cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.FixedController); + fixedController.setPosition(destination); + + // Set the destination orientation for the end of the transition. + if (destinationUp !== undefined) { + const destinationForward = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const destUp = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + destinationForward.neg(destination); + destinationForward.normalize(destinationForward); + destUp.setNormalTo(destinationForward, destinationUp); + const orientation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + orientation.setFromAxes(undefined, destinationForward, destUp); + fixedController.setOrientation(orientation); + } + + if (destinationInFocusFrame) { + const rotateByEntityOrientationController = cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.RotateByEntityOrientationController); + if (destinationUp === undefined) { + rotateByEntityOrientationController.setRotatingOrientation(false); + } + } + + this.focusOnEntity(cameraEntity, focusEntity, { up, orbiter }); + + // Setup the transition. + const transitionController = cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.TransitionController); + transitionController.setTransitionTime(duration); + transitionController.setParent(focusEntity.getName()); + if (transitionFunction) { + transitionController.setTransitionFunction(transitionFunction); + } + await transitionController.getEndPromise(); + + cameraEntity.clearControllers(); + const orbitController = cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitController); + if (up) { + if (orbiter) { + orbitController.setYawAxisType('position'); + } + else { + orbitController.setYawAxisType('z-axis'); + } + } + else { + cameraEntity.addController('roll'); + } + + if (fixedToParent) { + cameraEntity.addController('fixedToParent'); + } + + if (zoom) { + cameraEntity.addController('zoom'); + } + + this.focusOnEntity(cameraEntity, focusEntity, { up, orbiter }); + } + + /** + * Adds pick controller that calls the callback with the XYZ (ECEF) and the LatLonAlt of the location picked on the entity. + * @param {Pioneer.Entity} cameraEntity + * @param {Pioneer.Entity} pickedEntity + * @param {(xyz: Pioneer.Vector3, lla: Pioneer.LatLonAlt) => void} callback + */ + static pickOnEntity(cameraEntity, pickedEntity, callback) { + const pickController = cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.PickController); + pickController.setPickedEntity(pickedEntity); + pickController.setCallback((position) => { + const spheroidComponent = pickedEntity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent); + if (spheroidComponent !== null) { + const positionInSpheroidFrame = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + positionInSpheroidFrame.rotateInverse(pickedEntity.getOrientation(), position); + const lla = pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + spheroidComponent.llaFromXYZ(lla, positionInSpheroidFrame); + callback(positionInSpheroidFrame, lla); + pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionInSpheroidFrame); + } + }); + } + + /** + * Gets the distance that the camera entity should be so that all of the entities are in view. + * @param {Pioneer.Entity} cameraEntity - the camera entity + * @param {Pioneer.Quaternion} cameraOrientation - the orientation that the camera will have, assuming it will be centered on the focus entity + * @param {Pioneer.Entity} focusEntity - the entity that the child will be a child of and pointed at + * @param {Pioneer.Entity[]} entities - the list of entities to keep in view + * @returns {number} + */ + static getDistanceToFitEntities(cameraEntity, cameraOrientation, focusEntity, entities) { + const cameraComponent = cameraEntity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CameraComponent); + if (cameraComponent === null) { + return NaN; + } + + let distance = 0; + const positionOfEntity = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const sinHalfHorizontalFov = Math.sin(cameraComponent.getHorizontalFieldOfView() / 2.0); + const sinHalfVerticalFov = Math.sin(cameraComponent.getVerticalFieldOfView() / 2.0); + const tanHalfHorizontalFov = Math.tan(cameraComponent.getHorizontalFieldOfView() / 2.0); + const tanHalfVerticalFov = Math.tan(cameraComponent.getVerticalFieldOfView() / 2.0); + + for (let i = 0; i < entities.length; i++) { + const entity = entities[i]; + let ringsRadius = 0; + const ringsComponent = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.RingsComponent); + if (ringsComponent !== null) { + ringsRadius = ringsComponent.getOuterRadius(); + } + + // Get the position of the entity in the camera's rotated frame. + entity.getPositionRelativeToEntity(positionOfEntity, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, focusEntity); + positionOfEntity.rotateInverse(cameraOrientation, positionOfEntity); + + // Get the distances for the horizontal and vertical fovs. + distance = Math.max(distance, Math.abs(positionOfEntity.x) / tanHalfHorizontalFov + Math.max(entity.getExtentsRadius(), ringsRadius) / sinHalfHorizontalFov - positionOfEntity.y); + distance = Math.max(distance, Math.abs(positionOfEntity.z) / tanHalfVerticalFov + Math.max(entity.getExtentsRadius(), ringsRadius) / sinHalfVerticalFov - positionOfEntity.y); + } + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionOfEntity); + return distance; + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/components/annulus_component.js": +/*!**************************************************************!*\ + !*** ../pioneer/scripts/src/components/annulus_component.js ***! + \**************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "AnnulusComponent": function() { return /* binding */ AnnulusComponent; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * A component that renders a colored disc in the x-y plane with an inner and outer radius. + */ +class AnnulusComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The inner-radius of the circular-shaped plane. + * @type {number} + * @private + */ + this._sizeInner = 1; + + /** + * The outer-radius of the circular-shaped plane. + * @type {number} + * @private + */ + this._sizeOuter = 1; + + /** + * A flag the determines whether or not the plane ignores the distance when determining visibility. + * @type {boolean} + * @private + */ + this._ignoreDistance = false; + + /** + * The calculated transition slope at which the plane will fade out. This is calculated based on the value provided to setMinDistance. + * @type {number} + * @private + */ + this._minDistanceM = 0.0; + + /** + * The calculated transition offset at which the plane will fade out. This is calculated based on the value provided to setMinDistance. + * @type {number} + * @private + */ + this._minDistanceB = 0.0; + + /** + * The calculated transition slope at which the plane will fade out. This is calculated based on the value provided to setMaxDistance. + * @type {number} + * @private + */ + this._maxDistanceM = 0.0; + + /** + * The calculated transition offset at which the plane will fade out. This is calculated based on the value provided to setMaxDistance. + * @type {number} + * @private + */ + this._maxDistanceB = 0.0; + + /** + * The color of the annulus. + * @type {Pioneer.Color} + * @private + */ + this._color = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1); + this._color.freeze(); + + /** + * The alpha multiplier determined by fading. + * @type {number} + * @private + */ + this._alphaMultiplier = 1.0; + + /** + * The number of points on the circle. + * @type {number} + * @private + */ + this._numPointsOnCircle = 200; + + /** + * True if the mesh needs to be updated. + * @type {boolean} + * @private + */ + this._meshDirty = true; + + this.__setRadius(this._sizeOuter); + this.__setUsesEntityOrientation(true); + } + + /** + * Gets the size of the inner radius. Defaults to 1. + * @returns {number} + */ + getInnerRadius() { + return this._sizeInner; + } + + /** + * Sets the size of the inner radius. + * @param {number} size + */ + setInnerRadius(size) { + this._sizeInner = size; + this._meshDirty = true; + } + + /** + * Gets the size of the outer radius. + * @returns {number} + */ + getOuterRadius() { + return this._sizeOuter; + } + + /** + * Sets the size of the outer radius + * @param {number} size + */ + setOuterRadius(size) { + this._sizeOuter = size; + this._meshDirty = true; + this.__setRadius(size); + } + + /** + * Sets the component to either consider the distance (false) or ignore the distance (true). + * @param {boolean} ignoreDistance + */ + setIgnoreDistance(ignoreDistance) { + this._ignoreDistance = ignoreDistance; + this._alphaMultiplier = 1.0; + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._color, this._alphaMultiplier); + } + + /** + * Sets the minimum distance at which the component should be fully visible. + * @param {number} distance + */ + setMinDistance(distance) { + this._minDistanceM = 1.0 / (distance - distance / 1.1); + this._minDistanceB = -1.0 * this._minDistanceM * distance / 1.1; + } + + /** + * Sets the maximum distance at which the component should be fully visible. + * @param {number} distance + */ + setMaxDistance(distance) { + this._maxDistanceM = -1.0 / (distance * 1.1 - distance); + this._maxDistanceB = -1.0 * this._maxDistanceM * distance * 1.1; + } + + /** + * Gets the color of the annulus. Defaults to white. + * @returns {Pioneer.Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the color of the annulus. The alpha value should be provided at the component's maximum visibility. + * @param {Pioneer.Color} color + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._color, this._alphaMultiplier); + } + + /** + * Prepare the component for rendering. + * @param {Pioneer.CameraComponent} camera + * @override + * @package + */ + __prepareForRender(camera) { + // Set the orientation to the entity's orientation. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0], this.getEntity()); + + // Set the Three.js object position the entity's camera-space position. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + + if (this._meshDirty) { + this._updateMesh(); + } + + if (!this._ignoreDistance) { + const cameraSpacePosition = this.getEntity().getCameraSpacePosition(camera); + const distanceToObject = cameraSpacePosition.magnitude(); + const minimumDistanceTransition = this._minDistanceM * distanceToObject + this._minDistanceB; + const maximumDistanceTransition = this._maxDistanceM * distanceToObject + this._maxDistanceB; + this._alphaMultiplier = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(Math.min(minimumDistanceTransition, maximumDistanceTransition)); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._color, this._alphaMultiplier); + } + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + // Create the material. + const material = this.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('basic_alpha'); + this.getThreeJsMaterials().push(material); + // Set the properties. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(material, 'color', this._color, this._alphaMultiplier); + // Create the mesh object. + const object = pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this, material, [{ name: 'position', dimensions: 3 }], false); + this.getThreeJsObjects().push(object); + // Return it as loaded. + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyObject(this.getThreeJsObjects()[0]); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyMaterial(this.getThreeJsMaterials()[0]); + } + + /** + * Updates the mesh. + * @private + */ + _updateMesh() { + const positions = new Float32Array(this._numPointsOnCircle * 4 * 3); + const indices = new Uint16Array(this._numPointsOnCircle * 6); + + // Make the concentric circles. + let positionsIndex = 0; + let indicesIndex = 0; + const position0 = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const position1 = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + const circleSize = this._sizeOuter; + const circleInnerRatio = this._sizeInner / this._sizeOuter; + + for (let j = 0; j < this._numPointsOnCircle; j++) { + const angle1 = j / this._numPointsOnCircle * pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + const angle2 = ((j + 1) % this._numPointsOnCircle) / this._numPointsOnCircle * pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + + position0.set(circleSize * Math.cos(angle1), circleSize * Math.sin(angle1), 0); + position1.set(circleSize * Math.cos(angle2), circleSize * Math.sin(angle2), 0); + + positions[positionsIndex + 0] = position0.x * circleInnerRatio; // XYZ set for origin (inner) + positions[positionsIndex + 1] = position0.y * circleInnerRatio; + positions[positionsIndex + 2] = position0.z * circleInnerRatio; + + positions[positionsIndex + 3] = position0.x; + positions[positionsIndex + 4] = position0.y; + positions[positionsIndex + 5] = position0.z; // CW Edge (left) + + positions[positionsIndex + 6] = position1.x; + positions[positionsIndex + 7] = position1.y; + positions[positionsIndex + 8] = position1.z; // CCW Edge (right) + + positions[positionsIndex + 9] = position1.x * circleInnerRatio; + positions[positionsIndex + 10] = position1.y * circleInnerRatio; + positions[positionsIndex + 11] = position1.z * circleInnerRatio; // CCW Edge (Inner) + + indices[indicesIndex + 0] = positionsIndex / 3 + 0; + indices[indicesIndex + 1] = positionsIndex / 3 + 1; + indices[indicesIndex + 2] = positionsIndex / 3 + 2; + indices[indicesIndex + 3] = positionsIndex / 3 + 2; + indices[indicesIndex + 4] = positionsIndex / 3 + 3; + indices[indicesIndex + 5] = positionsIndex / 3 + 0; + + positionsIndex += 12; + indicesIndex += 6; + } + const geometry = /** @type {Pioneer.THREE.Mesh} */(this.getThreeJsObjects()[0]).geometry; + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(geometry, 'position', positions); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(geometry, indices); + this._meshDirty = false; + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/components/celestial_grid_component.js": +/*!*********************************************************************!*\ + !*** ../pioneer/scripts/src/components/celestial_grid_component.js ***! + \*********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "CelestialGridComponent": function() { return /* binding */ CelestialGridComponent; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * The Celestial Grid component. + * */ +class CelestialGridComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The number of degrees per line. + * @type {number} + * @private + */ + this._degreesPerLine = 10; + + /** + * The color of the grid. + * @type {Pioneer.Color} + * @private + */ + this._color = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1); + this._color.freeze(); + + /** + * The LineMesh object used to do the drawing. + * @type {Pioneer.LineMesh} + * @private + */ + this._lineMesh = null; + + /** + * True if the mesh needs to be updated. + * @type {boolean} + * @private + */ + this._meshDirty = true; + } + + /** + * Sets the radius of the grid. + * @param {number} radius + */ + setRadius(radius) { + this.__setRadius(radius); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setScale(this.getThreeJsObjects(), this.getRadius()); + } + + /** + * Gets the color of the grid. Defaults to white. + * @returns {Pioneer.Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the color of the grid. + * @param {Pioneer.Color} color + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + this._meshDirty = true; + } + + /** + * Gets the number of degrees per line. Defaults to 10. + * @returns {number} + */ + getDegreesPerLine() { + return this._degreesPerLine; + } + + /** + * Sets the number of degrees per line. + * @param {number} degreesPerLine + */ + setDegreesPerLine(degreesPerLine) { + this._degreesPerLine = degreesPerLine; + this._meshDirty = true; + } + + /** + * Prepare the component for rendering. + * @param {Pioneer.CameraComponent} camera + * @override + * @package + */ + __prepareForRender(camera) { + if (this._meshDirty) { + this._updateMesh(); + } + + // Set the Three.js object position the entity's camera-space position. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects(), this.getEntity(), camera); + + // Call the line mesh prepare for render. + this._lineMesh.prepareForRender(camera); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + this._lineMesh = new pioneer__WEBPACK_IMPORTED_MODULE_0__.LineMesh(this); + this._updateMesh(); + + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + this._lineMesh = null; + } + + /** + * Updates the mesh positions and colors. + * @private + */ + _updateMesh() { + const positions = []; + for (let lon0 = 0; lon0 < 360; lon0 += this._degreesPerLine) { + const lon1 = Math.min(lon0 + this._degreesPerLine, 360); + const lon0Rad = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(lon0); + const lon1Rad = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(lon1); + for (let lat0 = -90; lat0 < 90; lat0 += this._degreesPerLine) { + const lat1 = Math.min(lat0 + this._degreesPerLine, 90); + const lat0Rad = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(lat0); + const lat1Rad = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(lat1); + // Make a horizontal line. + if (-90 < lat0 && lat0 < 90) { + positions.push(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(Math.sin(lon0Rad) * Math.cos(lat0Rad), Math.cos(lon0Rad) * Math.cos(lat0Rad), Math.sin(lat0Rad))); + positions.push(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(Math.sin(lon1Rad) * Math.cos(lat0Rad), Math.cos(lon1Rad) * Math.cos(lat0Rad), Math.sin(lat0Rad))); + } + // Make a vertical line. + positions.push(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(Math.sin(lon0Rad) * Math.cos(lat0Rad), Math.cos(lon0Rad) * Math.cos(lat0Rad), Math.sin(lat0Rad))); + positions.push(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(Math.sin(lon0Rad) * Math.cos(lat1Rad), Math.cos(lon0Rad) * Math.cos(lat1Rad), Math.sin(lat1Rad))); + } + } + const colors = []; + for (let i = 0, l = positions.length; i < l; i++) { + colors.push(this._color); + } + const widths = []; + for (let i = 0, l = positions.length; i < l; i++) { + widths.push(2); + } + this._lineMesh.setPositions(positions); + this._lineMesh.setColors(colors); + this._lineMesh.setWidths(widths); + + // Set the Three.js object orientation to the identity. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(this.getThreeJsObjects(), pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + + // Set the Three.js object scale to be the radius of the component. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setScale(this.getThreeJsObjects(), this.getRadius()); + + this._meshDirty = false; + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/components/constellations_component.js": +/*!*********************************************************************!*\ + !*** ../pioneer/scripts/src/components/constellations_component.js ***! + \*********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ConstellationsComponent": function() { return /* binding */ ConstellationsComponent; } +/* harmony export */ }); +/* harmony import */ var _scene_helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene_helpers */ "../pioneer/scripts/src/scene_helpers.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +/** + * Constellations. + */ +class ConstellationsComponent extends pioneer__WEBPACK_IMPORTED_MODULE_1__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The url used for the database. + * @type {string} + * @private + */ + this._url = ''; + + /** + * The database. They match the ordering of the labelEntities. + * @type {DatabaseEntry[]} + */ + this._database = []; + + /** + * The number of vertices in each line mesh. + * @type {number[]} + * @private + */ + this._numVertices = []; + + /** + * The label entities. + * @type {Pioneer.Entity[]} + * @private + */ + this._labelEntities = []; + + /** + * The color of the lines. + * @type {Pioneer.Color} + * @private + */ + this._color = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(); + + /** + * The width of the lines. + * @type {number} + * @private + */ + this._lineWidth = 2; + + /** + * The glow width for the lines. + * @type {number} + * @private + */ + this._glowWidth = 0; + + /** + * The index of the constellation to be highlighted. + * @type {number | undefined} + * @private + */ + this._highlightedIndex = undefined; + + /** + * The color of the highlight. + * @type {Pioneer.Color} + * @private + */ + this._highlightColor = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(); + + /** + * The width of of the highlight lines. + * @type {number} + * @private + */ + this._highlightWidth = 0; + + /** + * The line meshes. + * @type {Pioneer.LineMesh[]} + * @private + */ + this._lineMeshes = []; + + // Set the radius to infinite, since it extends to all of the stars in the constellations. + this.__setRadius(Number.POSITIVE_INFINITY); + } + + /** + * Sets the color of the lines. + * @param {Pioneer.Color} color + */ + setColor(color) { + this._color.copy(color); + + // Set the color for every line mesh. + for (let i = 0; i < this._lineMeshes.length; i++) { + const colors = []; + for (let j = 0; j < this._numVertices[i]; j++) { + colors.push(this._color); + } + this._lineMeshes[i].setColors(colors); + } + } + + /** + * Sets the width of the lines. + * @param {number} lineWidth + */ + setLineWidth(lineWidth) { + this._lineWidth = lineWidth; + + // Set the width of the line meshes. + for (let i = 0; i < this._lineMeshes.length; i++) { + this._lineMeshes[i].setWidths(lineWidth); + } + } + + /** + * Sets the glow for the lines. + * @param {number} glowWidth + */ + setGlowWidth(glowWidth) { + this._glowWidth = glowWidth; + for (let i = 0, l = this._lineMeshes.length; i < l; i++) { + this._lineMeshes[i].setGlowWidth(this._glowWidth); + } + } + + /** + * Sets the database. + * @param {string} url + */ + setUrl(url) { + this._url = url; + this.resetResources(); + } + + /** + * Generates and returns a list of the constellation names. Each label entity is named "constellation_label_". + * @returns {string[]} + */ + getNames() { + const names = []; + for (let i = 0, l = this._database.length; i < l; i++) { + names.push(this._database[i].name); + } + return names; + } + + /** + * Sets the contellation at the index to be highlighted. Use undefined for the index to clear the highlighting. + * @param {number | undefined} hightlightedIndex + * @param {Pioneer.Color} highlightColor + * @param {number} highlightWidth + */ + setHighlight(hightlightedIndex, highlightColor, highlightWidth) { + // Unhighlight the previous lineMesh. + if (this._lineMeshes.length > 0 && this._highlightedIndex !== undefined) { + const colors = []; + for (let i = 0, l = this._numVertices[this._highlightedIndex]; i < l; i++) { + colors.push(this._color); + } + this._lineMeshes[this._highlightedIndex].setColors(colors); + this._lineMeshes[this._highlightedIndex].setWidths(this._lineWidth); + } + + // Set the highlight vars. + this._highlightedIndex = hightlightedIndex; + this._highlightColor.copy(highlightColor); + this._highlightWidth = highlightWidth; + + // Highlight the new lineMesh. + if (this._lineMeshes.length > 0 && this._highlightedIndex !== undefined) { + const colors = []; + for (let i = 0, l = this._numVertices[this._highlightedIndex]; i < l; i++) { + colors.push(this._highlightColor); + } + this._lineMeshes[this._highlightedIndex].setColors(colors); + this._lineMeshes[this._highlightedIndex].setWidths(this._highlightWidth); + } + } + + /** + * Gets the index of the constellation nearest to the pixel-space position. If there is none, returns undefined + * @param {Pioneer.Vector2} pixelSpacePosition + * @param {Pioneer.CameraComponent} camera + */ + getNearestConstellationIndex(pixelSpacePosition, camera) { + /** @type {number | undefined} */ + let nearestIndex; + let nearestDistance = Number.POSITIVE_INFINITY; + for (let i = 0, l = this._labelEntities.length; i < l; i++) { + const dist = pixelSpacePosition.distance(this._labelEntities[i].getPixelSpacePosition(camera)); + if (dist < nearestDistance) { + nearestDistance = dist; + nearestIndex = i; + } + } + return nearestIndex; + } + + /** + * Prepare the component for rendering. + * @param {Pioneer.CameraComponent} camera + * @override + * @package + */ + __prepareForRender(camera) { + // Set the Three.js object position the entity's camera-space position. + pioneer__WEBPACK_IMPORTED_MODULE_1__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects(), this.getEntity(), camera); + + // Call the line meshes prepare for render. + for (let i = 0; i < this._lineMeshes.length; i++) { + this._lineMeshes[i].prepareForRender(camera); + } + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + this._labelEntities = []; + this._lineMeshes = []; + this._numVertices = []; + + const result = await this.getEntity().getScene().getEngine().getDownloader().download(this._url, true); + if (result.status === 'completed' && result.content instanceof ArrayBuffer) { + const reader = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Reader(result.content); + + while (!reader.isAtEnd()) { + const entry = /** @type {DatabaseEntry} */({ + name: '', + stars: [], + segments: [], + color: [] + }); + + entry.name = reader.readString(reader.readByte()); + + entry.color = [ + reader.readByte(), + reader.readByte(), + reader.readByte(), + reader.readByte() + ]; + + const starCount = reader.readByte(); + for (let i = 0; i < starCount; i++) { + entry.stars.push([ + reader.readFloat32(), + reader.readFloat32(), + reader.readFloat32() + ]); + } + + const segmentCount = reader.readByte() * 2; + for (let i = 0; i < segmentCount; i++) { + entry.segments.push(reader.readByte()); + } + + this._database.push(entry); + } + } + + // Create the lines. + for (let i = 0; i < this._database.length; i++) { + const stars = this._database[i].stars; + const segments = this._database[i].segments; + const positions = []; + const colors = []; + const widths = []; + + for (let j = 0; j < segments.length; j++) { + const starIndex = segments[j]; + positions.push(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(stars[starIndex][2], -stars[starIndex][0], stars[starIndex][1])); + colors.push(i === this._highlightedIndex ? this._highlightColor : this._color); + widths.push(i === this._highlightedIndex ? this._highlightWidth : this._lineWidth); + } + const lineMesh = new pioneer__WEBPACK_IMPORTED_MODULE_1__.LineMesh(this); + lineMesh.setPositions(positions); + lineMesh.setColors(colors); + lineMesh.setWidths(widths); + lineMesh.setGlowWidth(this._glowWidth); + this._lineMeshes.push(lineMesh); + this._numVertices.push(segments.length); + } + pioneer__WEBPACK_IMPORTED_MODULE_1__.ThreeJsHelper.setOrientation(this.getThreeJsObjects(), _scene_helpers__WEBPACK_IMPORTED_MODULE_0__.SceneHelpers.getEclipJ2000ToJ2000Rotation()); + + // Create the labels as child entities with div components. + for (let i = 0; i < this._database.length; i++) { + const stars = this._database[i].stars; + // Calculate the min and max bounds for the center. + const minBounds = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); + const maxBounds = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY); + const distance = Math.sqrt(stars[0][0] * stars[0][0] + stars[0][1] * stars[0][1] + stars[0][2] * stars[0][2]); + for (let j = 0; j < stars.length; j++) { + const star = stars[j]; + const position = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(); + position.set(star[2], -star[0], star[1]); + position.rotate(_scene_helpers__WEBPACK_IMPORTED_MODULE_0__.SceneHelpers.getEclipJ2000ToJ2000Rotation(), position); + position.normalize(position); + position.mult(position, distance); + if (minBounds.x > position.x) { + minBounds.x = position.x; + } + if (maxBounds.x < position.x) { + maxBounds.x = position.x; + } + if (minBounds.y > position.y) { + minBounds.y = position.y; + } + if (maxBounds.y < position.y) { + maxBounds.y = position.y; + } + if (minBounds.z > position.z) { + minBounds.z = position.z; + } + if (maxBounds.z < position.z) { + maxBounds.z = position.z; + } + } + // Get the center point of the constellation. + const center = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(); + center.add(minBounds, maxBounds); + center.mult(center, 0.5); + // Create a new entity that's a child of this entity at the center. + const labelEntity = this.getEntity().getScene().addEntity('constellation_label_' + this._database[i].name); + labelEntity.setParent(this.getEntity()); + labelEntity.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity); + labelEntity.setPosition(center); + // Add a div component to that entity with the name of the constellation. + const divComponent = labelEntity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent); + divComponent.setAlignment(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector2(0.5, 0.5)); + const div = divComponent.getDiv(); + div.classList.add('pioneer-constellation-label'); + div.innerHTML = this._database[i].name; + // Add it to the list of label entities. + this._labelEntities.push(labelEntity); + } + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + // Clean up the label entities. + for (let i = 0; i < this._labelEntities.length; i++) { + this.getEntity().getScene().removeEntity(this._labelEntities[i]); + } + // Clean up the objects and materials created by the line meshes. + pioneer__WEBPACK_IMPORTED_MODULE_1__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + // Make the line meshes null. + this._lineMeshes = []; + // Clear the database. + this._database = []; + } +} + +/** + * @typedef {object} DatabaseEntry + * @property {string} name - the name of the constellation + * @property {number[][]} stars - the list of star positions, each entry being a 3-array XYZ in J2000Eclipse coordinates. + * @property {number[]} segments - the list of segments, each pair being a line, and each indexing an entry in the stars list. + * @property {number[]} color - a 3-array of RGB values from 0 to 255. + */ + + +/***/ }), + +/***/ "../pioneer/scripts/src/components/disc_grid_component.js": +/*!****************************************************************!*\ + !*** ../pioneer/scripts/src/components/disc_grid_component.js ***! + \****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "DiscGridComponent": function() { return /* binding */ DiscGridComponent; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * A grid in the shape of a disc. + */ +class DiscGridComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The size of the grid. + * @type {number} + * @private + */ + this._size = 1; + + /** + * The color of the grid. + * @type {Pioneer.Color} + * @private + */ + this._color = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1); + this._color.freeze(); + + /** + * The width of the lines in pixels. + * @type {number} + * @private + */ + this._lineWidth = 1; + + /** + * The number of radial points to render. + * @type {number} + * @private + */ + this._numCircles = 10; + + /** + * The number of circular points to render. + * @type {number} + * @private + */ + this._numSpokes = 20; + + /** + * The power that each concentric circle radius is raised to. + * @type {number} + * @private + */ + this._radialPower = 1; + + /** + * A flag the determines whether or not the grid ignores the distance when determining visibility. + * @type {boolean} + * @private + */ + this._ignoreDistance = false; + + /** + * The LineMesh object used to do the drawing. + * @type {Pioneer.LineMesh} + * @private + */ + this._lineMesh = null; + + /** + * True if the mesh needs to be updated. + * @type {boolean} + * @private + */ + this._meshDirty = true; + + // Set the initial size. + this.__setRadius(this._size); + + // It uses the entity's orientation. + this.__setUsesEntityOrientation(true); + } + + /** + * Gets the size of the grid. Defaults to 1. + * @returns {number} + */ + getSize() { + return this._size; + } + + /** + * Sets the size of the grid. + * @param {number} size + */ + setSize(size) { + this._size = size; + this.__setRadius(this._size); + if (this._lineMesh !== null) { + this._lineMesh.setScale(this._size); + } + } + + /** + * Gets the color of the grid. Defaults to white. + * @returns {Pioneer.Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the color of the grid. + * @param {Pioneer.Color} color + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + this._meshDirty = true; + } + + /** + * Gets the width of the lines in pixels. + * @returns {number} + */ + getLineWidth() { + return this._lineWidth; + } + + /** + * Sets the width of the lines in pixels. Defaults to 1. + * @param {number} lineWidth + */ + setLineWidth(lineWidth) { + this._lineWidth = lineWidth; + if (this._lineMesh !== null) { + this._lineMesh.setWidths(this._lineWidth); + } + } + + /** + * Gets the number of concentric circles to place. Defaults to 10. + * @returns {number} + */ + getNumCircles() { + return this._numCircles; + } + + /** + * Sets the number of concentric circles to place. + * @param {number} numCircles + */ + setNumCircles(numCircles) { + this._numCircles = numCircles; + this._meshDirty = true; + } + + /** + * Gets the number of spokes to place. Defaults to 50. + * @returns {number} + */ + getNumSpokes() { + return this._numSpokes; + } + + /** + * Sets the number of spokes to place. + * @param {number} numSpokes + */ + setNumSpokes(numSpokes) { + this._numSpokes = numSpokes; + this._meshDirty = true; + } + + /** + * Gets the power that each concentric circle is raised to compared to the next inner circle. Defaults to 1. + * @returns {number} + */ + getRadialPower() { + return this._radialPower; + } + + /** + * Sets the power that each concentric circle is raised to compared to the next inner circle. + * @param {number} radialPower + */ + setRadialPower(radialPower) { + this._radialPower = radialPower; + this._meshDirty = true; + } + + /** + * Ignores the distance when determining whether it should show the grid or not. Defaults to false. + * @param {boolean} ignoreDistance + */ + setIgnoreDistance(ignoreDistance) { + this._ignoreDistance = ignoreDistance; + } + + /** + * Prepare the component for rendering. + * @param {Pioneer.CameraComponent} camera + * @override + * @package + */ + __prepareForRender(camera) { + if (this._meshDirty) { + this._updateMesh(); + } + + if (!this._ignoreDistance) { + const normalizedSizeOfEntity = this.getEntity().getNormalSpaceExtentsRadius(camera); + const alphaMultiplier = (0.02 - normalizedSizeOfEntity) / 0.02; + this._lineMesh.setAlphaMultiplier(alphaMultiplier); + } + + this._lineMesh.prepareForRender(camera); + + // Set the orientation to the entity's orientation. + for (let i = 0, l = this.getThreeJsObjects().length; i < l; i++) { + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[i], this.getEntity()); + + // Set the Three.js object position the entity's camera-space position. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[i], this.getEntity(), camera); + } + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + // Create the line mesh. + this._lineMesh = new pioneer__WEBPACK_IMPORTED_MODULE_0__.LineMesh(this); + + // Update the vertices. + this._updateMesh(); + + // Set the scale. + this._lineMesh.setScale(this._size); + + // Resolve immediately. + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + this._lineMesh = null; + } + + /** + * Updates the mesh. + * @private + */ + _updateMesh() { + // Make the concentric circles. + const positions = []; + for (let i = 1; i <= this._numCircles; i++) { + const circleSize = this._radialPower !== 1 ? Math.pow(this._radialPower, i - this._numCircles) : (i / this._numCircles); + const numOfPointsOnCircle = 50; + for (let j = 0; j < numOfPointsOnCircle; j++) { + const angle1 = j / numOfPointsOnCircle * pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + const angle2 = ((j + 1) % numOfPointsOnCircle) / numOfPointsOnCircle * pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + positions.push(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(circleSize * Math.cos(angle1), circleSize * Math.sin(angle1), 0)); + positions.push(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(circleSize * Math.cos(angle2), circleSize * Math.sin(angle2), 0)); + } + } + for (let i = 0; i < this._numSpokes; i++) { + const angle1 = i / this._numSpokes * pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + positions.push(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero); + positions.push(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(Math.cos(angle1), Math.sin(angle1), 0)); + } + const colors = []; + for (let i = 0, l = positions.length; i < l; i++) { + colors.push(this._color); + } + this._lineMesh.setPositions(positions); + this._lineMesh.setColors(colors); + this._lineMesh.setWidths(this._lineWidth); + this._meshDirty = false; + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/components/orbit_line_component.js": +/*!*****************************************************************!*\ + !*** ../pioneer/scripts/src/components/orbit_line_component.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "OrbitLineComponent": function() { return /* binding */ OrbitLineComponent; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * The Orbit Line component. + * */ +class OrbitLineComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The color of the line. + * @type {Pioneer.Color} + * @private + */ + this._color = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1); + this._color.freeze(); + + /** + * The alpha fade on the far side of the orbit. + * @type {number} + * @private + */ + this._farSideAlphaFade = 1; + + /** + * The width of the line. + * @type {number} + * @private + */ + this._lineWidth = 5; + + /** + * The glow width for the lines. + * @type {number} + * @private + */ + this._glowWidth = 0; + + /** + * The LineMesh object used to do the drawing. + * @type {Pioneer.LineMesh} + * @private + */ + this._lineMesh = null; + + /** + * The positions for the line mesh. + * @type {Pioneer.Vector3[]} + * @private + */ + this._positions = []; + + /** + * The colors for the line mesh. + * @type {Pioneer.Color[]} + * @private + */ + this._colors = []; + + /** + * The widths for the line mesh. + * @type {number[]} + * @private + */ + this._widths = []; + + /** + * An array that determines the pixel-space radii at which it has 0 and 1 alpha. + * @type {[number, number]} + * @private + */ + this._pixelSpaceRadiiAlphaFade = [5, 1]; + + this.__setRadius(Number.POSITIVE_INFINITY); + } + + /** + * Gets the color of the grid. Defaults to white. + * @returns {Pioneer.Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the color of the grid. Defaults to white. + * @param {Pioneer.Color} color + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + if (this._lineMesh !== null) { + for (let i = 0, l = this._colors.length; i < l; i++) { + this._colors[i].copy(this._color); + } + this._lineMesh.setColors(this._colors); + } + } + + /** + * Gets the alpha fade on the far side of the orbit. + * @returns {number} + */ + getFarSideAlphaFade() { + return this._farSideAlphaFade; + } + + /** + * Sets the alpha fade on the far side of the orbit. Defaults to 1. + * @param {number} alphaFade + */ + setFarSideAlphaFade(alphaFade) { + this._farSideAlphaFade = alphaFade; + } + + /** + * Gets the width of the line. + * @returns {number} + */ + getLineWidth() { + return this._lineWidth; + } + + /** + * Sets the width of the line. Defaults to 5. + * @param {number} lineWidth + */ + setLineWidth(lineWidth) { + this._lineWidth = lineWidth; + if (this._lineMesh !== null) { + for (let i = 0, l = this._widths.length; i < l; i++) { + this._widths[i] = this._lineWidth; + } + this._lineMesh.setWidths(this._widths); + } + } + + /** + * Sets the glow for the lines. + * @param {number} glowWidth + */ + setGlowWidth(glowWidth) { + this._glowWidth = glowWidth; + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0], 'glowWidth', this._glowWidth); + } + + /** + * Sets values that determine the pixel-space radii at which it has 0 and 1 alpha. Defaults to 5, 1. + * @param {number} radiusFor0Alpha + * @param {number} radiusFor1Alpha + */ + setPixelSpaceRadiiAlphaFade(radiusFor0Alpha, radiusFor1Alpha) { + this._pixelSpaceRadiiAlphaFade[0] = radiusFor0Alpha; + this._pixelSpaceRadiiAlphaFade[1] = radiusFor1Alpha; + } + + /** + * Prepare the component for rendering. + * @param {Pioneer.CameraComponent} camera + * @override + * @package + */ + __prepareForRender(camera) { + + // Update the mesh. + this._updateMesh(); + + // Update the pixel-space radius alpha fade. + const pixelSpaceRadius = this.getEntity().getPixelSpaceExtentsRadius(camera); + if (!isNaN(pixelSpaceRadius)) { + const fadeU = (pixelSpaceRadius - this._pixelSpaceRadiiAlphaFade[0]) / (this._pixelSpaceRadiiAlphaFade[1] - this._pixelSpaceRadiiAlphaFade[0]); + this._lineMesh.setAlphaMultiplier(pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(0, 1, pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(fadeU))); + } + else { + this._lineMesh.setAlphaMultiplier(1); + } + + // Set the Three.js object position the entity's camera-space position. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects(), this.getEntity(), camera); + + // Call the line mesh prepare for render. + this._lineMesh.prepareForRender(camera); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + this._lineMesh = new pioneer__WEBPACK_IMPORTED_MODULE_0__.LineMesh(this); + + // Setup the arrays for the line mesh. + for (let i = 0, l = 360 * 2; i < l; i++) { + this._positions.push(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3()); + this._colors.push(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color()); + this._colors[i].copy(this._color); + this._widths.push(this._lineWidth); + } + + // Set the widths and colors for the line mesh. + this._lineMesh.setColors(this._colors); + this._lineMesh.setWidths(this._widths); + this._lineMesh.setGlowWidth(this._glowWidth); + + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + // Clean up the arrays for the line mesh. + this._positions = []; + this._colors = []; + this._widths = []; + + // Clean up the objects and line mesh. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + this._lineMesh = null; + } + + /** + * Updates the mesh positions and colors. + * @private + */ + _updateMesh() { + // Find the GM from the last covered dynamo orb controller. + const entity = this.getEntity(); + const currentTime = entity.getScene().getEngine().getTime(); + let gm = 0; + for (let i = entity.getNumControllers() - 1; i >= 0; i--) { + const controller = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.DynamoController, i); + if (controller !== null && controller.getCoverage().contains(currentTime)) { + if (controller.getPointType() === 'orb') { + gm = controller.getHeaderValue('gravitationalParameter1') + controller.getHeaderValue('gravitationalParameter2'); + break; + } + } + } + + // Get the orbital elements from the current position and velocity. + orbitalElements.setFromPositionAndVelocity(entity.getPosition(), entity.getVelocity(), currentTime, gm); + + // Get the true and eccentric anomaly of the current position, used for the alpha fade. + const entityPosition = entity.getPosition(); + const trueAnomalyAtCurrentTime = orbitalElements.getTrueAnomalyFromPosition(entityPosition); + const eccentricAnomalyAtCurrentTime = orbitalElements.getEccentricAnomalyFromTrueAnomaly(trueAnomalyAtCurrentTime); + + // Calculate the new positions and colors. + let lastMeanAnomalyNaN = false; + for (let angle = 0; angle < 360; angle += 1) { + // The indices for the vertices. + const index0 = angle * 2; + const index1 = (angle * 2 - 1 + this._positions.length) % this._positions.length; + + // Calculate the position given the angle, which is the true anomaly. + let eccentricAnomaly = orbitalElements.getEccentricAnomalyFromTrueAnomaly(pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(angle - 180)); + const eccentricAnomalyNext = orbitalElements.getEccentricAnomalyFromTrueAnomaly(pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(angle + 1 - 180)); + if ((eccentricAnomaly < eccentricAnomalyAtCurrentTime && eccentricAnomalyAtCurrentTime < eccentricAnomalyNext) + || (eccentricAnomalyNext < eccentricAnomalyAtCurrentTime && eccentricAnomalyAtCurrentTime < eccentricAnomaly)) { + eccentricAnomaly = eccentricAnomalyAtCurrentTime; + } + const meanAnomaly = orbitalElements.getMeanAnomalyFromEccentricAnomaly(eccentricAnomaly); + const time = orbitalElements.epoch + (meanAnomaly - orbitalElements.meanAnomalyAtEpoch) / orbitalElements.meanAngularMotion; + const position = this._positions[index0]; + orbitalElements.project(position, velocity, time); + position.sub(position, entityPosition); + this._positions[index1].copy(position); + + // If the mean anomaly is NaN, disconnect the segments around it. + if (isNaN(meanAnomaly)) { + lastMeanAnomalyNaN = true; + const index2 = (index0 + 1) % this._positions.length; + const index3 = (index1 - 1 + this._positions.length) % this._positions.length; + this._positions[index0].set(0, 0, 0); + this._positions[index1].set(0, 0, 0); + this._positions[index2].set(0, 0, 0); + this._positions[index3].set(0, 0, 0); + this._colors[index0].a = 0; + this._colors[index1].a = 0; + this._colors[index2].a = 0; + this._colors[index3].a = 0; + continue; + } + + // Get the alpha fade based on the current true anomaly of the entity. + let alphaFadeU = 0.0; + alphaFadeU = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.angle(eccentricAnomaly, eccentricAnomalyAtCurrentTime) / Math.PI; + alphaFadeU = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(alphaFadeU); + const alphaFade = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(1.0, this._farSideAlphaFade, alphaFadeU); + this._colors[index0].mult(this._color, alphaFade); + if (!lastMeanAnomalyNaN) { + this._colors[index1].mult(this._color, alphaFade); + } + + // It got here, so mark the last mean anomaly as valid. + lastMeanAnomalyNaN = false; + } + + // If we're at the end of the loop and the eccentricity is para/hyperbolic, disconnect the loop. + if (orbitalElements.eccentricity >= 1) { + this._positions[this._positions.length - 2].copy(this._positions[this._positions.length - 3]); + this._positions[this._positions.length - 1].copy(this._positions[this._positions.length - 3]); + this._colors[this._colors.length - 2].a = 0; + this._colors[this._colors.length - 1].a = 0; + } + + // Set the line mesh positions. + this._lineMesh.setPositions(this._positions); + this._lineMesh.setColors(this._colors); + } +} + +const orbitalElements = new pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements(); +const velocity = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + +/***/ }), + +/***/ "../pioneer/scripts/src/components/shadow_cone_component.js": +/*!******************************************************************!*\ + !*** ../pioneer/scripts/src/components/shadow_cone_component.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ShadowConeComponent": function() { return /* binding */ ShadowConeComponent; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * The Shadow Cone component. + * */ +class ShadowConeComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The color of the grid. + * @type {Pioneer.Color} + * @private + */ + this._color = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1); + this._color.freeze(); + + /** + * The other entity to use as the source of the cone. + * @type {Pioneer.EntityRef} + * @private + */ + this._sourceEntity = new pioneer__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + + /** + * The shadow type to use the umbra or penumbra. + * @type {'umbra' | 'penumbra'} + * @private + */ + this._shadowType = 'umbra'; + + /** + * The target entity for the shadow to extend to. + * @type {Pioneer.EntityRef} + * @private + */ + this._targetEntity = new pioneer__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + + /** + * The distance interval over which the component is visible. + * @type {Pioneer.Interval} + * @private + */ + this._visibleDistanceInterval = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(0, Number.POSITIVE_INFINITY); + this._visibleDistanceInterval.freeze(); + + /** + * The alpha multiplier determined by fading. + * @type {number} + * @private + */ + this._alphaMultiplier = 1.0; + + /** + * The number of vertices on the circle. + * @type {number} + * @private + */ + this._numberOfCirclePoints = 20; + + this.__setRadius(Number.POSITIVE_INFINITY); + } + + /** + * Gets the color of the grid. Defaults to white. + * @returns {Pioneer.Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the color of the cone. Defaults to white. + * @param {Pioneer.Color} color + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._color, this._alphaMultiplier); + } + + /** + * Gets the other entity to use as the source of the cone. + * @returns {string} + */ + getSourceEntity() { + return this._sourceEntity.getName(); + } + + /** + * Sets the other entity to use as the source of the cone. + * @param {string} name + */ + setSourceEntity(name) { + this._sourceEntity.setName(name); + } + + /** + * Gets the target entity for the shadow to extend to. + * @returns {string} + */ + getTargetEntity() { + return this._targetEntity.getName(); + } + + /** + * Sets the target entity for the shadow to extend to. + * @param {string} name + */ + setTargetEntity(name) { + this._targetEntity.setName(name); + } + + /** + * Gets the shadow type to use the umbra or penumbra. Defaults to 'umbra'. + * @returns {'umbra' | 'penumbra'} + */ + getShadowType() { + return this._shadowType; + } + + /** + * Sets the shadow type to use the umbra or penumbra. Defaults to 'umbra'. + * @param {'umbra' | 'penumbra'} shadowType + */ + setShadowType(shadowType) { + this._shadowType = shadowType; + this.resetResources(); + } + + /** + * Gets the distance interval over which the component is visible. Defaults to [0, infinity). + * @returns {Pioneer.Interval} + */ + getVisibleDistanceInterval() { + return this._visibleDistanceInterval; + } + + /** + * Sets the distance interval over which the component is visible. Defaults to [0, infinity). + * @param {Pioneer.Interval} distanceInterval + */ + setVisibleDistanceInterval(distanceInterval) { + this._visibleDistanceInterval.thaw(); + this._visibleDistanceInterval.copy(distanceInterval); + this._visibleDistanceInterval.freeze(); + } + + /** + * Prepare the component for rendering. + * @param {Pioneer.CameraComponent} camera + * @override + * @package + */ + __prepareForRender(camera) { + + // Update the mesh to reflect the cone. + this._updateMesh(); + + // Set the Three.js object position the entity's camera-space position. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + + // Make the cone fade if the camera is outside a visible distance interval. + const cameraSpacePosition = this.getEntity().getCameraSpacePosition(camera); + const distanceToObject = cameraSpacePosition.magnitude(); + const diffFadeDistance = (this._visibleDistanceInterval.max - this._visibleDistanceInterval.min) * 0.5; + const minFadeDistance = Math.min(this._visibleDistanceInterval.min * 0.5, diffFadeDistance); + const maxFadeDistance = Math.min(this._visibleDistanceInterval.max * 0.5, diffFadeDistance); + if (distanceToObject < this._visibleDistanceInterval.min + minFadeDistance) { + this._alphaMultiplier = Math.max(0, (distanceToObject - this._visibleDistanceInterval.min) / minFadeDistance); + } + else if (distanceToObject > this._visibleDistanceInterval.max - maxFadeDistance) { + this._alphaMultiplier = Math.max(0, (this._visibleDistanceInterval.max - distanceToObject) / maxFadeDistance); + } + else { + this._alphaMultiplier = 1.0; + } + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._color, this._alphaMultiplier); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + + // Create the material. + const material = this.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('basic_alpha'); + this.getThreeJsMaterials().push(material); + + // Set the uniforms. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(material, 'color', this._color, this._alphaMultiplier); + + // Create the mesh object. + const object = pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this, material, [{ name: 'position', dimensions: 3 }], false); + this.getThreeJsObjects().push(object); + + // Create the mesh geometry. + this._createMesh(); + + // Return it as loaded. + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + } + + /** + * Creates the mesh. + * @private + */ + _createMesh() { + + // The arrays. + const positions = new Float32Array(this._numberOfCirclePoints * 2 * 3); + const indices = new Uint16Array(this._numberOfCirclePoints * 6); + + // Go around the circle and set the indices. + for (let i = 0; i < this._numberOfCirclePoints; i++) { + const iPlus1 = (i + 1) % this._numberOfCirclePoints; + indices[i * 6 + 0] = i; + indices[i * 6 + 1] = iPlus1; + indices[i * 6 + 2] = iPlus1 + this._numberOfCirclePoints; + indices[i * 6 + 3] = iPlus1 + this._numberOfCirclePoints; + indices[i * 6 + 4] = i + this._numberOfCirclePoints; + indices[i * 6 + 5] = i; + } + + // Apply the positions and indices. + const geometry = /** @type {Pioneer.THREE.Mesh} */(this.getThreeJsObjects()[0]).geometry; + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(geometry, 'position', positions); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(geometry, indices); + } + + /** + * Updates the mesh positions and colors. + * @private + */ + _updateMesh() { + + // Get the source entity, and do nothing if not found. + const sourceEntity = this._sourceEntity.get(); + if (sourceEntity === null) { + return; + } + + // Get the target entity (it may be null). + const targetEntity = this._targetEntity.get(); + + // Get the source and this radius. + const sourceRadius = sourceEntity.getExtentsRadius(); + const thisRadius = this.getEntity().getExtentsRadius(); + + // Get the distance and axis from the sourceEntity to this entity. + const axis = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this.getEntity().getPositionRelativeToEntity(axis, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, sourceEntity); + const distanceToSource = axis.magnitude(); + axis.normalize(axis); + if (axis.isNaN()) { + return; + } + + // Get the distance between this entity and the target entity. + let distanceToTarget = thisRadius * 10; + if (targetEntity !== null) { + const targetAxis = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + targetEntity.getPositionRelativeToEntity(targetAxis, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, this.getEntity()); + distanceToTarget = targetAxis.magnitude(); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(targetAxis); + } + + // Get the attribute array to modify. + const attribute = /** @type {Pioneer.THREE.Mesh} */(this.getThreeJsObjects()[0]).geometry.getAttribute('position'); + const array = attribute.array; + + // Calculate the different offsets and radii of the cone. + let radius0; + let radius1; + let offset0; + let offset1; + if (this._shadowType === 'umbra') { + const cosAngleOfTangent = (sourceRadius - thisRadius) / distanceToSource; + const sinAngleOfTangent = Math.sqrt(1 - cosAngleOfTangent * cosAngleOfTangent); + const offsetFocus = thisRadius / cosAngleOfTangent; + const radiusFactor = cosAngleOfTangent / sinAngleOfTangent; + offset0 = thisRadius * cosAngleOfTangent; + offset1 = Math.min(distanceToTarget, offsetFocus); + radius0 = radiusFactor * (offsetFocus - offset0); + radius1 = radiusFactor * (offsetFocus - offset1); + } + else { // 'penumbra' + const cosAngleOfTangent = (sourceRadius + thisRadius) / distanceToSource; + const sinAngleOfTangent = Math.sqrt(1 - cosAngleOfTangent * cosAngleOfTangent); + const offsetFocus = -thisRadius / cosAngleOfTangent; + const radiusFactor = cosAngleOfTangent / sinAngleOfTangent; + offset0 = -thisRadius * cosAngleOfTangent; + offset1 = distanceToTarget; + radius0 = -radiusFactor * (offsetFocus - offset0); + radius1 = -radiusFactor * (offsetFocus - offset1); + } + + // If this entity has a spheroid, it might cause clipping issues with the cone, so increase the radius0 by a small amount. + if (this.getEntity().getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent) !== null) { + radius0 *= 1.02; + } + + // Go around the circle. + for (let i = 0; i < this._numberOfCirclePoints; i++) { + const angleI = i / this._numberOfCirclePoints * pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + const xI = Math.cos(angleI); + const yI = Math.sin(angleI); + + // Set the position. + array[i * 3 + 0] = radius0 * xI; + array[i * 3 + 1] = radius0 * yI; + array[i * 3 + 2] = offset0; + array[(i + this._numberOfCirclePoints) * 3 + 0] = radius1 * xI; + array[(i + this._numberOfCirclePoints) * 3 + 1] = radius1 * yI; + array[(i + this._numberOfCirclePoints) * 3 + 2] = offset1; + } + + // Mark that the attribute changed. + attribute.needsUpdate = true; + + // Set the Three.js object orientation to have the z-axis be the axis. + const orientation = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const rotation = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const forward = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + orientation.copyFromThreeJs(this.getThreeJsObjects()[0].quaternion); + orientation.getAxis(forward, 2); + rotation.setFromVectorFromTo(forward, axis); + orientation.mult(rotation, orientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(this.getThreeJsObjects()[0], orientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(forward); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(axis); + + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/components/torus_component.js": +/*!************************************************************!*\ + !*** ../pioneer/scripts/src/components/torus_component.js ***! + \************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "TorusComponent": function() { return /* binding */ TorusComponent; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * A component that renders a colored torus aligned in the x-y plane with an inner and outer radius. + */ +class TorusComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The color. + * @type {Pioneer.Color} + * @private + */ + this._color = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 1); + this._color.freeze(); + + /** + * The inner radius. + * @type {number} + * @private + */ + this._innerRadius = 1; + + /** + * The outer radius. + * @type {number} + * @private + */ + this._outerRadius = 10; + + /** + * The distance interval over which the component is visible. + * @type {Pioneer.Interval} + * @private + */ + this._visibleDistanceInterval = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(0, Number.POSITIVE_INFINITY); + this._visibleDistanceInterval.freeze(); + + /** + * The alpha multiplier determined by fading. + * @type {number} + * @private + */ + this._alphaMultiplier = 1.0; + + this.__setRadius(this._outerRadius); + this.__setUsesEntityOrientation(true); + } + + /** + * Gets the color of the annulus. Defaults to white. + * @returns {Pioneer.Color} + */ + getColor() { + return this._color; + } + + /** + * Sets the color of the annulus. The alpha value should be provided at the component's maximum visibility. + * @param {Pioneer.Color} color + */ + setColor(color) { + this._color.thaw(); + this._color.copy(color); + this._color.freeze(); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._color, this._alphaMultiplier); + } + + /** + * Gets the inner radius. + * @returns {number} + */ + getInnerRadius() { + return this._innerRadius; + } + + /** + * Sets the inner radius. Defaults to 1. + * @param {number} size + */ + setInnerRadius(size) { + this._innerRadius = size; + this.resetResources(); + } + + /** + * Gets the outer radius. + * @returns {number} + */ + getOuterRadius() { + return this._outerRadius; + } + + /** + * Sets the outer radius. Defaults to 10. + * @param {number} radius + */ + setOuterRadius(radius) { + this._outerRadius = radius; + this.__setRadius(this._outerRadius); + this.resetResources(); + } + + /** + * Gets the distance interval over which the component is visible. + * @returns {Pioneer.Interval} + */ + getVisibleDistanceInterval() { + return this._visibleDistanceInterval; + } + + /** + * Sets the distance interval over which the component is visible. Defaults to [0, infinity). + * @param {Pioneer.Interval} distanceInterval + */ + setVisibleDistanceInterval(distanceInterval) { + this._visibleDistanceInterval.thaw(); + this._visibleDistanceInterval.copy(distanceInterval); + this._visibleDistanceInterval.freeze(); + } + + /** + * Prepare the component for rendering. + * @param {Pioneer.CameraComponent} camera + * @override + * @package + */ + __prepareForRender(camera) { + // Set the orientation to the entity's orientation. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0], this.getEntity()); + + // Set the Three.js object position the entity's camera-space position. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0], this.getEntity(), camera); + + // Make the torus fade if the camera is outside a visible distance interval. + const cameraSpacePosition = this.getEntity().getCameraSpacePosition(camera); + const distanceToObject = cameraSpacePosition.magnitude(); + const diffFadeDistance = (this._visibleDistanceInterval.max - this._visibleDistanceInterval.min) * 0.5; + const minFadeDistance = Math.min(this._visibleDistanceInterval.min * 0.5, diffFadeDistance); + const maxFadeDistance = Math.min(this._visibleDistanceInterval.max * 0.5, diffFadeDistance); + if (distanceToObject < this._visibleDistanceInterval.min + minFadeDistance) { + this._alphaMultiplier = Math.max(0, (distanceToObject - this._visibleDistanceInterval.min) / minFadeDistance); + } + else if (distanceToObject > this._visibleDistanceInterval.max - maxFadeDistance) { + this._alphaMultiplier = Math.max(0, (this._visibleDistanceInterval.max - distanceToObject) / maxFadeDistance); + } + else { + this._alphaMultiplier = 1.0; + } + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0], 'color', this._color, this._alphaMultiplier); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + __loadResources() { + // Create the material. + const material = this.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('basic_alpha'); + this.getThreeJsMaterials().push(material); + + // Set the uniforms. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(material, 'color', this._color, this._alphaMultiplier); + + // Create the mesh object. + const object = pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this, material, [{ name: 'position', dimensions: 3 }], false); + this.getThreeJsObjects().push(object); + + // Create the mesh geometry. + this._createMesh(); + + // Return it as loaded. + return Promise.resolve(); + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this); + } + + /** + * Creates the mesh. + * @private + */ + _createMesh() { + // Constants to use for a good number of segments. + const numberOfCirclePoints = 100; + const numberOfTorusPoints = 20; + + // The arrays. + const positions = new Float32Array(numberOfCirclePoints * numberOfTorusPoints * 3); + const indices = new Uint16Array(numberOfCirclePoints * numberOfTorusPoints * 6); + + // Saved variables for quicker calculations. + const middleRadius = (this._outerRadius + this._innerRadius) / 2; + const diffRadius = (this._outerRadius - this._innerRadius) / 2; + + // Go around the main circle. + for (let i = 0; i < numberOfCirclePoints; i++) { + const angleI = i / numberOfCirclePoints * pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + const xI = Math.cos(angleI); + const yI = Math.sin(angleI); + + // Go around a circle segment of the main circle. + for (let j = 0; j < numberOfTorusPoints; j++) { + const angleJ = j / numberOfTorusPoints * pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi; + const rJ = Math.cos(angleJ); + const zJ = Math.sin(angleJ); + + // Set the position. + const positionsIndex = (i * numberOfTorusPoints + j) * 3; + positions[positionsIndex + 0] = xI * (middleRadius + diffRadius * rJ); + positions[positionsIndex + 1] = yI * (middleRadius + diffRadius * rJ); + positions[positionsIndex + 2] = diffRadius * zJ; + + // Set the indices of the quad. + const indicesIndex = (i * numberOfTorusPoints + j) * 6; + const iPlus1 = (i + 1) % numberOfCirclePoints; + const jPlus1 = (j + 1) % numberOfTorusPoints; + indices[indicesIndex + 0] = i * numberOfTorusPoints + j; + indices[indicesIndex + 1] = iPlus1 * numberOfTorusPoints + j; + indices[indicesIndex + 2] = i * numberOfTorusPoints + jPlus1; + indices[indicesIndex + 3] = iPlus1 * numberOfTorusPoints + jPlus1; + indices[indicesIndex + 4] = i * numberOfTorusPoints + jPlus1; + indices[indicesIndex + 5] = iPlus1 * numberOfTorusPoints + j; + } + } + + // Apply the positions and indices. + const geometry = /** @type {Pioneer.THREE.Mesh} */(this.getThreeJsObjects()[0]).geometry; + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(geometry, 'position', positions); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(geometry, indices); + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/components/wmts.js": +/*!*************************************************!*\ + !*** ../pioneer/scripts/src/components/wmts.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Capabilities": function() { return /* binding */ Capabilities; }, +/* harmony export */ "Layer": function() { return /* binding */ Layer; }, +/* harmony export */ "TileMatrixSet": function() { return /* binding */ TileMatrixSet; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var proj4__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! proj4 */ "../pioneer/scripts/node_modules/proj4/lib/index.js"); +/** @module pioneer-scripts */ + + + +/** + * The capabilities XML file. + * @private + */ +class Capabilities { + /** + * The constructor. + * @param {string} endPoint + * @param {Pioneer.Engine} engine + */ + constructor(endPoint, engine) { + /** + * The end point for the WMTS protocol. + * @type {string} + * @private + */ + this._endPoint = endPoint; + + /** + * The XML content of the capabilities. + * @type {Document} + * @private + */ + this._capabilitiesXML = null; + + /** + * The list of layers as a map from titles to identifiers. + * @type {Map} + * @private + */ + this._layers = new Map(); + + /** + * A promise that resolves when the capabilities is ready to be used. + * @type {Promise} + * @private + */ + this._readyPromise = null; + + // Get the capabilities. + this._readyPromise = engine.getDownloader().download(this._endPoint + '/1.0.0/WMTSCapabilities.xml', false).then((download) => { + if (typeof download.content === 'string') { + this._capabilitiesXML = new DOMParser().parseFromString(download.content, 'application/xml'); + } + + // Populate the layers. + if (this._capabilitiesXML !== null) { + const layerElems = this._capabilitiesXML.querySelectorAll('Contents > Layer'); + for (const layerElem of layerElems) { + const title = layerElem.querySelector('*|Title').textContent; + const identifier = layerElem.querySelector('*|Identifier').textContent; + this._layers.set(title, identifier); + } + } + }); + } + + /** + * Gets the promise that resolves when it is ready to be used. + * @returns {Promise} + */ + get readyPromise() { + return this._readyPromise; + } + + /** + * Gets the end point. + * @returns {string} + */ + get endPoint() { + return this._endPoint; + } + + /** + * Gets the list of layers as a map from titles to identifiers. + * @returns {Map} + */ + get layers() { + return this._layers; + } + + /** + * Gets a layer from its identifier. Returns null if the identifier is invalid. + * @param {string} identifier + * @returns {Layer} + */ + getLayer(identifier) { + let layer = null; + if (this._capabilitiesXML !== null) { + const layerElems = this._capabilitiesXML.querySelectorAll('Contents > Layer'); + for (const layerElem of layerElems) { + const layerIdentifier = layerElem.querySelector('*|Identifier').textContent; + if (identifier === layerIdentifier) { + layer = new Layer(layerElem, this._endPoint + '/1.0.0'); + } + } + } + return layer; + } + + /** + * Gets a tile matrix set from its identifier. Returns null if the identifier is invalid. + * @param {string} identifier + * @returns {TileMatrixSet} + */ + getTileMatrixSet(identifier) { + let tileMatrixSet = null; + if (this._capabilitiesXML !== null) { + const tileMatrixSetElems = this._capabilitiesXML.querySelectorAll('Contents > TileMatrixSet'); + for (const tileMatrixSetElem of tileMatrixSetElems) { + const tileMatrixSetIdentifier = tileMatrixSetElem.querySelector('*|Identifier').textContent; + if (identifier === tileMatrixSetIdentifier) { + tileMatrixSet = new TileMatrixSet(tileMatrixSetElem); + } + } + } + return tileMatrixSet; + } +} + +/** + * A capabilities layer. + * @internal + */ +class Layer { + /** + * Constructor. + * @param {Element} elem + * @param {string} baseUrl + */ + constructor(elem, baseUrl) { + /** + * The base URL + * @type {string} + * @private + */ + this._baseUrl = baseUrl; + + /** + * The title. + * @type {string} + * @private + */ + this._title = elem.querySelector('*|Title').textContent; + + /** + * The WMTS layer identifier. + * @type {string} + * @private + */ + this._identifier = elem.querySelector('*|Identifier').textContent; + + /** + * The mapping of styles from title to identifier. + * @type {Map} + * @private + */ + this._styles = new Map(); + + /** + * The style that is the default. + * @type {string} + * @private + */ + this._defaultStyle = ''; + + /** + * The bounding box of the layer. + * @type {Pioneer.Rect} + * @private + */ + this._boundingBox = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Rect(); + + /** + * The possible extra dimensions of the layer, along with its default. + * @type {Map} + * @private + */ + this._dimensions = new Map(); + + /** + * The tile matrix sets. + * @type {Set} + * @private + */ + this._tileMatrixSets = new Set(); + + /** + * The WMTS layer url. + * @type {string} + * @private + */ + this._url = ''; + + // Get the styles. + const styleElems = elem.querySelectorAll('Style'); + for (const styleElem of styleElems) { + const title = styleElem.querySelector('*|Title').textContent; + const identifier = styleElem.querySelector('*|Identifier').textContent; + this._styles.set(title, identifier); + + if (styleElem.getAttribute('isDefault') === 'true') { + this._defaultStyle = identifier; + } + } + + // Get the bounding box and crs. + let boundingBoxElem = elem.querySelector('*|BoundingBox'); + if (boundingBoxElem === null) { + boundingBoxElem = elem.querySelector('*|WGS84BoundingBox'); + } + if (boundingBoxElem === null) { + throw new Error('Layer "' + this._identifier + '" missing a BoundingBox or a WGS84BoundingBox tag.'); + } + const lowerCornerArray = boundingBoxElem.querySelector('*|LowerCorner').textContent.split(' '); + const upperCornerArray = boundingBoxElem.querySelector('*|UpperCorner').textContent.split(' '); + this._boundingBox.origin.set(Number.parseFloat(lowerCornerArray[0]), Number.parseFloat(lowerCornerArray[1])); + this._boundingBox.size.set(Number.parseFloat(upperCornerArray[0]) - this._boundingBox.origin.x, Number.parseFloat(upperCornerArray[1]) - this._boundingBox.origin.y); + + // Get the extra dimensions of the layer. + const dimensionElems = elem.querySelectorAll('Dimension'); + for (const dimensionElem of dimensionElems) { + const identifier = dimensionElem.querySelector('*|Identifier').textContent; + const defaultValue = dimensionElem.querySelector('Default').textContent; + this._dimensions.set(identifier, defaultValue); + } + + // Get the tile matrix sets. + const tileMatrixSetLinkElems = elem.querySelectorAll('TileMatrixSetLink'); + for (const tileMatrixSetLinkElem of tileMatrixSetLinkElems) { + const tileMatrixSet = tileMatrixSetLinkElem.querySelector('TileMatrixSet').textContent; + this._tileMatrixSets.add(tileMatrixSet); + } + + // Get the url. + const resourceURLElem = elem.querySelector('ResourceURL'); + this._url = resourceURLElem.getAttribute('template'); + // If it is relative, prepend the base url. + if (!/^(?:[a-z]+:)?\/\//i.test(this._url)) { + this._url = this._baseUrl + this._url; + } + } + + /** + * Gets the title. + * @returns {string} + */ + get title() { + return this._title; + } + + /** + * Gets the identifiers. + * @returns {string} + */ + get identifier() { + return this._identifier; + } + + /** + * Gets the mapping of style titles to identifiers. + * @returns {Map} + */ + get styles() { + return this._styles; + } + + /** + * Gets the default style. + * @returns {string} + */ + get defaultStyle() { + return this._defaultStyle; + } + + /** + * Gets the bounding box. + * @returns {Pioneer.Rect} + */ + get boundingBox() { + return this._boundingBox; + } + + /** + * Gets the dimension options as a mapping of the identifier to its default. + * @return {Map} + */ + get dimensions() { + return this._dimensions; + } + + /** + * Gets the tile matrix sets associated with this layer. + * @return {Set} + */ + get tileMatrixSets() { + return this._tileMatrixSets; + } + + /** + * Gets the url template for the layer. + * @returns {string} + */ + get url() { + return this._url; + } +} + +/** + * A tile matrix set. + * @internal + */ +class TileMatrixSet { + /** + * Constructor. + * @param {Element} elem + */ + constructor(elem) { + /** + * The WMTS layer identifier. + * @type {string} + * @private + */ + this._identifier = elem.querySelector('*|Identifier').textContent; + + /** + * The CRS of the tile matrix set. + * @type {string} + * @private + */ + this._crs = elem.querySelector('*|SupportedCRS').textContent; + + /** + * The bounding box of the tile matrix set. + * @type {Pioneer.Rect} + * @private + */ + this._boundingBox = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Rect(); + + /** + * The number of levels that the matrix has. + * @type {Pioneer.Vector2[]} + * @private + */ + this._numTiles = []; + + /** + * A promise that resolves when it is ready to be used. + * @type {Promise} + * @private + */ + this._readyPromise = null; + + // Check if it has proper power-of-two levels and set the number of tiles for each tile matrix. + let scalePrev; + let level = 0; + for (const node of elem.querySelectorAll('TileMatrix')) { + const scaleElem = node.querySelector('ScaleDenominator'); + if (!scaleElem) { + throw new Error('ScaleDenominator tag not found for TileMatrix ' + level + '.'); + } + const scale = parseFloat(scaleElem.innerHTML); + if (scalePrev !== undefined && Math.abs(scale * 2 - scalePrev) / scale > 0.01) { + throw new Error('ScaleDenominator for TileMatrix ' + level + ' must be half of the next higher level, but is not.'); + } + scalePrev = scale; + this._numTiles[level] = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2( + parseFloat(node.querySelector('MatrixWidth').innerHTML), + parseFloat(node.querySelector('MatrixHeight').innerHTML)); + level += 1; + } + + // Get the number of levels from the iteration above + this._numLevels = level; + + // Calculate the bounding box. + // It uses the ScaleDenominator, TileWidth/Height, and MatrixWidth/Height of level 0 + // to calculate the bounding box size. Since the calculation yields a number in + // km / matrix and we need it in CRS units, we have to get the CRS unitsPerMeter value + // in order to get the bounding box size in CRS units. + const tileMatrix0Elem = elem.querySelector('TileMatrix'); + const scaleDenominator = Number.parseFloat(tileMatrix0Elem.querySelector('ScaleDenominator').textContent); + const pixelsPerTile = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(Number.parseFloat(tileMatrix0Elem.querySelector('TileWidth').textContent), Number.parseFloat(tileMatrix0Elem.querySelector('TileHeight').textContent)); + const kmPerPixel = scaleDenominator * 0.28e-6; + const kmPerTile = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(kmPerPixel * pixelsPerTile.x, kmPerPixel * pixelsPerTile.y); + const kmPerMatrix = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(kmPerTile.x * this._numTiles[0].x, kmPerTile.y * this._numTiles[0].y); + // Get the bounding box origin. + const topLeftCornerArray = tileMatrix0Elem.querySelector('TopLeftCorner').textContent.split(' '); + this._boundingBox.origin.set(Number.parseFloat(topLeftCornerArray[0]), Number.parseFloat(topLeftCornerArray[1])); + // Get the CRS to convert km/matrix to CRS units/matrix. + this._readyPromise = TileMatrixSet.setCRS(this._crs).then((crs) => { + this._crs = crs; + let unitsPerKm = 1e3; + const proj = proj4__WEBPACK_IMPORTED_MODULE_1__["default"].defs(this._crs); + if (proj.to_meter) { + unitsPerKm = 1000 / proj.to_meter; + } + else if (proj.units === 'degrees') { + unitsPerKm = 0.00898315284; + } + else if (proj.units === 'feet' || proj.units === 'us feet') { + unitsPerKm = 3280.83333335; + } + + // Set the size, rounding off extra digits to prevent slight overflows. + this._boundingBox.size.x = Math.round(kmPerMatrix.x * unitsPerKm * 1e6) / 1e6; + this._boundingBox.size.y = Math.round(kmPerMatrix.y * unitsPerKm * 1e6) / 1e6; + this._boundingBox.origin.y = this._boundingBox.origin.y - this._boundingBox.size.y; + }); + } + + /** + * Gets a promise that resolves when it is ready to be used. + * @returns {Promise} + */ + get readyPromise() { + return this._readyPromise; + } + + /** + * Gets the identifier. + * @returns {string} + */ + get identifier() { + return this._identifier; + } + + /** + * Gets the bounding box in CRS coordinates. + * @returns {Pioneer.Rect} + */ + get boundingBox() { + return this._boundingBox; + } + + /** + * Gets the number of levels. + * @returns {number} + */ + get numLevels() { + return this._numLevels; + } + + /** + * Gets the number of tiles in each direction at the given level. + * @param {number} level + * @returns {Pioneer.Vector2} + */ + getNumTiles(level) { + return this._numTiles[level]; + } + + /** + * Converts CRS units to an XYZ. + * @param {Pioneer.Vector3} outXYZ + * @param {Pioneer.Vector2} crsUnits + * @param {Pioneer.SpheroidComponent} spheroid + */ + crsUnitsToXYZ(outXYZ, crsUnits, spheroid) { + const lla = pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + // Clamp the x and y to the bounding box so that we don't get crazy values. + const x = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(crsUnits.x, this._boundingBox.origin.x, this._boundingBox.origin.x + this._boundingBox.size.x); + const y = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(crsUnits.y, this._boundingBox.origin.y, this._boundingBox.origin.y + this._boundingBox.size.y); + // Convert it to regular geodetic latitude and longitude. + const ll = (0,proj4__WEBPACK_IMPORTED_MODULE_1__["default"])(this._crs, 'WGS84', [x, y]); + lla.set(pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(ll[1]), pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(ll[0]), 0); + // Convert it to xyz. + spheroid.xyzFromLLA(outXYZ, lla); + pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + } + + /** + * Defines a projection in proj4 from the crs. Returns the string to be used on subsequent proj4 calls. + * @param {string} crs + * @returns {Promise} + */ + static async setCRS(crs) { + if (crs.startsWith('urn:ogc:def:crs:')) { + crs = crs.substring('urn:ogc:def:crs:'.length); + } + // Try to get it locally first. + let proj4Text = crsToWKT.get(crs); + if (proj4Text === undefined && crs.startsWith('EPSG::')) { + const url = 'https://epsg.io/' + crs.substring('EPSG::'.length) + '.proj4'; + const result = await fetch(url); + proj4Text = await result.text(); + } + proj4__WEBPACK_IMPORTED_MODULE_1__["default"].defs(crs, proj4Text); + return crs; + } +} + +const crsToWKT = /** @type {Map} */(new Map()); +// Some common ones to start us off. +crsToWKT.set('EPSG::104903', 'GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]'); +crsToWKT.set('EPSG::104905', 'GEOGCS["GCS_Mars_2000",DATUM["D_Mars_2000",SPHEROID["Mars_2000_IAU_IAG",3396190.0,169.8944472236118]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]'); +crsToWKT.set('EPSG::4326', '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'); +crsToWKT.set('EPSG::3857', '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs'); +crsToWKT.set('OGC:1.3:84', proj4__WEBPACK_IMPORTED_MODULE_1__["default"].defs('WGS84')); +crsToWKT.set('OGC:1.3:CRS84', proj4__WEBPACK_IMPORTED_MODULE_1__["default"].defs('WGS84')); +crsToWKT.set('OGC:2:84', proj4__WEBPACK_IMPORTED_MODULE_1__["default"].defs('WGS84')); + + + + +/***/ }), + +/***/ "../pioneer/scripts/src/components/wmts_component.js": +/*!***********************************************************!*\ + !*** ../pioneer/scripts/src/components/wmts_component.js ***! + \***********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "WMTSComponent": function() { return /* binding */ WMTSComponent; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _wmts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./wmts */ "../pioneer/scripts/src/components/wmts.js"); +/** @module pioneer-scripts */ + + + +/** + * @callback TransitionsCompleteCallback + * @returns {void} + */ + +/** + * The WMTS component. + * */ +class WMTSComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent { + /** + * Constructor. + * @param {string} type - the type of the component + * @param {string} name - the name of the component + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The WMTS Capabilities + * @type {Capabilities} + * @private + */ + this._capabilities = null; + + /** + * The WMTS end point. + * @type {string} + * @private + */ + this._endPoint = ''; + + /** + * The WMTS layer identifier + * @type {string} + * @private + */ + this._layerIdentifier = ''; + + /** + * The WMTS tile matrix set identifier + * @type {string} + * @private + */ + this._tileMatrixSetIdentifier = ''; + + /** + * The style identifier. + * @type {string} + * @private + */ + this._style = ''; + + /** + * Dimension values used to get the right tile. + * @type {Map} + * @private + */ + this._dimensionValues = new Map(); + + /** + * The minimum level to which the tiles must split. + * @type {number} + * @private + */ + this._minLevel = Number.NEGATIVE_INFINITY; + + /** + * The maximum level to which the tiles can split. + * @type {number} + * @private + */ + this._maxLevel = Number.POSITIVE_INFINITY; + + /** + * A factor that determines when to split the tiles. Higher means more splits. + * @type {number} + * @private + */ + this._splitJoinThresholdFactor = 512; + + /** + * The layer. + * @type {Layer} + * @private + */ + this._layer = null; + + /** + * The tile matrix set. + * @type {TileMatrixSet} + * @private + */ + this._tileMatrixSet = null; + + /** + * The url to be used by the tiles for the images. + * @type {string} + * @private + */ + this._tileUrl = ''; + + /** + * The entities used for shadows. Derived from the shadow entity names. + * @type {Pioneer.EntityRef[]} + * @private + */ + this._shadowEntities = []; + + /** + * The downloader for easier future access. + * @private + */ + this._engine = this.getEntity().getScene().getEngine(); + + /** + * The positions of all active cameras. + * @type {Pioneer.Vector3[]} + * @private + */ + this._cameraPositions = []; + + /** + * The root tile. + * @type {WMTSTile} + * @private + */ + this._rootTile = null; + + /** + * The pixel size of each tile. Starts out as undefined and then on the first image load is set. + * @type {number} + * @private + */ + this._tilePixelSize = undefined; + + /** + * A promise that resolves when all tiles are no longer transitioning. + * @type {Promise} + * @private + */ + this._tilesLoadedPromise = null; + + /** + * The callback that gets called when all tiles are no longer transitioning. + * @type {TransitionsCompleteCallback} + * @private + */ + this._transitionsCompleteCallback = null; + + /** + * A counter that ensures that we don't do too many splits or joins in a single frame. + * @type {number} + * @private + */ + this._loadsThisFrame = 0; + + /** + * A reference to the atmosphere component. + * @type {Pioneer.ComponentRef} + * @private + */ + this._atmosphereComponentRef = new pioneer__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene()); + this._atmosphereComponentRef.setByType(this.getEntity().getName(), 'atmosphere'); + + /** + * A reference to the spheroid component. + * @type {Pioneer.ComponentRef} + * @private + */ + this._spheroidComponentRef = new pioneer__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene()); + this._spheroidComponentRef.setByType(this.getEntity().getName(), 'spheroid'); + this._spheroidComponentRef.setRefChangedCallback(this._spheroidRefChangedCallback.bind(this)); + + // Bind the callbacks to this. + this._spheroidChangedCallback = this._spheroidChangedCallback.bind(this); + + // Lets the base component to check for valid orientation when determining whether this is visible. + this.__setUsesEntityOrientation(true); + } + + /** + * Sets the end point for the WMTS protocol. + * @param {string} endPoint + */ + async setEndPoint(endPoint) { + this._endPoint = endPoint; + this.resetResources(); + } + + /** + * Sets the layer identifier. + * @param {string} identifier + */ + setLayer(identifier) { + this._layerIdentifier = identifier; + this.resetResources(); + } + + /** + * Sets the tile matrix set identifier. + * @param {string} identifier + */ + setTileMatrixSet(identifier) { + this._tileMatrixSetIdentifier = identifier; + this.resetResources(); + } + + /** + * Sets the style of the layer. + * @param {string} identifier + */ + setStyle(identifier) { + this._style = identifier; + this.resetResources(); + } + + /** + * Sets the value of a dimension in the layer. + * @param {string} dimension + * @param {string} value + */ + setDimensionValue(dimension, value) { + this._dimensionValues.set(dimension, value); + this.resetResources(); + } + + /** + * Gets the list of layers as a map from titles to identifiers. + * @returns {Map} + */ + getLayers() { + if (this._capabilities !== null) { + return this._capabilities.layers; + } + else { + return new Map(); + } + } + + /** + * Gets the minimum level to which the tiles must split. + * @returns {number} + */ + getMinLevel() { + return this._minLevel; + } + + /** + * Sets the minimum level to which the tiles must split. Defaults to negative infinity. + * @param {number} minLevel + */ + setMinLevel(minLevel) { + this._minLevel = minLevel; + } + + /** + * Gets the maximum level to which the tiles can split. + * @returns {number} + */ + getMaxLevel() { + return this._maxLevel; + } + + /** + * Sets the maximum level to which the tiles can split. Defaults to positive infinity. + * @param {number} maxLevel + */ + setMaxLevel(maxLevel) { + this._maxLevel = maxLevel; + } + + /** + * Returns a promise when no more tiles are loading. + * @returns {Promise} + */ + getTilesLoadedPromise() { + return this._tilesLoadedPromise || Promise.resolve(); + } + + /** + * Sets the reference to use for the spheroid component, by name or the type index. + * @param {string | number} nameOrTypeIndex + */ + setSpheroidReference(nameOrTypeIndex) { + if (typeof nameOrTypeIndex === 'string') { + this._spheroidComponentRef.setByName(this.getEntity().getName(), nameOrTypeIndex); + } + else { + this._spheroidComponentRef.setByType(this.getEntity().getName(), 'spheroid', nameOrTypeIndex); + } + } + + /** + * Gets the layer. + * @returns {Layer} + * @internal + */ + __getLayer() { + return this._layer; + } + + /** + * Gets the tile matrix set. + * @returns {TileMatrixSet} + * @internal + */ + __getTileMatrixSet() { + return this._tileMatrixSet; + } + + /** + * Gets the url to be used by the tiles. + * @returns {string} + * @internal + */ + __getTileUrl() { + return this._tileUrl; + } + + /** + * Gets the layer bounds or null if there is no layer. + * @returns {Pioneer.Rect} + * @internal + */ + __getLayerBounds() { + if (this._layer !== null) { + return this._layer.boundingBox; + } + else { + return null; + } + } + + /** + * Gets the max level. + * @returns {number} + * @internal + */ + __getMaxLevel() { + return this._maxLevel; + } + + /** + * Gets the min level. + * @returns {number} + * @internal + */ + __getMinLevel() { + return this._minLevel; + } + + /** + * Gets the split-join factor. + * @returns {number} + * @internal + */ + __getSplitJoinFactor() { + return this._splitJoinThresholdFactor; + } + + /** + * Gets the pixel size of each tile. Starts out as undefined and then on the first image load is set. + * @returns {number} + */ + __getTilePixelSize() { + return this._tilePixelSize; + } + + /** + * Sets the pixel size of each tile. Starts out as undefined and then on the first image load is set. + * @param {number} tilePixelSize + */ + __setTilePixelSize(tilePixelSize) { + this._tilePixelSize = tilePixelSize; + } + + /** + * Gets the number of loads this frame. + * @returns {number} + */ + __getLoadsThisFrame() { + return this._loadsThisFrame; + } + + /** + * Increments the number of loads this frame. + * @internal + */ + __incLoadsThisFrame() { + this._loadsThisFrame += 1; + } + + /** + * Gets the current camera positions. + * @returns {Pioneer.Vector3[]} + * @internal + */ + __getCameraPositions() { + return this._cameraPositions; + } + + /** + * Gets the spheroid component this is using. Used by Tile. + * @returns {Pioneer.SpheroidComponent} + * @internal + */ + __getSpheroidComponent() { + return this._spheroidComponentRef.get(); + } + + /** + * Cleans up the component. + * @override + * @internal + */ + __destroy() { + // Remove the spheroid changed callback. + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent !== null) { + spheroidComponent.removeChangedCallback(this._spheroidChangedCallback); + } + + super.__destroy(); + } + + /** + * Updates the component. + * @override + * @internal + */ + __update() { + // Update the references. + this._spheroidComponentRef.update(); + + // If there's no root tile, do nothing else. + if (this._rootTile === null) { + return; + } + + // Get the positions of all cameras. + while (this._cameraPositions.length > this._engine.getNumViewports()) { + this._cameraPositions.pop(); + } + while (this._cameraPositions.length < this._engine.getNumViewports()) { + this._cameraPositions.push(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3()); + } + const cameraPosition = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + for (let i = 0, l = this._engine.getNumViewports(); i < l; i++) { + cameraPosition.neg(this.getEntity().getCameraSpacePosition(this._engine.getViewport(i).getCamera())); + this._cameraPositions[i].rotateInverse(this.getEntity().getOrientation(), cameraPosition); + } + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraPosition); + + this._loadsThisFrame = 0; + + // Do the update on all of the tiles recursively. + // If any tile is still transitioning, set transitioning to true. + const transitioning = this._rootTile.update(); + + // If there is no current promise (there were no tiles) and now there are, + // Create the loaded promise and record its resolve callback. + if (this._tilesLoadedPromise === null && transitioning) { + this._tilesLoadedPromise = new Promise((resolve) => { + this._transitionsCompleteCallback = resolve; + }); + } + + // If the loaded promise callback exists and we're no longer transitioning, + // Clear the loaded promise and callback and call the callback (the resolve function of the promise). + if (this._tilesLoadedPromise !== null && !transitioning) { + const callback = this._transitionsCompleteCallback; + this._tilesLoadedPromise = null; + this._transitionsCompleteCallback = null; + callback(); + } + } + + /** + * Prepares the component for render. + * @param {Pioneer.CameraComponent} camera + * @override + * @internal + */ + __prepareForRender(camera) { + // Set the orientation to the entity's orientation. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects(), this.getEntity()); + + // Set the position to the entity's camera position. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects(), this.getEntity(), camera); + + // Get the atmosphere. + const atmosphere = this._atmosphereComponentRef.get(); + + // Setup the regular uniforms. + pioneer__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setUniforms(this.getThreeJsMaterials(), camera, this.getEntity(), this._shadowEntities, atmosphere, true); + } + + /** + * Loads the resources needed by the component. + * @returns {Promise} + * @override + * @protected + */ + async __loadResources() { + if (this._endPoint !== '') { + // Load the capabilities end point XML. + this._capabilities = new _wmts__WEBPACK_IMPORTED_MODULE_1__.Capabilities(this._endPoint, this._engine); + await this._capabilities.readyPromise; + + // If no layer is specified and there is only one choice, choose that one. + let layerIdentifier = this._layerIdentifier; + if (layerIdentifier === '') { + const layers = this._capabilities.layers; + if (layers.size === 1) { + for (const [, identifier] of layers) { + layerIdentifier = identifier; + } + } + } + // If there's still no layer specified, nothing to do. + if (layerIdentifier === '') { + return; + } + // Load the layer. + this._layer = this._capabilities.getLayer(layerIdentifier); + if (this._layer === null) { + throw new Error('Invalid layer: "' + layerIdentifier + '".'); + } + + // If no tile matrix set is specified and there is only one choice, choose that one. + let tileMatrixSetIdentifier = this._tileMatrixSetIdentifier; + if (tileMatrixSetIdentifier === '') { + const tileMatrixSets = this._layer.tileMatrixSets; + if (tileMatrixSets.size === 1) { + for (const identifier of tileMatrixSets) { + tileMatrixSetIdentifier = identifier; + } + } + } + // Load the tile matrix set. + this._tileMatrixSet = this._capabilities.getTileMatrixSet(tileMatrixSetIdentifier); + if (this._tileMatrixSet === null) { + throw new Error('Invalid tile matrix set: "' + tileMatrixSetIdentifier + '".'); + } + await this._tileMatrixSet.readyPromise; + + // Get the root tile bounds. + const rootTileBounds = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Rect(); + rootTileBounds.copy(this._tileMatrixSet.boundingBox); + // Make sure the level -1 tile matrix can be 2x2 when split. + if (this._tileMatrixSet.getNumTiles(0).x === 1) { + rootTileBounds.size.x *= 2.0; + } + if (this._tileMatrixSet.getNumTiles(0).y === 1) { + rootTileBounds.origin.y -= rootTileBounds.size.y; + rootTileBounds.size.y *= 2.0; + } + + // If no style is specified, get the default one. + let style = this._style; + if (style === '') { + style = this._layer.defaultStyle; + } + // Add default dimension values. + for (const [identifier, defaultValue] of this._layer.dimensions) { + if (!this._dimensionValues.has(identifier)) { + this._dimensionValues.set(identifier, defaultValue); + } + } + + // The tile url to be used by the tiles. + this._tileUrl = this._layer.url; + this._tileUrl = this._tileUrl.replace('{TileMatrixSet}', this._tileMatrixSet.identifier); + this._tileUrl = this._tileUrl.replace('{Style}', style); + this._dimensionValues.forEach((value, dimension) => { + this._tileUrl = this._tileUrl.replace('{' + dimension + '}', value); + }); + + this._rootTile = new WMTSTile(this, null, -1, 0, 0, rootTileBounds); + } + } + + /** + * Unloads any resources used by the component. + * @override + * @protected + */ + __unloadResources() { + this._capabilities = null; + this._layer = null; + this._tileMatrixSet = null; + this._tileUrl = ''; + this._rootTile.destroy(); + this._rootTile = null; + } + + /** + * Callback called when the spheroid reference is found or lost. + * @param {Pioneer.SpheroidComponent} oldRef + * @param {Pioneer.SpheroidComponent} newRef + * @private + */ + _spheroidRefChangedCallback(oldRef, newRef) { + if (oldRef !== null) { + oldRef.removeChangedCallback(this._spheroidChangedCallback); + } + if (newRef !== null) { + newRef.addChangedCallback(this._spheroidChangedCallback); + } + this._spheroidChangedCallback(); + } + + /** + * Callback to be called when the spheroid component changed. + * @private + */ + _spheroidChangedCallback() { + // Set the radii uniforms. + const spheroidComponent = this._spheroidComponentRef.get(); + if (spheroidComponent !== null) { + this.__setRadius(Math.max(spheroidComponent.getEquatorialRadius(), spheroidComponent.getPolarRadius())); + } + else { + this.__setRadius(0); + } + this.resetResources(); + } +} + +/** + * A single tile with mesh, material, and bounds. + * @extends Pioneer.Tile + * @private + */ +class WMTSTile extends pioneer__WEBPACK_IMPORTED_MODULE_0__.Tile { + /** + * Constructor. + * @param {WMTSComponent} component + * @param {WMTSTile} parent + * @param {number} level + * @param {number} row + * @param {number} col + * @param {Pioneer.Rect} tileBounds + */ + constructor(component, parent, level, row, col, tileBounds) { + super(parent); + + /** + * The WMTS component. + * @type {WMTSComponent} + * @private + */ + this._component = component; + + /** + * The TileMatrix level starting from -1. + * @type {number} + * @private + */ + this._level = level; + + /** + * The row in the TileMatrix of the tile. + * @type {number} + * @private + */ + this._row = row; + + /** + * The column in the TileMatrix of the tile. + * @type {number} + * @private + */ + this._col = col; + + /** + * The bounds of the tile in CRS coordinates. + * @type {Pioneer.Rect} + * @private + */ + this._tileBounds = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Rect(); + this._tileBounds.copy(tileBounds); + + /** + * The "center", the average between the origin and end of the tile bounds. + * @type {Pioneer.Vector3} + * @private + */ + this._center = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + + /** + * The "radius", the distance from the center to one of the corners. + * @type {number} + * @private + */ + this._radius = 0; + + /** + * The material used by the tile, from a pool of materials. + * @type {Pioneer.THREE.ShaderMaterial} + * @private + */ + this._threeJsMaterial = null; + + /** + * The Three.js object of the tile. + * @type {Pioneer.THREE.Mesh} + * @private + */ + this._threeJsObject = null; + + // Calculate the center and diagonal length of a box that includes + // the start and end points and the average of the two. + const spheroid = component.__getSpheroidComponent(); + const tileMatrixSet = this._component.__getTileMatrixSet(); + // Get the origin as XYZ. + const originXYZ = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + tileMatrixSet.crsUnitsToXYZ(originXYZ, this._tileBounds.origin, spheroid); + // Get the end as XYZ. + const end = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + end.add(this._tileBounds.origin, this._tileBounds.size); + const endXYZ = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + tileMatrixSet.crsUnitsToXYZ(endXYZ, end, spheroid); + // Get the average of the start and end points. + const tileBoundsCenter = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + tileBoundsCenter.addMult(this._tileBounds.origin, this._tileBounds.size, 0.5); + tileMatrixSet.crsUnitsToXYZ(this._center, tileBoundsCenter, spheroid); + // Get the min and max points. + const min = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + const max = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + min.x = Math.min(originXYZ.x, endXYZ.x, this._center.x); + min.y = Math.min(originXYZ.y, endXYZ.y, this._center.y); + min.z = Math.min(originXYZ.z, endXYZ.z, this._center.z); + max.x = Math.max(originXYZ.x, endXYZ.x, this._center.x); + max.y = Math.max(originXYZ.y, endXYZ.y, this._center.y); + max.z = Math.max(originXYZ.z, endXYZ.z, this._center.z); + // Get the center of the box. + this._center.add(min, max); + this._center.mult(this._center, 0.5); + // Get the radius. + const diagonal = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + diagonal.sub(this._center, min); + this._radius = diagonal.magnitude(); + } + + /** + * @param {WMTSTile} parent + * @param {number} row - 0 or 1 + * @param {number} col - 0 or 1 + * @returns {WMTSTile} + * @override + */ + createNewTile(parent, row, col) { + // Get new tile params. + const newLevel = parent._level + 1; + const newRow = parent._row * 2 + row; + const newCol = parent._col * 2 + col; + + // Check if it's within the tile bounds. + const numTiles = parent._component.__getTileMatrixSet().getNumTiles(parent._level + 1); + if (newRow >= numTiles.y || newCol >= numTiles.x) { + return null; + } + + // Calculate the new CRS tile bounds. + const tileBounds = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Rect(); + tileBounds.origin.set(parent._tileBounds.origin.x + col * 0.5 * parent._tileBounds.size.x, parent._tileBounds.origin.y + (1 - row) * 0.5 * parent._tileBounds.size.y); + tileBounds.size.set(0.5 * parent._tileBounds.size.x, 0.5 * parent._tileBounds.size.y); + + return new WMTSTile(parent._component, parent, newLevel, newRow, newCol, tileBounds); + } + + /** + * Returns true if this tile should be split. + * @returns {boolean} + * @override + */ + checkSplit() { + // Don't split if there are no more tiles in the tile matrix set. + if (this._level >= this._component.__getTileMatrixSet().numLevels - 1) { + return false; + } + // Don't split if the whole tile is not in the layer. + if (!this._tileBounds.intersects(this._component.__getLayerBounds())) { + return false; + } + // Don't split if we're at the maximum level of detail. + if (this._level >= this._component.__getMaxLevel()) { + return false; + } + // Don't split if we've already done a lot this frame. + if (this._component.__getLoadsThisFrame() >= 1) { + return false; + } + // Always split if we're below the minimum level of detail. + if (this._level < this._component.__getMinLevel()) { + return true; + } + // Always split if we're at the invisible root node. + if (this._level === -1) { + return true; + } + // Split if the nearest camera distance is less than the threshold. + let tilePixelSize = this._component.__getTilePixelSize(); + if (tilePixelSize === undefined && this._threeJsMaterial !== null) { + tilePixelSize = this._threeJsMaterial.uniforms['colorTexture'].value.image.width; + if (tilePixelSize === 1) { // It is using a single pixel color, so don't go further. + return false; + } + this._component.__setTilePixelSize(tilePixelSize); + } + return this._getNearestDistance() < this._component.__getSplitJoinFactor() * this._radius / tilePixelSize; + } + + /** + * Returns true if this tile should join its children. + * @returns {boolean} + * @override + */ + checkJoin() { + // If we're at the root node, never join. + if (this._level === -1) { + return false; + } + // Don't join if we've already done a lot this frame. + if (this._component.__getLoadsThisFrame() >= 1) { + return false; + } + // Always join is we're above the maximum level of detail. + if (this._level > this._component.__getMaxLevel()) { + return true; + } + // Never join if we're at or below the minimum level of detail. + if (this._level <= this._component.__getMinLevel()) { + return false; + } + // Check if the nearest camera distance is greater than the threshold. + let tilePixelSize = this._component.__getTilePixelSize(); + if (tilePixelSize === undefined && this._threeJsMaterial !== null) { + tilePixelSize = this._threeJsMaterial.uniforms['colorTexture'].value.image.width; + this._component.__setTilePixelSize(tilePixelSize); + } + return this._getNearestDistance() > this._component.__getSplitJoinFactor() * this._radius * 4 / tilePixelSize; + } + + /** + * Asynchronously loads the tile so that it may be used. + * @returns {Promise} + * @override + */ + async load() { + if (this._level === -1) { + return Promise.resolve(); + } + + this._component.__incLoadsThisFrame(); + + if (this._threeJsMaterial !== null) { + throw new Error('Tile already has material.'); + } + + // Check if it's within the layer bounds. + if (this._tileBounds.intersects(this._component.__getLayerBounds())) { + // Get a material from the component's materials cache. + this._threeJsMaterial = pioneer__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.get(); + this._component.getThreeJsMaterials().push(this._threeJsMaterial); + // this._threeJsMaterial.wireframe = true; + // this._threeJsMaterial.defines['baseColor'] = true; + // this._threeJsMaterial.uniforms['color'].value.setRGB(0.25 + 0.75 * Math.random(), 0.25 + 0.75 * Math.random(), 0.25 + 0.75 * Math.random()); + + let url = this._component.__getTileUrl(); + url = url.replace('{TileMatrix}', '' + this._level); + url = url.replace('{TileRow}', '' + this._row); + url = url.replace('{TileCol}', '' + this._col); + try { + // Download the texture. + await pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTextureIntoUniform(this._component, this._threeJsMaterial, 'colorTexture', url, false, false); + } + catch (e) { + await pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTextureIntoUniform(this._component, this._threeJsMaterial, 'colorTexture', 'gray', false, false); + } + } + } + + /** + * Asynchronously unloads the tile. + * @returns {Promise} + * @override + */ + async unload() { + if (this._level === -1) { + return; + } + if (this._threeJsMaterial !== null) { + // Remove up the material from the materials list. + const materials = this._component.getThreeJsMaterials(); + for (let i = 0, l = materials.length; i < l; i++) { + if (materials[i] === this._threeJsMaterial) { + materials.splice(i, 1); + break; + } + } + if (this._threeJsMaterial.uniforms['colorTexture'].value) { + this._threeJsMaterial.uniforms['colorTexture'].value.dispose(); + } + // Dispose of the material. + this._threeJsMaterial.dispose(); + this._threeJsMaterial = null; + } + this._threeJsMaterial = null; + } + + /** + * Asynchronously activates the tile. + * @returns {Promise} + * @override + */ + async activate() { + if (this._level === -1) { + return; + } + // Create the Three.js object. + this._threeJsObject = pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this._component, this._threeJsMaterial, [ + { name: 'position', dimensions: 3 }, + { name: 'normal', dimensions: 3 }, + { name: 'uv', dimensions: 2 } + ], false); + this._component.getThreeJsObjects().push(this._threeJsObject); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.useInDynEnvMap(this._threeJsObject, true); + + // Create the vertices, normals, uvs, and indices arrays. + const numVVerts = 21; + const numUVerts = 21; + const numVerts = numUVerts * numVVerts; + const meshPositions = new Float32Array(numVerts * 3); + const meshNormals = new Float32Array(numVerts * 3); + const meshUVs = new Float32Array(numVerts * 2); + const meshIndices = new Uint16Array(numUVerts * (numVVerts - 1) * 6); + + // Get the bounding box. + const boundingBox = this._component.__getLayer().boundingBox; + + // Set the vertices, normals, uvs, and indices arrays. + const crsUnits = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + const clampedCRSUnits = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(); + const xyz = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + for (let y = 0; y < numVVerts; y++) { + let yF = 1.0 - y / (numVVerts - 1); + crsUnits.y = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(this._tileBounds.origin.y, this._tileBounds.origin.y + this._tileBounds.size.y, yF); + clampedCRSUnits.y = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(crsUnits.y, boundingBox.origin.y, boundingBox.origin.y + boundingBox.size.y); + yF += (clampedCRSUnits.y - crsUnits.y) / this._tileBounds.size.y; + for (let x = 0; x < numUVerts; x++) { + let xF = x / (numUVerts - 1); + crsUnits.x = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(this._tileBounds.origin.x, this._tileBounds.origin.x + this._tileBounds.size.x, xF); + clampedCRSUnits.x = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(crsUnits.x, boundingBox.origin.x, boundingBox.origin.x + boundingBox.size.x); + xF += (clampedCRSUnits.x - crsUnits.x) / this._tileBounds.size.x; + // Set the latitude and longitude coordinate. + this._component.__getTileMatrixSet().crsUnitsToXYZ(xyz, clampedCRSUnits, this._component.__getSpheroidComponent()); + + const vertexI = y * numUVerts + x; + meshPositions[vertexI * 3 + 0] = xyz.x; + meshPositions[vertexI * 3 + 1] = xyz.y; + meshPositions[vertexI * 3 + 2] = xyz.z; + xyz.normalize(xyz); + meshNormals[vertexI * 3 + 0] = xyz.x; + meshNormals[vertexI * 3 + 1] = xyz.y; + meshNormals[vertexI * 3 + 2] = xyz.z; + meshUVs[vertexI * 2 + 0] = xF; + meshUVs[vertexI * 2 + 1] = 1.0 - yF; + + const triangleI = y * numUVerts + x; + if (x < numUVerts - 1 && y < numVVerts - 1) { + meshIndices[triangleI * 6 + 0] = numUVerts * (y + 0) + (x + 0); + meshIndices[triangleI * 6 + 1] = numUVerts * (y + 1) + (x + 0); + meshIndices[triangleI * 6 + 2] = numUVerts * (y + 1) + (x + 1); + meshIndices[triangleI * 6 + 3] = numUVerts * (y + 0) + (x + 0); + meshIndices[triangleI * 6 + 4] = numUVerts * (y + 1) + (x + 1); + meshIndices[triangleI * 6 + 5] = numUVerts * (y + 0) + (x + 1); + } + } + } + + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(this._threeJsObject.geometry, 'position', meshPositions); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(this._threeJsObject.geometry, 'normal', meshNormals); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(this._threeJsObject.geometry, 'uv', meshUVs); + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(this._threeJsObject.geometry, meshIndices); + } + + /** + * Asynchronously deactivates the tile. + * @returns {Promise} + * @override + */ + async deactivate() { + if (this._level === -1) { + return; + } + // Remove the object from the objects list. + const objects = this._component.getThreeJsObjects(); + for (let i = 0, l = objects.length; i < l; i++) { + if (objects[i] === this._threeJsObject) { + objects.splice(i, 1); + break; + } + } + // Destroy the object and its geometry. + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyObject(this._threeJsObject); + this._threeJsObject = null; + } + + /** + * Updates the tiles recursively. Returns true if the tile or any descendant is transitioning. + * @returns {boolean} + */ + update() { + let transitioning = this.check(); + for (let i = 0, l = this.children.length; i < l; i++) { + transitioning = this.children[i].update() || transitioning; + } + return transitioning; + } + + _getNearestDistance() { + // Calculate the nearest distance to see if we need to split or join this node. + let nearestDistance = Number.POSITIVE_INFINITY; + const diff = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + for (let i = 0, l = this._component.__getCameraPositions().length; i < l; i++) { + const position = this._component.__getCameraPositions()[i]; + diff.sub(this._center, position); + const distance = Math.max(0, diff.magnitude() - this._radius); + if (nearestDistance > distance) { + nearestDistance = distance; + } + } + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(diff); + return nearestDistance; + } + + /** + * Converts the tile to a string. + * @returns {string} + * @override + */ + toString() { + return this._level + '-' + this._row + '-' + this._col; + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/controllers/keyframe_pointing_controller.js": +/*!**************************************************************************!*\ + !*** ../pioneer/scripts/src/controllers/keyframe_pointing_controller.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "KeyframePointingController": function() { return /* binding */ KeyframePointingController; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * A controller that points the entity's frame-space direction given by keyframes. + */ +class KeyframePointingController extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The keyframes. + * @type {[number, string][]} + * @private + */ + this._keyframes = []; + + /** + * The frame-space direction to use for the pointing. + * @type {Pioneer.Vector3} + * @private + */ + this._direction = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(1, 0, 0); + + this.addModifiedState('orientation'); + } + + /** + * Sets the keyframes. Each keyframe is a [time, value]. Possible keyframe values are any entity name or 'velocity', + * with an optional prefix of '-' to indicate the opposite direction. + * @param {[number, string][]} keyframes + */ + setKeyframes(keyframes) { + // Remove any previous dependent states. + for (let i = 0, l = this._keyframes.length; i < l; i++) { + let value = this._keyframes[i][1]; + if (value.startsWith('-')) { + value = value.substring(1); + } + if (value === 'velocity') { + this.removeDependentState(this.getEntity().getName(), 'velocity'); + } + else { + this.removeDependentState(value, 'position'); + } + } + this._keyframes = []; + for (let i = 0, l = keyframes.length; i < l; i++) { + this._keyframes.push([keyframes[i][0], keyframes[i][1]]); + // Add any new dependent states. + let value = this._keyframes[i][1]; + if (value.startsWith('-')) { + value = value.substring(1); + } + if (value === 'velocity') { + this.addDependentState(this.getEntity().getName(), 'velocity'); + } + else { + this.addDependentState(value, 'position'); + } + } + this._keyframes.sort((a, b) => a[0] - b[0]); + } + + /** + * Sets the frame-space direction to use for the pointing. + * @param {Pioneer.Vector3} direction + */ + setDirection(direction) { + this._direction.copy(direction); + } + + /** + * Updates given orientation for the given time. + * @param {Pioneer.Quaternion} orientation - The orientation to update. + * @param {number} time - The time to check. + * @override + */ + __updateOrientationAtTime(orientation, time) { + if (orientation.isNaN()) { + orientation.copy(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + this._getNewOrientation(orientation, time, orientation); + } + + /** + * Updates the controller. + * @override + */ + __update() { + if (this._keyframes.length === 0) { + return; + } + const entity = this.getEntity(); + const time = entity.getScene().getEngine().getTime(); + if (entity.getOrientation().isNaN()) { + entity.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + const newOrientation = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + this._getNewOrientation(newOrientation, time, entity.getOrientation()); + entity.setOrientation(newOrientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation); + } + + /** + * Gets a new orientation, given the time and an existing orientation. + * @param {Pioneer.Quaternion} newOrientation + * @param {number} time + * @param {Pioneer.Quaternion} oldOrientation + * @private + */ + _getNewOrientation(newOrientation, time, oldOrientation) { + const index = pioneer__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._keyframes, (a, time) => a[0] < time); + let prevIndex = 0; + let nextIndex = 0; + if (index === this._keyframes.length) { // After last keyframe time. + prevIndex = this._keyframes.length - 1; + nextIndex = this._keyframes.length - 1; + } + else if (index > 0) { + prevIndex = index - 1; + nextIndex = index; + } + const prevKeyframe = this._keyframes[prevIndex]; + const nextKeyframe = this._keyframes[nextIndex]; + const u = (nextKeyframe[0] > prevKeyframe[0]) + ? (time - prevKeyframe[0]) / (nextKeyframe[0] - prevKeyframe[0]) + : 0; + const prevDirection = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const nextDirection = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + this._getDirection(prevDirection, time, prevKeyframe[1]); + this._getDirection(nextDirection, time, nextKeyframe[1]); + nextDirection.slerp(prevDirection, nextDirection, u); + nextDirection.normalize(nextDirection); + prevDirection.rotate(oldOrientation, this._direction); + const rotation = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + rotation.setFromVectorFromTo(prevDirection, nextDirection); + newOrientation.mult(rotation, oldOrientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(nextDirection); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(prevDirection); + } + + /** + * Gets a dynamic direction using the type. It can be the name of another entity or 'velocity', and can be prefixed with '-'. + * @param {Pioneer.Vector3} outDirection + * @param {number} time + * @param {string} type + * @private + */ + _getDirection(outDirection, time, type) { + const entity = this.getEntity(); + const isNeg = type.startsWith('-'); + if (isNeg) { + type = type.substring(1); + } + if (type.startsWith('velocity')) { + type = type.substring(8); + if (type.startsWith(' rel ')) { + type = type.substring(5); + const relEntity = entity.getScene().getEntity(type); + if (relEntity !== null) { + entity.getVelocityRelativeToEntity(outDirection, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, relEntity, time); + } + } + else { + entity.getVelocityAtTime(outDirection, time); + } + } + else { + const otherEntity = entity.getScene().getEntity(type); + if (otherEntity !== null) { + otherEntity.getPositionRelativeToEntity(outDirection, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, entity, time); + } + else { + outDirection.copy(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]); + } + } + outDirection.normalize(outDirection); + if (isNeg) { + outDirection.mult(outDirection, -1); + } + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/controllers/keyframe_spin_controller.js": +/*!**********************************************************************!*\ + !*** ../pioneer/scripts/src/controllers/keyframe_spin_controller.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "KeyframeSpinController": function() { return /* binding */ KeyframeSpinController; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * A controller that spins an entity at keyframed rates along a given axis. + */ +class KeyframeSpinController extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The keyframes. The components are [time, rate, starting angle]. + * @type {[number, number, number][]} + * @private + */ + this._keyframes = []; + + /** + * The frame-space axis to use for the spinning. + * @type {Pioneer.Vector3} + * @private + */ + this._axis = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(1, 0, 0); + + /** + * The starting angle at keyframe 0. + * @type {number} + * @private + */ + this._startingAngle = 0; + + this.addModifiedState('orientation'); + } + + /** + * Sets the keyframes. Each keyframe is a [time, rate]. The rate uses the right-hand rotation along the specified axis. + * @param {[number, number][]} keyframes + */ + setKeyframes(keyframes) { + this._keyframes = []; + let lastAngle = 0; + for (let i = 0, l = keyframes.length; i < l; i++) { + if (i > 0) { + // Get the accumulated angle over the previous duration, taking into account changing spin rates. + lastAngle = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(lastAngle + (keyframes[i][0] - keyframes[i - 1][0]) * (keyframes[i - 1][1] + keyframes[i][1]) * 0.5, 0, 2 * Math.PI); + } + this._keyframes.push([keyframes[i][0], keyframes[i][1], lastAngle]); + } + this._keyframes.sort((a, b) => a[0] - b[0]); + } + + /** + * Sets the frame-space axis to use for the spinning. + * @param {Pioneer.Vector3} axis + */ + setAxis(axis) { + this._axis.copy(axis); + } + + /** + * Sets the starting angle at keyframe 0. + * @param {number} angle + */ + setStartingAngle(angle) { + this._startingAngle = angle; + } + + /** + * Updates given orientation for the given time. + * @param {Pioneer.Quaternion} orientation - The orientation to update. + * @param {number} time - The time to check. + * @override + */ + __updateOrientationAtTime(orientation, time) { + if (orientation.isNaN()) { + orientation.copy(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + this._getNewOrientation(orientation, time, orientation); + } + + /** + * Updates the controller. + * @override + */ + __update() { + if (this._keyframes.length === 0) { + return; + } + const entity = this.getEntity(); + const time = entity.getScene().getEngine().getTime(); + if (entity.getOrientation().isNaN()) { + entity.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity); + } + const newOrientation = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + this._getNewOrientation(newOrientation, time, entity.getOrientation()); + entity.setOrientation(newOrientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation); + } + + /** + * Gets a new orientation, given the time and an existing orientation. + * @param {Pioneer.Quaternion} newOrientation + * @param {number} time + * @param {Pioneer.Quaternion} oldOrientation + * @private + */ + _getNewOrientation(newOrientation, time, oldOrientation) { + const index = pioneer__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time, this._keyframes, (a, time) => a[0] < time); + let prevIndex = 0; + let nextIndex = 0; + if (index === this._keyframes.length) { // After last keyframe time. + prevIndex = this._keyframes.length - 1; + nextIndex = this._keyframes.length - 1; + } + else if (index > 0) { + prevIndex = index - 1; + nextIndex = index; + } + const prevKeyframe = this._keyframes[prevIndex]; + const nextKeyframe = this._keyframes[nextIndex]; + const u = (nextKeyframe[0] > prevKeyframe[0]) + ? (time - prevKeyframe[0]) / (nextKeyframe[0] - prevKeyframe[0]) + : 0; + const angle = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(this._startingAngle + prevKeyframe[2] + (time - prevKeyframe[0]) * (prevKeyframe[1] + u * nextKeyframe[1]) / (1 + u), 0, 2 * Math.PI); + const axis = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + axis.rotate(oldOrientation, this._axis); + const rotation = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + rotation.setFromAxisAngle(axis, angle); + newOrientation.mult(rotation, oldOrientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(axis); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation); + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/controllers/position_sum_controller.js": +/*!*********************************************************************!*\ + !*** ../pioneer/scripts/src/controllers/position_sum_controller.js ***! + \*********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "PositionSumController": function() { return /* binding */ PositionSumController; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** A controller that adds a factor of different positions. */ +class PositionSumController extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The list of entities and their factors. + * @type {Pioneer.FastMap} + * @private + */ + this._entities = new pioneer__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + this.addModifiedState('position'); + } + + /** + * Adds an entity with mult and add factors. + * @param {string} entityName - The entity whose position to use. + * @param {number} mult - A multiply factor of the position. + * @param {number} add - An added offset in the direction of the position. + */ + addEntity(entityName, mult, add) { + // Set the ref. + const ref = new pioneer__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + ref.setName(entityName); + + // Add it to the list. + this._entities.set(entityName, { ref, mult, add }); + + // Mark that this is dependent on the position of the entity. + this.addDependentState(entityName, 'position'); + } + + /** + * Removes an entity. + * @param {string} entityName + */ + removeEntity(entityName) { + // Remove it from the list. + this._entities.delete(entityName); + + // Mark that this is no longer dependent on the position of the entity. + this.removeDependentState(entityName, 'position'); + } + + /** + * Sets the params of the entity, which has already been added. + * @param {string} entityName - The entity whose position to use. + * @param {number | undefined} mult - A multiply factor of the position. + * @param {number | undefined} add - An added offset in the direction of the position. + */ + setEntityParams(entityName, mult, add) { + + // Check if it already exists. + if (!this._entities.has(entityName)) { + throw new Error(`The entity ${entityName} has not been previously added to the controller.`); + } + + // Update the params. + const params = this._entities.get(entityName); + if (mult !== undefined) { + params.mult = mult; + } + if (add !== undefined) { + params.add = add; + } + } + + /** + * Updates the position. + * @override + * @package + */ + __update() { + const accumulatedPosition = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const position = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + + // Go through each entity, + accumulatedPosition.set(0, 0, 0); + for (let i = 0, l = this._entities.size; i < l; i++) { + const entry = this._entities.getAt(i).value; + + // Get the entity. + const entity = entry.ref.get(); + if (entity === null) { + continue; + } + + // Get the position of the entity relative to the current parent. + entity.getPositionRelativeToEntity(position, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, this.getEntity().getParent()); + + // Accumulate the position with the factors. + const magnitude = position.magnitude(); + accumulatedPosition.addMult(accumulatedPosition, position, entry.mult + (magnitude > 0 ? entry.add / magnitude : 0)); + } + + // Set the accumulated position. + this.getEntity().setPosition(accumulatedPosition); + + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(accumulatedPosition); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/controllers/zoom_fit_controller.js": +/*!*****************************************************************!*\ + !*** ../pioneer/scripts/src/controllers/zoom_fit_controller.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ZoomFitController": function() { return /* binding */ ZoomFitController; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** A controller that zooms the camera to fit a list of entities within view. */ +class ZoomFitController extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseController { + /** + * Constructor. + * @param {string} type - the type of the controller + * @param {string} name - the name of the controller + * @param {Pioneer.Entity} entity - the parent entity + */ + constructor(type, name, entity) { + super(type, name, entity); + + /** + * The list of entities and their factors. + * @type {Pioneer.FastMap} + * @private + */ + this._entities = new pioneer__WEBPACK_IMPORTED_MODULE_0__.FastMap(); + + /** + * The flag that determines if the fit radius will take into account the point of view of the camera for a tighter fit. + * @type {boolean} + * @private + */ + this._tightFit = false; + + /** + * The flag that determines if the camera will zoom out only, or both in and out. + * @type {boolean} + * @private + */ + this._zoomOutOnly = false; + + /** + * The edge size as a fraction of the minimum of the viewport width and height. + * @type {number} + * @private + */ + this._edgeSize = 0; + + this.addModifiedState('position'); + } + + /** + * Adds an entity with mult and add factors. + * @param {string} entityName - The entity whose position to use. + */ + addEntity(entityName) { + // Set the ref. + const ref = new pioneer__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene()); + ref.setName(entityName); + + // Add it to the list. + this._entities.set(entityName, { ref }); + + // Mark that this is dependent on the position of the entity. + this.addDependentState(entityName, 'position'); + } + + /** + * Removes an entity. + * @param {string} entityName + */ + removeEntity(entityName) { + // Remove it from the list. + this._entities.delete(entityName); + + // Mark that this is no longer dependent on the position of the entity. + this.removeDependentState(entityName, 'position'); + } + + /** + * Sets the flag that determines if the fit radius will take into account the point of view of the camera for a tighter fit. + * @param {boolean} tightFit + */ + setTightFit(tightFit) { + this._tightFit = tightFit; + } + + /** + * Sets the flag that determines if the camera will zoom out only, or both in and out. + * @param {boolean} zoomOutOnly + */ + setZoomOutOnly(zoomOutOnly) { + this._zoomOutOnly = zoomOutOnly; + } + + /** + * Sets the edge size as a fraction of the minimum of the viewport width and height. + * @param {number} edgeSize + */ + setEdgeSize(edgeSize) { + this._edgeSize = edgeSize; + } + + /** + * Updates the position. + * @override + * @package + */ + __update() { + // Get the sin and tan field of view variables for distance calculations. + let tanHalfFov = 1; + const camera = this.getEntity().getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CameraComponent); + if (camera !== null) { + const fieldOfView = Math.min(camera.getHorizontalFieldOfView(), camera.getVerticalFieldOfView()); + if (this._tightFit) { + tanHalfFov = Math.tan(fieldOfView / 2.0); + } + tanHalfFov = Math.tan(fieldOfView / 2.0); + } + + // Get the direction upon which we'll be zooming. + // It will be the unit vector of the camera's position, or the camera's backward if the position vector is 0. + const direction = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + direction.normalize(this.getEntity().getPosition()); + if (direction.magnitudeSqr() === 0) { + this.getEntity().getOrientation().getAxis(direction, 1); + direction.neg(direction); + } + if (direction.isNaN()) { + direction.copy(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg); + } + + // Get the edge factor that widens the view appropriately depending on the field of view. + const factor = (1 + this._edgeSize / (0.5 - this._edgeSize)) / tanHalfFov; + + // Get the distance the camera should be at to see everything. + let maxDistance = 0; + const position = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + for (let i = 0, l = this._entities.size; i < l; i++) { + const entry = this._entities.getAt(i).value; + + // Get the entity. + const entity = entry.ref.get(); + if (entity === null) { + continue; + } + + // Get the position of the entity relative to the current parent. + entity.getPositionRelativeToEntity(position, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, this.getEntity().getParent()); + + // Get the extents radius of the entity. + const radius = entity.getExtentsRadius(); + + // Get the distance that we should be away from this entity. + let distance = 0; + if (this._tightFit) { + // Get the position part along the direction. + const distanceAlongDirection = position.dot(direction); + + // Get the position part along the plane normal to the direction. + position.addMult(position, direction, -distanceAlongDirection); + const distanceAlongPane = position.magnitude(); + + // Get the distance to zoom back for this object. + distance = distanceAlongDirection + factor * distanceAlongPane + radius * Math.sqrt(factor * factor + 1); + } + else { + // It's not using the tight-fit flag, so we're just going to use the distances for the (dist + radius) + // and do the distance calculation after the loop. + distance = position.magnitude() + radius; + } + + // Max out the distance needed to see all of the entities. + maxDistance = Math.max(maxDistance, distance); + } + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + + // If it's not a tight fit, the maxDistance is just the max (dist + radius) all entities, so apply the equation to get the distance to zoom back. + if (!this._tightFit) { + maxDistance = maxDistance * Math.sqrt(factor * factor + 1); + } + + // If we're either zooming out or we can zoom in, + if (!this._zoomOutOnly || maxDistance > this.getEntity().getPosition().magnitude()) { + // Add the distance along the backward vector to the position. + direction.mult(direction, maxDistance); + + // Set the position. + this.getEntity().setPosition(direction); + } + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(direction); + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/date_time.js": +/*!*******************************************!*\ + !*** ../pioneer/scripts/src/date_time.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "DateTime": function() { return /* binding */ DateTime; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * A simple date and time class. Month starts at 1. + * This is needed because the Date object (and moment.js) doesn't handle leap seconds. + * Note that month starts at 1, not 0. + */ +class DateTime { + /** + * Constructor. + * @param {number} [year=1] + * @param {number} [month=1] + * @param {number} [day=1] + * @param {number} [hour=0] + * @param {number} [minute=0] + * @param {number} [second=0] + * @param {number} [millisecond=0] + */ + constructor(year = 1, month = 1, day = 1, hour = 0, minute = 0, second = 0, millisecond = 0) { + /** + * Year starting at 1 A.D. + * @type {number} + */ + this.year = year; + + /** + * Month starting at 1. + * @type {number} + */ + this.month = month; + + /** + * Day starting at 1. + * @type {number} + */ + this.day = day; + + /** + * The 24-hour. + * @type {number} + */ + this.hour = hour; + + /** + * The minute. + * @type {number} + */ + this.minute = minute; + + /** + * The second. Can go up to 60 for leap seconds. + * @type {number} + */ + this.second = second; + + /** + * The millisecond. Can be fractional. + * @type {number} + */ + this.millisecond = millisecond; + } + + /** + * Copies a dateTime to this. + * @param {DateTime} dateTime + */ + copy(dateTime) { + this.year = dateTime.year; + this.month = dateTime.month; + this.day = dateTime.day; + this.hour = dateTime.hour; + this.minute = dateTime.minute; + this.second = dateTime.second; + this.millisecond = dateTime.millisecond; + } + + /** + * Sets this from an ET time. + * @param {number} et + */ + fromET(et) { + const unixTime = pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(et); + _date.setTime(unixTime * 1000.0); + this.year = _date.getUTCFullYear(); + this.month = _date.getUTCMonth() + 1; + this.day = _date.getUTCDate(); + this.hour = _date.getUTCHours(); + this.minute = _date.getUTCMinutes(); + this.second = _date.getUTCSeconds(); + this.millisecond = _date.getUTCMilliseconds(); + for (let i = 0, l = pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.leapSeconds.length; i < l; i++) { + if (Math.floor(unixTime) === pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.leapSeconds[i] && unixTime === pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(et - 1)) { + this.second += 1; + break; + } + } + } + + /** + * Gets an ET time from this. + * @returns {number} + */ + toET() { + _date.setUTCFullYear(this.year); + _date.setUTCMonth(this.month - 1); + _date.setUTCDate(this.day); + _date.setUTCHours(this.hour); + _date.setUTCMinutes(this.minute); + _date.setUTCSeconds(this.second); + _date.setUTCMilliseconds(this.millisecond); + const unixTime = _date.getTime() / 1000.0; + let etTime = pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.unixToEt(unixTime); + if (this.second === 60) { + for (let i = 0, l = pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.leapSeconds.length; i < l; i++) { + if (Math.floor(unixTime) === pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.leapSeconds[i] + 1) { + etTime -= 1; + break; + } + } + } + return etTime; + } + + /** + * Sets this from an ordinal date (day of year) and time. + * @param {number} year + * @param {number} doy + * @param {number} [hour=0] + * @param {number} [minute=0] + * @param {number} [second=0] + * @param {number} [millisecond=0] + */ + fromDOY(year, doy, hour = 0, minute = 0, second = 0, millisecond = 0) { + let passedDays = 0; + this.year = year; + this.month = 1; + this.hour = hour; + this.minute = minute; + this.second = second; + this.millisecond = millisecond; + let daysInMonth = this.getDaysInMonth(); + while (doy > passedDays + daysInMonth && this.month < 12) { + passedDays += daysInMonth; + this.month += 1; + daysInMonth = this.getDaysInMonth(); + } + this.day = doy - passedDays; + } + + /** + * Gets the day of year for this. + * @returns {number} + */ + toDOY() { + const originalMonth = this.month; + let doy = 0; + for (this.month = 1; this.month < originalMonth; this.month++) { + doy += this.getDaysInMonth(); + } + this.month = originalMonth; + doy += this.day; + return doy; + } + + /** + * Returns true if this is a leap year. + * @returns {boolean} + */ + isLeapYear() { + return ((this.year % 4 === 0) && (this.year % 100 !== 0)) || (this.year % 400 === 0); + } + + /** + * Returns the number of days in the month for this. + * @returns {number} + */ + getDaysInMonth() { + let daysInMonth = _daysInMonth[this.month - 1]; + if (this.month === 2 && this.isLeapYear()) { + daysInMonth += 1; + } + return daysInMonth; + } + + /** + * Parses text in the form of YYYY-MM-DD HH:MM:SS.ssssss, with the time and milliseconds optional. + * @param {string} text + */ + parse(text) { + this.year = parseInt(text.substring(0, 4)); + if (text.length > 5) { + this.month = parseInt(text.substring(5, 7)); + } + else { + this.month = 1; + } + if (text.length > 8) { + this.day = parseInt(text.substring(8, 10)); + } + else { + this.day = 1; + } + if (text.length > 11) { + this.hour = parseInt(text.substring(11, 13)); + this.minute = parseInt(text.substring(14, 16)); + } + else { + this.hour = 0; + this.minute = 0; + } + if (text.length > 17) { + this.second = parseInt(text.substring(17, 19)); + } + else { + this.second = 0; + } + if (text.length > 20) { + this.millisecond = parseInt(text.substring(20)) * Math.pow(10, 23 - text.length); + } + else { + this.millisecond = 0; + } + } + + /** + * Parses text in the form of YYYY-DDD HH:MM:SS.ssssss. + * @param {string} text + */ + parseDOY(text) { + const year = parseInt(text.substring(0, 4)); + let doy = 1; + if (text.length > 5) { + doy = parseInt(text.substring(5, 8)); + } + this.fromDOY(year, doy); + if (text.length > 9) { + this.hour = parseInt(text.substring(9, 11)); + this.minute = parseInt(text.substring(12, 14)); + } + else { + this.hour = 0; + this.minute = 0; + } + if (text.length > 15) { + this.second = parseInt(text.substring(15, 17)); + } + else { + this.second = 0; + } + if (text.length > 18) { + this.millisecond = parseInt(text.substring(18)) * Math.pow(10, 21 - text.length); + } + else { + this.millisecond = 0; + } + } + + /** + * Converts this to a string of the form YYYY-MM-DD HH:MM:SS.ssssss. + * @returns {string} + */ + toString() { + return `${this.year.toString().padStart(4, '0')}-${this.month.toString().padStart(2, '0')}-${this.day.toString().padStart(2, '0')} ${this.hour.toString().padStart(2, '0')}:${this.minute.toString().padStart(2, '0')}:${this.second.toString().padStart(2, '0')}.${Math.floor(this.millisecond * 1e3).toString().padStart(6, '0')}`; + } + + /** + * Converts this to a string of the form YYYY-DDD. + * @returns {string} + */ + toStringDOY() { + return `${this.year.toString().padStart(4, '0')}-${this.toDOY().toString().padStart(3, '0')}`; + } +}; + +/** + * The number of days in a non-leap year month. + * @type {number[]} + * @private + */ +const _daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + +/** + * Temporary date that can be reused within functions. + * @type {Date} + * @private + */ +const _date = new Date(); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/comets.js": +/*!*************************************************!*\ + !*** ../pioneer/scripts/src/entities/comets.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var _entity_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./entity_utils */ "../pioneer/scripts/src/entities/entity_utils.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + '1i_oumuamua': { + groups: ['comets'], + occlusionRadius: 0.030, + extentsRadius: 0.225, + label: 'ʻOumuamua', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/1i_oumuamua/oumuamua.gltf' + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: '1i_oumuamua/sun/orb' + }, { + type: 'spin', + axis: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.57735026919, 0.57735026919, 0.57735026919), + periodInHours: 8.10 + }] + }, + '1p_halley': { + groups: ['comets'], + radius: 6.0, + label: 'Halley (1P/Halley)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [6, 6, 6] + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: '1p_halley/sun/orb' + }, { + type: 'spin', + periodInHours: 52, + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + axisInFrameSpace: false + }] + }, + '103p_hartley_2': { + groups: ['comets'], + radius: 2.0, + label: 'Hartley 2 (103P/Hartley)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/103p_hartley_2/hartley_2.gltf' + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: '103p_hartley_2/sun/orb' + }, { + type: 'dynamo', + url: '103p_hartley_2/ori' + }] + }, + '9p_tempel_1': { + groups: ['comets'], + radius: 5.0, + label: 'Tempel 1 (9P/Tempel)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/9p_tempel_1/9p_tempel.gltf', + rotate: [ + { y: 90 } + ] + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: '9p_tempel_1/sun/orb' + }, { + type: 'dynamo', + url: '9p_tempel_1/ori' + }] + }, + '81p_wild_2': { + groups: ['comets'], + radius: 2.5, + label: 'Wild 2 (81P/Wild)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'], + [-800047271, 'jupiter'], + [-797029475, 'sun'] + ], + trail: { + length: undefined, + lengthCoverages: [ + [1356976800, Number.NEGATIVE_INFINITY, -611927948.817], + [189345600, -611927948.817, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.5, 2.5, 2.5] + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: '81p_wild_2/sun/1/orb' + }, { + type: 'dynamo', + url: '81p_wild_2/jupiter/orb' + }, { + type: 'dynamo', + url: '81p_wild_2/sun/2/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }] + }, + '67p_churyumov_gerasimenko': { + groups: ['comets'], + radius: 4.1, + label: 'Churyumov–Gerasimenko (67P/C-G)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/67p_churyumov_gerasimenko/67p_churyumov_gerasimenko.gltf', + rotate: [ + { x: 90 } + ], + scale: 0.00124 + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: '67p_churyumov_gerasimenko/sun/orb' + }, { + type: 'spin', + axis: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.15191127889562422, 0.404099951782066, 0.9020123016422935), + axisInFrameSpace: false, + periodInHours: 12.0550932412 + }, { + type: 'dynamo', + url: '67p_churyumov_gerasimenko/ori' + }], + postCreateFunction: (entity) => { + // Get the orientation just right for working with Rosetta photos. + entity.setOrientation(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.26732846830704055, 0.017948528101847026, 0.22012096235022358, 0.9379552773483394)); + + // Geysers + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 1, 1, 100, 1, 1, [1, -0.25, 1.2], [0, 0, 1]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 2, 0.5, 100, 1, 1, [-1.2, -0.25, 0.6], [0.2, -0.5, 1]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 1, 0.07, 100, 1, 10, [-1.2, 0.1, 0.6], [0.2, -0.5, 1]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 1, 1, 100, 1, 1, [-0.8, 0.75, 1.0], [0.2, 0.5, 1]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 1, 0.5, 100, 1, 1, [-0.8, 0.35, -1.0], [0.2, 0.25, -1]); + } + }, + '19p_borrelly': { + groups: ['comets'], + radius: 2.4, + label: 'Borrelly (19P/Borrelly)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/19p_borrelly/borrelly.gltf' + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: '19p_borrelly/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }] + }, + c_1995_o1: { + groups: ['comets'], + radius: 5.0, + label: 'Hale-Bopp (C/1995 O1)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [5, 5, 5] + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: 'c_1995_o1/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + axisInFrameSpace: false, + periodInHours: 11.766666666 + }] + }, + c_2010_x1: { + groups: ['comets'], + radius: 5.0, + label: 'Elenin (C/2010 X1)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'], + [370699266.182, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [5, 5, 5] + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: 'c_2010_x1/sun/pos' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }] + }, + c_2012_s1: { + groups: ['comets'], + radius: 3.0, + label: 'ISON (C/2012 S1)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'], + [440596867.184, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [3, 3, 3] + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: 'c_2012_s1/sun/pos' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }] + }, + c_2013_a1: { + groups: ['comets'], + radius: 5.0, + label: 'Siding Spring (C/2013 A1)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [5, 5, 5] + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: 'c_2013_a1/sun/pos' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + axisInFrameSpace: false, + periodInHours: 8 + }] + }, + c_2019_y4: { + groups: ['comets'], + radius: 3.0, + label: 'ATLAS (C/2019 Y4)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [3, 3, 3] + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: 'c_2019_y4/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }] + }, + c_2020_f3: { + groups: ['comets'], + radius: 6.0, + label: 'NEOWISE (C/2020 F3)', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [6, 6, 6] + }, + comet: {}, + controllers: [{ + type: 'dynamo', + url: 'c_2020_f3/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + axisInFrameSpace: false, + periodInHours: 7.58 + }] + } +}); + +// Default export to help with tree-shaking. + + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/comparison.js": +/*!*****************************************************!*\ + !*** ../pioneer/scripts/src/entities/comparison.js ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + rose_bowl: { + groups: ['comparison'], + radius: 0.15, + label: 'Rose Bowl', + parents: [], + model: { + url: '$STATIC_ASSETS_URL/models/comparison/rose_bowl/rose_bowl.gltf', + rotate: [ + { x: 90 }, + { z: -90 } + ] + }, + controllers: [{ + type: 'fixed', + position: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + school_bus: { + groups: ['comparison'], + radius: 0.0065, + label: 'School bus', + parents: [], + model: { + url: '$STATIC_ASSETS_URL/models/comparison/school_bus/school_bus.gltf', + rotate: [ + { x: 90 }, + { z: -90 } + ] + }, + controllers: [{ + type: 'fixed', + position: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + scientist: { + groups: ['comparison'], + radius: 0.000835, + label: 'Scientist', + parents: [], + model: { + url: '$STATIC_ASSETS_URL/models/comparison/scientist/scientist.gltf', + rotate: [ + { x: 90 } + ] + }, + controllers: [{ + type: 'fixed', + position: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/earth_moon.js": +/*!*****************************************************!*\ + !*** ../pioneer/scripts/src/entities/earth_moon.js ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/** @module pioneer-scripts */ + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + moon: { + groups: ['earth', 'moons'], + radius: 1737.4, + label: 'Moon', + parents: [ + [Number.NEGATIVE_INFINITY, 'earth'] + ], + trail: { + length: undefined, + color: [0.0, 0.6, 0.8, 0.7] + }, + spheroid: { + equatorialRadius: 1737.4, + polarRadius: 1737.4, + planetographic: true + }, + spheroidLOD: { + features: ['normalMap', 'shadowEntities'], + textures: { + color: { + url: 'moon/color_$SIZE_$FACE.png', + sizes: [16, 512, 4096] + }, + normal: { + url: 'moon/normal_$SIZE_$FACE.png', + sizes: [16, 512, 2048] + } + }, + shadowEntities: ['earth'] + }, + controllers: [{ + type: 'dynamo', + url: 'moon/earth/orb' + }, { + type: 'dynamo', + url: 'moon/ori' + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/earth_spacecraft.js": +/*!***********************************************************!*\ + !*** ../pioneer/scripts/src/entities/earth_spacecraft.js ***! + \***********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var _entity_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./entity_utils */ "../pioneer/scripts/src/entities/entity_utils.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + sc_3d_winds: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00200, + extentsRadius: 0.00250, + label: '3D-Winds', + parents: [ + [347025366.1839032, 'earth'] + ], + trail: { + length: 5573.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_3d_winds' + }] + }, + sc_ace: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0008, + extentsRadius: 0.0023, + label: 'ACE', + parents: [ + [265550465.18489534, 'earth'], + [694267269.1839212, ''] + ], + trail: { + length: 31715490.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_ace/ace.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_ace', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg, + periodInHours: 0.0033 + }] + }, + sc_acrimsat: { + groups: ['earth', 'spacecraft'], + radius: 0.0015, + label: 'ACRIMSAT', + parents: [ + [-963797, 'earth'], + [459950467, ''] // End of mission + ], + trail: { + length: 5933.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_acrimsat/acrimsat.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_acrimsat' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg, + periodInHours: 0.00238 + }] + }, + sc_aim: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00070, + extentsRadius: 0.0014, + label: 'AIM', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5788.83 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_aim' + }] + }, + sc_aqua: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00400, + extentsRadius: 0.015, + label: 'Aqua', + parents: [ + [73781738, 'earth'] + ], + trail: { + length: 5933.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_aqua/Aqua.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_aqua' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_aqua', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_ascends: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'ASCENDS', + parents: [ + [347025366.1839032, 'earth'] + ], + trail: { + length: 5573.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_ascends' + }] + }, + sc_aura: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.003450, + extentsRadius: 0.017, + label: 'Aura', + parents: [ + [143161358, 'earth'] + ], + trail: { + length: 5933.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_aura/Aura.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_aura' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_aura', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_c_nofs: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'C/NOFS', + parents: [ + [352800006.1854904, 'earth'], + [502051928.18300515, ''] + ], + trail: { + length: 5573.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_c_nofs' + }] + }, + sc_calipso: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.001650, + extentsRadius: 0.005, + label: 'CALIPSO', + parents: [ + [199506047, 'earth'] + ], + trail: { + length: 5933.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_calipso/calipso.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_calipso' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_calipso', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }] + }, + sc_chandra: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0059, + extentsRadius: 0.010, + label: 'Chandra', + parents: [ + [339465600, 'earth'], + [709344000, ''] + ], + trail: { + length: 228505.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_chandra/chandra.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_chandra/earth/all', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.70710678118, -0.70710678118, 0) + } + }] + }, + sc_clarreo: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'CLARREO', + parents: [ + [347025366.1839032, 'earth'] + ], + trail: { + length: 5573.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_clarreo' + }] + }, + sc_cloudsat: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0025, + extentsRadius: 0.0025, + label: 'CloudSat', + parents: [ + [199491286, 'earth'] + ], + trail: { + length: 5933.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cloudsat/CloudSat.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cloudsat' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_cloudsat', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_cluster_ii_fm5: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.001450, + extentsRadius: 0.00435, + label: 'Rumba', + parents: [ + [19105314, 'earth'] + ], + trail: { + length: 195541.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cluster_ii/cluster_ii.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cluster_ii_fm5' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_cluster_ii_fm5', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_cluster_ii_fm6: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.001450, + extentsRadius: 0.00435, + label: 'Salsa', + parents: [ + [17028089, 'earth'] + ], + trail: { + length: 195351.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cluster_ii/cluster_ii.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cluster_ii_fm6' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_cluster_ii_fm6', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_cluster_ii_fm7: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.001450, + extentsRadius: 0.00435, + label: 'Samba', + parents: [ + [17028093, 'earth'] + ], + trail: { + length: 195316.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cluster_ii/cluster_ii.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cluster_ii_fm7' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_cluster_ii_fm7', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_cluster_ii_fm8: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.001450, + extentsRadius: 0.00435, + label: 'Tango', + parents: [ + [19105052, 'earth'] + ], + trail: { + length: 195388.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cluster_ii/cluster_ii.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cluster_ii_fm8' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_cluster_ii_fm8', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_cygnss_1: { + groups: ['earth', 'spacecraft'], + radius: 0.0008, + label: 'CYGNSS 1', + parents: [ + [548415404.1851876, 'earth'] + ], + trail: { + length: 5573.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cygnss_1' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_cygnss_1', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + } + }] + }, + sc_cygnss_2: { + groups: ['earth', 'spacecraft'], + radius: 0.0008, + label: 'CYGNSS 2', + parents: [ + [548415404.1851876, 'earth'] + ], + trail: { + length: 5573.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cygnss_2' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_cygnss_2', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + } + }] + }, + sc_cygnss_3: { + groups: ['earth', 'spacecraft'], + radius: 0.0008, + label: 'CYGNSS 3', + parents: [ + [548415404.1851876, 'earth'] + ], + trail: { + length: 5573.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cygnss_3' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_cygnss_3', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + } + }] + }, + sc_cygnss_4: { + groups: ['earth', 'spacecraft'], + radius: 0.0008, + label: 'CYGNSS 4', + parents: [ + [548415404.1851876, 'earth'] + ], + trail: { + length: 5573.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cygnss_4' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_cygnss_4', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + } + }] + }, + sc_cygnss_5: { + groups: ['earth', 'spacecraft'], + radius: 0.0008, + label: 'CYGNSS 5', + parents: [ + [548415404.1851876, 'earth'] + ], + trail: { + length: 5573.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cygnss_5' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_cygnss_5', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + } + }] + }, + sc_cygnss_6: { + groups: ['earth', 'spacecraft'], + radius: 0.0008, + label: 'CYGNSS 6', + parents: [ + [548415404.1851876, 'earth'], + [722736069, ''] + ], + trail: { + length: 5573.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cygnss_6' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_cygnss_6', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + } + }] + }, + sc_cygnss_7: { + groups: ['earth', 'spacecraft'], + radius: 0.0008, + label: 'CYGNSS 7', + parents: [ + [548415404.1851876, 'earth'] + ], + trail: { + length: 5573.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cygnss_7' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_cygnss_7', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + } + }] + }, + sc_cygnss_8: { + groups: ['earth', 'spacecraft'], + radius: 0.0008, + label: 'CYGNSS 8', + parents: [ + [548415404.1851876, 'earth'] + ], + trail: { + length: 5573.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cygnss_8' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_cygnss_8', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + } + }] + }, + sc_dscovr: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00090, + extentsRadius: 0.0020, + label: 'DSCOVR', + parents: [ + [476711467.18497694, 'earth'] + ], + trail: { + length: 60 * 60 * 24 * 365 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_dscovr/dscovr.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_dscovr/earth/all', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_dscovr', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + } + }] + }, + sc_eo_1: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0030, + extentsRadius: 0.0010, + label: 'EO-1', + parents: [ + [344589947.18311954, 'earth'], + [544104069.186, ''] + ], + trail: { + length: 5933.33 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_eo_1/eo-1.gltf', + rotate: [ + { y: 45 } + ], + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_eo_1' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'velocity', + target: 'sc_eo_1', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + } + }] + }, + sc_explorer_1: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0010, + extentsRadius: 0.0010, + label: 'Explorer 1', + parents: [ + [-1322726967, 'earth'], + [-939025103, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_explorer_1_v2/explorer_1.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_explorer_1/earth' + }, { + type: 'align', + primary: { + type: 'velocity', + target: 'sc_explorer_1', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg, + periodInHours: 0.000022 + }] + }, + sc_face: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'FACE', + parents: [ + [347025366.1839032, 'earth'], + [631022168.1838934, ''] + ], + trail: { + length: 5933.33 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_face' + }] + }, + sc_fgrst: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00140, + extentsRadius: 0.0040, + label: 'FGRST', + parents: [ + [344589947.18311954, 'earth'], + [661006268.1833516, ''] + ], + trail: { + length: 5733.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_fgrst' + }] + }, + sc_gacm: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'GACM', + parents: [ + [347025366.1839032, 'earth'] + ], + trail: { + length: 5733.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_gacm' + }] + // mission is cancelled + }, + sc_galex: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0010, + extentsRadius: 0.00140, + label: 'GALEX', + parents: [ + [352800006.1854904, 'earth'], + [425718607.184, ''] + ], + trail: { + length: 5733.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_galex' + }] + }, + sc_geo_cape: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'GEO-CAPE', + parents: [ + [347025366.1839032, 'earth'] + ], + trail: { + length: 5733.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_geo_cape' + }] + // mission is cancelled + }, + sc_geotail: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0018, + extentsRadius: 0.003, + label: 'Geotail', + parents: [ + [-234758765, 'earth'], + [722891591, ''] + ], + trail: { + length: 450372.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_geotail/geotail.gltf', + shadowEntities: ['earth'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_geotail/earth/orb' + }, { + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.662, 0.749, 0, 0) + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis, + periodInHours: 0.00083333333, + relativeToTime: 0 + }] + }, + sc_goes_12: { + groups: ['earth', 'spacecraft'], + radius: 0.003, + label: 'GOES 12', + parents: [ + [344589947.18311954, 'earth'], + [661006268.1833516, ''] + ], + trail: { + length: 5733.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_goes_12' + }] + }, + sc_goes_13: { + groups: ['earth', 'spacecraft'], + radius: 0.003, + label: 'GOES 13', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5733.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_goes_13' + }] + }, + sc_goes_14: { + groups: ['earth', 'spacecraft'], + radius: 0.003, + label: 'GOES 14', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5733.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_goes_14' + }] + }, + sc_goes_15: { + groups: ['earth', 'spacecraft'], + radius: 0.003, + label: 'GOES 15', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5733.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_goes_15' + }] + }, + sc_gpm: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0020, + extentsRadius: 0.007, + label: 'GPM', + parents: [ + [629484755.7856493, 'earth'] + ], + trail: { + length: 5549.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_gpm/GPM.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_gpm' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_gpm', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }], + postCreateFunction: (entity) => { + const spin = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpinController); + spin.setJoint('GPM_antenna'); + spin.setRate(pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.degToRad(192)); + spin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg, true); + spin.setClampedToRealTime(true); + } + }, + sc_grace_1: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0015, + extentsRadius: 0.0019, + label: 'GRACE-1', + parents: [ + [69656411.096817, 'earth'], + [562382552.2587994, ''] + ], + trail: { + length: 5575.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_grace/grace.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_grace_1/earth/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sc_grace_2', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }, { + type: 'coverage', + coverage: [Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY], + update: (entity) => { + const microwave = /** @type {Pioneer.ConnectedSpriteComponent} */(entity.getComponent('microwave')); + const engine = entity.getScene().getEngine(); + const newOffset = pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.wrap(microwave.getTextureYOffset() - pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.clamp(engine.getTimeRate(), -1, +1) * engine.getDeltaTime(), 0, 1); + microwave.setTextureYOffset(newOffset); + const other = entity.getScene().getEntity('sc_grace_2'); + const shouldBeEnabled = other !== null && other.getPosition().distance(entity.getPosition()) <= 3929; + if (shouldBeEnabled !== microwave.isEnabled()) { + microwave.setEnabled(shouldBeEnabled); + } + } + }], + postCreateFunction: entity => { + const microwave = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ConnectedSpriteComponent, 'microwave'); + microwave.setTextureUrl('$STATIC_ASSETS_URL/sprites/sine_wave.png'); + microwave.setEntity1('sc_grace_1'); + microwave.setEntity1Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, -0.00165, 0)); + microwave.setEntity2('sc_grace_2'); + microwave.setEntity2Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, -0.00165, 0)); + microwave.setWidths(0.0005, 0.0005); + microwave.setColorMultiplier(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(0.5, 1.0, 1.0)); + microwave.setTextureRepeat(true); + microwave.setTextureStretch(4); + } + }, + sc_grace_2: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0015, + extentsRadius: 0.0019, + label: 'GRACE-2', + parents: [ + [69656411.096817, 'earth'], + [562382552.2588, ''] + ], + trail: { + length: 5575.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_grace/grace.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_grace_2/earth/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sc_grace_1', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_grace_fo1: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0015, + extentsRadius: 0.0019, + label: 'GRACE-FO 1', + parents: [ + [580290547.185, 'earth'] + ], + trail: { + length: 5575.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_grace_fo/graceFO.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_grace_fo1' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sc_grace_fo2', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + }, + secondary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + } + }, { + type: 'coverage', + coverage: [Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY], + update: (entity) => { + const microwave = /** @type {Pioneer.ConnectedSpriteComponent} */(entity.getComponent('microwave')); + const engine = entity.getScene().getEngine(); + const newOffset = pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.wrap(microwave.getTextureYOffset() - pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.clamp(engine.getTimeRate(), -1, +1) * engine.getDeltaTime(), 0, 1); + microwave.setTextureYOffset(newOffset); + const other = entity.getScene().getEntity('sc_grace_fo2'); + const shouldBeEnabled = other !== null && other.getPosition().distance(entity.getPosition()) <= 3929; + if (shouldBeEnabled !== microwave.isEnabled()) { + const laser1 = /** @type {Pioneer.ConnectedSpriteComponent} */(entity.getComponent('laser1')); + const laser2 = /** @type {Pioneer.ConnectedSpriteComponent} */(entity.getComponent('laser2')); + microwave.setEnabled(shouldBeEnabled); + laser1.setEnabled(shouldBeEnabled); + laser2.setEnabled(shouldBeEnabled); + } + } + }], + postCreateFunction: entity => { + const microwave = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ConnectedSpriteComponent, 'microwave'); + microwave.setTextureUrl('$STATIC_ASSETS_URL/sprites/sine_wave.png'); + microwave.setEntity1('sc_grace_fo1'); + microwave.setEntity1Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 0, -0.00165)); + microwave.setEntity2('sc_grace_fo2'); + microwave.setEntity2Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 0, -0.00165)); + microwave.setWidths(0.0005, 0.0005); + microwave.setColorMultiplier(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(0.5, 1.0, 1.0)); + microwave.setTextureRepeat(true); + microwave.setTextureStretch(4); + + const laser1 = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ConnectedSpriteComponent, 'laser1'); + laser1.setTextureUrl('$STATIC_ASSETS_URL/sprites/line.png'); + laser1.setEntity1('sc_grace_fo1'); + laser1.setEntity1Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(+0.0003, 0.00015, -0.00165)); + laser1.setEntity2('sc_grace_fo2'); + laser1.setEntity2Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.0003, 0.00015, -0.00165)); + laser1.setWidths(0.00002, 0.00002); + laser1.setColorMultiplier(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(1, 0.24, 0.64)); + laser1.setTextureRepeat(false); + + const laser2 = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ConnectedSpriteComponent, 'laser2'); + laser2.setTextureUrl('$STATIC_ASSETS_URL/sprites/line.png'); + laser2.setEntity1('sc_grace_fo1'); + laser2.setEntity1Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.0003, 0.00015, -0.00165)); + laser2.setEntity2('sc_grace_fo2'); + laser2.setEntity2Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(+0.0003, 0.00015, -0.00165)); + laser2.setWidths(0.00002, 0.00002); + laser2.setColorMultiplier(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(1, 0.24, 0.64)); + laser2.setTextureRepeat(false); + } + }, + sc_grace_fo2: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0015, + extentsRadius: 0.0019, + label: 'GRACE-FO 2', + parents: [ + [580290547.185, 'earth'] + ], + trail: { + length: 5575.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_grace_fo/graceFO.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_grace_fo2' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sc_grace_fo1', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + }, + secondary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + } + }] + }, + sc_grifex: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.000150, + extentsRadius: 0.00034, + label: 'GRIFEX', + parents: [ + [476542806.1849232, 'earth'] + ], + trail: { + length: 5706.25 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_grifex/grifex.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_grifex' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_grifex', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + } + }] + }, + sc_hubble_space_telescope: { + groups: ['earth', 'spacecraft', 'telescope'], + occlusionRadius: 0.0066, + extentsRadius: 0.0066, + label: 'Hubble', + parents: [ + [-305719099.92837775, 'earth'] + ], + trail: { + length: 5748.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_hubble/Hubble.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_hubble_space_telescope/earth/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_hubble_space_telescope', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }] + }, + sc_hyspiri: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.004, + extentsRadius: 0.012, + label: 'HyspIRI', + parents: [ + [347025366.1839032, 'earth'] + ], + trail: { + length: 5733.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_hyspiri/HyspIRI.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_hyspiri' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_hyspiri', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_ibex: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0005, + extentsRadius: 0.001, + label: 'IBEX', + parents: [ + [277718464.1823969, 'earth'] + ], + trail: { + length: 797489.16 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_ibex/iBEX.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_ibex', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis, + periodInHours: 0.00416 + }] + }, + sc_icesat_2: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00198, + extentsRadius: 0.0065, + label: 'ICESat-2', + parents: [ + [590288589.182, 'earth'] + ], + trail: { + length: 5653.2 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_icesatii/ICESat2.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_icesat_2' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'velocity', + target: 'sc_icesat_2', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_image: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00113, + extentsRadius: 0.006, + label: 'IMAGE', + // Boom is 500 meters long! Does not appear in explorer. + parents: [ + [7288547.186, 'earth'], + [188163587.1835355, ''] + ], + trail: { + length: 55541 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_image/image.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_image' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_image', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_integral: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0025, + extentsRadius: 0.005, + label: 'INTEGRAL', + parents: [ + [367498866.18276465, 'earth'] + ], + trail: { + length: 229689.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_integral' + }] + }, + sc_ipex: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0001, + extentsRadius: 0.00015, + label: 'IPEX', + parents: [ + [439586087.183, 'earth'] + ], + trail: { + length: 5862.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_ipex/IPEX.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_ipex' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_ipex', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_isas: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.001, + extentsRadius: 0.0015, + label: 'ISAS', + parents: [ + [-186102945.06492478, 'earth'], + [-183424845.06434903, ''] + ], + trail: { + length: 92680.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_isas/isas.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_isas', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_isas', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_iss: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.008, + extentsRadius: 0.072, + label: 'ISS', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5573.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_iss/ISS_stationary.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_iss' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_iss', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }], + postCreateFunction: (entity) => { + const vectorForAlphaGimbal = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 0.5, 0.5 * Math.sqrt(3.0)); + const vectorForBetaGimbalAxis = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 0.5 * Math.sqrt(3.0), -0.5); + const vectorForBetaGimbalPoint = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 0.5, 0.5 * Math.sqrt(3.0)); + + // Align the right solar panel alpha gimbal to the sun. + let align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + align.setJoint('20_P4_Truss'); + align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis); + align.setSecondaryAxis(vectorForAlphaGimbal); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + + // Align the left solar panel alpha gimbal to the sun. + align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + align.setJoint('23_S4_Truss'); + align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis); + align.setSecondaryAxis(vectorForAlphaGimbal); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + + // Align the right solar panel alpha gimbal to the sun. + align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + align.setJoint('20_P4_Truss_01'); + align.setPrimaryAxis(vectorForBetaGimbalAxis); + align.setSecondaryAxis(vectorForBetaGimbalPoint); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + + // Align the right solar panel alpha gimbal to the sun. + align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + align.setJoint('20_P4_Truss_02'); + align.setPrimaryAxis(vectorForBetaGimbalAxis); + align.setSecondaryAxis(vectorForBetaGimbalPoint); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + + // Align the right solar panel alpha gimbal to the sun. + align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + align.setJoint('23_S4_Truss_01'); + align.setPrimaryAxis(vectorForBetaGimbalAxis); + align.setSecondaryAxis(vectorForBetaGimbalPoint); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + + // Align the right solar panel alpha gimbal to the sun. + align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + align.setJoint('23_S4_Truss_02'); + align.setPrimaryAxis(vectorForBetaGimbalAxis); + align.setSecondaryAxis(vectorForBetaGimbalPoint); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + + // Align the right solar panel alpha gimbal to the sun. + align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + align.setJoint('32_S6_Truss_01'); + align.setPrimaryAxis(vectorForBetaGimbalAxis); + align.setSecondaryAxis(vectorForBetaGimbalPoint); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + + // Align the right solar panel alpha gimbal to the sun. + align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + align.setJoint('32_S6_Truss_02'); + align.setPrimaryAxis(vectorForBetaGimbalAxis); + align.setSecondaryAxis(vectorForBetaGimbalPoint); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + + // Align the right solar panel alpha gimbal to the sun. + align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + align.setJoint('08_P6_Truss_01'); + align.setPrimaryAxis(vectorForBetaGimbalAxis); + align.setSecondaryAxis(vectorForBetaGimbalPoint); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + + // Align the right solar panel alpha gimbal to the sun. + align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + align.setJoint('08_P6_Truss_02'); + align.setPrimaryAxis(vectorForBetaGimbalAxis); + align.setSecondaryAxis(vectorForBetaGimbalPoint); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + + // Make RapidScat antenna spin. + const rapidScatSpin = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpinController); + rapidScatSpin.setJoint('RapidScat_dish'); + rapidScatSpin.setRate(pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.degToRad(108)); + rapidScatSpin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, true); + rapidScatSpin.setClampedToRealTime(true); + rapidScatSpin.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(465418867.184, 524890952.183)); // Lost power at 2016-08-19T15:01:24. + + // Show ECOSTRESS only when mounted. + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.showSubObjectDuringInterval(entity, 'Ecostress', 584127348, Number.POSITIVE_INFINITY); + + // Show EMIT only when mounted. + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.showSubObjectDuringInterval(entity, 'EMIT', 711345507, Number.POSITIVE_INFINITY); + + // Show OCO-3 only when mounted. + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.showSubObjectDuringInterval(entity, 'OCO3', 610718469, Number.POSITIVE_INFINITY); + + // Show RapidScat only when mounted. + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.showSubObjectDuringInterval(entity, '45_RapidScat', 465418867.184, 575406069.184); + } + }, + sc_iss_ecostress: { + groups: ['instrument', 'sc_iss'], + occlusionRadius: 0.001, + extentsRadius: 0.0012, + label: 'ECOSTRESS', + parents: [ + [584127348, 'sc_iss'] + ], + controllers: [{ + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity, + position: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.0200195, -0.00202631, 0.0161099), + coverage: [584127348, Number.POSITIVE_INFINITY] + }], + postCreateFunction: (entity) => { + const rotateByEntityOrientation = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RotateByEntityOrientationController); + rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(584127348, Number.POSITIVE_INFINITY)); + } + }, + sc_iss_emit: { + groups: ['instrument', 'sc_iss'], + occlusionRadius: 0.0008, + extentsRadius: 0.0013, + label: 'EMIT', + parents: [ + [711345507, 'sc_iss'] + ], + controllers: [{ + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity, + position: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.024, -0.00225, 0.00325), + coverage: [711345507, Number.POSITIVE_INFINITY] + }], + postCreateFunction: (entity) => { + const rotateByEntityOrientation = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RotateByEntityOrientationController); + rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(711345507, Number.POSITIVE_INFINITY)); + } + }, + sc_iss_oco_3: { + groups: ['instrument', 'sc_iss'], + occlusionRadius: 0.0008, + extentsRadius: 0.0012, + label: 'OCO-3', + parents: [ + [610718469, 'sc_iss'] + ], + controllers: [{ + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity, + position: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.0156458, -0.00195982, 0.0200232), + coverage: [610718469, Number.POSITIVE_INFINITY] + }], + postCreateFunction: (entity) => { + const rotateByEntityOrientation = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RotateByEntityOrientationController); + rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(610718469, Number.POSITIVE_INFINITY)); + } + }, + sc_iss_rapidscat: { + groups: ['instrument', 'sc_iss'], + occlusionRadius: 0.0008, + extentsRadius: 0.0002, + label: 'RapidScat', + parents: [ + [465418867.184, 'sc_iss'], + [575406069.184, ''] + ], + controllers: [{ + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity, + position: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.0100725, -0.00133401, 0.0162145), + coverage: [465418867.184, 575406069.184] + }], + postCreateFunction: (entity) => { + const rotateByEntityOrientation = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RotateByEntityOrientationController); + rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(465418867.184, 575406069.184)); + } + }, + sc_ixpe: { + groups: ['earth', 'spacecraft', 'telescope'], + occlusionRadius: 0.0055, + extentsRadius: 0.0026, + label: 'IXPE', + parents: [ + [692324766.6007013, 'earth'] + ], + trail: { + length: 5400 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_ixpe/ixpe.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_ixpe' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }] + }, + sc_jason_1: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0014, + extentsRadius: 0.004, + label: 'Jason-1', + parents: [ + [352800006.1854904, 'earth'], + [458074266.1839004, ''] + ], + trail: { + length: 6744.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_ostm/ostm.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_jason_1', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_jason_1', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + } + }] + }, + sc_jason_2: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0014, + extentsRadius: 0.004, + label: 'OSTM/Jason-2', + parents: [ + [344589947.18311954, 'earth'], + [623851269.182, ''] + ], + trail: { + length: 6744.25 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_ostm/ostm.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_jason_2' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_jason_2', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + } + }] + }, + sc_jason_3: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0014, + extentsRadius: 0.004, + label: 'Jason-3', + parents: [ + [506497796.18443054, 'earth'] + ], + trail: { + length: 6721.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_ostm/ostm.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_jason_3' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_jason_3', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + } + }] + }, + sc_jwst: { + groups: ['earth', 'spacecraft'], + radius: 0.010, + label: 'James Webb Space Telescope', + parents: [ + [693708549.184, 'earth'] + ], + trail: { + length: 5900033.33 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_jwst/webb_deployed.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_jwst/earth/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'align', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }, { + type: 'coverage', + coverage: [Number.NEGATIVE_INFINITY, 694937889.184], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + model.setUrl('$STATIC_ASSETS_URL/models/sc_jwst/webb_stowed.gltf'); + }, + exit: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + model.setUrl('$STATIC_ASSETS_URL/models/sc_jwst/webb_deployed.gltf'); + } + }] + }, + sc_landsat_5: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'Landsat 5', + parents: [ + [352800006.1854904, 'earth'], + [473889066.18410677, ''] + ], + trail: { + length: 5933.33 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_landsat_5' + }] + }, + sc_landsat_7: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.004, + extentsRadius: 0.012, + label: 'Landsat 7', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5933.33 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_landsat_7/LandSat7.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_landsat_7' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'velocity', + target: 'sc_landsat_7', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + } + }] + }, + sc_landsat_8: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.004, + extentsRadius: 0.0095, + label: 'Landsat 8', + parents: [ + [413877787.185, 'earth'] + ], + trail: { + length: 5933.33 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_landsat_8/LandSat8.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_landsat_8' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_landsat_8', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }] + }, + sc_landsat_9: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.004, + extentsRadius: 0.015, + label: 'Landsat 9', + parents: [ + [686043940.723348, 'earth'] + ], + trail: { + length: 5933.33 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_landsat_9/Landsat9.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_landsat_9' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'velocity', + target: 'sc_landsat_9', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_list: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'LIST', + parents: [ + [347025366.1839032, 'earth'] + ], + trail: { + length: 5933.33 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_list' + }] + }, + sc_m_cubed: { + groups: ['earth', 'spacecraft'], + radius: 0.0001, + label: 'M-Cubed', + parents: [ + [373032066.182, 'earth'] + ], + trail: { + length: 5768.333333333333 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_m_cubed/mCubed.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_m_cubed' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_m_cubed', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + } + }] + }, + sc_mcubed_2: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0001, + extentsRadius: 0.0002, + label: 'MCubed-2', + parents: [ + [439560067.183, 'earth'] + ], + trail: { + length: 5861.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mcubed_2/M-Cubed2.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mcubed_2' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_mcubed_2', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_mms_1: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0017, + extentsRadius: 0.013, + label: 'MMS 1', + parents: [ + [479519767.1855569, 'earth'] + ], + trail: { + length: 85994.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mms/MMS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mms_1' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg, + periodInHours: 0.00556 + }] + }, + sc_mms_2: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0017, + extentsRadius: 0.013, + label: 'MMS 2', + parents: [ + [479519767.1855569, 'earth'] + ], + trail: { + length: 85962.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mms/MMS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mms_2' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg, + periodInHours: 0.00556 + }] + }, + sc_mms_3: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0017, + extentsRadius: 0.013, + label: 'MMS 3', + parents: [ + [479519767.1855569, 'earth'] + ], + trail: { + length: 86347.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mms/MMS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mms_3' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg, + periodInHours: 0.00556 + }] + }, + sc_mms_4: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0017, + extentsRadius: 0.013, + label: 'MMS 4', + parents: [ + [479519767.1855569, 'earth'] + ], + trail: { + length: 86024.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mms/MMS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mms_4' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg, + periodInHours: 0.00556 + }] + }, + sc_nisar: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.006, + extentsRadius: 0.017, + label: 'NISAR', + parents: [ + [757339269, 'earth'] + ], + trail: { + length: 5573.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_nisar/Nisar.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'orbitalElements', + eccentricity: 0, + semiMajorAxis: 7118, + meanAngularMotion: 0.0011382582, + meanAnomalyAtEpoch: 0, + inclination: Math.PI / 180 * 98.5, + longitudeOfAscendingNode: 0, + argumentOfPeriapsis: 0, + coverage: [757339269, Number.POSITIVE_INFINITY] + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_nisar', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_noaa_14: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'NOAA 14', + parents: [ + [344589947.18311954, 'earth'], + [661006268.1833516, ''] + ], + trail: { + length: 5933.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_noaa_14' + }] + }, + sc_noaa_15: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'NOAA 15', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5933.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_noaa_15' + }] + }, + sc_noaa_16: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'NOAA 16', + parents: [ + [344589947.18311954, 'earth'], + [661006268.1833516, ''] + ], + trail: { + length: 5933.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_noaa_16' + }] + }, + sc_noaa_17: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'NOAA 17', + parents: [ + [344589947.18311954, 'earth'], + [661006268.1833516, ''] + ], + trail: { + length: 5933.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_noaa_17' + }] + }, + sc_noaa_18: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'NOAA 18', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5933.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_noaa_18' + }] + }, + sc_noaa_19: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'NOAA 19', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5933.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_noaa_19' + }] + }, + sc_nustar: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.006, + extentsRadius: 0.006, + label: 'NuSTAR', + parents: [ + [392875303.185, 'earth'] + ], + trail: { + length: 5798.66 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_nustar/nustar.gltf', + shadowEntities: ['earth'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_nustar' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis, + target: 'sun', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_oco_2: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0021, + extentsRadius: 0.004, + label: 'OCO-2', + parents: [ + [457567050.184, 'earth'] + ], + trail: { + length: 5933.333333333333 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_oco_2/oco2.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_oco_2' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + }, + secondary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }] + }, + sc_path: { + // mission cancelled + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'PATH', + parents: [ + [347025366.1839032, 'earth'] + ], + trail: { + length: 5933.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_path' + }] + }, + sc_polar: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0012, + extentsRadius: 0.005, + label: 'Polar', + parents: [ + [-121608237.81469652, 'earth'], + [262612565.1855274, ''] + ], + trail: { + length: 66571.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_polar/polar.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_polar', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_polar', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_quikscat: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0016, + extentsRadius: 0.0018, + label: 'QuikSCAT', + parents: [ + [344589947.18311954, 'earth'], + [591710469.182, ''] + ], + trail: { + length: 6061.33 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_quikscat/QuikSCAT.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_quikscat' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_quikscat', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + } + }] + }, + sc_race: { + groups: ['earth', 'spacecraft'], + radius: 0.00015, + label: 'RACE', + parents: [ + [467726467.182, 'earth'], + [467812867.182, ''] + ], + trail: { + length: 5933.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_race' + }] + }, + sc_raincube: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00035, + extentsRadius: 0.0005, + label: 'RainCube', + parents: [ + [608189026.1856545, 'earth'], + [662040069.184, ''] + ], + trail: { + length: 5743.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_raincube/Raincube.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_raincube' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_raincube', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_rax_2: { + groups: ['earth', 'spacecraft'], + radius: 0.0002, + label: 'RAX-2', + parents: [ + [373067348.182, 'earth'], + [418824067.186, ''] + ], + trail: { + length: 5743.0 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_rax_2' + }] + }, + sc_rbsp_a: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'Van Allen Probe A', + parents: [ + [399585967.183, 'earth'], + [624628869.182, ''] + ], + trail: { + length: 32214.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_rbsp/rbsp.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_rbsp_a' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_rbsp_a', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_rbsp_b: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'Van Allen Probe B', + parents: [ + [399585967.183, 'earth'], + [616766469.184, ''] + ], + trail: { + length: 32574.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_rbsp/rbsp.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_rbsp_b' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_rbsp_b', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_sac_d: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.003, + extentsRadius: 0.0045, + label: 'Aquarius', + parents: [ + [360987666.185, 'earth'], + [486907267.185, ''] + ], + trail: { + length: 5884.25 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_sac_d/aquarius.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_sac_d' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + }, + secondary: { + type: 'velocity', + target: 'sc_sac_d', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }] + }, + sc_sclp: { + groups: ['earth', 'spacecraft'], + radius: 0.004, + label: 'SCLP', + parents: [ + [347025366.1839032, 'earth'] + ], + trail: { + length: 5933 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_sclp' + }] + }, + sc_sdo: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0022, + extentsRadius: 0.00315, + label: 'SDO', + parents: [ + [505918808.18474686, 'earth'] + ], + trail: { + length: 86137.66 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_sdo/sdo.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_sdo' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_sdo', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_sentinel_6: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0026, + extentsRadius: 0.0031, + label: 'Sentinel-6 Michael Freilich', + parents: [ + [659322339.7879795, 'earth'] + ], + trail: { + length: 5933.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_sentinel_6/Sentinel6.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_sentinel_6' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_sentinel_6', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_smap: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.003, + extentsRadius: 0.009, + label: 'SMAP', + parents: [ + [476542806.1849232, 'earth'] + ], + trail: { + length: 5906.8 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_smap/SMAP.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_smap' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_smap', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }], + postCreateFunction: (entity) => { + const spin = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpinController); + spin.setJoint('arm_etc'); + spin.setRate(pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.degToRad(87.6)); + spin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis, true); + spin.setClampedToRealTime(true); + } + }, + sc_soho: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00215, + extentsRadius: 0.00425, + label: 'SOHO', + parents: [ + [265550465.18489534, 'earth'] + ], + trail: { + length: 60 * 60 * 24 * 365 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_soho/soho.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_soho', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_soho', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_sorce: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.001, + extentsRadius: 0.0022, + label: 'SORCE', + parents: [ + [344589947.18311954, 'earth'], + [635860869.185, ''] + ], + trail: { + length: 5812.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_sorce/sorce.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_sorce' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_sorce', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + } + }] + }, + sc_starling_1: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00023, + extentsRadius: 0.00076, + label: 'Starling-1', + parents: [ + [Number.NEGATIVE_INFINITY, 'earth'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_starling/starling.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_starling_1' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_starling_1', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_starling_2: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00023, + extentsRadius: 0.00076, + label: 'Starling-2', + parents: [ + [Number.NEGATIVE_INFINITY, 'earth'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_starling/starling.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_starling_2' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_starling_2', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_starling_3: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00023, + extentsRadius: 0.00076, + label: 'Starling-3', + parents: [ + [Number.NEGATIVE_INFINITY, 'earth'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_starling/starling.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_starling_3' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_starling_3', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_starling_4: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00023, + extentsRadius: 0.00076, + label: 'Starling-4', + parents: [ + [Number.NEGATIVE_INFINITY, 'earth'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_starling/starling.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_starling_4' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_starling_4', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis + } + }] + }, + sc_suomi_npp: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0022, + extentsRadius: 0.008, + label: 'Suomi NPP', + parents: [ + [373067348.01, 'earth'] + ], + trail: { + length: 5798.66 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_npp/NPP.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_suomi_npp' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_suomi_npp', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }] + }, + sc_swift: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0028, + extentsRadius: 0.0028, + label: 'Swift', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5933 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_swift' + }] + }, + sc_swot: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.005, + extentsRadius: 0.009, + label: 'SWOT', + parents: [ + [347025366.1839032, 'earth'] + ], + trail: { + length: 5933 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_swot_v2/swot.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_swot' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_swot', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + } + }] + }, + sc_tdrs_3: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.0085, + label: 'TDRS 3', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 86137.33 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tdrs_3' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_tdrs_5: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.0085, + label: 'TDRS 5', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 86137.66 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tdrs_5' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_tdrs_6: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.0085, + label: 'TDRS 6', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 86137.66 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tdrs_6' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_tdrs_7: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.0085, + label: 'TDRS 7', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 86151.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tdrs_7' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_tdrs_8: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.0085, + label: 'TDRS 8', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 86151.2 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tdrs_8' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_tdrs_9: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.0085, + label: 'TDRS 9', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 86151.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tdrs_9' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_tdrs_10: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.0085, + label: 'TDRS 10', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 86151.2 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tdrs_10' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_tdrs_11: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.0085, + label: 'TDRS 11', + parents: [ + [412868947.185, 'earth'] + ], + trail: { + length: 86151.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tdrs_11' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_tdrs_12: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.0085, + label: 'TDRS 12', + parents: [ + [443808067.185, 'earth'] + ], + trail: { + length: 86151.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tdrs_12' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_tdrs_13: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.0085, + label: 'TDRS 13', + parents: [ + [556338669.183, 'earth'] + ], + trail: { + length: 86151.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tdrs_13' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }] + }, + sc_terra: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0034, + extentsRadius: 0.012, + label: 'Terra', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5933.33 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_terra/Terra.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_terra' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_terra', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + } + }] + }, + sc_tess: { + groups: ['earth', 'spacecraft', 'telescope'], + occlusionRadius: 0.002, + extentsRadius: 0.003, + label: 'TESS', + parents: [ + [577366932.3626, 'earth'] + ], + trail: { + length: 591840 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_tess/TESS.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_tess/earth/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }] + }, + sc_themis_a: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.000400, + extentsRadius: 0.00170, + label: 'THEMIS A', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 98428.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_themis/themis.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_themis_a' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis, + periodInHours: 0.0008333 + }] + }, + sc_themis_d: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.000400, + extentsRadius: 0.00170, + label: 'THEMIS D', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 114807.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_themis/themis.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_themis_d' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis, + periodInHours: 0.0008333 + }] + }, + sc_themis_e: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.000400, + extentsRadius: 0.00170, + label: 'THEMIS E', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 105907.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_themis/themis.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_themis_e' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis, + periodInHours: 0.0008333 + }] + }, + sc_timed: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0015, + extentsRadius: 0.005, + label: 'TIMED', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5933 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_timed' + }] + }, + sc_trmm: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.002550, + extentsRadius: 0.0073, + label: 'TRMM', + parents: [ + [-66052736.817, 'earth'], + [482328067.186, ''] + ], + trail: { + length: 5545.6 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_trmm/TRMM.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'orbitalElements', + eccentricity: 0.00111201719, + semiMajorAxis: 6744.5, + meanAngularMotion: 0.0011382582, + meanAnomalyAtEpoch: 0, + inclination: Math.PI / 180 * 30, + longitudeOfAscendingNode: 0, + argumentOfPeriapsis: 0, + coverage: [-66052736.817, 482328067.186] + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_trmm', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + } + }] + }, + sc_uars: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00535, + extentsRadius: 0.00535, + label: 'UARS', + parents: [ + [352800006.1854904, 'earth'], + [370106644.184, ''] + ], + trail: { + length: 5490.0 + }, + controllers: [{ + type: 'animdata', + url: 'sc_uars', + dataType: 'pos' + }] + }, + sc_wind: { + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.00120, + extentsRadius: 0.00750, + label: 'WIND', + parents: [ + [543931270, 'earth'] + ], + trail: { + length: 16485927.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_wind/wind.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_wind/earth/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg + }, + secondary: { + type: 'velocity', + target: 'sc_wind', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + } + }] + }, + sc_wise: { + // no model at all, 2D still in explorer + groups: ['earth', 'spacecraft'], + occlusionRadius: 0.0014200, + extentsRadius: 0.001420, + label: 'WISE', + parents: [ + [344589947.18311954, 'earth'] + ], + trail: { + length: 5715.4 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_wise' + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/entity_utils.js": +/*!*******************************************************!*\ + !*** ../pioneer/scripts/src/entities/entity_utils.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "EntityUtils": function() { return /* binding */ EntityUtils; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); + + +/** + * A collection of utilities for entity creation. + */ +class EntityUtils { + /** + * Adds a geyser to an entity. + * @param {Pioneer.Entity} entity + * @param {number} size + * @param {number} alpha + * @param {number} particleNumber + * @param {number} speed + * @param {number} spread + * @param {number[]} position + * @param {number[] | undefined} direction + */ + static addGeyser(entity, size, alpha, particleNumber, speed, spread, position, direction) { + const particleSpray = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ParticleSprayComponent); + particleSpray.setNumberOfParticles(particleNumber); + particleSpray.setSizeOfParticles(0.25 * size * spread); + particleSpray.setSpeedOfParticles(speed * size); + particleSpray.setColorOfParticles(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 0.5 * alpha)); + particleSpray.setSpread(1 * spread); + particleSpray.setParticleSpacingRandom(false); + particleSpray.setLength(2.5 * size); + particleSpray.setOriginOffset(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(position[0], position[1], position[2])); + particleSpray.setDirection(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(direction[0], direction[1], direction[2])); + } + + /** + * Shows the subobject of an entity only during the given interval. + * @param {Pioneer.Entity} entity + * @param {string} subObjectName + * @param {number} startTime + * @param {number} endTime + */ + static showSubObjectDuringInterval(entity, subObjectName, startTime, endTime) { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent); + model.setHiddenObject(subObjectName, true); + const coverageController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CoverageController); + coverageController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(startTime, endTime)); + coverageController.setEnterFunction((entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent); + model.setHiddenObject(subObjectName, false); + }); + coverageController.setExitFunction((entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent); + model.setHiddenObject(subObjectName, true); + }); + } +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/jupiter_irregular_moons.js": +/*!******************************************************************!*\ + !*** ../pioneer/scripts/src/entities/jupiter_irregular_moons.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + aitne: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1.5, + label: 'Aitne', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'aitne/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + ananke: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 14.0, + label: 'Ananke', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [14, 14, 14], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'ananke/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + aoede: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 2.0, + label: 'Aoede', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2, 2, 2], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'aoede/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + arche: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1.5, + label: 'Arche', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'arche/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + autonoe: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 2.0, + label: 'Autonoe', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2, 2, 2], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'autonoe/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + callirrhoe: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 4.3, + label: 'Callirrhoe', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [4.3, 4.3, 4.3], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'callirrhoe/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + carme: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 23.0, + label: 'Carme', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [23, 23, 23], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'carme/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + carpo: { + groups: ['jupiter', 'moons', 'irregular'], + radius: 1.5, + label: 'Carpo', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'carpo/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + chaldene: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1.9, + label: 'Chaldene', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.9, 1.9, 1.9], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'chaldene/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + cyllene: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 1.0, + label: 'Cyllene', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'cyllene/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + dia: { + groups: ['jupiter', 'moons', 'irregular', 'himalia'], + radius: 2, + label: 'Dia', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: 2, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'dia/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + eirene: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 2, + label: 'Eirene', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: 2, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'eirene/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + elara: { + groups: ['jupiter', 'moons', 'irregular', 'himalia'], + radius: 43.0, + label: 'Elara', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [43, 43, 43], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'elara/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + erinome: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1.6, + label: 'Erinome', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.6, 1.6, 1.6], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'erinome/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + ersa: { + groups: ['jupiter', 'moons', 'irregular', 'himalia'], + radius: 1.5, + label: 'Ersa', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: 1.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'ersa/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + euanthe: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1.5, + label: 'Euanthe', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'euanthe/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + eukelade: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 2.0, + label: 'Eukelade', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2, 2, 2], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'eukelade/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + eupheme: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1, + label: 'Eupheme', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'eupheme/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + euporie: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1.0, + label: 'Euporie', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'euporie/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + eurydome: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 1.5, + label: 'Eurydome', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'eurydome/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + harpalyke: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 2.2, + label: 'Harpalyke', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.2, 2.2, 2.2], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'harpalyke/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + hegemone: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 1.5, + label: 'Hegemone', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'hegemone/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + helike: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 2.0, + label: 'Helike', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2, 2, 2], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'helike/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + hermippe: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 2.0, + label: 'Hermippe', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2, 2, 2], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'hermippe/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + herse: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1.0, + label: 'Herse', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'herse/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + himalia: { + groups: ['jupiter', 'moons', 'irregular', 'himalia'], + radius: 85.0, + label: 'Himalia', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [85, 85, 85], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'himalia/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + iocaste: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 2.6, + label: 'Iocaste', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.6, 2.6, 2.6], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'iocaste/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + isonoe: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1.9, + label: 'Isonoe', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.9, 1.9, 1.9], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'isonoe/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_li: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1, + label: 'Jupiter LI', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_li/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lii: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 0.5, + label: 'Jupiter LII', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lii/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_liv: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 0.5, + label: 'Jupiter LIV', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_liv/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lv: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1, + label: 'Jupiter LV', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lv/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lvi: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 0.5, + label: 'Jupiter LVI', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lvi/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lix: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 1, + label: 'Jupiter LIX', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lix/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lxi: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1, + label: 'Jupiter LXI', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lxi/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lxiii: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1, + label: 'Jupiter LXIII', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lxiii/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lxiv: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1, + label: 'Jupiter LXIV', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lxiv/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lxvi: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1, + label: 'Jupiter LXVI', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lxvi/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lxvii: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 1, + label: 'Jupiter LXVII', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lxvii/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lxviii: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1, + label: 'Jupiter LXVIII', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lxviii/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lxix: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 0.5, + label: 'Jupiter LXIX', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lxix/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lxx: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1.5, + label: 'Jupiter LXX', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lxx/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + jupiter_lxxii: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1, + label: 'Jupiter LXXII', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter_lxxii/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + kale: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1.0, + label: 'Kale', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'kale/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + kallichore: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1.0, + label: 'Kallichore', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'kallichore/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + kalyke: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 2.6, + label: 'Kalyke', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.6, 2.6, 2.6], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'kalyke/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + kore: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 1.0, + label: 'Kore', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'kore/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + leda: { + groups: ['jupiter', 'moons', 'irregular', 'himalia'], + radius: 10.0, + label: 'Leda', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [10, 10, 10], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'leda/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + lysithea: { + groups: ['jupiter', 'moons', 'irregular', 'himalia'], + radius: 18.0, + label: 'Lysithea', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [18, 18, 18], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'lysithea/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + megaclite: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 2.7, + label: 'Megaclite', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.7, 2.7, 2.7], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'megaclite/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + mneme: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1.0, + label: 'Mneme', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'mneme/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + orthosie: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1.0, + label: 'Orthosie', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'orthosie/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + pandia: { + groups: ['jupiter', 'moons', 'irregular', 'himalia'], + radius: 1.5, + label: 'Pandia', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: 1.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'pandia/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + pasiphae: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 30.0, + label: 'Pasiphae', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [30, 30, 30], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'pasiphae/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + pasithee: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1.0, + label: 'Pasithee', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'pasithee/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + philophrosyne: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 1, + label: 'Philophrosyne', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'philophrosyne/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + praxidike: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 3.4, + label: 'Praxidike', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [3.4, 3.4, 3.4], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'praxidike/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2003_j_2: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1, + label: 'S/2003 J 2', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2003_j_2/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2003_j_4: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 1, + label: 'S/2003 J 4', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2003_j_4/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2003_j_9: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 0.5, + label: 'S/2003 J 9', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2003_j_9/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2003_j_10: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1, + label: 'S/2003 J 10', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2003_j_10/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2003_j_12: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 0.5, + label: 'S/2003 J 12', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2003_j_12/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2003_j_16: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1, + label: 'S/2003 J 16', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2003_j_16/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2003_j_23: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 1, + label: 'S/2003 J 23', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2003_j_23/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2003_j_24: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1, + label: 'S/2003 J 24', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2003_j_24/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2011_j_3: { + groups: ['jupiter', 'moons', 'irregular', 'himalia'], + radius: 1.5, + label: 'S/2011 J 3', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2011_j_3/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2016_j_3: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1, + label: 'S/2016 J 3', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2016_j_3/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2016_j_4: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 0.5, + label: 'S/2016 J 4', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2016_j_4/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2018_j_2: { + groups: ['jupiter', 'moons', 'irregular', 'himalia'], + radius: 1.5, + label: 'S/2018 J 2', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2018_j_2/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2018_j_3: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 0.5, + label: 'S/2018 J 3', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2018_j_3/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2018_j_4: { + groups: ['jupiter', 'moons', 'irregular', 'carpo'], + radius: 1, + label: 'S/2018 J 4', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2018_j_4/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2021_j_1: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 0.5, + label: 'S/2021 J 1', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2021_j_1/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2021_j_2: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1, + label: 'S/2021 J 2', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2021_j_2/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2021_j_3: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1, + label: 'S/2021 J 3', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2021_j_3/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2021_j_4: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 0.5, + label: 'S/2021 J 4', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2021_j_4/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2021_j_5: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 1, + label: 'S/2021 J 5', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2021_j_5/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2021_j_6: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 0.5, + label: 'S/2021 J 6', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2021_j_6/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2022_j_1: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 0.5, + label: 'S/2022 J 1', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2022_j_1/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2022_j_2: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 0.5, + label: 'S/2022 J 2', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2022_j_2/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2022_j_3: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 0.5, + label: 'S/2022 J 3', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2022_j_3/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + sinope: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 19.0, + label: 'Sinope', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [19, 19, 19], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'sinope/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + sponde: { + groups: ['jupiter', 'moons', 'irregular', 'pasiphae'], + radius: 1.0, + label: 'Sponde', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'sponde/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + taygete: { + groups: ['jupiter', 'moons', 'irregular', 'carme'], + radius: 2.5, + label: 'Taygete', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.5, 2.5, 2.5], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'taygete/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + thelxinoe: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 1.0, + label: 'Thelxinoe', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1, 1, 1], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'thelxinoe/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + themisto: { + groups: ['jupiter', 'moons', 'irregular'], + radius: 4.0, + label: 'Themisto', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [4, 4, 4], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'themisto/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + thyone: { + groups: ['jupiter', 'moons', 'irregular', 'ananke'], + radius: 2.0, + label: 'Thyone', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2, 2, 2], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'thyone/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + valetudo: { + groups: ['jupiter', 'moons', 'irregular'], + radius: 0.5, + label: 'Valetudo', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.5, + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'valetudo/jupiter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/jupiter_regular_moons.js": +/*!****************************************************************!*\ + !*** ../pioneer/scripts/src/entities/jupiter_regular_moons.js ***! + \****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/** @module pioneer-scripts */ + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + adrastea: { + groups: ['jupiter', 'moons', 'amalthea', 'inner', 'regular'], + radius: 8.2, + label: 'Adrastea', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [8.2, 8.2, 8.2], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'adrastea/jupiter/orb' + }, { + type: 'dynamo', + url: 'adrastea/ori' + }] + }, + amalthea: { + groups: ['jupiter', 'moons', 'amalthea', 'inner', 'regular'], + radius: 83.5, + label: 'Amalthea', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [83.5, 83.5, 83.5], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'amalthea/jupiter/orb' + }, { + type: 'dynamo', + url: 'amalthea/ori' + }] + }, + callisto: { + groups: ['jupiter', 'moons', 'main', 'galilean', 'regular'], + radius: 2410.3, + label: 'Callisto', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + spheroid: { + equatorialRadius: 2410.3, + polarRadius: 2410.3, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'callisto/color_$SIZE_$FACE.png', + sizes: [4, 512] + } + }, + shadowEntities: ['jupiter', 'io', 'europa', 'ganymede'] + }, + controllers: [{ + type: 'dynamo', + url: 'callisto/jupiter/orb' + }, { + type: 'dynamo', + url: 'callisto/ori' + }] + }, + europa: { + groups: ['jupiter', 'moons', 'main', 'galilean', 'regular'], + radius: 1569.0, + label: 'Europa', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + spheroid: { + equatorialRadius: 1569.0, + polarRadius: 1569.0, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'europa/color_$SIZE_$FACE.png', + sizes: [4, 512, 1024] + } + }, + shadowEntities: ['jupiter', 'io', 'callisto', 'ganymede'] + }, + controllers: [{ + type: 'dynamo', + url: 'europa/jupiter/orb' + }, { + type: 'dynamo', + url: 'europa/ori' + }] + }, + ganymede: { + groups: ['jupiter', 'moons', 'main', 'galilean', 'regular'], + radius: 2634.1, + label: 'Ganymede', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + spheroid: { + equatorialRadius: 2634.1, + polarRadius: 2634.1, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'ganymede/color_$SIZE_$FACE.png', + sizes: [4, 512] + } + }, + shadowEntities: ['jupiter', 'io', 'europa', 'callisto'] + }, + controllers: [{ + type: 'dynamo', + url: 'ganymede/jupiter/orb' + }, { + type: 'dynamo', + url: 'ganymede/ori' + }] + }, + io: { + groups: ['jupiter', 'moons', 'main', 'galilean', 'regular'], + radius: 1821.3, + label: 'Io', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + spheroid: { + equatorialRadius: 1821.3, + polarRadius: 1821.3, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'io/color_$SIZE_$FACE.png', + sizes: [4, 512, 1024] + } + // I believe there is a heightmap version as well, but the min-to-max radius is not noticable + }, + shadowEntities: ['jupiter', 'europa', 'ganymede', 'callisto'] + }, + controllers: [{ + type: 'dynamo', + url: 'io/jupiter/orb' + }, { + type: 'dynamo', + url: 'io/ori' + }] + }, + metis: { + groups: ['jupiter', 'moons', 'amalthea', 'inner', 'regular'], + radius: 21.5, + label: 'Metis', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [21.5, 21.5, 21.5], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'metis/jupiter/orb' + }, { + type: 'dynamo', + url: 'metis/ori' + }] + }, + thebe: { + groups: ['jupiter', 'moons', 'amalthea', 'inner', 'regular'], + radius: 49.0, + label: 'Thebe', + parents: [ + [Number.NEGATIVE_INFINITY, 'jupiter'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [49, 49, 49], + shadowEntities: ['jupiter'] + }, + controllers: [{ + type: 'dynamo', + url: 'thebe/jupiter/orb' + }, { + type: 'dynamo', + url: 'thebe/ori' + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/lunar_spacecraft.js": +/*!***********************************************************!*\ + !*** ../pioneer/scripts/src/entities/lunar_spacecraft.js ***! + \***********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + sc_apollo_15: { + groups: ['moon', 'spacecraft'], + radius: 0.004, + label: 'Apollo 15', + parents: [ + [-897044358.3260887, 'moon'], + [-896822958.3195117, ''] + ], + trail: { + length: 6855.0 + }, + controllers: [{ + type: 'animdata', + url: 'sc_apollo_15', + dataType: 'pos' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + sc_artemis_1: { + groups: ['moon', 'spacecraft'], + radius: 0.005, + label: 'Artemis I', + parents: [ + [721860361, 'earth'], + [724052473, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_artemis_1/artemis_cmsm.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_artemis_1/earth/pos' + }, { + type: 'align', + primary: { + type: 'velocity', + target: 'sc_artemis_1', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + }, + secondary: { + type: 'align', + target: 'moon', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }] + }, + sc_capstone: { + groups: ['moon', 'spacecraft'], + radius: 0.0005, + label: 'CAPSTONE', + parents: [ + [710192447.9999855, 'earth'], + [721583059, 'moon'] + ], + trail: { + length: undefined, + lengthCoverages: [ + [4000000, Number.NEGATIVE_INFINITY, 721583059], + [1210909, 721583059, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_capstone/capstone.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_capstone/earth/orb' + }, { + type: 'dynamo', + url: 'sc_capstone/moon/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + }, + secondary: { + type: 'align', + target: 'moon', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }] + }, + sc_clementine: { + groups: ['moon', 'spacecraft'], + radius: 0.002, + label: 'Clementine', + parents: [ + [-187185539.81536362, 'moon'], + [-178496939.81459716, ''] + ], + trail: { + length: 5408.5 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_clementine/clementine.gltf', + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_clementine/moon/all', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg + }, + secondary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + } + }] + }, + sc_grail_a: { + groups: ['moon', 'spacecraft'], + radius: 0.001, + label: 'Ebb', + parents: [ + [368763000, 'moon'], + [414201667.18513304, ''] + ], + trail: { + length: 41115.75 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_grail/grail_b.gltf', + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_grail_a/moon/all', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'velocity', + target: 'sc_grail_a', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg + }, + secondary: { + type: 'point', + target: 'moon', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }] + }, + sc_grail_b: { + groups: ['moon', 'spacecraft'], + radius: 0.001, + label: 'Flow', + parents: [ + [368763000, 'moon'], + [414201667.18513304, ''] + ], + trail: { + length: 41239.8 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_grail/grail_b.gltf', + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_grail_b/moon/all', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'velocity', + target: 'sc_grail_b', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg + }, + secondary: { + type: 'point', + target: 'moon', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }] + }, + sc_ladee: { + groups: ['moon', 'spacecraft'], + radius: 0.0012, + label: 'LADEE', + parents: [ + [431798467.18253195, 'moon'], + [451355187.44558257, ''] + ], + trail: { + length: 7889.57 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_ladee/ladee.gltf', + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_ladee/moon/all', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'velocity', + target: 'sc_ladee', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg + }, + secondary: { + type: 'point', + target: 'moon', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }] + }, + sc_lcross: { + groups: ['moon', 'spacecraft'], + occlusionRadius: 0.00130, + extentsRadius: 0.0022, + label: 'LCROSS', + parents: [ + [298635466.0304444, 'moon'], + [308360200.75, ''] + ], + trail: { + length: 3598022.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_lcross/lcross.gltf', + rotate: [ + { z: -90 } + ], + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_lcross/moon/all', + dataType: 'pos', + coverage: [Number.NEGATIVE_INFINITY, 308360200.750] + }, { + type: 'align', + primary: { + type: 'velocity', + target: 'sc_lcross', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg + }, + secondary: { + type: 'point', + target: 'moon', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }] + }, + sc_lcross_impact_site: { + groups: ['moon', 'sc_lcross', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'LCROSS Impact Site', + parents: [ + [298635466.0304444, 'moon'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(-1.4782008103461848, -0.8648271467797672, 0), + coverage: [298635466.0304444, Number.POSITIVE_INFINITY] + }] + }, + sc_lunar_flashlight: { + groups: ['moon', 'spacecraft'], + occlusionRadius: 0.00025, + extentsRadius: 0.0005, + label: 'Lunar Flashlight', + parents: [ + [724019554, 'earth'], + [737164869, ''] + ], + trail: { + length: 10000000 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_lunar_flashlight/lunar_flashlight.gltf', + shadowEntities: ['earth'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_lunar_flashlight/earth_v3' + }, { + type: 'align', + primary: { + type: 'align', + target: 'moon', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + }, + secondary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + } + }] + }, + sc_lunar_icecube: { + groups: ['moon', 'spacecraft'], + occlusionRadius: 0.0002, + extentsRadius: 0.0012, + label: 'Lunar IceCube', + parents: [ + [721864426, 'earth'], + [734111601, 'moon'] + ], + trail: { + length: undefined, + lengthCoverages: [ + [3000000, Number.NEGATIVE_INFINITY, 734111601], + [441920, 734111601, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_lunar_icecube/lunar_icecube.gltf', + shadowEntities: ['earth', 'moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_lunar_icecube/earth/pos' + }, { + type: 'dynamo', + url: 'sc_lunar_icecube/moon/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + }, + secondary: { + type: 'align', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }] + }, + sc_lunar_prospector: { + groups: ['moon', 'spacecraft'], + occlusionRadius: 0.00065300, + extentsRadius: 0.0022, + label: 'Lunar Prospector', + parents: [ + [-62206800, 'moon'], + [-13402020, ''] + ], + trail: { + length: 7260.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_lunar_prospector/lunar_prospector.gltf', + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_lunar_prospector/moon/all', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'align', + target: 'moon', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg, + periodInHours: 0.008333 + }] + }, + sc_lunar_reconnaissance_orbiter: { + groups: ['moon', 'spacecraft'], + occlusionRadius: 0.00272, + extentsRadius: 0.0038, + label: 'Lunar Reconnaissance Orbiter', + parents: [ + [298635426.1844444, 'earth'], + [298929666, 'moon'] + ], + trail: { + length: 7106.66, + lengthCoverages: [ + [1000000, Number.NEGATIVE_INFINITY, 299040641], + [7106.66, 299040641, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_lunar_reconnaissance_orbiter/LRO.gltf', + rotate: [ + { z: -90 } + ], + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_lunar_reconnaissance_orbiter/earth/orb' + }, { + type: 'dynamo', + url: 'sc_lunar_reconnaissance_orbiter/moon/orb' + }, { + type: 'align', + primary: { + type: 'velocity', + target: 'sc_lunar_reconnaissance_orbiter', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg + }, + secondary: { + type: 'point', + target: 'moon', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }, { + type: 'dynamo', + url: 'sc_lunar_reconnaissance_orbiter/ori' + }] + }, + sc_smart_1: { + // no model at all; 2D still + groups: ['moon', 'spacecraft'], + occlusionRadius: 0.0015, + extentsRadius: 0.006530, + label: 'SMART-1', + parents: [ + [117977163.35299999, 'moon'], + [210585600, ''] + ], + trail: { + length: 273091.0 + }, + controllers: [{ + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }, { + type: 'animdata', + url: 'sc_smart_1/moon/all', + dataType: 'pos' + }] + }, + sc_themis_b: { + groups: ['moon', 'spacecraft'], + occlusionRadius: 0.000400, + extentsRadius: 0.00170, + label: 'ARTEMIS P1', + parents: [ + [366638466.1829504, 'moon'], + [694267209.1839211, ''] + ], + trail: { + length: 94838.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_themis/themis.gltf', + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_themis_b/moon/all', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + } + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis, + periodInHours: 0.0008333 + }] + }, + sc_themis_c: { + groups: ['moon', 'spacecraft'], + occlusionRadius: 0.000400, + extentsRadius: 0.00170, + label: 'ARTEMIS P2', + parents: [ + [366638466.1829504, 'moon'], + [694267209.1839211, ''] + ], + trail: { + length: 204186.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_themis/themis.gltf', + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_themis_c/moon/all', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + } + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis, + periodInHours: 0.0008333 + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/mars_moons.js": +/*!*****************************************************!*\ + !*** ../pioneer/scripts/src/entities/mars_moons.js ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/** @module pioneer-scripts */ + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + phobos: { + groups: ['mars', 'moons'], + radius: 14.0, + label: 'Phobos', + parents: [ + [Number.NEGATIVE_INFINITY, 'mars'] + ], + trail: { + length: undefined, + color: [0.89, 0.51, 0.35, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/phobos/phobos.gltf', + scale: [1, 1, 1], + rotate: [ + { z: 90 }, + { y: 90 } + ], + shadowEntities: ['mars'] + }, + controllers: [{ + type: 'dynamo', + url: 'phobos/mars/orb' + }, { + type: 'dynamo', + url: 'phobos/ori' + }] + }, + deimos: { + groups: ['mars', 'moons'], + radius: 8.70951, + label: 'Deimos', + parents: [ + [Number.NEGATIVE_INFINITY, 'mars'] + ], + trail: { + length: undefined, + color: [0.89, 0.51, 0.35, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/deimos/deimos.gltf', + scale: [1, 1, 1], + rotate: [ + { y: -180 } + ], + shadowEntities: ['mars'] + }, + controllers: [{ + type: 'dynamo', + url: 'deimos/mars/orb' + }, { + type: 'dynamo', + url: 'deimos/ori' + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/mars_spacecraft.js": +/*!**********************************************************!*\ + !*** ../pioneer/scripts/src/entities/mars_spacecraft.js ***! + \**********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + sc_mars_2020: { + groups: ['mars', 'spacecraft', 'landers'], + occlusionRadius: 0.0015, + extentsRadius: 0.003, + label: 'Mars 2020', + parents: [ + [649385564, 'earth'], + [649595376, 'sun'], + [666932224, 'mars'], + [666952859, 'sc_mars_2020_landing_site'] + ], + trail: { + length: 10000000.0, + lengthCoverages: [ + [10000000, 649385564, 666932224], + [3000, 666932224, 666953098.003000], + [9676800, 666953098.003000 + 9676800, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mars_2020/cruise_whole/msl_cruise_stage.gltf', + rotate: [ + { x: -90 } + ], + shadowEntities: ['mars'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mars_2020/earth/orb' + }, { + type: 'dynamo', + url: 'sc_mars_2020/sun/orb' + }, { + type: 'dynamo', + url: 'sc_mars_2020/mars/pos' + }, { + type: 'dynamo', + url: 'sc_mars_2020/surface/lin' + }, { + type: 'custom', + func: (entity) => { // This is needed because M2020_LANDING_SITE is slightly off of M2020_DIMU_A. + const controller = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController); + controller.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-0.125148, 0.026867, -0.023641)); + return controller; + }, + coverage: [666952859, 666953098.003000] + }, { + type: 'dynamo', + url: 'sc_mars_2020/quat' + }, { + type: 'dynamo', + url: 'sc_mars_2020/surface/quat_v2' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 0.00833333333, + relativeToTime: 649385564, + coverage: [649385564, 666952859] + }, { + type: 'rotateByEntityOrientation', // Rotate the position for IAU_MARS dynamo. + entityForOrientation: 'mars', + coverage: [666952859, Number.POSITIVE_INFINITY] + }, { + type: 'custom', + func: (entity) => { + const groundClamp = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.GroundClampController); + groundClamp.setDistanceFromGround(0.001); + groundClamp.setGroundComponentRef('mars', 'cmts'); + groundClamp.setUp(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg); + groundClamp.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(666953086.614, Number.POSITIVE_INFINITY)); + return groundClamp; + } + }, { + type: 'coverage', // Make it change to Perseverance when it lands. + coverage: [666953086.614, Number.POSITIVE_INFINITY], + enter: (entity) => { + const div = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent); + div.getDiv().innerHTML.replace('Mars 2020', 'Perseverance'); + }, + exit: (entity) => { + const div = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent); + div.getDiv().innerHTML.replace('Perseverance', 'Mars 2020'); + } + }, { + type: 'coverage', // Make the first part of the rover surface trail start at landing. + coverage: [666953098.003000, 666953098.003000 + 9676800], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setStartTime(666953098.003000); + trail.setRelativeStartTime(false); + } + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeStartTime(true); + } + } + }, { + type: 'coverage', // Coverage for making trail relative to entity. + coverage: [666932224, Number.POSITIVE_INFINITY], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(true); + } + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(false); + } + } + }, { + type: 'coverage', // Change the model to the rover at the right time. + coverage: [666953086.614, Number.POSITIVE_INFINITY], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_2020/rover/perseverance.gltf'); + model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.5, -0.5, 0.5, -0.5)); + model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0, 0.001)); + }, + exit: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_2020/cruise_whole/msl_cruise_stage.gltf'); + model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.7071067811865478, -0.7071067811865472, 0, 0)); + model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0, 0)); + } + }, { + type: 'coverage', // Make the trail not fade when on the ground. + coverage: [666953098.003000, Number.POSITIVE_INFINITY], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setIgnoreDistance(true); + } + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setIgnoreDistance(false); + } + } + }, { // Remove the cruise pieces when starting the EDL. + type: 'coverage', + coverage: [666952458, 666953086.614], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setHiddenObject('solar_panels', true); + model.setHiddenObject('frame_etc', true); + } + }, + exit: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setHiddenObject('solar_panels', false); + model.setHiddenObject('frame_etc', false); + } + } + }, { + // Since the ground clamp controller and the CMTS map the trail will need to be repopulated. + // Right now the only method is to add an update every few seconds: + type: 'coverage', + coverage: [666953086.614, Number.POSITIVE_INFINITY], + update: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.resetPoints(); + } + }, + updateInterval: 10 + }] + }, + sc_mars_2020_landing_site: { + groups: ['mars', 'sc_mars_2020', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'Mars 2020 Landing Site', + parents: [ + [649385563.6433017, 'mars'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(0.32191947313922714, 1.351772964399859, -2.2364351843552868), + coverage: [649385563.6433017, Number.POSITIVE_INFINITY] + }] + }, + sc_mars_science_laboratory: { + groups: ['mars', 'spacecraft', 'landers'], + occlusionRadius: 0.001515, + extentsRadius: 0.004, + label: 'Mars Science Laboratory', + parents: [ + [375594733, 'earth'], + [376039259, 'sun'], + [397477501, 'mars'], + [397502386.832, 'sc_mars_science_laboratory_landing_site'] + ], + trail: { + length: 10000000, + lengthCoverages: [ + [10000000, 375594733, 397501373], + [3000, 397501373, 397502386.832 + 9676800], + [9676800, 397502386.832 + 9676800, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mars_science_laboratory/cruise/msl_cruisestage.gltf', + rotate: [ + { x: -90 } + ], + shadowEntities: ['mars'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mars_science_laboratory/earth/orb' + }, { + type: 'dynamo', + url: 'sc_mars_science_laboratory/sun/orb' + }, { + type: 'dynamo', + url: 'sc_mars_science_laboratory/mars/orb' + }, { + type: 'dynamo', + url: 'sc_mars_science_laboratory/edl/pos' + }, { + type: 'custom', + func: (entity) => { // This is needed because MSL_LANDING_SITE is slightly off of MSL_SITE_1. + const controller = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController); + controller.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.002583, 0.002995, 0.001937)); + return controller; + }, + coverage: [397501373, 397502386.832] + }, { + type: 'dynamo', + url: 'sc_mars_science_laboratory/surface/lin_v2' + }, { + type: 'dynamo', + url: 'sc_mars_science_laboratory/quat' + }, { + type: 'dynamo', + url: 'sc_mars_science_laboratory/surface/quat_v2' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 0.00833333333, + relativeToTime: 375594733, + coverage: [375594733, 397501866] + }, { + type: 'rotateByEntityOrientation', // Rotate the position for IAU_MARS dynamo. + entityForOrientation: 'mars', + rotatingOrientation: false, + coverage: [397501373, Number.POSITIVE_INFINITY] + }, { + type: 'rotateByEntityOrientation', // Rotate the orientation for IAU_MARS dynamo. + entityForOrientation: 'mars', + rotatingPosition: false, + coverage: [397502386.832, Number.POSITIVE_INFINITY] + }, { + type: 'custom', + func: (entity) => { + // Add a ground clamp when the rover is on the ground. The dymamo gets pretty close, but this is closer. + const groundClamp = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.GroundClampController); + groundClamp.setDistanceFromGround(0.00098); + groundClamp.setGroundComponentRef('mars', 'cmts'); + groundClamp.setUp(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg); + groundClamp.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(397502386.832, Number.POSITIVE_INFINITY)); + return groundClamp; + } + }, { + type: 'coverage', // Make it change to Curiosity when it lands. + coverage: [397502386.832, Number.POSITIVE_INFINITY], + enter: (entity) => { + const div = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent); + div.getDiv().innerHTML.replace('Mars Science Laboratory', 'Curiosity'); + }, + exit: (entity) => { + const div = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent); + div.getDiv().innerHTML.replace('Curiosity', 'Mars Science Laboratory'); + } + }, { // Coverage for making trail relative to entity. + type: 'coverage', + coverage: [397501373, Number.POSITIVE_INFINITY], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(true); + } + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(false); + } + } + }, { // Change the model to the rover at the right time. + type: 'coverage', + coverage: [397502324, Number.POSITIVE_INFINITY], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_science_laboratory/rover/curiosity_static.gltf'); + model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.5, -0.5, 0.5, -0.5)); + model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0, 0.001)); + } + }, + exit: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_science_laboratory/cruise/msl_cruisestage.gltf'); + model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.7071067811865478, -0.7071067811865472, 0, 0)); + model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0, 0)); + } + } + }, { + type: 'coverage', // Make the trail not fade when on the ground. + coverage: [397502386.832, Number.POSITIVE_INFINITY], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setIgnoreDistance(true); + } + + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setIgnoreDistance(false); + } + } + }, { // Remove the cruise pieces when starting the EDL. + type: 'coverage', + coverage: [397501758, 397502386.832], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setHiddenObject('solar_panels', true); + model.setHiddenObject('frame_etc', true); + } + }, + exit: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setHiddenObject('solar_panels', false); + model.setHiddenObject('frame_etc', false); + } + } + }, { + // Since the ground clamp controller and the CMTS map the trail will need to be repopulated. + // Right now the only method is to add an update every few seconds: + type: 'coverage', + coverage: [397502386.832, Number.POSITIVE_INFINITY], + update: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.resetPoints(); + } + }, + updateInterval: 10 + }] + }, + sc_mars_science_laboratory_landing_site: { + groups: ['mars', 'sc_mars_science_laboratory', 'sites'], + occlusionRadius: 0.001515, + extentsRadius: 0.004, + systemRadius: 200, + label: 'Curiosity Landing Site', + parents: [ + [375594732.3829685, 'mars'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(-4.589466996319 / 180 * Math.PI, 137.441632996891 / 180 * Math.PI, -4.927711819685555), + coverage: [375594732.3829685, Number.POSITIVE_INFINITY] + }] + }, + sc_mars_exploration_rover_1: { + groups: ['mars', 'spacecraft', 'landers'], + occlusionRadius: 0.0013, + extentsRadius: 0.0026, + label: 'Opportunity', + parents: [ + [110911022.184, 'earth'], + [111234172, 'sun'], + [128262836, 'mars'], + [128278419, 'sc_mars_exploration_rover_1_landing_site'], + [581920316.8566707, ''] + ], + trail: { + length: 6720.0, + lengthCoverages: [ + [10000000, Number.NEGATIVE_INFINITY, 128262836], + [6720.0, 128262836, 128278419], + [0, 128278523.336, 581920316.856] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/cruise/mpf_mera_merb_cruise.gltf', + rotate: [ + { x: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mars_exploration_rover_1/earth/orb' + }, { + type: 'dynamo', + url: 'sc_mars_exploration_rover_1/sun/orb' + }, { + type: 'dynamo', + url: 'sc_mars_exploration_rover_1/mars/pos' + }, { + type: 'dynamo', + url: 'sc_mars_exploration_rover_1/edl/pos' + }, { + type: 'dynamo', + url: 'sc_mars_exploration_rover_1/surface/pos' + }, { + type: 'align', + primary: { + type: 'velocity', + target: 'sc_mars_exploration_rover_1', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + }, + secondary: { + type: 'align', + target: 'mars', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + }, + coverage: [Number.NEGATIVE_INFINITY, 128278523.336] + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity, + coverage: [128278523.336, 581920316.856] + }, { + type: 'coverage', + coverage: [128278419, 581920316.856], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(true); + } + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(false); + } + } + }, { + type: 'coverage', + coverage: [128278523.336, 581920316.856], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/rover/mer_static.gltf'); + } + }, + exit: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/cruise/mpf_mera_merb_cruise.gltf'); + } + } + }, { + type: 'coverage', + coverage: [Number.NEGATIVE_INFINITY, 128262836], + enter: (entity) => { + const align = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController); + if (align !== null) { + align.setPrimaryAlignType('point'); + align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis); + align.setPrimaryTargetEntity('sun'); + } + }, + exit: (entity) => { + const align = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController); + if (align !== null) { + align.setPrimaryAlignType('velocity'); + align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg); + align.setPrimaryTargetEntity('sc_mars_exploration_rover_1'); + } + } + }], + postCreateFunction: (entity) => { + // Get it into the MER-1_TOPO frame. + const rotate = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.RotateController); + const rot90 = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(); + rot90.setFromAxes(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis, pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg, undefined); + rotate.setRotation(rot90); + rotate.setRotatingOrientation(false); + rotate.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(128278419, 581920316.856)); + + // Get it into the J2000 frame. + const rotateByEntityOrientation = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.RotateByEntityOrientationController, 'landingRotateByEntity', entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController)); + rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(128278419, 581920316.856)); + } + }, + sc_mars_exploration_rover_1_landing_site: { + groups: ['mars', 'sc_mars_exploration_rover_1', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'Opportunity Landing Site', + parents: [ + [110911022.184, 'mars'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(-0.034003934569818886, -0.09644392740547784, -2.018490164449304), + coverage: [110911022.184, Number.POSITIVE_INFINITY] + }] + }, + sc_mars_exploration_rover_2: { + groups: ['mars', 'spacecraft', 'landers'], + occlusionRadius: 0.0013, + extentsRadius: 0.0026, + label: 'Spirit', + parents: [ + [108541883.184, 'earth'], + [108887371, 'sun'], + [126444477, 'mars'], + [126462105, 'sc_mars_exploration_rover_2_landing_site'], + [322567479.3896215, ''] + ], + trail: { + length: 6720.0, + lengthCoverages: [ + [10000000, Number.NEGATIVE_INFINITY, 126444477], + [6720.0, 126444477, 126462105], + [0, 126462396.105800, 322567479.389620] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/cruise/mpf_mera_merb_cruise.gltf', + rotate: [ + { x: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mars_exploration_rover_2/earth/orb' + }, { + type: 'dynamo', + url: 'sc_mars_exploration_rover_2/sun/orb' + }, { + type: 'dynamo', + url: 'sc_mars_exploration_rover_2/mars/pos' + }, { + type: 'dynamo', + url: 'sc_mars_exploration_rover_2/edl/pos' + }, { + type: 'dynamo', + url: 'sc_mars_exploration_rover_2/surface/pos' + }, { + type: 'rotateByEntityOrientation', // Get surface dynamo into J2000 frame. + coverage: [126462105, 322567479.389620] + }, { + type: 'align', + primary: { + type: 'velocity', + target: 'sc_mars_exploration_rover_2', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + }, + secondary: { + type: 'align', + target: 'mars', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + }, + coverage: [Number.NEGATIVE_INFINITY, 126462105] + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity, + coverage: [126462105, 322567479.389620] + }, { + type: 'coverage', + coverage: [126462105, 322567479.389620], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(true); + } + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(false); + } + } + }, { + type: 'coverage', + coverage: [126462396.105800, 322567479.389620], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/rover/mer_static.gltf'); + } + }, + exit: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/cruise/mpf_mera_merb_cruise.gltf'); + } + } + }, { + type: 'coverage', + coverage: [Number.NEGATIVE_INFINITY, 126444477], + enter: (entity) => { + const align = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController); + if (align !== null) { + align.setPrimaryAlignType('point'); + align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis); + align.setPrimaryTargetEntity('sun'); + } + }, + exit: (entity) => { + const align = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController); + if (align !== null) { + align.setPrimaryAlignType('velocity'); + align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg); + align.setPrimaryTargetEntity('sc_mars_exploration_rover_2'); + } + } + }], + postCreateFunction: (entity) => { + // Get it into the MER-2_TOPO frame. + const rotate = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.RotateController); + const rot90 = new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(); + rot90.setFromAxes(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis, pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg, undefined); + rotate.setRotation(rot90); + rotate.setRotatingOrientation(false); + rotate.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(126462105, 322567479.389620)); + } + }, + sc_mars_exploration_rover_2_landing_site: { + groups: ['mars', 'sc_mars_exploration_rover_2', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'Spirit Landing Site', + parents: [ + [108541883.184, 'mars'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(-0.25432749290990797, 3.062677242395019, -2.614394925059969), + coverage: [108541883.184, Number.POSITIVE_INFINITY] + }] + }, + sc_insight: { + groups: ['mars', 'spacecraft', 'landers'], + radius: 0.00306, + label: 'InSight', + parents: [ + [578795968.9654216, 'earth'], + [579182469.185, 'sun'], + [596376069.183, 'mars'] + ], + trail: { + length: 32137022.16, + lengthCoverages: [ + [32137022.16, Number.NEGATIVE_INFINITY, 596376069.183], + [14400, 596376069.183, 596533471.284 - 3600], + [3600, 596533471.284 - 3600, 596533602], + [0, 596533602, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_insight/lander/insight.gltf', + rotate: [ + { y: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_insight/earth/pos' + }, { + type: 'dynamo', + url: 'sc_insight/sun/orb' + }, { + type: 'dynamo', + url: 'sc_insight/mars/orb' + }, { + type: 'dynamo', + url: 'sc_insight_edl/mars/pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'mars', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + }, + secondary: { + type: 'align', + target: 'mars', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + }, + coverage: [578795968.9654216, 596533602] + }, { + type: 'dynamo', + url: 'sc_insight/ori' + }, { + type: 'dynamo', + url: 'sc_insight_edl/ori' + }, { + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(0.07881611091588075, 2.3734709256393973, -2.996371903616364), + llaOnSpheroidEntity: 'mars', + coverage: [596533602, Number.POSITIVE_INFINITY] + }, { + type: 'coverage', + coverage: [596533471.284 - 3600, 596533602], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(true); + } + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(false); + } + } + }, { + type: 'coverage', + coverage: [578795968.9654216, 596533602], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setUrl('$STATIC_ASSETS_URL/models/sc_insight/cruise/model.gltf'); + model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(Math.sqrt(0.5), 0, Math.sqrt(0.5), 0)); + model.setTranslation(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero); + } + } + }, { + type: 'coverage', + coverage: [596533602, Number.POSITIVE_INFINITY], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (model !== null) { + model.setUrl('$STATIC_ASSETS_URL/models/sc_insight/lander/insight.gltf'); + model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(Math.sqrt(0.5), Math.sqrt(0.5), 0, 0)); + model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0, 0.00085)); + } + } + }] + }, + sc_insight_landing_site: { + groups: ['mars', 'sc_insight', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'InSight Landing Site', + parents: [ + [578795968.9654216, 'mars'], + [596533602, ''] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(0.07881611091588075, 2.3734709256393973, -2.996371903616364), + coverage: [578795968.9654216, 596533602] + }] + }, + sc_marco_a: { + groups: ['mars', 'spacecraft'], + radius: 0.00044375, + label: 'MarCO A', + parents: [ + [578796051, 'earth'], + [579182469.185, 'sun'], + [596376069.183, 'mars'], + [596552080, 'sun'], + [631152000, ''] + ], + trail: { + length: 6720.0, + lengthCoverages: [ + [10000000, Number.NEGATIVE_INFINITY, 579182469.185], + [6720.0, 579182469.185, 596552080], + [10000000, 596552080, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_marco/model.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_marco_a/earth/orb' + }, { + type: 'dynamo', + url: 'sc_marco_a/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_marco_a/mars/orb' + }, { + type: 'dynamo', + url: 'sc_marco_a/sun/2/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + } + }] + }, + sc_marco_b: { + groups: ['mars', 'spacecraft'], + radius: 0.00044375, + label: 'MarCO B', + parents: [ + [578796051, 'earth'], + [579182469.185, 'sun'], + [596376069.183, 'mars'], + [596552080, 'sun'], + [631152000, ''] + ], + trail: { + length: 6720.0, + lengthCoverages: [ + [10000000, Number.NEGATIVE_INFINITY, 579182469.185], + [6720.0, 579182469.185, 596552080], + [10000000, 596552080, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_marco/model.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_marco_b/earth/orb' + }, { + type: 'dynamo', + url: 'sc_marco_b/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_marco_b/mars/orb' + }, { + type: 'dynamo', + url: 'sc_marco_b/sun/2/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + } + }] + }, + sc_mars_odyssey: { + groups: ['mars', 'spacecraft'], + occlusionRadius: 0.0013, + extentsRadius: 0.004, + label: 'Mars Odyssey', + parents: [ + [39932700, 'earth'], + [40233664, 'sun'], + [57128464, 'mars'] + ], + trail: { + length: 6727.0, + lengthCoverages: [ + [10000000, Number.NEGATIVE_INFINITY, 57128464], + [6727.0, 57128464, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mars_odyssey/mars_odyssey.gltf', + environmentMap: { + cubemap: '$STATIC_ASSETS_URL/env_maps/park_gray/$FACE.jpg' + }, + shadowEntities: ['mars', 'deimos', 'phobos'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mars_odyssey/earth/orb' + }, { + type: 'dynamo', + url: 'sc_mars_odyssey/sun/orb' + }, { + type: 'dynamo', + url: 'sc_mars_odyssey/mars/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'mars', + axis: new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-0.95630475596, 0.29237170472, 0) + }, + secondary: { + type: 'velocity', + target: 'sc_mars_odyssey', + axis: new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.29237170472, 0.95630475596, 0) + } + }, { + type: 'dynamo', + url: 'sc_mars_odyssey/ori' + }] + }, + sc_mars_reconnaissance_orbiter: { + groups: ['mars', 'spacecraft'], + radius: 0.0068, + label: 'Mars Reconnaissance Orbiter', + parents: [ + [177122516, 'earth'], + [177429664, 'sun'], + [195285665, 'mars'] + ], + trail: { + length: 6720.0, + lengthCoverages: [ + [10000000, Number.NEGATIVE_INFINITY, 195285665], + [6720.0, 195285665, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mars_reconnaissance_orbiter/MRO.gltf', + environmentMap: { + cubemap: '$STATIC_ASSETS_URL/env_maps/park_gray/$FACE.jpg' + }, + shadowEntities: ['mars', 'deimos', 'phobos'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mars_reconnaissance_orbiter/earth/orb' + }, { + type: 'dynamo', + url: 'sc_mars_reconnaissance_orbiter/sun/orb' + }, { + type: 'dynamo', + url: 'sc_mars_reconnaissance_orbiter/mars/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'mars', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_mars_reconnaissance_orbiter', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis + } + }, { + type: 'dynamo', + url: 'sc_mars_reconnaissance_orbiter/ori' + }] + }, + sc_maven: { + groups: ['mars', 'spacecraft'], + radius: 0.0057, + label: 'MAVEN', + parents: [ + [438074509.3428109, 'earth'], + [438296467, 'sun'], + [464590867, 'mars'] + ], + trail: { + length: 16139.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_maven/Maven.gltf', + rotate: [ + { x: 90 }, + { z: 90 } + ], + environmentMap: { + cubemap: '$STATIC_ASSETS_URL/env_maps/park_gray/$FACE.jpg' + }, + shadowEntities: ['mars', 'deimos', 'phobos'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_maven/earth/orb' + }, { + type: 'dynamo', + url: 'sc_maven/sun/orb' + }, { + type: 'dynamo', + url: 'sc_maven/mars/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }, { + type: 'dynamo', + url: 'sc_maven/ori' + }] + }, + sc_mars_express: { + groups: ['mars', 'spacecraft'], + radius: 0.006, + label: 'Mars Express', + parents: [ + [107853140.59600002, 'earth'], + [108232264, 'sun'], + [125539264, 'mars'] + ], + trail: { + length: 25000.0, + lengthCoverages: [ + [10000000, Number.NEGATIVE_INFINITY, 126749131], + [12720.0, 126749131, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mars_express/mars_express.gltf', + rotate: [ + { x: 90 }, + { z: -180 } + ], + environmentMap: { + cubemap: '$STATIC_ASSETS_URL/env_maps/park_gray/$FACE.jpg' + }, + shadowEntities: ['mars', 'deimos', 'phobos'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_mars_express/earth/orb' + }, { + type: 'dynamo', + url: 'sc_mars_express/sun/orb' + }, { + type: 'dynamo', + url: 'sc_mars_express/mars/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'mars', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg + } + }, { + type: 'dynamo', + url: 'sc_mars_express/ori' + }] + }, + sc_phoenix: { + groups: ['mars', 'spacecraft'], + radius: 0.0027, + label: 'Phoenix', + parents: [ + [239496427, 'earth'], + [239618121, 'sun'], + [265008306, 'mars'], + [265030318, 'sc_phoenix_landing_site'], + [278942465, ''] + ], + trail: { + length: 45411186.0, + lengthCoverages: [ + [45411186, Number.NEGATIVE_INFINITY, 265008306], + [50000, 265008306, 265030318], + [500, 265030318, 265030769], + [0, 265030769, 278942465] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_phoenix/cruise/phoenix_cruise.gltf', + rotate: [ + { z: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_phoenix/earth/orb' + }, { + type: 'dynamo', + url: 'sc_phoenix/sun/orb' + }, { + type: 'dynamo', + url: 'sc_phoenix/mars/orb' + }, { + type: 'dynamo', + url: 'sc_phoenix/phx_topo/pos' + }, { + type: 'dynamo', + url: 'sc_phoenix/ori' + }, { + type: 'fixed', + position: new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.027059368126568832, 0.013878235928918032, -0.04367634407940447), + coverage: [265030769, 278942465] + }, { + type: 'rotateByEntityOrientation', + rotatingOrientation: false, + coverage: [265030769, 278942465] + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + } + }, { + type: 'coverage', + coverage: [265030324 - 7 * 60, Number.POSITIVE_INFINITY], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + model.setUrl('$STATIC_ASSETS_URL/models/sc_phoenix/edl/phoenix_edl.gltf'); + }, + exit: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + model.setUrl('$STATIC_ASSETS_URL/models/sc_phoenix/cruise/phoenix_cruise.gltf'); + } + }], + postCreateFunction: (entity) => { + entity.addParentChangedCallback((entity, _, newParent) => { + if (newParent !== null) { + const parentName = newParent.getName(); + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (parentName === 'sc_phoenix_landing_site') { + trail.setRelativeToEntity('mars'); + trail.setRelativeToEntityOrientation(true); + } + else { + trail.setRelativeToEntity(''); + trail.setRelativeToEntityOrientation(false); + } + } + }); + } + }, + sc_phoenix_landing_site: { + groups: ['mars', 'sc_phoenix', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'Phoenix Landing Site', + parents: [ + [239496427, 'mars'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(1.1906355815662266, -2.1947740491302206, -2.5912352775421823), + coverage: [239496427, Number.POSITIVE_INFINITY] + }] + }, + sc_trace_gas_orbiter: { + groups: ['mars', 'spacecraft'], + radius: 0.00875915, + label: 'Trace Gas Orbiter', + parents: [ + [511257268, 'earth'], + [511941668, 'sun'], + [530107268, 'mars'] + ], + trail: { + length: 6720.0, + lengthCoverages: [ + [10000000, Number.NEGATIVE_INFINITY, 530160041], + [6720.0, 530160041, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_trace_gas_orbiter/TGO.gltf', + rotate: [ + { x: -90 }, + { y: -90 } + ], + environmentMap: { + cubemap: '$STATIC_ASSETS_URL/env_maps/park_gray/$FACE.jpg' + }, + shadowEntities: ['mars', 'deimos', 'phobos'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_trace_gas_orbiter/earth/orb' + }, { + type: 'dynamo', + url: 'sc_trace_gas_orbiter/sun/orb' + }, { + type: 'dynamo', + url: 'sc_trace_gas_orbiter/mars/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'mars', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg + }, + secondary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg + } + }, { + type: 'dynamo', + url: 'sc_trace_gas_orbiter/ori' + }], + postCreateFunction: (entity) => { + // Align the right solar panel to the sun. + let align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController); + align.setJoint('right_array_1'); + align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis); + align.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + // Align the left solar panel to the sun. + align = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController); + align.setJoint('left_array_1'); + align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis); + align.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis); + align.setSecondaryAlignType('point'); + align.setSecondaryTargetEntity('sun'); + } + }, + sc_mars_orbiter_mission: { + groups: ['mars', 'spacecraft'], + radius: 0.00275, + label: 'Mars Orbiter Mission', + parents: [ + [623211069.1823474, 'mars'] + ], + trail: { + length: 234146.0 + }, + controllers: [{ + type: 'animdata', + url: 'sc_mars_orbiter_mission/mars', + dataType: 'pos' + }] + }, + sc_mars_global_surveyor: { + groups: ['mars', 'spacecraft'], + occlusionRadius: 0.003, + extentsRadius: 0.005, + label: 'Mars Global Surveyor', + parents: [ + [-72699545, 'mars'], + [215697664.184, ''] + ], + trail: { + length: 7068.67 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_mars_global_surveyor/mars_global_surveyor.gltf', + shadowEntities: ['mars'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_mars_global_surveyor_mission', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'mars', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg + } + }] + }, + sc_mars_climate_orbiter: { + groups: ['mars', 'spacecraft'], + radius: 0.0011, + label: 'Mars Climate Orbiter', + parents: [ + [-33318000, 'sun'], + [-8650375.816, ''] + ], + trail: { + length: 24587405.0 * 3.0 + }, + controllers: [{ + type: 'animdata', + url: 'sc_mars_climate_orbiter', + dataType: 'pos' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + sc_mars_pathfinder: { + groups: ['mars', 'spacecraft'], + radius: 0.00033, + label: 'Mars Pathfinder', + parents: [ + [-91704541, 'sun'], + [-78692880, ''] + ], + trail: { + length: 12874372.0 * 4.0 + }, + controllers: [{ + type: 'animdata', + url: 'sc_mars_pathfinder', + dataType: 'pos' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + sc_mars_pathfinder_landing_site: { + groups: ['mars', 'sc_mars_pathfinder', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'Mars Pathfinder Landing Site', + parents: [ + [-97045250.817, 'mars'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(19.13 * Math.PI / 180, -33.22 * Math.PI / 180, 0), + coverage: [-97045250.817, Number.POSITIVE_INFINITY] + }] + }, + sc_mars_polar_lander: { + groups: ['mars', 'spacecraft'], + radius: 0.0018, + label: 'Mars Polar Lander', + parents: [ + [-31298400, 'sun'], + [-2476735.816, ''] + ], + trail: { + length: 41109006.0 + }, + controllers: [{ + type: 'animdata', + url: 'sc_mars_polar_lander', + dataType: 'pos' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + sc_viking_1_orbiter: { + groups: ['mars', 'spacecraft'], + radius: 0.0047, + label: 'Viking 1 Orbiter', + parents: [ + [-742490410, 'mars'], + [-663249600, ''] + ], + trail: { + length: 88649.0 + }, + controllers: [{ + type: 'animdata', + url: 'sc_viking_1_orbiter', + dataType: 'pos' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + sc_viking_1_lander_landing_site: { + groups: ['mars', 'sc_viking_1_lander', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'Viking 1 Lander Landing Site', + parents: [ + [-768926233.817, 'mars'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(22.27 * Math.PI / 180, 312.05 * Math.PI / 180, 0), + coverage: [-768926233.817, Number.POSITIVE_INFINITY] + }] + }, + sc_viking_2_orbiter: { + groups: ['mars', 'spacecraft'], + radius: 0.0047, + label: 'Viking 2 Orbiter', + parents: [ + [-738460186, 'mars'], + [-676517400, ''] + ], + trail: { + length: 98694.0 + }, + controllers: [{ + type: 'animdata', + url: 'sc_viking_2_orbiter', + dataType: 'pos' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + sc_viking_2_lander_landing_site: { + groups: ['mars', 'sc_viking_2_lander', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'Viking 2 Lander Landing Site', + parents: [ + [-767208013.818, 'mars'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(47.64 * Math.PI / 180, -225.71 * Math.PI / 180, 0), + coverage: [-767208013.818, Number.POSITIVE_INFINITY] + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/mercury_spacecraft.js": +/*!*************************************************************!*\ + !*** ../pioneer/scripts/src/entities/mercury_spacecraft.js ***! + \*************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + sc_messenger: { + groups: ['mercury', 'spacecraft'], + occlusionRadius: 0.00133, + extentsRadius: 0.0035, + label: 'MESSENGER', + parents: [ + [144789279.39320505, 'earth'], + [145066469, 'sun'], + [175801890, 'earth'], + [176659095, 'sun'], + [214828942, 'venus'], + [215033751, 'sun'], + [234289415, 'venus'], + [234436749, 'sun'], + [253547108, 'mercury'], + [253671753, 'sun'], + [276485360, 'mercury'], + [276627276, 'sun'], + [307423681, 'mercury'], + [307651285, 'sun'], + [353474040, 'mercury'], + [483694028.351, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_messenger/Messenger.gltf', + rotate: [ + { z: -90 }, + { y: 90 } + ], + shadowEntities: ['mercury'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_messenger/earth/launch/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/earth/flyby/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/sun/2/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/venus/flyby1/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/sun/3/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/venus/flyby2/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/sun/4/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/mercury/flyby1/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/sun/5/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/mercury/flyby2/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/sun/6/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/mercury/flyby3/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/sun/7/orb' + }, { + type: 'dynamo', + url: 'sc_messenger/mercury/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'mercury', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + }, + secondary: { + type: 'velocity', + target: 'sc_messenger', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }, { + type: 'dynamo', + url: 'sc_messenger/ori' + }] + }, + sc_messenger_impact_site: { + groups: ['mercury', 'sc_messenger', 'sites'], + radius: 0.001, + label: 'MESSENGER Impact Site', + parents: [ + [Number.NEGATIVE_INFINITY, 'mercury'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(0.9501527254431932, -2.615904550043192, -0.910251923861324), + coverage: [483694028.351, Number.POSITIVE_INFINITY] + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/minor_planets.js": +/*!********************************************************!*\ + !*** ../pioneer/scripts/src/entities/minor_planets.js ***! + \********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +// NEOs are near-earth objects +// PHAs are potentially hazardous asteroids +// TNOs are trans-neptunian objects + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + '1_ceres': { + groups: ['dwarf planets'], + radius: 473.0, + label: 'Ceres', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + spheroid: { + equatorialRadius: 482.6, + polarRadius: 445.6, + planetographic: false + }, + spheroidLOD: { + textures: { + color: { + url: '1_ceres/color_$SIZE_$FACE.jpg', + sizes: [16, 512, 4096] + } + } + }, + controllers: [{ + type: 'dynamo', + url: '1_ceres/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '101955_bennu': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.246, + label: 'Bennu', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/101955_bennu/Bennu.gltf', + rotate: [ + { x: 83 }, + { z: -168 } + ], + scale: 0.0009956 + }, + controllers: [{ + type: 'dynamo', + url: '101955_bennu/sun/orb' + }, { + type: 'dynamo', + url: '101955_bennu/ori' + }] + }, + '11351_leucus': { + groups: ['asteroids'], + radius: 17.0775, + label: 'Leucus', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: 17.0775 + }, + controllers: [{ + type: 'dynamo', + url: '11351_leucus/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 445.732 + }] + }, + '12923_zephyr': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 1.03, + label: 'Zephyr', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.03, 1.03, 1.03] + }, + controllers: [{ + type: 'dynamo', + url: '12923_zephyr/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 3.891 + }] + }, + '134340_pluto': { + groups: ['dwarf planets', 'moons', '134340_pluto_barycenter'], + radius: 1187.0, + label: 'Pluto', + labelFadeEntity: 'sun', + parents: [ + [Number.NEGATIVE_INFINITY, '134340_pluto_barycenter'] + ], + trail: { + length: undefined + }, + spheroid: { + equatorialRadius: 1187.0, + polarRadius: 1187.0, + planetographic: false + }, + spheroidLOD: { + textures: { + color: { + url: '134340_pluto/color_$SIZE_$FACE.png', + sizes: [4, 512, 4096] + } + } + }, + controllers: [{ + type: 'dynamo', + url: '134340_pluto/134340_pluto_barycenter/orb' + }, { + type: 'align', + primary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis, + target: 'charon' + }, + secondary: { + type: 'velocity', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis, + target: 'charon' + } + }] + }, + '134340_pluto_barycenter': { + groups: ['134340_pluto', 'barycenters'], + occlusionRadius: 0.001, + extentsRadius: 28000, + systemRadius: 130153, + label: 'Barycenter', + labelFadeEntity: '134340_pluto', + trail: { + length: undefined + }, + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + controllers: [{ + type: 'dynamo', + url: '134340_pluto_barycenter/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }], + postCreateFunction: (entity) => { + const divComponent = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent); + divComponent.setFadeWhenCloseToCamera(false); + entity.setCanOcclude(false); + } + }, + '136108_haumea': { + groups: ['dwarf planets', 'TNOs'], + radius: 816.0, + label: 'Haumea', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/136108_haumea/haumea.gltf', + scale: [1, 1, 1] + }, + controllers: [{ + type: 'dynamo', + url: '136108_haumea/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + '136199_eris': { + groups: ['dwarf planets', 'TNOs'], + radius: 1163.0, + label: 'Eris', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + spheroid: { + equatorialRadius: 1163.0, + polarRadius: 1163.0, + planetographic: false + }, + spheroidLOD: { + textures: { + color: { + url: '136199_eris/color_$SIZE_$FACE.png', + sizes: [4, 512] + } + } + }, + controllers: [{ + type: 'dynamo', + url: '136199_eris/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + '136472_makemake': { + groups: ['dwarf planets', 'TNOs'], + radius: 715.0, + label: 'Makemake', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + spheroid: { + equatorialRadius: 717.0, + polarRadius: 710.0, + planetographic: false + }, + spheroidLOD: { + textures: { + color: { + url: '136472_makemake/color_$SIZE_$FACE.png', + sizes: [4, 512] + } + } + }, + controllers: [{ + type: 'dynamo', + url: '136472_makemake/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + '14827_hypnos': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.4535, + label: 'Hypnos', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.4535, 0.4535, 0.4535] + }, + controllers: [{ + type: 'dynamo', + url: '14827_hypnos/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '15094_polymele': { + groups: ['asteroids'], + radius: 10.5375, + label: 'Polymele', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 10.5375 + }, + controllers: [{ + type: 'dynamo', + url: '15094_polymele/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 5.8607 + }] + }, + '1566_icarus': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.805, + label: 'Icarus', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.805, 0.800, 0.585] + }, + controllers: [{ + type: 'dynamo', + url: '1566_icarus/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 2.2726 + }] + }, + '16_psyche': { + groups: ['asteroids'], + radius: 125.0, + label: '16 Psyche', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/16_psyche/psycheAsteroid.gltf', + scale: [100, 100, 100], + rotate: [ + { x: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: '16_psyche/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + '1620_geographos': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 2.5, + label: 'Geographos', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.5, 1.0, 1.05] + }, + controllers: [{ + type: 'dynamo', + url: '1620_geographos/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 5.224 + }] + }, + '162173_ryugu': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.45, + label: 'Ryugu', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/162173_ryugu/ryugu.gltf', + rotate: [ + { x: -90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'ssd/162173_ryugu/sun/orb' + }, { + type: 'dynamo', + url: '162173_ryugu/ori' + }] + }, + '1862_apollo': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.75, + label: 'Apollo', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.75, 0.75, 0.75] + }, + controllers: [{ + type: 'dynamo', + url: '1862_apollo/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 3.065 + }] + }, + '1981_midas': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.975, + label: 'Midas', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.975, 0.975, 0.975] + }, + controllers: [{ + type: 'dynamo', + url: '1981_midas/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 5.22 + }] + }, + '1991_vg': { + groups: ['asteroids', 'NEOs'], + radius: 0.00425, + label: '1991 VG', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.00425, 0.00425, 0.00425] + }, + controllers: [{ + type: 'dynamo', + url: '1991_vg/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '1993_hd': { + groups: ['asteroids', 'asteroid belt'], + radius: 0.005, + label: '1993 HD', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '1993_hd/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '1994_cc_a': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.325, + label: '1994 CC', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.325, 0.325, 0.325] + }, + controllers: [{ + type: 'dynamo', + url: '1994_cc_a/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 2.38860 + }] + }, + // Needs spice + // '1994_cc_b': { + // groups: ['asteroids', 'NEOs', 'PHAs'], + // radius: 0.025, + // label: '1994 CC B', + // parents: [ + // [Number.NEGATIVE_INFINITY, 'sun'] + // ], + // trail: { + // length: undefined + // }, + // model: { + // url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + // scale: [0.025, 0.025, 0.025] + // }, + // dynamo: [{ + // url: '1994_cc_b/1994_cc_a/orb', + // parent: '1994_cc_a' + // }, { + // url: '1994_cc_b/ori' + // }] + // }, + // Needs spice + // '1994_cc_c': { + // groups: ['asteroids', 'NEOs', 'PHAs'], + // radius: 0.00417, + // label: '1994 CC C', + // parents: [ + // [Number.NEGATIVE_INFINITY, 'sun'] + // ], + // trail: { + // length: undefined + // }, + // model: { + // url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + // scale: [0.00417, 0.00417, 0.00417] + // }, + // dynamo: [{ + // url: '1994_cc_c/1994_cc_a/orb', + // parent: '1994_cc_a' + // }, { + // url: '1994_cc_c/ori' + // }] + // }, + '1996_xb27': { + groups: ['asteroids', 'NEOs'], + radius: 0.042, + label: '1996 XB27', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.042, 0.042, 0.042] + }, + controllers: [{ + type: 'dynamo', + url: '1996_xb27/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 1.195 + }] + }, + '1998_ky26': { + groups: ['asteroids', 'NEOs'], + radius: 0.015, + label: '1998 KY26', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.015, 0.015, 0.015] + }, + controllers: [{ + type: 'dynamo', + url: '1998_ky26/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 0.1784 + }] + }, + '1998_ml14': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.5, + label: '1998 ML14', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.5, 0.5, 0.5] + }, + controllers: [{ + type: 'dynamo', + url: '1998_ml14/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 14.28 + }] + }, + '1998_qe2': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 1.375, + label: '1998 QE2', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.375, 1.375, 1.375] + }, + controllers: [{ + type: 'dynamo', + url: '1998_qe2/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 4.749 + }] + }, + '1999_ao10': { + groups: ['asteroids', 'NEOs'], + radius: 0.025, + label: '1999 AO10', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.025, 0.025, 0.025] + }, + controllers: [{ + type: 'dynamo', + url: '1999_ao10/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '1999_cg9': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '1999 CG9', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '1999_cg9/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '1999_vx25': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '1999 VX25', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '1999_vx25/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2_pallas': { + groups: ['asteroids', 'asteroid belt'], + radius: 291, + label: 'Pallas', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [291, 278, 250] + }, + controllers: [{ + type: 'dynamo', + url: '2_pallas/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 7.8132 + }] + }, + '2000_ae205': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2000 AE205', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2000_ae205/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2000_lg6': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2000 LG6', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2000_lg6/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2000_sg344': { + groups: ['asteroids', 'NEOs'], + radius: 0.0185, + label: '2000 SG344', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.0185, 0.0185, 0.0185] + }, + controllers: [{ + type: 'dynamo', + url: '2000_sg344/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2001_bb16': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2001 BB16', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2001_bb16/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2001_fr85': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2001 FR85', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2001_fr85/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2001_gp2': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2001 GP2', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2001_gp2/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2001_qj142': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2001 QJ142', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2001_qj142/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2001_sn263_a': { + groups: ['asteroids', 'NEOs'], + radius: 1.45, + label: '(153591) 2001 SN263', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.4, 1.35, 1.45] + }, + controllers: [{ + type: 'dynamo', + url: '2001_sn263_a/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 3.423 + }] + }, + // Needs spice + // '2001_sn263_b': { + // groups: ['asteroids', 'NEOs'], + // radius: 0.215, + // label: '2001 SN263 B', + // parents: [ + // [Number.NEGATIVE_INFINITY, 'sun'] + // ], + // trail: { + // length: 537840 + // }, + // model: { + // url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + // scale: [0.215, 0.215, 0.215] + // }, + // dynamo: [{ + // url: '2001_sn263_b/2001_sn263_a/orb', + // parent: '2001_sn263_a' + // }, { + // url: '2001_sn263_b/ori' + // }] + // }, + // Needs spice + // '2001_sn263_c': { + // groups: ['asteroids', 'NEOs'], + // radius: 0.385, + // label: '2001 SN263 C', + // parents: [ + // [Number.NEGATIVE_INFINITY, 'sun'] + // ], + // trail: { + // length: 59270 + // }, + // model: { + // url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + // scale: [0.385, 0.385, 0.385] + // }, + // dynamo: [{ + // url: '2001_sn263_c/2001_sn263_a/orb', + // parent: '2001_sn263_a' + // }, { + // url: '2001_sn263_c/ori' + // }] + // }, + '2003_sm84': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2003 SM84', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2003_sm84/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2003_uv11': { + groups: ['asteroids', 'NEOs'], + radius: 0.13, + label: '(503941) 2003 UV11', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.13, 0.13, 0.13] + }, + controllers: [{ + type: 'dynamo', + url: '2003_uv11/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 18.25 + }] + }, + '2003_yn107': { + groups: ['asteroids', 'NEOs'], + radius: 0.01, + label: '2003 YN107', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.01, 0.01, 0.01] + }, + controllers: [{ + type: 'dynamo', + url: '2003_yn107/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2005_er95': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2003 ER95', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2005_er95/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2005_lc': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2005 LC', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2005_lc/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2005_qp87': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2005 QP87', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2005_qp87/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2005_yu55': { + groups: ['asteroids', 'NEOs'], + radius: 0.18, + label: '2005 YU55', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.18, 0.18, 0.18] + }, + controllers: [{ + type: 'dynamo', + url: '2005_yu55/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 18 + }] + }, + '2006_bz147': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2006 BZ147', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2006_bz147/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2006_jy26': { + groups: ['asteroids', 'NEOs'], + radius: 0.00475, + label: '2006 JY26', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.00475, 0.00475, 0.00475] + }, + controllers: [{ + type: 'dynamo', + url: '2006_jy26/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2006_qq56': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2006 QQ56', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2006_qq56/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2006_rh120': { + groups: ['asteroids', 'NEOs'], + radius: 0.00125, + label: '2006 RH120', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.00125, 0.00125, 0.00125] + }, + controllers: [{ + type: 'dynamo', + url: '2006_rh120/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 0.04583 + }] + }, + '2006_ub17': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2006 UB17', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2006_ub17/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2007_tf15': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2007 TF15', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2007_tf15/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2007_un12': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2007 UN12', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2007_un12/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2007_vu6': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2007 VU6', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2007_vu6/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2008_bt2': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2008 BT2', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2008_bt2/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2008_cx118': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2008 CX118', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2008_cx118/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2008_ea9': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2008 EA9', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2008_ea9/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2008_el': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2008 EL', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2008_el/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2008_hu4': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2008 HU4', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2008_hu4/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2008_jl24': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2008 JL24', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2008_jl24/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 0.05385 + }] + }, + '2008_kt': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2008 KT', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2008_kt/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2008_tc3': { + groups: ['asteroids', 'NEOs'], + radius: 0.00205, + label: '2008 TC3', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.00205, 0.00205, 0.00205] + }, + controllers: [{ + type: 'dynamo', + url: '2008_tc3/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 0.0269409 + }] + }, + '2008_ts10': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2008 TS10', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2008_ts10/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2008_ua202': { + groups: ['asteroids', 'NEOs'], + radius: 0.025, + label: '2008 UA202', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.025, 0.025, 0.025] + }, + controllers: [{ + type: 'dynamo', + url: '2008_ua202/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2009_bd': { + groups: ['asteroids', 'NEOs'], + radius: 0.0055, + label: '2009 BD', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.0055, 0.0055, 0.0055] + }, + controllers: [{ + type: 'dynamo', + url: '2009_bd/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2009_os5': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2009 OS5', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2009_os5/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2009_rt1': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2009 RT1', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2009_rt1/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2009_yf': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2009 YF', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2009_yf/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2010_an61': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2010 AN61', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2010_an61/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2010_dj': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2010 DJ', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2010_dj/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2010_jw34': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2010 JW34', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2010_jw34/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2010_tg19': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2010 TG19', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2010_tg19/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2010_tn167': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2010 TN167', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2010_tn167/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2010_ub': { + groups: ['asteroids', 'NEOs'], + radius: 0.005, + label: '2010 UB', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.005, 0.005, 0.005] + }, + controllers: [{ + type: 'dynamo', + url: '2010_ub/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2063_bacchus': { + groups: ['asteroids', 'NEOs'], + radius: 0.555, + label: 'Bacchus', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.555, 0.265, 0.25] + }, + controllers: [{ + type: 'dynamo', + url: '2063_bacchus/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 14.904 + }] + }, + '21_lutetia': { + groups: ['asteroids', 'asteroid belt'], + radius: 60.5, + label: 'Lutetia', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [60.5, 50.5, 37.5] + }, + controllers: [{ + type: 'dynamo', + url: '21_lutetia/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 8.1655 + }] + }, + '2101_adonis': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.2615, + label: 'Adonis', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.2615, 0.2615, 0.2615] + }, + controllers: [{ + type: 'dynamo', + url: '2101_adonis/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '2102_tantalus': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.8245, + label: 'Tantalus', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.8245, 0.8245, 0.8245] + }, + controllers: [{ + type: 'dynamo', + url: '2102_tantalus/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 2.384 + }] + }, + '2135_aristaeus': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.5, + label: 'Aristaeus', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.5, 0.5, 0.5] + }, + controllers: [{ + type: 'dynamo', + url: '2135_aristaeus/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '216_kleopatra': { + groups: ['asteroids', 'asteroid belt'], + radius: 138, + label: 'Kleopatra', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [138, 47, 39] + }, + controllers: [{ + type: 'dynamo', + url: '216_kleopatra/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 5.385 + }] + }, + '21900_orus': { + groups: ['asteroids'], + radius: 25.405, + label: 'Orus', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: 25.405 + }, + controllers: [{ + type: 'dynamo', + url: '21900_orus/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 13.45 + }] + }, + '225088_2007_or10': { + groups: ['dwarf planets', 'TNOs'], + radius: 615, + label: '2007 OR10', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [615, 615, 596.55] + }, + controllers: [{ + type: 'dynamo', + url: '225088_2007_or10/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 22.40 + }] + }, + '2340_hathor': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.105, + label: 'Hathor', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.105, 0.105, 0.105] + }, + controllers: [{ + type: 'dynamo', + url: '2340_hathor/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 3.350 + }] + }, + '243_ida': { + groups: ['asteroids', 'asteroid belt'], + radius: 29.9, + label: 'Ida', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [18.6 * 1.3, 25.4 * 1.3, 59.8 * 1.3], + rotate: [ + { y: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: '243_ida/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 4.634 + }] + }, + '25143_itokawa': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.165, + label: 'Itokawa', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/25143_itokawa/itokawa.gltf', + rotate: [ + { x: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: '25143_itokawa/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12.132 + }] + }, + '253_mathilde': { + groups: ['asteroids', 'asteroid belt'], + radius: 33, + label: 'Mathilde', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [33, 24, 23] + }, + controllers: [{ + type: 'dynamo', + url: '253_mathilde/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 417.7 + }] + }, + '2867_steins': { + groups: ['asteroids', 'asteroid belt'], + radius: 3.415, + label: 'Šteins', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [3.415, 2.85, 2.21] + }, + controllers: [{ + type: 'dynamo', + url: '2867_steins/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 6.049 + }] + }, + '3_juno': { + groups: ['asteroids', 'asteroid belt'], + radius: 160, + label: 'Juno', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [160, 133.5, 100] + }, + controllers: [{ + type: 'dynamo', + url: '3_juno/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 7.210 + }] + }, + '3122_florence': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 2.2, + label: 'Florence', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.2, 2.2, 2.2] + }, + controllers: [{ + type: 'dynamo', + url: '3122_florence/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 2.3581 + }] + }, + '3200_phaethon': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 2.9, + label: 'Phaethon', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.9, 2.9, 2.9] + }, + controllers: [{ + type: 'dynamo', + url: '3200_phaethon/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 3.604 + }] + }, + '3362_khufu': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.35, + label: 'Khufu', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.35, 0.35, 0.35] + }, + controllers: [{ + type: 'dynamo', + url: '3362_khufu/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '3548_eurybates': { + groups: ['asteroids'], + radius: 31.9425, + label: 'Eurybates', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: 31.9425 + }, + controllers: [{ + type: 'dynamo', + url: '3548_eurybates/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 8.711 + }] + }, + '367943_duende': { + groups: ['asteroids', 'NEOs'], + radius: 0.020, + label: 'Duende', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.01, 0.01, 0.02] + }, + controllers: [{ + type: 'dynamo', + url: '367943_duende/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 9.485 + }] + }, + '37655_illapa': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.75, + label: 'Illapa', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.75, 0.75, 0.75] + }, + controllers: [{ + type: 'dynamo', + url: '37655_illapa/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 2.6556 + }] + }, + '4_vesta': { + groups: ['asteroids', 'asteroid belt'], + radius: 262.7, + label: 'Vesta', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/4_vesta/4_vesta.gltf', + rotate: [ + { x: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: '4_vesta/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '4015_wilson-harrington': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 2.0, + label: 'Wilson-Harrington', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2, 2, 2] + }, + controllers: [{ + type: 'dynamo', + url: '4015_wilson-harrington/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 3.5736 + }] + }, + '4179_toutatis': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 2.13, + label: 'Toutatis', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.35, 1.015, 2.13] + }, + controllers: [{ + type: 'dynamo', + url: '4179_toutatis/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 176 + }] + }, + '4183_cuno': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 1.8255, + label: 'Cuno', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.8255, 1.8255, 1.89255] + }, + controllers: [{ + type: 'dynamo', + url: '4183_cuno/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 3.5595 + }] + }, + '433_eros': { + groups: ['asteroids', 'NEOs'], + radius: 8.42, + label: 'Eros', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/433_eros/433_eros.gltf' + }, + controllers: [{ + type: 'dynamo', + url: '433_eros/sun/orb' + }, { + type: 'dynamo', + url: '433_eros/ori' + }] + }, + '4450_pan': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.5, + label: 'Pan', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.5, 0.5, 0.5] + }, + controllers: [{ + type: 'dynamo', + url: '4450_pan/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 56.48 + }] + }, + '4486_mithra': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 1.175, + label: 'Mithra', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.175, 0.825, 0.72] + }, + controllers: [{ + type: 'dynamo', + url: '4486_mithra/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 67.5 + }] + }, + '4769_castalia': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.9, + label: 'Castalia', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.4, 0.4, 0.9] + }, + controllers: [{ + type: 'dynamo', + url: '4769_castalia/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 4.095 + }] + }, + '486958_arrokoth': { + groups: ['TNOs'], + radius: 15.0, + label: 'Arrokoth', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/486958_arrokoth/mu69.gltf', + scale: [1, 1, 1], + rotate: [ + { x: -110 }, + { y: 180 } + ] + }, + controllers: [{ + type: 'dynamo', + url: '486958_arrokoth/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }, { + type: 'spin', + axis: new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-6.121453676996425e-10, 0.9396926211599973, 0.34202014229786787), + periodInHours: 13 + }], + postCreateFunction: (entity) => { + const spin = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.SpinController); + if (spin !== null) { + spin.setReferenceAngle(0); + spin.setReferenceTime(599590968); + } + } + }, + '5011_ptah': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.78, + label: 'Ptah', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.78, 0.78, 0.78] + }, + controllers: [{ + type: 'dynamo', + url: '5011_ptah/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 12 + }] + }, + '52246_donaldjohanson': { + groups: ['asteroids'], + radius: 1.9475, + label: 'Donaldjohanson', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: 1.9475 + }, + controllers: [{ + type: 'dynamo', + url: '52246_donaldjohanson/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + '5535_annefrank': { + groups: ['asteroids'], + radius: 2.412, + label: 'Annefrank', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: 2.412 + }, + controllers: [{ + type: 'dynamo', + url: '5535_annefrank/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 15.12 + }] + }, + '617_patroclus': { + groups: ['asteroids', '617_patroclus_barycenter'], + radius: 64, + label: 'Patroclus', + labelFadeEntity: 'sun', + parents: [ + [Number.NEGATIVE_INFINITY, '617_patroclus_barycenter'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [64, 58, 49], + shadowEntities: ['menoetius'] + }, + controllers: [{ + type: 'align', + primary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis, + target: 'menoetius' + } + }], + postCreateFunction: (entity) => { + // Add the controller for going around sun from earth to venus. + const oeController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController, undefined, entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController)); + const oe = new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements(); + oe.epoch = 0; + oe.eccentricity = 0; + oe.semiMajorAxis = 664; + oe.meanAngularMotion = 0.00001697791; + oe.meanAnomalyAtEpoch = Math.PI; + oe.setOrbitOrientationFromElements(1.97244894756, 0, 0); + oeController.addOrbitalElements(-1e100, oe); + oeController.addOrbitalElements(+1e100, oe); + } + }, + '617_patroclus_barycenter': { + groups: ['asteroids'], + radius: 664, + label: 'Patroclus', + labelFadeEntity: '617_patroclus', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + controllers: [{ + type: 'dynamo', + url: '617_patroclus/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }], + postCreateFunction: (entity) => { + entity.setCanOcclude(false); + } + }, + '6239_minos': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.237, + label: 'Minos', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.237, 0.237, 0.237] + }, + controllers: [{ + type: 'dynamo', + url: '6239_minos/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 3.5558 + }] + }, + '6489_golevka': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.265, + label: 'Golevka', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.265, 0.265, 0.265] + }, + controllers: [{ + type: 'dynamo', + url: '6489_golevka/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 6.026 + }] + }, + '65803_didymos': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.39, + label: 'Didymos', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/65803_didymos/Didymos.gltf', + rotate: [ + { z: 180 }, + { x: -90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: '65803_didymos/sun/orb' + }, { + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0, 1, 0, 0) + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 2.2593, + relativeToTime: 0 + }] + }, + '66391_moshup': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.766, + label: 'Moshup', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.766, 0.7475, 0.6735] + }, + controllers: [{ + type: 'dynamo', + url: '66391_moshup/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 2.7645 + }] + }, + // Needs spice + // 'squannit': { + // groups: ['asteroids', 'NEOs', 'PHAs'], + // radius: 0.180, + // label: 'Squannit', + // parents: [ + // [Number.NEGATIVE_INFINITY, 'sun'] + // ], + // trail: { + // length: 57600 + // }, + // model: { + // url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + // scale: [0.180, 0.180, 0.180] + // }, + // dynamo: [{ + // url: 'squannit/66391_moshup/orb', + // parent: '66391_moshup' + // }], + // spin: { + // axis: Pioneer.Vector3.ZAxis, + // periodInHours: 12 + // } + // }, + '69230_hermes': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.425, + label: 'Hermes', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [0.425, 0.425, 0.425] + }, + controllers: [{ + type: 'dynamo', + url: '69230_hermes/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 13.894 + }] + }, + '90377_sedna': { + groups: ['dwarf planets', 'TNOs'], + radius: 497.5, + label: 'Sedna', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [497.5, 497.5, 497.5] + }, + controllers: [{ + type: 'dynamo', + url: '90377_sedna/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 10.273 + }] + }, + '951_gaspra': { + groups: ['asteroids', 'asteroid belt'], + radius: 9.1, + label: 'Gaspra', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/951_gaspra/gaspra.gltf' + }, + controllers: [{ + type: 'dynamo', + url: '951_gaspra/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 7.042 + }] + }, + '9969_braille': { + groups: ['asteroids', 'asteroid belt'], + radius: 1.05, + label: 'Braille', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.05, 0.5, 0.5] + }, + controllers: [{ + type: 'dynamo', + url: '9969_braille/sun/orb' + }, { + type: 'spin', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + periodInHours: 226.4 + }] + }, + '99942_apophis': { + groups: ['asteroids', 'NEOs', 'PHAs'], + radius: 0.225, + label: 'Apophis', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/99942_apophis/apophis.gltf' + }, + controllers: [{ + type: 'dynamo', + url: '99942_apophis/sun/orb' + }, { + type: 'spin', + // Goldstone and Arecibo radar observations of (99942) Apophis in 2012–2013, Marina Brozovic et al, 2018 + // Converted 246.8°, -59.3° to XYZ. + axis: new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.20112425201023415, 0.46925803805904115, 0.8598522715968735), + periodInHours: 30.4 + }] + }, + '152830_dinkinesh': { + groups: ['asteroids'], + radius: 0.45, + label: 'Dinkinesh', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: 0.45 + }, + controllers: [{ + type: 'dynamo', + url: '152830_dinkinesh/sun/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + charon: { + groups: ['134340_pluto', 'moons', '134340_pluto_barycenter'], + radius: 603.5, + label: 'Charon', + parents: [ + [Number.NEGATIVE_INFINITY, '134340_pluto_barycenter'] + ], + trail: { + length: undefined + }, + spheroid: { + equatorialRadius: 603.5, + polarRadius: 603.5, + planetographic: false + }, + spheroidLOD: { + textures: { + color: { + url: 'charon/color_$SIZE_$FACE.png', + sizes: [4, 512, 2048] + } + } + }, + controllers: [{ + type: 'dynamo', + url: 'charon/134340_pluto_barycenter/orb' + }, { + type: 'align', + primary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis, + target: '134340_pluto' + }, + secondary: { + type: 'velocity', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis, + target: '134340_pluto' + } + }] + }, + dactyl: { + groups: ['243_ida', 'moons'], + radius: 0.7, + label: 'Dactyl', + parents: [ + [Number.NEGATIVE_INFINITY, '243_ida'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [0.8, 0.7, 0.6], + rotate: [ + { z: 90 } + ] + }, + controllers: [{ + type: 'align', + primary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis, + target: '243_ida' + } + }], + postCreateFunction: (entity) => { + // Add the controller for going around sun from earth to venus. + const oeController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController, undefined, entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController)); + const oe = new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements(); + oe.epoch = 0; + oe.eccentricity = 0; + oe.semiMajorAxis = 90; + oe.meanAngularMotion = 8.726646e-5; // 20 hrs per orbit + oe.meanAnomalyAtEpoch = 0; + oe.orbitOrientation.set(0.8728453580255966, 0.1876084386162498, -0.08948587100888229, 0.4415159494547423); + oeController.addOrbitalElements(-1e100, oe); + oeController.addOrbitalElements(+1e100, oe); + } + }, + dimorphos: { + groups: ['65803_didymos', 'moons'], + radius: 0.085, + label: 'Dimorphos', + parents: [ + [Number.NEGATIVE_INFINITY, '65803_didymos'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/dimorphos/Dimorphos.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'dimorphos/65803_didymos/orb' + }, { + type: 'align', + primary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis, + target: '65803_didymos' + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + target: '65803_didymos', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }] + }, + hiiaka: { + groups: ['136108_haumea', 'moons'], + radius: 160.0, + label: 'Hi\'iaka', + parents: [ + [Number.NEGATIVE_INFINITY, '136108_haumea'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [160, 160, 160] + }, + controllers: [{ + type: 'align', + primary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis, + target: '136108_haumea' + } + }], + postCreateFunction: (entity) => { + // Add the controller for going around sun from earth to venus. + const oeController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController, undefined, entity.getControllerByType('align')); + const oe = new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements(); + oe.epoch = 0; + oe.eccentricity = 0.0513; + oe.semiMajorAxis = 49880; + oe.meanAngularMotion = 1.48049e-6; // 49.12 days per orbit + oe.meanAnomalyAtEpoch = 0; + oe.setOrbitOrientationFromElements(2.20532822965, 0, 0); + oeController.addOrbitalElements(-1e100, oe); + oeController.addOrbitalElements(+1e100, oe); + } + }, + hydra: { + groups: ['134340_pluto', 'moons', '134340_pluto_barycenter'], + radius: 25.0, + label: 'Hydra', + parents: [ + [Number.NEGATIVE_INFINITY, '134340_pluto_barycenter'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [25, 25, 25], + shadowEntities: ['134340_pluto'] + }, + controllers: [{ + type: 'dynamo', + url: 'hydra/134340_pluto_barycenter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + kerberos: { + groups: ['134340_pluto', 'moons', '134340_pluto_barycenter'], + radius: 8.25, + label: 'Kerberos', + parents: [ + [Number.NEGATIVE_INFINITY, '134340_pluto_barycenter'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [8.25, 8.25, 8.25], + shadowEntities: ['134340_pluto'] + }, + controllers: [{ + type: 'dynamo', + url: 'kerberos/134340_pluto_barycenter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + menoetius: { + groups: ['617_patroclus_barycenter', 'moons'], + radius: 58, + label: 'Menoetius', + parents: [ + [Number.NEGATIVE_INFINITY, '617_patroclus_barycenter'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [58, 54, 45], + shadowEntities: ['617_patroclus'] + }, + controllers: [{ + type: 'align', + primary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis, + target: '617_patroclus' + } + }], + postCreateFunction: (entity) => { + // Add the controller for going around sun from earth to venus. + const oeController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController, undefined, entity.getControllerByType('align')); + const oe = new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements(); + oe.epoch = 0; + oe.eccentricity = 0; + oe.semiMajorAxis = 664; + oe.meanAngularMotion = 0.00001697791; + oe.meanAnomalyAtEpoch = 0; + oe.setOrbitOrientationFromElements(1.97244894756, 0, 0); + oeController.addOrbitalElements(-1e100, oe); + oeController.addOrbitalElements(+1e100, oe); + } + }, + namaka: { + groups: ['136108_haumea', 'moons'], + radius: 85.0, + label: 'Nāmaka', + parents: [ + [Number.NEGATIVE_INFINITY, '136108_haumea'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [85, 85, 85] + }, + controllers: [{ + type: 'align', + primary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis, + target: '136108_haumea' + } + }], + postCreateFunction: (entity) => { + // Add the controller for going around sun from earth to venus. + const oeController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController, undefined, entity.getControllerByType('align')); + const oe = new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements(); + oe.epoch = 0; + oe.eccentricity = 0.249; + oe.semiMajorAxis = 25657; + oe.meanAngularMotion = 3.9786e-6; // 18.2783 days per orbit + oe.meanAnomalyAtEpoch = 0; + oe.setOrbitOrientationFromElements(1.97244894756, 0, 0); + oeController.addOrbitalElements(-1e100, oe); + oeController.addOrbitalElements(+1e100, oe); + } + }, + nix: { + groups: ['134340_pluto', 'moons', '134340_pluto_barycenter'], + radius: 24.0, + label: 'Nix', + parents: [ + [Number.NEGATIVE_INFINITY, '134340_pluto_barycenter'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [24, 24, 24], + shadowEntities: ['134340_pluto'] + }, + controllers: [{ + type: 'dynamo', + url: 'nix/134340_pluto_barycenter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + styx: { + groups: ['134340_pluto', 'moons', '134340_pluto_barycenter'], + radius: 5.5, + label: 'Styx', + parents: [ + [Number.NEGATIVE_INFINITY, '134340_pluto_barycenter'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [5.5, 5.5, 5.5], + shadowEntities: ['134340_pluto'] + }, + controllers: [{ + type: 'dynamo', + url: 'styx/134340_pluto_barycenter/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/neptune_moons.js": +/*!********************************************************!*\ + !*** ../pioneer/scripts/src/entities/neptune_moons.js ***! + \********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + despina: { + groups: ['neptune', 'moons', 'regular'], + radius: 90, + label: 'Despina', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [90, 90, 90], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'despina/neptune/orb' + }, { + type: 'dynamo', + url: 'despina/ori' + }] + }, + galatea: { + groups: ['neptune', 'moons', 'regular'], + radius: 102, + label: 'Galatea', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [102, 102, 102], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'galatea/neptune/orb' + }, { + type: 'dynamo', + url: 'galatea/ori' + }] + }, + halimede: { + groups: ['neptune', 'moons', 'irregular'], + radius: 31, + label: 'Halimede', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [31, 31, 31], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'halimede/neptune/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + hippocamp: { + groups: ['neptune', 'moons', 'regular'], + radius: 17.4, + label: 'Hippocamp', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [17.4, 17.4, 17.4], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'hippocamp/neptune/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + laomedeia: { + groups: ['neptune', 'moons', 'irregular'], + radius: 21, + label: 'Laomedeia', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [21, 21, 21], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'laomedeia/neptune/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + larissa: { + groups: ['neptune', 'moons', 'regular'], + radius: 108, + label: 'Larissa', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [108, 108, 108], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'larissa/neptune/orb' + }, { + type: 'dynamo', + url: 'larissa/ori' + }] + }, + naiad: { + groups: ['neptune', 'moons', 'regular'], + radius: 48, + label: 'Naiad', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [48, 48, 48], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'naiad/neptune/orb' + }, { + type: 'dynamo', + url: 'naiad/ori' + }] + }, + nereid: { + groups: ['neptune', 'moons', 'irregular'], + radius: 170.0, + label: 'Nereid', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [170, 170, 170], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'nereid/neptune/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + neso: { + groups: ['neptune', 'moons', 'irregular'], + radius: 30, + label: 'Neso', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [30, 30, 30], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'neso/neptune/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + proteus: { + groups: ['neptune', 'moons', 'regular'], + radius: 232.5, + label: 'Proteus', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/proteus/proteus.gltf', + scale: [1, 1, 1] + }, + controllers: [{ + type: 'dynamo', + url: 'proteus/neptune/orb' + }, { + type: 'dynamo', + url: 'proteus/ori' + }] + }, + psamathe: { + groups: ['neptune', 'moons', 'irregular'], + radius: 20, + label: 'Psamathe', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [20, 20, 20], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'psamathe/neptune/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + sao: { + groups: ['neptune', 'moons', 'irregular'], + radius: 22, + label: 'Sao', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [22, 22, 22], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'sao/neptune/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + thalassa: { + groups: ['neptune', 'moons', 'regular'], + radius: 54, + label: 'Thalassa', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [54, 54, 54], + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'thalassa/neptune/orb' + }, { + type: 'dynamo', + url: 'thalassa/ori' + }] + }, + triton: { + groups: ['neptune', 'moons', 'irregular'], + radius: 1353.4, + label: 'Triton', + parents: [ + [Number.NEGATIVE_INFINITY, 'neptune'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + spheroid: { + equatorialRadius: 1353.4, + polarRadius: 1353.4, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'triton/color_$SIZE_$FACE.jpg', + sizes: [16, 512, 4096] + } + }, + shadowEntities: ['neptune'] + }, + controllers: [{ + type: 'dynamo', + url: 'triton/neptune/orb' + }, { + type: 'dynamo', + url: 'triton/ori' + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/outer_planet_spacecraft.js": +/*!******************************************************************!*\ + !*** ../pioneer/scripts/src/entities/outer_planet_spacecraft.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _controllers_keyframe_pointing_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../controllers/keyframe_pointing_controller */ "../pioneer/scripts/src/controllers/keyframe_pointing_controller.js"); +/* harmony import */ var _controllers_keyframe_spin_controller__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../controllers/keyframe_spin_controller */ "../pioneer/scripts/src/controllers/keyframe_spin_controller.js"); +/** @module pioneer-scripts */ + + + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + sc_juno: { + groups: ['jupiter', 'spacecraft'], + occlusionRadius: 0.001732, + extentsRadius: 0.010000, + label: 'Juno', + parents: [ + [365836752.1832, 'earth'], + [366088266.183, 'sun'], + [434433667.182, 'earth'], + [434793667.182, 'sun'], + [519652868.184, 'jupiter'], + [676339597, 'ganymede'], + [676381521, 'jupiter'], + [717700360, 'europa'], + [717727733, 'jupiter'], + [757191924, 'io'], + [757203571, 'jupiter'], + [760247560, 'io'], + [760262808, 'jupiter'] + ], + trail: { + length: undefined, + lengthCoverages: [ + [63072000, Number.NEGATIVE_INFINITY, 519652868.184], + [5184000, 519652868.184, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_juno/Juno.gltf', + rotate: [{ + x: 90 + }], + shadowEntities: ['jupiter', 'europa', 'ganymede', 'callisto', 'io'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_juno/earth/launch/orb' + }, { + type: 'dynamo', + url: 'sc_juno/sun/preflyby/orb' + }, { + type: 'dynamo', + url: 'sc_juno/earth/flyby/orb' + }, { + type: 'dynamo', + url: 'sc_juno/sun/postflyby/orb' + }, { + type: 'dynamo', + url: 'sc_juno/jupiter/orb' + }, { + type: 'dynamo', + url: 'sc_juno/ganymede/orb' + }, { + type: 'dynamo', + url: 'sc_juno/europa/orb' + }, { + type: 'dynamo', + url: 'sc_juno/io/1/orb' + }, { + type: 'dynamo', + url: 'sc_juno/io/2/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity, + coverage: [365836752.1832, Number.POSITIVE_INFINITY] + }, { + type: 'dynamo', + url: 'sc_juno/ori' + }, { + type: 'coverage', + coverage: [393471366, 529748408 + 600], + update: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + const cover = model.getThreeJsObjectByName('engine_cover'); + if (cover !== null) { + const time = entity.getScene().getEngine().getTime(); + const nextCloseIndex = pioneer__WEBPACK_IMPORTED_MODULE_1__.Sort.getIndex(time, junoEngineCoverOpenings, (a, b) => a[1] < b); + const openTime = junoEngineCoverOpenings[nextCloseIndex][0]; + const closeTime = junoEngineCoverOpenings[nextCloseIndex][1]; + const u = pioneer__WEBPACK_IMPORTED_MODULE_1__.MathUtils.clamp01(((closeTime - openTime) / 2 - Math.abs(time - (closeTime + openTime) / 2)) / 600); + cover.rotation.x = pioneer__WEBPACK_IMPORTED_MODULE_1__.MathUtils.lerp(Math.PI, Math.PI / 8, u); + } + }, + exit: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + const cover = model.getThreeJsObjectByName('engine_cover'); + if (cover !== null) { + cover.rotation.x = Math.PI; + } + } + }, { + type: 'coverage', + coverage: [399637867.183, 520959604.184], + update: (entity) => { + const particleSpray = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent); + const time = entity.getScene().getEngine().getTime(); + const nextCloseIndex = pioneer__WEBPACK_IMPORTED_MODULE_1__.Sort.getIndex(time, junoEngineBurns, (a, b) => a[1] < b); + const startTime = junoEngineBurns[nextCloseIndex][0]; + const endTime = junoEngineBurns[nextCloseIndex][1]; + const enabled = startTime <= time && time < endTime; + particleSpray.setEnabled(enabled); + }, + exit: (entity) => { + const particleSpray = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent); + particleSpray.setEnabled(false); + } + }, { + type: 'coverage', + coverage: [519652868.184, Number.POSITIVE_INFINITY], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail) { + trail.setRelativeToEntity('jupiter'); + } + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail) { + trail.setRelativeToEntity(''); + } + } + }], + postCreateFunction: (entity) => { + // Use the keyframes to point in the right direction. + const keyframePointing = entity.addControllerByClass(_controllers_keyframe_pointing_controller__WEBPACK_IMPORTED_MODULE_2__.KeyframePointingController); + keyframePointing.setKeyframes(junoPointingKeyframes); + keyframePointing.setDirection(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis); + keyframePointing.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(365836752.1832, 521025625)); + + // Use the keyframes to spin at the right rates. + const keyframeSpin = entity.addControllerByClass(_controllers_keyframe_spin_controller__WEBPACK_IMPORTED_MODULE_3__.KeyframeSpinController); + keyframeSpin.setKeyframes(junoSpinKeyframes); + keyframeSpin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis); + keyframeSpin.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(365836752.1832, 521025625)); + keyframeSpin.setStartingAngle(-0.96); // an angle to match the start of the ori dynamo. + + // Set up the engine burn. + const particleSpray = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent); + particleSpray.setNumberOfParticles(100); + particleSpray.setSizeOfParticles(0.0003); + particleSpray.setSpeedOfParticles(0.01); + particleSpray.setColorOfParticles(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(1, 0.75, 0, 0.25)); + particleSpray.setSpread(-3); + particleSpray.setParticleSpacingRandom(false); + particleSpray.setLength(0.003); + particleSpray.setOriginOffset(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0, -0.0017)); + particleSpray.setDirection(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg); + particleSpray.setEnabled(false); + } + }, + sc_cassini: { + groups: ['saturn', 'spacecraft'], + occlusionRadius: 0.0034, + extentsRadius: 0.005500, + label: 'Cassini', + parents: [ + [-69820368.42763124, 'earth'], + [-69537536.818, 'sun'], + [-53179136.814, 'venus'], + [-53092736.814, 'sun'], + [-16495135.816, 'venus'], + [-16451935.816, 'sun'], + [-11951935.817, 'earth'], + [-11660335.817, 'sun'], + [139219264.185, 'saturn'], + [558743640, ''] + ], + dependents: ['sc_huygens'], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_cassini/Cassini.gltf', + rotate: [ + { x: -90 }, + { z: 180 } + ], + shadowEntities: ['saturn', 'titan', 'enceladus', 'mimas', 'tethys'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_cassini/earth/launch/orb' + }, { + type: 'dynamo', + url: 'sc_cassini/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_cassini/venus/flyby1/orb' + }, { + type: 'dynamo', + url: 'sc_cassini/sun/2/orb' + }, { + type: 'dynamo', + url: 'sc_cassini/venus/flyby2/orb' + }, { + type: 'dynamo', + url: 'sc_cassini/sun/3/orb' + }, { + type: 'dynamo', + url: 'sc_cassini/earth/flyby/orb' + }, { + type: 'dynamo', + url: 'sc_cassini/sun/4/orb' + }, { + type: 'dynamo', + url: 'sc_cassini/saturn/orb' + }, { + type: 'dynamo', + url: 'sc_cassini/quat' + }, { + type: 'coverage', + coverage: [-13098535.817, 534124760.143], + update: (entity) => { + const particleSpray = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent); + const time = entity.getScene().getEngine().getTime(); + const nextCloseIndex = pioneer__WEBPACK_IMPORTED_MODULE_1__.Sort.getIndex(time, cassiniEngineBurns, (a, b) => a[1] < b); + const startTime = cassiniEngineBurns[nextCloseIndex][0]; + const endTime = cassiniEngineBurns[nextCloseIndex][1]; + const enabled = startTime <= time && time < endTime; + particleSpray.setEnabled(enabled); + }, + exit: (entity) => { + const particleSpray = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent); + particleSpray.setEnabled(false); + } + }, { + type: 'coverage', + coverage: [157212064.184, Number.POSITIVE_INFINITY], + enter: (entity) => { + const modelComponent = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (modelComponent !== null) { + modelComponent.setHiddenObject('huygens_probe', true); + } + }, + exit: (entity) => { + const modelComponent = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + if (modelComponent !== null) { + modelComponent.setHiddenObject('huygens_probe', false); + } + } + }], + postCreateFunction: (entity) => { + // Set up the engine burn. + const particleSpray = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent); + particleSpray.setNumberOfParticles(50); + particleSpray.setSizeOfParticles(0.0003); + particleSpray.setSpeedOfParticles(0.01); + particleSpray.setColorOfParticles(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(1, 0.75, 0, 0.25)); + particleSpray.setSpread(-3); + particleSpray.setParticleSpacingRandom(false); + particleSpray.setLength(0.002); + particleSpray.setOriginOffset(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0.00029, 0.0033)); + particleSpray.setDirection(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis); + particleSpray.setEnabled(false); + } + }, + // sc_europa_clipper: { // Consistent breaking error when loading the Dynamo file. Not worth fixing atm. + // groups: ['jupiter', 'europa', 'ganymede', 'callisto', 'spacecraft'], + // occlusionRadius: 0.003, + // extentsRadius: 0.011, + // label: 'Europa Clipper', + // parents: [ + // [781796651, 'sun'], + // [849443647, 'earth'], + // [849694384, 'sun'], + // [954569001, 'jupiter'], + // [1096736672, ''] + // ], + // trail: { + // length: undefined + // }, + // model: { + // url: '$STATIC_ASSETS_URL/models/sc_europa_clipper/europa_clipper.gltf', + // shadowEntities: ['jupiter', 'earth', 'mars', 'europa'] + // }, + // controllers: [{ + // type: 'dynamo', + // url: 'sc_europa_clipper/sun/orb' + // }, { + // type: 'dynamo', + // url: 'sc_europa_clipper/earth/flyby/orb' + // }, { + // type: 'dynamo', + // url: 'sc_europa_clipper/jupiter/orb' + // }, { + // type: 'align', + // primary: { + // type: 'point', + // target: 'sun', + // axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + // } + // }] + // }, + sc_galileo: { + groups: ['jupiter', 'spacecraft'], + occlusionRadius: 0.003, + extentsRadius: 0.0055, + label: 'Galileo', + parents: [ + [-321964226.73959994, 'earth'], + [-321559829, 'sun'], + [-312199026, 'venus'], + [-311946958, 'sun'], + [-286252262, 'earth'], + [-285827020, 'sun'], + [-223105356, 'earth'], + [-222610262, 'sun'], + [-129268796, 'jupiter'], + [117442702, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_galileo/galileo.gltf', + shadowEntities: ['jupiter', 'earth', 'venus'], + rotate: [ + { x: -90 }, + { z: 180 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_galileo/earth/launch/orb' + }, { + type: 'dynamo', + url: 'sc_galileo/sun/orb' + }, { + type: 'dynamo', + url: 'sc_galileo/venus/flyby/orb' + }, { + type: 'dynamo', + url: 'sc_galileo/earth/flyby1/orb' + }, { + type: 'dynamo', + url: 'sc_galileo/earth/flyby2/orb' + }, { + type: 'dynamo', + url: 'sc_galileo/jupiter/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'mercury', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis, + target: 'earth', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }, { + type: 'dynamo', + url: 'sc_galileo/quat' + }], + postCreateFunction: (entity) => { + // Make the rotor spin. + const spin = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.SpinController); + spin.setJoint('spinning_section'); + spin.setRate(3 * 2 * Math.PI / 60); + spin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg, true); + } + }, + sc_galileo_probe: { + groups: ['jupiter', 'spacecraft'], + radius: 0.00072, + label: 'Galileo Probe', + parents: [ + [-321964226.73959994, 'sc_galileo'], + [-129268796, 'jupiter'], + [-128353980, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_galileo_probe/galileo_probe.gltf', + rotate: [ + { x: -90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_galileo_probe/galileo/orb' + }, { + type: 'dynamo', + url: 'sc_galileo_probe/jupiter/orb' + }, { + type: 'fixed', + position: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero, + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity, + coverage: [-321964226.73959994, -141114537.48322043] + }, { + type: 'coverage', + coverage: [Number.NEGATIVE_INFINITY, -141114537.48322043], + enter: (entity) => { + const div = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent); + if (div !== null) { + div.setEnabled(false); + } + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setEnabled(false); + } + const translateController = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController); + translateController.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0, 0.001)); + }, + exit: (entity) => { + const div = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent); + if (div !== null) { + div.setEnabled(true); + } + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trail !== null) { + trail.setEnabled(true); + } + const translateController = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController); + translateController.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-0.000016, 0.000024, 0.0007)); + } + }], + postCreateFunction: (entity) => { + // Make the model centered. + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0, -0.001)); + + // Move it so that its dynamo start lines up with galileo on release. + const translateController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController); + translateController.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-0.000016, 0.000024, 0.0007)); + translateController.setRelativeToOrientation(true); + translateController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(-321964226.73959994, -128353980)); + + // Orient it so that it lines up with galileo on release. + const rotateByEntityOrientation = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.RotateByEntityOrientationController); + rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(-321964226.73959994, -141114537.48322043)); + const fixed = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.FixedController); + fixed.setOrientation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.40004226980201746, 0.3894033591393042, -0.7928008139628516, 0.24453645053961984)); + fixed.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(-141114537.48322043, Number.POSITIVE_INFINITY)); + } + }, + sc_huygens: { + groups: ['saturn', 'spacecraft', 'titan'], + occlusionRadius: 0.00130, + extentsRadius: 0.00130, + label: 'Huygens', + parents: [ + [157212064.184, 'saturn'], + [158945582, 'titan'], + [158974766.184, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_huygens/Huygens.gltf', + rotate: [ + { x: -90 }, + { z: 180 } + ], + shadowEntities: ['saturn', 'titan', 'enceladus', 'mimas', 'tethys'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_huygens/saturn/orb' + }, { + type: 'dynamo', + url: 'sc_huygens/titan/orb' + }, { + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.8295521744501194, 0.09912464029342342, -0.04158756948048668, -0.5479853735424731) + }, { + type: 'custom', + func: (entity) => { + // Needed because spice doesn't go all the way down. + const keyframeController1 = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.KeyframeController); + keyframeController1.addPositionKeyframe(158965616.707, // When the spice runs out. + new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-74.84608000701567, -3832.0774028380238, -305.9513410781612)); + keyframeController1.addPositionKeyframe(158965667.7750001, + new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-168.19015737501377, -3541.733393771429, -291.12326824195395)); + keyframeController1.addPositionKeyframe(158965894.184, // When Huygens deploys its parachute at 152 km altitude + new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-376.8992769951708, -2686.9622048526126, -273.33138256355716)); + return keyframeController1; + } + }, { + type: 'custom', + func: (entity) => { + // Separate keyframe controller needed for parachute landing, since it is a sharp edge, slowing the velocity drastically. + const keyframeController2 = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.KeyframeController); + keyframeController2.addPositionKeyframe(158965894.184, // When Huygens deploys its parachute at 152 km altitude + new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-376.8992769951708, -2686.9622048526126, -273.33138256355716)); + keyframeController2.addPositionKeyframe(158974766.184, // When Huygens lands on the ground + new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-251.2479743710496, -2548.813556954952, -266.5500089234507)); + return keyframeController2; + } + }, { + type: 'custom', + func: (entity) => { + // Reverse the model translation. + const translateController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController); + translateController.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-0.0013, 0, 0.0011)); + translateController.setRelativeToOrientation(true); + translateController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(157212064.184, 158974766.184)); + return translateController; + } + }, { + type: 'custom', + func: (entity) => { + // Use the keyframes to spin at the right rates. + const keyframeSpin = entity.addControllerByClass(_controllers_keyframe_spin_controller__WEBPACK_IMPORTED_MODULE_3__.KeyframeSpinController); + keyframeSpin.setKeyframes(huygensSpinKeyframes); + keyframeSpin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg); + keyframeSpin.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(157212064.184, Number.POSITIVE_INFINITY)); + return keyframeSpin; + } + }, { + type: 'coverage', + coverage: [158965616.707, Number.POSITIVE_INFINITY], + enter: (entity) => { + const trailComponent = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trailComponent !== null) { + trailComponent.setRelativeToEntityOrientation(true); + } + }, + exit: (entity) => { + const trailComponent = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent); + if (trailComponent !== null) { + trailComponent.setRelativeToEntityOrientation(false); + } + } + }], + postCreateFunction: (entity) => { + // Make the model centered. + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent); + model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.0013, 0, -0.0011)); + } + }, + sc_huygens_landing_site: { + groups: ['titan', 'sc_huygens', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'Huygens Landing Site', + parents: [ + [157212064.184, 'titan'] + ], + controllers: [{ + type: 'fixed', + llaOnSpheroid: new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(-0.18453331247520502, 2.9263055188728955, 0), + coverage: [157212064.184, Number.POSITIVE_INFINITY] + }] + }, + sc_juice: { + groups: ['jupiter', 'ganymede', 'spacecraft'], + occlusionRadius: 0.007, + extentsRadius: 0.0135, + label: 'JUICE', + parents: [ + [734748207, 'earth'], + [735606318, 'sun'], + [777026548, 'earth'], + [778061110, 'sun'], + [809697014, 'venus'], + [810162491, 'sun'], + [843697642, 'earth'], + [844049179, 'sun'], + [916393497, 'earth'], + [916903199, 'sun'], + [994471790, 'jupiter'], + [1103217877, 'ganymede'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_juice/juice.gltf', + shadowEntities: ['ganymede', 'jupiter', 'earth'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_juice/earth/launch' + }, { + type: 'dynamo', + url: 'sc_juice/sun' + }, { + type: 'dynamo', + url: 'sc_juice/earth/flyby1' + }, { + type: 'dynamo', + url: 'sc_juice/venus/flyby' + }, { + type: 'dynamo', + url: 'sc_juice/earth/flyby2' + }, { + type: 'dynamo', + url: 'sc_juice/earth/flyby3' + }, { + type: 'dynamo', + url: 'sc_juice/jupiter' + }, { + type: 'dynamo', + url: 'sc_juice/ganymede' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg + }, + secondary: { + type: 'align', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }, { + type: 'dynamo', + url: 'sc_juice/quat' + }] + }, + sc_pioneer_10: { + groups: ['sun', 'jupiter', 'spacecraft'], + occlusionRadius: 0.002118055, + extentsRadius: 0.003, + label: 'Pioneer 10', + parents: [ + [-878291717.8145751, 'earth'], + [-878146409, 'sun'], + [-824046472, 'jupiter'], + [-822011429, 'sun'] + ], + trail: { + length: 60 * 60 * 24 * 365 * 10 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_pioneer/pioneer.gltf', + rotate: [ + { x: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_pioneer_10/earth/orb' + }, { + type: 'dynamo', + url: 'sc_pioneer_10/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_pioneer_10/jupiter/orb' + }, { + type: 'dynamo', + url: 'sc_pioneer_10/sun/2/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + } + }] + }, + sc_pioneer_11: { + groups: ['sun', 'jupiter', 'saturn', 'spacecraft'], + occlusionRadius: 0.002118055, + extentsRadius: 0.003, + label: 'Pioneer 11', + parents: [ + [-843816855.8143449, 'earth'], + [-843644357, 'sun'], + [-792658454, 'jupiter'], + [-790152245, 'sun'], + [-643302619, 'saturn'], + [-640194311, 'sun'] + ], + trail: { + length: 60 * 60 * 24 * 365 * 10 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_pioneer/pioneer.gltf', + rotate: [ + { x: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_pioneer_11/earth/orb' + }, { + type: 'dynamo', + url: 'sc_pioneer_11/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_pioneer_11/jupiter/orb' + }, { + type: 'dynamo', + url: 'sc_pioneer_11/sun/2/orb' + }, { + type: 'dynamo', + url: 'sc_pioneer_11/saturn/orb' + }, { + type: 'dynamo', + url: 'sc_pioneer_11/sun/3/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + } + }] + }, + sc_voyager_1: { + groups: ['jupiter', 'saturn', 'sun', 'spacecraft'], + occlusionRadius: 0.00183, + extentsRadius: 0.0043000, + label: 'Voyager 1', + parents: [ + [-704412035.617, 'earth'], + [-703530245, 'sun'], + [-660264745, 'jupiter'], + [-655057463, 'sun'], + [-606239665, 'saturn'], + [-600733702, 'sun'] + ], + trail: { + length: 946080000, + lengthCoverages: [ + [157680000, Number.NEGATIVE_INFINITY, 377123932.454], + [946080000, 377123932.454, Number.POSITIVE_INFINITY], + [5184000, -660264745, -655057463], + [5184000, -606239665, -600733702] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_voyager/Voyager.gltf', + rotate: [ + { x: -90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_voyager_1/earth/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_1/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_1/jupiter/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_1/sun/2/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_1/saturn/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_1/sun/3/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + } + }, { + type: 'dynamo', + url: 'sc_voyager_1/ori' + }] + }, + sc_voyager_2: { + groups: ['jupiter', 'saturn', 'uranus', 'neptune', 'sun', 'spacecraft'], + occlusionRadius: 0.00183, + extentsRadius: 0.0043000, + label: 'Voyager 2', + parents: [ + [-705788847.817, 'earth'], + [-704774613, 'sun'], + [-650828783, 'jupiter'], + [-642276063, 'sun'], + [-582886481, 'saturn'], + [-574538624, 'sun'], + [-440395228, 'uranus'], + [-439259319, 'sun'], + [-327233138, 'neptune'], + [-326252606, 'sun'] + ], + trail: { + length: 946080000, + lengthCoverages: [ + [157680000, Number.NEGATIVE_INFINITY, 651751314.724], + [946080000, 651751314.724, Number.POSITIVE_INFINITY], + [5184000, -650828783, -642276063], + [5184000, -582886481, -574538624], + [5184000, -440395228, -439259319], + [5184000, -327233138, -326252606] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_voyager/Voyager.gltf', + rotate: [ + { x: -90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_voyager_2/earth/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_2/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_2/jupiter/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_2/sun/2/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_2/saturn/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_2/sun/3/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_2/uranus/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_2/sun/4/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_2/neptune/orb' + }, { + type: 'dynamo', + url: 'sc_voyager_2/sun/5/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + } + }, { + type: 'dynamo', + url: 'sc_voyager_2/ori' + }] + } +}); + +// Cassini engine burn start/stop times +const cassiniEngineBurns = [ + [-13098535.817, -13098146.797], + [-12342535.817, -12342421.197], + [-10612735.817, -10612663.357], + [14274064.185, 14274070.255], + [36653454.185, 36653459.605], + [71128864.186, 71128875.066], + [105091264.185, 105091282.755], + [118339264.182, 118339287.092], + [138968824.185, 138969181.735], + [140692084.184, 140692123.174], + [141916392.184, 141922237.024], + [146548444.183, 146551498.073], + [147846664.183, 147846668.693], + [152302564.182, 152302569.842], + [154285264.183, 154285267.193], + [156518584.184, 156518669.274], + [157466284.184, 157466438.074], + [159139264.184, 159139404.074], + [160168144.185, 160168264.795], + [161978464.185, 161978469.745], + [163011064.185, 163011104.295], + [163869664.186, 163869667.996], + [164528404.186, 164528414.466], + [165853384.186, 165853391.046], + [166370464.186, 166370502.696], + [168008344.186, 168008476.766], + [174127084.184, 174127086.454], + [176341864.183, 176341881.793], + [176952124.183, 176952139.533], + [178261744.183, 178261753.433], + [178699444.183, 178699535.673], + [180420064.182, 180420240.372], + [182368684.182, 182368777.962], + [184039204.183, 184039282.793], + [185162584.183, 185162597.343], + [196273205.186, 196273208.936], + [197566385.186, 197566387.476], + [199978145.185, 199978148.205], + [202994705.185, 202994717.245], + [207734765.183, 207734800.073], + [211183265.182, 211183306.302], + [211500485.182, 211500537.082], + [212965745.182, 212965786.692], + [214371665.182, 214371670.582], + [216354545.183, 216354568.983], + [219456245.183, 219456251.063], + [219887345.184, 219887389.034], + [220835165.184, 220835169.094], + [221266265.184, 221266275.434], + [222644225.185, 222644240.975], + [224109485.185, 224109487.885], + [226090325.185, 226090329.355], + [227038025.186, 227038032.946], + [227469065.186, 227469075.266], + [228387005.186, 228387008.496], + [228846905.186, 228846923.006], + [230225585.186, 230225608.176], + [231577265.185, 231577300.725], + [232982885.185, 232982919.625], + [233930525.185, 233930529.665], + [234334565.185, 234334641.855], + [235309205.185, 235309210.915], + [235740245.184, 235740294.424], + [239704565.183, 239704568.933], + [242004965.183, 242004968.253], + [242979665.182, 242979748.272], + [244876985.182, 244876993.442], + [247203665.183, 247203671.283], + [248986685.183, 248986692.503], + [249417845.183, 249417942.863], + [250365665.183, 250365669.503], + [250801865.183, 250801924.453], + [252201785.184, 252201798.884], + [253728965.184, 253728983.974], + [255535625.185, 255535853.415], + [256682225.185, 256682228.065], + [257684225.185, 257684269.165], + [258146525.185, 258146533.105], + [258722525.186, 258722543.076], + [261147905.186, 261147925.516], + [262453685.186, 262453688.326], + [264259265.185, 264259272.395], + [267474305.184, 267474379.954], + [271073765.183, 271073780.663], + [272731805.183, 272731887.753], + [275208605.182, 275208611.692], + [276214805.182, 276214829.892], + [277127525.182, 277127545.362], + [277506665.182, 277506708.062], + [279455045.183, 279455100.823], + [279799805.183, 279799837.073], + [280747565.183, 280747571.013], + [282126485.183, 282126503.483], + [282471245.183, 282471256.053], + [286040946.185, 286040974.915], + [287532306.185, 287532308.475], + [289858866.186, 289858897.046], + [291603966.186, 291603971.806], + [292809906.186, 292809948.366], + [294188586.186, 294188602.066], + [295567266.185, 295567279.505], + [296945946.185, 296945956.015], + [297893586.185, 297893599.995], + [299272206.184, 299272220.614], + [300687786.184, 300687808.034], + [302066526.183, 302066563.313], + [303703506.183, 303703583.793], + [304824006.183, 304824009.283], + [305390946.183, 305390972.583], + [308925306.182, 308925311.352], + [309355506.182, 309355530.682], + [310684866.183, 310684869.093], + [312200586.183, 312200601.223], + [534124756.143, 534124760.143] +]; + +/** The times when the Juno engine cover starts opening or finishes closing, respectively. + * The 600 is because the hatch takes 600 seconds to close and the number given is the start of the closing time. */ +const junoEngineCoverOpenings = [ + [393471366, 393500886 + 600], + [399019747, 399882847 + 600], + [400569547, 400988287 + 600], + [420541747, 420794047 + 600], + [454490527, 454649587 + 600], + [487136707, 487309087 + 600], + [519804068, 521041148 + 600], + [528958868, 529748408 + 600] +]; + +const junoEngineBurns = [ + [399637867.183, 399639659.183], + [400933867.182, 400935660.182], + [420714067.185, 420714067.185 + 5], + [454572067.185, 454572067.185 + 5], + [487231267.185, 487231267.185 + 5], + [520957868.184, 520959604.184] +]; + +/** Pointing for Juno, since its orientation doesn't work so well. It can point at an entity, 'velocity', or '-velocity'. + * The transition happens for the 5 minutes prior to the start time of the next event. */ +const junoPointingKeyframes = /** @type {[number, string][]} */([ + [365835906, 'velocity'], + [365836206, 'sun'], + [371908866, 'sun'], + [371909466, 'earth'], + [399631646, 'earth'], + [399632628, 'sun'], + [399635271, 'sun'], + [399636306, '-velocity'], // DSM-1 + [399640481, '-velocity'], + [399641686, 'sun'], + [399700717, 'sun'], + [399641887, 'earth'], + [400927646, 'earth'], + [400928454, 'sun'], + [400931272, 'sun'], + [400932282, '-velocity'], // DSM-2 + [400936477, '-velocity'], + [400937632, 'sun'], + [401003197, 'sun'], + [401009197, 'earth'], + [423014467, 'earth'], + [423014767, 'sun'], + [436924867, 'sun'], + [436925167, 'earth'], + [520954868, 'earth'], + [520955888, '-velocity'], // JOI + [520960808, '-velocity'], + [520962008, 'sun'], + [521018048, 'sun'], + [521025625, 'earth'] // Dynamo ori starts here +]); + +const junoSpinKeyframes = /** @type {[number, number][]} */([ + [394545667, 1 * Math.PI / 30], // convert from rpm to rad/sec + [394545967, 2 * Math.PI / 30], + [399636967, 2 * Math.PI / 30], + [399637264, 5 * Math.PI / 30], // DSM-1 + [399637866, 5 * Math.PI / 30], + [399639659, 5.5 * Math.PI / 30], + [399639788, 5.5 * Math.PI / 30], + [399640072, 2 * Math.PI / 30], + [400932921, 2 * Math.PI / 30], + [400933214, 5 * Math.PI / 30], // DSM-2 + [400933866, 5 * Math.PI / 30], + [400935660, 5.5 * Math.PI / 30], + [400935790, 5.5 * Math.PI / 30], + [400936068, 2 * Math.PI / 30], + [520956548, 2 * Math.PI / 30], + [520956848, 5 * Math.PI / 30], // JOI + [520960088, 5 * Math.PI / 30], + [520960388, 2 * Math.PI / 30], + [521025625, 2 * Math.PI / 30] // Dynamo ori starts here +]); + +const huygensSpinKeyframes = /** @type {[number, number][]} */([ + [157212064.184, 7.5 * Math.PI / 30], // convert from rpm to rad/sec + [158965863.184, 7.5 * Math.PI / 30], + [158966163.184, 2.6 * Math.PI / 30], + [158966434.184, 0], + [158966883.184, -5.6 * Math.PI / 30], // starts spinning clockwise + [158967123.184, -9.7 * Math.PI / 30], + [158967363.184, -7.3 * Math.PI / 30], + [158968263.184, -2.8 * Math.PI / 30], + [158973723.184, -1 * Math.PI / 30] +]); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/planets_and_stars.js": +/*!************************************************************!*\ + !*** ../pioneer/scripts/src/entities/planets_and_stars.js ***! + \************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var _scene_helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../scene_helpers */ "../pioneer/scripts/src/scene_helpers.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + observable_universe: { + groups: ['stars'], + radius: 5e23, + systemRadius: 5e23, + label: 'Observable Universe', + parents: [], + controllers: [{ + type: 'fixed', + position: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.Zero, + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }], + postCreateFunction: (entity) => { + entity.setCanOcclude(false); + } + }, + milky_way: { + groups: ['stars'], + radius: 1e18, + systemRadius: 1.3e+19, + label: 'Milky Way', + parents: [ + [Number.NEGATIVE_INFINITY, 'observable_universe'] + ], + controllers: [{ + type: 'fixed', + position: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.Zero, + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }], + postCreateFunction: (entity, extraOptions) => { + entity.setCanOcclude(false); + + const fixedController = entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.FixedController); + // Get it in the right orientation, using the galactic north and galactic center. + // Galactic North Pole in J2000: 12h 51m 26.27549s, +27° 07′ 41.7043" + // Galactic Center in J2000: 7h 45m 37.19910s, −28° 56′ 10.2207" + // From Liu, Jia-Cheng & Zhu, Zi & Zhang, Hong. (2010). Reconsidering the Galactic coordinate system. Astronomy and Astrophysics. 526. 10.1051/0004-6361/201014961. + const northPole = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(); + const northPoleRa = 192.85948120833 * Math.PI / 180; + const northPoleDec = 27.12825119444 * Math.PI / 180; + northPole.x = Math.cos(northPoleRa) * Math.cos(northPoleDec); + northPole.y = Math.sin(northPoleRa) * Math.cos(northPoleDec); + northPole.z = Math.sin(northPoleDec); + const center = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(); + const centerRa = 266.40499625 * Math.PI / 180; + const centerDec = -28.93617241667 * Math.PI / 180; + center.x = Math.cos(centerRa) * Math.cos(centerDec); + center.y = Math.sin(centerRa) * Math.cos(centerDec); + center.z = Math.sin(centerDec); + const orientation = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(); + orientation.setFromAxes(center, undefined, northPole); + fixedController.setOrientation(orientation); + + // Add milky way sprite, if it's in the options. + if (extraOptions && extraOptions.milkyWaySprite) { + const sprite = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpriteComponent); + sprite.setTextureUrl('$STATIC_ASSETS_URL/sprites/milky_way.png'); + sprite.setSize(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector2(12e17, 12e17)); + sprite.setTransparent(true); + sprite.setBlending('normal'); + sprite.setFadeDistance(12e15); + } + + // Spin of the milky way. Later I should change it to work with particles and use the galaxy rotation curve. + const spinController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpinController); + spinController.setAxis(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.8676661356982597, -0.19807638974470915, 0.45598379452940485), false); + spinController.setRate(-2.192686e-17); + spinController.setReferenceAngle(0); + spinController.setReferenceTime(0); + } + }, + sun: { + groups: ['stars'], + radius: 695500, + systemRadius: 2.991957e+13, + label: 'Sun', + parents: [ + [Number.NEGATIVE_INFINITY, 'milky_way'] + ], + spheroid: { + equatorialRadius: 695500, + polarRadius: 695500, + planetographic: false + }, + spheroidLOD: { + features: ['colorMapEmmissive'], + textures: { + color: { + url: 'sun/color_$SIZE_$FACE.png', + sizes: [4, 512] + } + } + }, + controllers: [{ + type: 'fixed', + position: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.Zero, + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }], + postCreateFunction: (entity, extraOptions) => { + // Add the light source for the sun. + const lightSourceComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.LightSourceComponent); + lightSourceComponent.setAbsoluteMagnitude(4.83); + + // Atmosphere glow when you're close up to the sun. + const sunAtmosphere = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent); + sunAtmosphere.setEmissivity(1.0); + sunAtmosphere.setScaleHeight(2e5); + sunAtmosphere.setDensity(8e-7); + sunAtmosphere.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(255.0 / 255.0, 255.0 / 255.0, 64.0 / 255.0)); + + // Sprite glow when you're far away from the sun. + const sunGlowSprite = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpriteComponent); + sunGlowSprite.setBillboard(true); + sunGlowSprite.setTextureUrl('$STATIC_ASSETS_URL/sprites/sun_glow.png'); + sunGlowSprite.setSize(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector2(100, 100)); + sunGlowSprite.setSizeUnits('pixels'); + sunGlowSprite.setTransparent(true); + sunGlowSprite.setColorMultiplier(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(1.0, 1.0, 0.5)); + sunGlowSprite.setRenderOrder(-2); // Make it render in the same order as the stars. + + // Set the position in the milky way. + // Distance from sun to galactic center: 7.98 kpc. + // From Malkin, Zinovy. (2012). The current best estimate of the Galactocentric distance of the Sun based on comparison of different statistical techniques. + const oeController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.OrbitalElementsController); + const oe = new pioneer__WEBPACK_IMPORTED_MODULE_2__.OrbitalElements(); + oe.epoch = 0; + oe.eccentricity = 0; + oe.semiMajorAxis = 246237071000000000.0; + oe.meanAngularMotion = -2.192686e-17; // 230 million years per orbit. + oe.meanAnomalyAtEpoch = Math.PI; + // Use the orientation calculated from the milky way above. + oe.orbitOrientation.set(-0.48894750765094835, -0.4832106839985283, 0.19625375824756275, 0.6992297419646486); + oeController.addOrbitalElements(-1e100, oe); + oeController.addOrbitalElements(+1e100, oe); + + // Add the stars and the galaxies, since they are sun-centric. + if (extraOptions !== undefined && extraOptions.skybox === true) { + const skyboxComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SkyboxComponent); + skyboxComponent.setTextureUrl('$STATIC_ASSETS_URL/textures/starmap_' + (extraOptions.skyboxResolution || 2048) + '.jpg'); + } + if (extraOptions === undefined || (extraOptions.skybox === true && extraOptions.starfield === true) || extraOptions.starfield !== false) { + const galaxyComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.StarfieldComponent); + galaxyComponent.setUrl('$STATIC_ASSETS_URL/stars/galaxies.0.bin'); + for (let i = 0; i < 6; i++) { + const starfieldComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.StarfieldComponent); + starfieldComponent.setUrl('$STATIC_ASSETS_URL/stars/stars.' + i + '.bin'); + } + } + + // Add the heliosphere, if specified. + // Using "A Three-dimensional Map of the Heliosphere from IBEX", 2021 Reisenfeld et al. as a reference. + if (extraOptions !== undefined && extraOptions.heliosphere) { + const model = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + model.setUrl('$STATIC_ASSETS_URL/models/heliosphere/voyager_heliosphere.gltf'); + // Get it just the right size so Voyager 1 leaves it around 2012-08 and Voyager 2 leaves it around 2018-11. + model.setScale(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(2.01e8, 1.9e8, 1.9e8)); + model.setForceLoaded(true); + // Rotate so it's heading in the correct direction. + const llaNose = new pioneer__WEBPACK_IMPORTED_MODULE_2__.LatLonAlt(0, -105 * Math.PI / 180, 0); // Lat/lon of nose in J2000 Ecliptic. + const xyzNose = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(); + pioneer__WEBPACK_IMPORTED_MODULE_2__.Geometry.getXYZFromLLAOnSphere(xyzNose, llaNose, 1); + xyzNose.rotate(_scene_helpers__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.getEclipJ2000ToJ2000Rotation(), xyzNose); + xyzNose.normalize(xyzNose); + const rotation = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(); + rotation.setFromVectorFromTo( + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.9937396508197329, 0.11171728072160429, 0.0008692392338424033), + xyzNose); + model.setRotation(rotation); + } + } + }, + mercury: { + groups: ['planets'], + radius: 2439.4, + systemRadius: 292764, + label: 'Mercury', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined, + color: [0.6, 0.6, 0.6, 0.7] + }, + spheroid: { + equatorialRadius: 2439.4, + polarRadius: 2439.4, + planetographic: false + }, + spheroidLOD: { + textures: { + color: { + url: 'mercury/color_$SIZE_$FACE.png', + sizes: [4, 512, 4096] + } + } + }, + controllers: [{ + type: 'dynamo', + url: 'mercury/sun/orb' + }, { + type: 'dynamo', + url: 'mercury/ori' + }] + }, + venus: { + groups: ['planets'], + radius: 6051.8, + systemRadius: 726216, + label: 'Venus', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined, + color: [0.9, 0.80, 0.45, 0.7] + }, + spheroid: { + equatorialRadius: 6051.8, + polarRadius: 6051.8, + planetographic: false + }, + spheroidLOD: { + textures: { + color: { + url: 'venus/color_$SIZE_$FACE.png', + sizes: [4, 512] + } + } + }, + controllers: [{ + type: 'dynamo', + url: 'venus/sun/orb' + }, { + type: 'dynamo', + url: 'venus/ori' + }], + postCreateFunction: (entity) => { + const atmosphereComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent); + atmosphereComponent.setScaleHeight(15.0); + atmosphereComponent.setDensity(0.001); + atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(213.0 / 255.0, 160.0 / 255.0, 94.0 / 255.0)); + atmosphereComponent.setSunBrightness(0.25); + } + }, + earth: { + groups: ['planets'], + radius: 6378.1, + systemRadius: 765372, + label: 'Earth', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined, + color: [0.0, 0.6, 0.8, 0.7] + }, + spheroid: { + equatorialRadius: 6378.137, + polarRadius: 6356.752, + planetographic: true + }, + spheroidLOD: { + features: ['normalMap', 'specularMap', 'nightMap', 'decalMap', 'nightMapEmmissive', 'shadowEntities'], + textures: { + color: { + url: 'earth/color_$SIZE_$FACE.png', + sizes: [16, 512, 4096] + }, + normal: { + url: 'earth/normal_$SIZE_$FACE.png', + sizes: [16, 512, 4096] + }, + specular: { + url: 'earth/specular_$SIZE_$FACE.png', + sizes: [16, 512, 4096] + }, + night: { + url: 'earth/night_$SIZE_$FACE.png', + sizes: [16, 512, 4096] + }, + decal: { + url: 'earth/cloud_$SIZE_$FACE.png', + sizes: [16, 512, 4096] + } + }, + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'earth/sun/orb' + }, { + type: 'dynamo', + url: 'earth/ori' + }], + postCreateFunction: (entity, extraOptions) => { + if (extraOptions && extraOptions.clouds === false) { + const spheroidLODComponent = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpheroidLODComponent); + spheroidLODComponent.setTexture('decal', ''); + } + + const atmosphereComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent); + atmosphereComponent.setScaleHeight(8.0); + atmosphereComponent.setDensity(0.0015); + atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(1.5 * 143.0 / 255.0, 1.5 * 178.0 / 255.0, 1.5 * 255.0 / 255.0)); + atmosphereComponent.setSunBrightness(2.0); + atmosphereComponent.setSunsetColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(1, 0.5, 0)); + atmosphereComponent.setSunsetIntensity(1.2); + } + }, + mars: { + groups: ['planets'], + radius: 3396.2, + systemRadius: 46922, + label: 'Mars', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined, + color: [0.89, 0.51, 0.35, 0.7] + }, + spheroid: { + equatorialRadius: 3396.19, + polarRadius: 3376.2, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'mars/color_$SIZE_$FACE.png', + sizes: [4, 512, 4096] + } + // normal: 'mars/normal_$SIZE_$FACE.png', + }, + shadowEntities: ['phobos', 'deimos'] + }, + controllers: [{ + type: 'dynamo', + url: 'mars/sun/orb' + }, { + type: 'dynamo', + url: 'mars/ori' + }], + postCreateFunction: (entity) => { + const atmosphereComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent); + atmosphereComponent.setScaleHeight(10.8); + atmosphereComponent.setDensity(0.001); + atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(225.0 / 255.0, 178.0 / 255.0, 112.0 / 255.0)); + atmosphereComponent.setSunBrightness(0.8); + atmosphereComponent.setSunsetColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(10.0 / 255.0, 75.0 / 255.0, 140.0 / 255.0)); + atmosphereComponent.setSunsetIntensity(1.0); + } + }, + jupiter: { + groups: ['planets'], + radius: 71492, + systemRadius: 3782501, + label: 'Jupiter', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined, + color: [0.95, 0.71, 0.64, 0.7] + }, + spheroid: { + equatorialRadius: 71492, + polarRadius: 66854, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'jupiter/color_$SIZE_$FACE.jpg', + sizes: [16, 512, 4096] + } + }, + shadowEntities: ['io', 'europa', 'ganymede', 'callisto'] + }, + controllers: [{ + type: 'dynamo', + url: 'jupiter/sun/orb' + }, { + type: 'dynamo', + url: 'jupiter/ori' + }, { + type: 'coverage', + coverage: [Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY], + update: (entity) => { + if (entity.getOrientation().isNaN()) { + return; + } + + /* + In order to update the spots, you can use these helpful functions. + + // Get the camera the view from earth. + e = () => { c = app._pioneer.getViewport(0).getCamera(); p = new Pioneer.Vector3(); p.sub(app._scene.get('earth').getPosition(), app._scene.get('jupiter').getPosition()); p.mult(p, .99); c.getEntity().setPosition(p); c.setFieldOfView(0.0008); }; + + // The code moves time backward by the light-time distance between earth and jupiter. + // So if a photo was taken at time T, then the will move to T - ltej. + // VERY useful for getting photos exact, and works perfectly for photos as far back as 1963 (and likely further). + // It moves time backward by the light-time distance between earth and jupiter. + // So if a photo was taken at time T, then the will move to T - ltej. + // VERY useful for getting photos exact, and works perfectly for photos as far back as 1963 (and likely further). + t = () => { p = new Pioneer.Vector3(); p.sub(app._scene.get('earth').getPosition(), app._scene.get('jupiter').getPosition()); app._pioneer.setTime(app._pioneer.getTime() - p.magnitude() / 299792.458); console.log(app._pioneer.getTime()); }; + + // Rotate jupiter by the given angle to match. + r = (angle) => { s = app._scene.get('jupiter', 'spheroidLOD'); s.setLongitudeRotation(Pioneer.MathUtils.degToRad(angle)); }; + + Make sure to turn off the coverage controller below. + Find a photo from earth of Jupiter (https://www.missionjuno.swri.edu/junocam/planning). Go to the time when the photo was taken. + Run e(); + Run t(); + Now you'll be at the right time and position from earth to see the photo. + Run r(angle) until the spot matches the right location. + Add this angle to the Jupiter GRS spreadsheet column F. Do this for a number of photos. + Also look up http://jupos.privat.t-online.de/index.htm for numbers to add to array above. + */ + + // Get the right index for the current time. + const time = entity.getScene().getEngine().getTime(); + const rotations = jupiterRotationData.rotations; + const currentDriftRate = (rotations[rotations.length - 1][1] - rotations[rotations.length - 2][1]) / (rotations[rotations.length - 1][0] - rotations[rotations.length - 2][0]); + let rate = currentDriftRate; // The rate of drift in degrees per second from the index point. It is set to the current rate of jupiter's rotation. + let index = jupiterRotationData.hintIndex; + if (time < rotations[index][0] || (index < rotations.length - 1 && rotations[index + 1][0] <= time)) { + if (time >= rotations[rotations.length - 1][0]) { // After the last point. + index = rotations.length - 1; + // The rate just stays the current rate. + } + else if (time < rotations[0][0]) { // Before the first point. + index = 0; + rate = 0; // No rate, since not enough data. + } + else { // Somewhere in between points. + for (let i = rotations.length - 2; i >= 0; i--) { + if (rotations[i][0] <= time && time < rotations[i + 1][0]) { + index = i; + rate = (rotations[i + 1][1] - rotations[i][1]) / (rotations[i + 1][0] - rotations[i][0]); + } + } + } + } + else if (index < rotations.length - 1) { + rate = (rotations[index + 1][1] - rotations[index][1]) / (rotations[index + 1][0] - rotations[index][0]); + } + jupiterRotationData.hintIndex = index; + // Get the angle in system II. + const angle = rotations[index][1] + (time - rotations[index][0]) * rate; + // Do the calculation from System II to System III and taking into account the texture offset. + const actualAngle = pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.wrap(jupiterRotationData.referenceAngleInSystemIII + - (angle + jupiterRotationData.textureAngleOffset - jupiterRotationData.referenceAngleInSystemII) + + (time - jupiterRotationData.referenceTime) * jupiterRotationData.offsetFactor, 0, 360); + // Apply the rotation. + const spheroidLOD = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpheroidLODComponent); + if (spheroidLOD !== null) { + spheroidLOD.setLongitudeRotation(pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.degToRad(actualAngle)); + } + } + }], + postCreateFunction: (entity) => { + const atmosphereComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent); + atmosphereComponent.setScaleHeight(200.0); + atmosphereComponent.setDensity(5.0e-5); + atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(234.0 / 255.0, 202.0 / 255.0, 170.0 / 255.0)); + atmosphereComponent.setSunBrightness(0.25); + } + }, + saturn: { + groups: ['planets'], + radius: 60268, + systemRadius: 7184413, + label: 'Saturn', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + spheroid: { + equatorialRadius: 60268, + polarRadius: 54364, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities', 'shadowRings'], + textures: { + color: { + url: 'saturn/color_$SIZE_$FACE.png', + sizes: [4, 512] + } + }, + shadowEntities: ['iapetus', 'dione', 'rhea', 'tethys', 'titan'] + }, + controllers: [{ + type: 'dynamo', + url: 'saturn/sun/orb' + }, { + type: 'dynamo', + url: 'saturn/ori' + }], + postCreateFunction: (entity) => { + const ringsComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RingsComponent); + ringsComponent.setInnerRadius(74270.580913); + ringsComponent.setOuterRadius(140478.924731); + ringsComponent.setTopTextureUrl('$STATIC_ASSETS_URL/sprites/saturn_rings_top.png'); + ringsComponent.setBottomTextureUrl('$STATIC_ASSETS_URL/sprites/saturn_rings_bottom.png'); + ringsComponent.setFadeDistance(250); + ringsComponent.setShadowEntities(['iapetus', 'dione', 'rhea', 'tethys', 'titan']); + + const atmosphereComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent); + atmosphereComponent.setScaleHeight(200.0); + atmosphereComponent.setDensity(5.0e-5); + atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(234.0 / 255.0, 202.0 / 255.0, 151.0 / 255.0)); + } + }, + uranus: { + groups: ['planets'], + radius: 25559, + systemRadius: 1164893, + label: 'Uranus', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + spheroid: { + equatorialRadius: 25559, + polarRadius: 24973, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'uranus/color_$SIZE_$FACE.png', + sizes: [4, 256] + } + }, + shadowEntities: ['titania', 'oberon', 'umbriel', 'ariel', 'miranda'] + }, + controllers: [{ + type: 'dynamo', + url: 'uranus/sun/orb' + }, { + type: 'dynamo', + url: 'uranus/ori' + }], + postCreateFunction: (entity) => { + const ringsComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RingsComponent); + ringsComponent.setInnerRadius(26840); + ringsComponent.setOuterRadius(103000); + ringsComponent.setTopTextureUrl('$STATIC_ASSETS_URL/sprites/uranus_rings.png'); + ringsComponent.setBottomTextureUrl('$STATIC_ASSETS_URL/sprites/uranus_rings.png'); + ringsComponent.setFadeDistance(250); + ringsComponent.setShadowEntities(['miranda', 'ariel', 'umbriel', 'titania', 'oberon']); + + const atmosphereComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent); + atmosphereComponent.setScaleHeight(200.0); + atmosphereComponent.setDensity(5.0e-5); + atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(147.0 / 255.0, 183.0 / 255.0, 201.0 / 255.0)); + atmosphereComponent.setSunsetColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(164.0 / 255.0, 168.0 / 255.0, 102.0 / 255.0)); + atmosphereComponent.setSunsetIntensity(1.0); + } + }, + neptune: { + groups: ['planets'], + radius: 24764, + systemRadius: 43213894, + label: 'Neptune', + parents: [ + [Number.NEGATIVE_INFINITY, 'sun'] + ], + trail: { + length: undefined, + color: [0.48, 0.69, 1.00, 0.7] + }, + spheroid: { + equatorialRadius: 24764, + polarRadius: 24341, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'neptune/color_$SIZE_$FACE.png', + sizes: [4, 256] + } + }, + shadowEntities: ['triton', 'proteus', 'despina', 'galatea', 'larissa'] + }, + controllers: [{ + type: 'dynamo', + url: 'neptune/sun/orb' + }, { + type: 'dynamo', + url: 'neptune/ori' + }], + postCreateFunction: (entity) => { + const ringsComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RingsComponent); + ringsComponent.setInnerRadius(40900); + ringsComponent.setOuterRadius(62964); + ringsComponent.setTopTextureUrl('$STATIC_ASSETS_URL/sprites/neptune_rings.png'); + ringsComponent.setBottomTextureUrl('$STATIC_ASSETS_URL/sprites/neptune_rings.png'); + ringsComponent.setFadeDistance(250); + + const atmosphereComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent); + atmosphereComponent.setScaleHeight(200.0); + atmosphereComponent.setDensity(5.0e-5); + atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(138.0 / 255.0, 160.0 / 255.0, 255.0 / 255.0)); + } + } +}); + +const jupiterRotationData = { + hintIndex: 0, // A special variable to keep track of the current index in the rotations array below. + textureAngleOffset: -60.38, // Get the red spot at 0 degrees longitude in System III. + referenceTime: 617098056, // A known good photo from JunoCam planning on 2019-07-22T20:44 + referenceAngleInSystemII: 313.47, // The angle in System II for the photo. + referenceAngleInSystemIII: 305, // The angle in System III for that photo. + offsetFactor: -0.000003074, // The scaling factor that moves from System II to System III. + rotations: [ // Data in System II from charts at http://jupos.org. + [-1136116758, 15], // 1964-01-01 + [-1037534358, 28], // 1967-02-15 + [-938951958, 22], // 1970-04-01 + [-867931156, 0], // 1972-07-01 + [-812721554, 12], // 1974-04-01 + [-744292752, 47], // 1976-06-01 + [-639143949, 62], // 1979-10-01 + [-533822346, 48], // 1983-02-01 + [-483883145, 27], // 1984-09-01 + [-391953544, 15], // 1987-08-01 + [102427264, 85], // 2003-04-01 + [315576066, 138], // 2010-01-01 + [615211269, 312], // 2019-06-30 + [660052869, 347] // 2020-11-30 + ] +}; + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/saturn_major_moons.js": +/*!*************************************************************!*\ + !*** ../pioneer/scripts/src/entities/saturn_major_moons.js ***! + \*************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var _entity_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./entity_utils */ "../pioneer/scripts/src/entities/entity_utils.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + dione: { + groups: ['saturn', 'moons', 'inner', 'major'], + radius: 561.7, + label: 'Dione', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + spheroid: { + equatorialRadius: 561.7, + polarRadius: 561.7, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'dione/color_$SIZE_$FACE.png', + sizes: [4, 512, 2048] + } + }, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'dione/saturn/orb' + }, { + type: 'dynamo', + url: 'dione/ori' + }] + }, + enceladus: { + groups: ['saturn', 'moons', 'inner', 'major'], + radius: 252.1, + label: 'Enceladus', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + spheroid: { + equatorialRadius: 252.1, + polarRadius: 252.1, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'enceladus/color_$SIZE_$FACE.png', + sizes: [4, 512, 2048] + } + }, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'enceladus/saturn/orb' + }, { + type: 'dynamo', + url: 'enceladus/ori' + }], + postCreateFunction: (entity) => { + // A + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [-25.20 * 0.8, -69.23 * 0.8, -240.99 * 0.8], [-0.0999, -0.2747, -0.9563]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [-61.73 * 0.8, -24.61 * 0.8, -243.08 * 0.8], [-0.2449, -0.0976, -0.9646]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [-35.82 * 0.8, -46.87 * 0.8, -245.00 * 0.8], [-0.1421, -0.1859, -0.9722]); + + // B + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [30.37 * 0.7, -17.54 * 0.7, -249.55 * 0.7], [0.1205, -0.0696, -0.9902]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [0.00 * 0.7, 2.20 * 0.7, -251.99 * 0.7], [0, 0.0087, -0.9999]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [-30.94 * 0.7, 30.94 * 0.7, -248.17 * 0.7], [-0.1227, 0.1227, -0.9848]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [45.99 * 0.7, -34.55 * 0.7, -245.35 * 0.7], [0.1824, -0.1371, -0.9736]); + + // C + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [-51.91 * 0.9, 0.68 * 0.9, -246.59 * 0.9], [-0.2059, 0.0026, -0.9785]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [-31.81 * 0.9, -13.36 * 0.9, -249.63 * 0.9], [-0.1262, -0.0530, -0.9905]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [-5.49 * 0.9, -29.77 * 0.9, -250.18 * 0.9], [-0.0217, -0.1181, -0.9927]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [16.54 * 0.9, -47.1 * 0.9, -247.01 * 0.9], [0.0656, -0.1869, -0.9801]); + + // D + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [-16.47 * 0.8, 60.14 * 0.8, -244.16 * 0.8], [-0.0653, 0.2386, -0.9689]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [51.52 * 0.8, 23.97 * 0.8, -245.51 * 0.8], [0.2044, 0.0951, -0.9742]); + _entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity, 100, 0.1, 20, 0.002, 4, [28.13 * 0.8, 33.52 * 0.8, -248.17 * 0.8], [0.1116, 0.1330, -0.9848]); + } + }, + hyperion: { + groups: ['saturn', 'moons', 'outer', 'major'], + radius: 135.0, + label: 'Hyperion', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/hyperion/hyperion.gltf', + scale: [1, 1, 1] + }, + controllers: [{ + type: 'dynamo', + url: 'hyperion/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }] + }, + iapetus: { + groups: ['saturn', 'moons', 'outer', 'major'], + radius: 735.6, + label: 'Iapetus', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + spheroid: { + equatorialRadius: 735.6, + polarRadius: 735.6, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'iapetus/color_$SIZE_$FACE.png', + sizes: [4, 512, 2048] + } + }, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'iapetus/saturn/orb' + }, { + type: 'dynamo', + url: 'iapetus/ori' + }] + }, + mimas: { + groups: ['saturn', 'moons', 'inner', 'major'], + radius: 198.3, + label: 'Mimas', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/mimas/mimas.gltf', + scale: [1, 1, 1] + }, + controllers: [{ + type: 'dynamo', + url: 'mimas/saturn/orb' + }, { + type: 'dynamo', + url: 'mimas/ori' + }] + }, + rhea: { + groups: ['saturn', 'moons', 'outer', 'major'], + radius: 764.3, + label: 'Rhea', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + spheroid: { + equatorialRadius: 764.3, + polarRadius: 764.3, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'rhea/color_$SIZE_$FACE.png', + sizes: [4, 512, 2048] + } + }, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'rhea/saturn/orb' + }, { + type: 'dynamo', + url: 'rhea/ori' + }] + }, + tethys: { + groups: ['saturn', 'moons', 'inner', 'major'], + radius: 538.4, + label: 'Tethys', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + spheroid: { + equatorialRadius: 538.4, + polarRadius: 527.5, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'tethys/color_$SIZE_$FACE.png', + sizes: [4, 512, 2048] + } + }, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'tethys/saturn/orb' + }, { + type: 'dynamo', + url: 'tethys/ori' + }] + }, + titan: { + groups: ['saturn', 'moons', 'outer', 'major'], + radius: 2575.0, + label: 'Titan', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + spheroid: { + equatorialRadius: 2575.0, + polarRadius: 2575.0, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'titan/color_$SIZE_$FACE.png', + sizes: [4, 512, 1024] + } + }, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'titan/saturn/orb' + }, { + type: 'dynamo', + url: 'titan/ori' + }], + postCreateFunction: (entity) => { + const atmosphereComponent = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent); + atmosphereComponent.setScaleHeight(75.0); + atmosphereComponent.setDensity(0.0005); + atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(179.0 / 255.0, 145.0 / 255.0, 53.0 / 255.0)); + atmosphereComponent.setSunsetColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(0.0 / 255.0, 71.0 / 255.0, 204.0 / 255.0)); + atmosphereComponent.setSunsetIntensity(0.5); + } + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/saturn_minor_moons.js": +/*!*************************************************************!*\ + !*** ../pioneer/scripts/src/entities/saturn_minor_moons.js ***! + \*************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + aegaeon: { + groups: ['saturn', 'moons', 'minor', 'ring moonlet'], + radius: 0.12, + label: 'Aegaeon', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.12, 0.12, 0.12], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'aegaeon/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + aegir: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Aegir', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'aegir/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + albiorix: { + groups: ['saturn', 'moons', 'minor', 'gallic'], + radius: 16.0, + label: 'Albiorix', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [16, 16, 16], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'albiorix/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + alvaldi: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3, + label: 'Alvaldi', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 3, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'alvaldi/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + angrboda: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'Angrboda', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1.5, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'angrboda/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + anthe: { + groups: ['saturn', 'moons', 'minor', 'alkyonides'], + radius: 0.9, + label: 'Anthe', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [0.9, 0.9, 0.9], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'anthe/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + atlas: { + groups: ['saturn', 'moons', 'minor', 'ring shepherd'], + radius: 15.1, + label: 'Atlas', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [15.1, 15.1, 15.1], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'atlas/saturn/orb' + }, { + type: 'dynamo', + url: 'atlas/ori' + }] + }, + bebhionn: { + groups: ['saturn', 'moons', 'minor', 'gallic'], + radius: 3.0, + label: 'Bebhionn', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'bebhionn/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + beli: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'Beli', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1.5, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'beli/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + bergelmir: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Bergelmir', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'bergelmir/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + bestla: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.5, + label: 'Bestla', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [3.5, 3.5, 3.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'bestla/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + calypso: { + groups: ['saturn', 'moons', 'minor', 'trojan'], + radius: 10.7, + label: 'Calypso', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [10.7, 10.7, 10.7], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'calypso/saturn/orb' + }, { + type: 'dynamo', + url: 'calypso/ori' + }] + }, + daphnis: { + groups: ['saturn', 'moons', 'minor', 'ring shepherd'], + radius: 3.8, + label: 'Daphnis', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [3.8, 3.8, 3.8], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'daphnis/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + eggther: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3, + label: 'Eggther', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 3, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'eggther/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + epimetheus: { + groups: ['saturn', 'moons', 'minor', 'co-orbital'], + radius: 58.1, + label: 'Epimetheus', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [58.1, 58.1, 58.1], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'epimetheus/saturn/orb' + }, { + type: 'dynamo', + url: 'epimetheus/ori' + }] + }, + erriapus: { + groups: ['saturn', 'moons', 'minor', 'gallic'], + radius: 5.0, + label: 'Erriapus', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [5, 5, 5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'erriapus/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + farbauti: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.5, + label: 'Farbauti', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.5, 2.5, 2.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'farbauti/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + fenrir: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'Fenrir', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2, 2, 2], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'fenrir/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + fornjot: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Fornjot', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'fornjot/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + geirrod: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2, + label: 'Geirrod', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'geirrod/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + gerd: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2, + label: 'Gerd', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'gerd/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + greip: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Greip', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'greip/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + gridr: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2, + label: 'Gridr', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'gridr/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + gunnlod: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2, + label: 'Gunnlod', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'gunnlod/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + hati: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Hati', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'hati/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + helene: { + groups: ['saturn', 'moons', 'minor', 'trojan'], + radius: 17.6, + label: 'Helene', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [17.6, 17.6, 17.6], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'helene/saturn/orb' + }, { + type: 'dynamo', + url: 'helene/ori' + }] + }, + hyrrokkin: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Hyrrokkin', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'hyrrokkin/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + ijiraq: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 6.0, + label: 'Ijiraq', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [6, 6, 6], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'ijiraq/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + janus: { + groups: ['saturn', 'moons', 'minor', 'co-orbital'], + radius: 89.5, + label: 'Janus', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [89.5, 89.5, 89.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'janus/saturn/orb' + }, { + type: 'dynamo', + url: 'janus/ori' + }] + }, + jarnsaxa: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Jarnsaxa', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'jarnsaxa/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + kari: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Kari', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'kari/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + kiviuq: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 8.0, + label: 'Kiviuq', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [8, 8, 8], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'kiviuq/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + loge: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Loge', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'loge/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + methone: { + groups: ['saturn', 'moons', 'minor', 'alkyonides'], + radius: 1.6, + label: 'Methone', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.6, 1.6, 1.6], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'methone/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + mundilfari: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.5, + label: 'Mundilfari', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [3.5, 3.5, 3.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'mundilfari/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + narvi: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.5, + label: 'Narvi', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [3.5, 3.5, 3.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'narvi/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + paaliaq: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 11.0, + label: 'Paaliaq', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [11, 11, 11], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'paaliaq/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + pallene: { + groups: ['saturn', 'moons', 'minor', 'alkyonides'], + radius: 2.5, + label: 'Pallene', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.5, 2.5, 2.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'pallene/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + pan: { + groups: ['saturn', 'moons', 'minor', 'ring shepherd'], + radius: 14.1, + label: 'Pan', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [14.1, 14.1, 14.1], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'pan/saturn/orb' + }, { + type: 'dynamo', + url: 'pan/ori' + }] + }, + pandora: { + groups: ['saturn', 'moons', 'minor', 'ring shepherd'], + radius: 40.7, + label: 'Pandora', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [40.7, 40.7, 40.7], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'pandora/saturn/orb' + }, { + type: 'dynamo', + url: 'pandora/ori' + }] + }, + phoebe: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 106.5, + label: 'Phoebe', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/phoebe/phoebe.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'phoebe/saturn/orb' + }, { + type: 'dynamo', + url: 'phoebe/ori' + }] + }, + polydeuces: { + groups: ['saturn', 'moons', 'minor', 'trojan'], + radius: 1.3, + label: 'Polydeuces', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.3, 1.3, 1.3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'polydeuces/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + prometheus: { + groups: ['saturn', 'moons', 'minor', 'ring shepherd'], + radius: 43.1, + label: 'Prometheus', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [43.1, 43.1, 43.1], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'prometheus/saturn/orb' + }, { + type: 'dynamo', + url: 'prometheus/ori' + }] + }, + s_2004_s_7: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3, + label: 'S/2004 S 7', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 3, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_7/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_12: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.5, + label: 'S/2004 S 12', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2.5, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_12/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_13: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3, + label: 'S/2004 S 13', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 3, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_13/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_17: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2, + label: 'S/2004 S 17', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_17/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_21: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2004 S 21', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1.5, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_21/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_24: { + groups: ['saturn', 'moons', 'minor', 'gallic'], + radius: 1.5, + label: 'S/2004 S 24', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1.5, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_24/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_28: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2, + label: 'S/2004 S 28', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_28/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_31: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 2, + label: 'S/2004 S 31', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_31/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_36: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2004 S 36', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1.5, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_36/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_37: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2, + label: 'S/2004 S 37', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_37/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_39: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2004 S 39', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1.5, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_39/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_1: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.5, + label: 'S/2006 S 1', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2.5, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_1/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_3: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3, + label: 'S/2006 S 3', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 3, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_3/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2007_s_2: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3, + label: 'S/2007 S 2', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 3, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2007_s_2/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2007_s_3: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.5, + label: 'S/2007 S 3', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2.5, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2007_s_3/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2009_s_1: { + groups: ['saturn', 'moons', 'propeller moonlet'], + radius: 0.150, + label: 'S/2009 S 1', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 0.150, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }], + postCreateFunction: (entity) => { + // Add the controller for going around sun from earth to venus. + const oeController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController, undefined, entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.FixedController)); + const oe = new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements(); + oe.epoch = 0; + oe.eccentricity = 0; + oe.semiMajorAxis = 1.17e5; + oe.meanAngularMotion = 1.5472777e-4; + oe.meanAnomalyAtEpoch = -1.5; + oe.orbitOrientation.set(-0.9397445462795919, 0.02005900203250964, -0.052689008288728606, -0.33719681579275607); + oeController.addOrbitalElements(-1e100, oe); + oeController.addOrbitalElements(+1e100, oe); + } + }, + s_2019_s_1: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 3, + label: 'S/2019 S 1', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 3, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_1/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + saturn_lviii: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2, + label: 'Saturn LVIII', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'saturn_lviii/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + saturn_lx: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 2, + label: 'Saturn LX', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'saturn_lx/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + saturn_lxiv: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'Saturn LXIV', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 1.5, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'saturn_lxiv/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + siarnaq: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 20.0, + label: 'Siarnaq', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [20, 20, 20], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'siarnaq/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + skathi: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 4.0, + label: 'Skathi', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [4, 4, 4], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'skathi/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + skoll: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Skoll', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'skoll/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + skrymir: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2, + label: 'Skrymir', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'skrymir/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + surtur: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.0, + label: 'Surtur', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'surtur/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + suttungr: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.5, + label: 'Suttungr', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [3.5, 3.5, 3.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'suttungr/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + tarqeq: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 3.0, + label: 'Tarqeq', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [3, 3, 3], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'tarqeq/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + tarvos: { + groups: ['saturn', 'moons', 'minor', 'gallic'], + radius: 7.5, + label: 'Tarvos', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [7.5, 7.5, 7.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'tarvos/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + telesto: { + groups: ['saturn', 'moons', 'minor', 'trojan'], + radius: 12.4, + label: 'Telesto', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [12.4, 12.4, 12.4], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'telesto/saturn/orb' + }, { + type: 'dynamo', + url: 'telesto/ori' + }] + }, + thiazzi: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2, + label: 'Thiazzi', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: 2, + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'thiazzi/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + thrymr: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 3.5, + label: 'Thrymr', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [3.5, 3.5, 3.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'thrymr/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + ymir: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 9.0, + label: 'Ymir', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: undefined, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [9, 9, 9], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 'ymir/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_40: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2004 S 40', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 66061440, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_40/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_41: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2004 S 41', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 79022304, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_41/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_42: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2004 S 42', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 79998624, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_42/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_43: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2004 S 43', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 84678912, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_43/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_44: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.5, + label: 'S/2004 S 44', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 88660224, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.5, 2.5, 2.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_44/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_45: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2004 S 45', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 89743680, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_45/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_46: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2004 S 46', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 95694912, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_46/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_47: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2004 S 47', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 65879136, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_47/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_48: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2004 S 48', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 107343360, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_48/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_49: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2004 S 49', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 109231200, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_49/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_50: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2004 S 50', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 108902016, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_50/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_51: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2004 S 51', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 131278752, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_51/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_52: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2004 S 52', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 141175872, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_52/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2004_s_53: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2004 S 53', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 115986816, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2004_s_53/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2005_s_4: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 2.5, + label: 'S/2005 S 4', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 38899008, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.5, 2.5, 2.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2005_s_4/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2005_s_5: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2005 S 5', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 101763648, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2005_s_5/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_10: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2006 S 10', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 84943296, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_10/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_11: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2006 S 11', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 90052992, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_11/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_12: { + groups: ['saturn', 'moons', 'minor', 'gallic'], + radius: 2.0, + label: 'S/2006 S 12', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 89428320, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_12/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_13: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2006 S 13', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 91638432, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_13/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_14: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2006 S 14', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 99591552, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_14/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_15: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2006 S 15', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 104886144, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_15/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_16: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2006 S 16', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 104329728, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_16/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_17: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2006 S 17', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 109259712, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_17/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_18: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2006 S 18', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 112181760, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_18/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_19: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2006 S 19', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 120038112, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_19/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_20: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.5, + label: 'S/2006 S 20', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 49012128, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.5, 2.5, 2.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_20/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2006_s_9: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2006 S 9', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 55977696, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2006_s_9/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2007_s_5: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2007 S 5', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 64530432, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2007_s_5/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2007_s_6: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2007 S 6', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 82036800, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2007_s_6/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2007_s_7: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2007 S 7', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 65170656, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2007_s_7/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2007_s_8: { + groups: ['saturn', 'moons', 'minor', 'gallic'], + radius: 2.0, + label: 'S/2007 S 8', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 72308160, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2007_s_8/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2007_s_9: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2007 S 9', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 93145248, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2007_s_9/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_10: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2019 S 10', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 97030656, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_10/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_11: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2019 S 11', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 96336000, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_11/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_12: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2019 S 12', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 98396640, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_12/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_13: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2019 S 13', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 98921088, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_13/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_14: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 2.0, + label: 'S/2019 S 14', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 77167296, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_14/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_15: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2019 S 15', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 100357056, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_15/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_16: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2019 S 16', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 115877088, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_16/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_17: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2019 S 17', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 111576096, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_17/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_18: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2019 S 18', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 114657984, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_18/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_19: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2019 S 19', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 113879520, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_19/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_2: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2019 S 2', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 69104448, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_2/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_20: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2019 S 20', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 118838880, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_20/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_21: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2019 S 21', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 141378048, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_21/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_3: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2019 S 3', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 72380736, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_3/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_4: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2019 S 4', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 78128064, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_4/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_5: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2019 S 5', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 85568832, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_5/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_6: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 2.0, + label: 'S/2019 S 6', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 79202880, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_6/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_7: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2019 S 7', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 93337056, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_7/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_8: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2019 S 8', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 94061952, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_8/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2019_s_9: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2019 S 9', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 94444704, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2019_s_9/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2020_s_1: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 2.0, + label: 'S/2020 S 1', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 38975040, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2020_s_1/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2020_s_10: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2020 S 10', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 131951808, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2020_s_10/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2020_s_2: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2020 S 2', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 77552640, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2020_s_2/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2020_s_3: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 1.5, + label: 'S/2020 S 3', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 78450336, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2020_s_3/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2020_s_4: { + groups: ['saturn', 'moons', 'minor', 'gallic'], + radius: 1.5, + label: 'S/2020 S 4', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 80085888, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2020_s_4/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2020_s_5: { + groups: ['saturn', 'moons', 'minor', 'inuit'], + radius: 1.5, + label: 'S/2020 S 5', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 80687232, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2020_s_5/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2020_s_6: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2020 S 6', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 100989504, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2020_s_6/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2020_s_7: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2020 S 7', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 74450880, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2020_s_7/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2020_s_8: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 1.5, + label: 'S/2020 S 8', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 106109568, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [1.5, 1.5, 1.5], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2020_s_8/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + s_2020_s_9: { + groups: ['saturn', 'moons', 'minor', 'norse'], + radius: 2.0, + label: 'S/2020 S 9', + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + trail: { + length: 132621408, + color: [0.72, 0.65, 0.52, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [2.0, 2.0, 2.0], + shadowEntities: ['saturn'] + }, + controllers: [{ + type: 'dynamo', + url: 's_2020_s_9/saturn/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/small_body_spacecraft.js": +/*!****************************************************************!*\ + !*** ../pioneer/scripts/src/entities/small_body_spacecraft.js ***! + \****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var _animation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../animation */ "../pioneer/scripts/src/animation.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + sc_dart: { + groups: ['small body spacecraft', 'asteroid spacecraft', '65803_didymos', 'dimorphos', 'spacecraft'], + occlusionRadius: 0.0012, + extentsRadius: 0.00625, + label: 'DART', + parents: [ + [691007069, 'earth'], + [691418893, 'sun'], + [717454117, '65803_didymos'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_dart/dart.gltf', + shadowEntities: ['earth'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_dart/earth/orb' + }, { + type: 'dynamo', + url: 'sc_dart/sun/orb' + }, { + type: 'dynamo', + url: 'sc_dart/65803_didymos/pos' + }, { + type: 'custom', + func: (entity) => { + // The current spice misses Dimorphos, so we cut the spice short and keyframe the rest to make it hit. + const keyframeController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.KeyframeController); + keyframeController.addPositionKeyframe(717503237, // Forced end of spice. + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-10320.163052194115, 13421.106828492655, 5349.381737812169)); + keyframeController.addPositionKeyframe(717503237 + 2890.2383179924736, // Dimorphos impact + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.9047084058613565, -0.7147384471771195, -0.30125475602973617)); + return keyframeController; + } + }, { + type: 'align', + primary: { + type: 'velocity', + target: 'sc_dart', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + }, + secondary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + coverage: [Number.NEGATIVE_INFINITY, 717454117] + }, { + type: 'align', + primary: { + type: 'point', + target: 'dimorphos', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg + }, + secondary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + }, + coverage: [717454117, Number.POSITIVE_INFINITY] + }] + }, + sc_dawn: { + groups: ['small body spacecraft', 'asteroid spacecraft', 'dwarf planet spacecraft', '4_vesta', '1_ceres', 'spacecraft'], + occlusionRadius: 0.000885, + extentsRadius: 0.00985, + label: 'Dawn', + parents: [ + [244168849.8323595, 'earth'], + [244461608, 'sun'], + [288169447, 'mars'], + [288210177, 'sun'], + [363182466, '4_vesta'], + [400075267, 'sun'], + [476712067, '1_ceres'], + [594302469.184, ''] + ], + trail: { + length: 659889.75 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_dawn/model.gltf', + rotate: [ + { z: -90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_dawn/earth/orb' + }, { + type: 'dynamo', + url: 'sc_dawn/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_dawn/mars/orb' + }, { + type: 'dynamo', + url: 'sc_dawn/sun/2/orb' + }, { + type: 'dynamo', + url: 'sc_dawn/vesta/orb' + }, { + type: 'dynamo', + url: 'sc_dawn/sun/3/orb' + }, { + type: 'dynamo', + url: 'sc_dawn/ceres/orb' + }, { + // Beginning of launch has bad spice, so we supplement with fixed. + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.9999478154504517, 0.008904517167862874, 0.004868284692665544, -0.0011729254143642916), + coverage: [244168849.8323595, 244171353.18400002] + }, { + type: 'dynamo', + url: 'sc_dawn/ori' + }] + }, + sc_deep_impact: { + groups: ['small body spacecraft', 'comet spacecraft', '9p_tempel_1', '103p_hartley_2', 'spacecraft'], + occlusionRadius: 0.001650, + extentsRadius: 0.00300, + label: 'Deep Impact', + parents: [ + [158829812.068274, 'earth'], + [159287744, 'sun'], + [173560752, '9p_tempel_1'], + [173923158, 'sun'], + [251798121, 'earth'], + [253531474, 'sun'], + [282984399, 'earth'], + [285405903, 'sun'], + [330384030, 'earth'], + [331534813, 'sun'], + [342017751, '103p_hartley_2'], + [342368983, 'sun'], + [429192067, ''] + ], + trail: { + length: 47421459.0, + lengthCoverages: [ + [362406, 173560752, 173923158], // 9/P Tempel flyby + [1733353, 251798121, 253531474], // Earth flyby 1 + [2421504, 282984399, 285405903], // Earth blyby 2 + [1150783, 330384030, 331534813], // Earth flyby 3 + [351232, 342017751, 342368983] // 103/P Hartley flyby + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_deep_impact/deep_impact_wo_impactor.gltf', + rotate: [ + { y: -90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_deep_impact/earth/launch/orb' + }, { + type: 'dynamo', + url: 'sc_deep_impact/sun/orb' + }, { + type: 'dynamo', + url: 'sc_deep_impact/9p_tempel_1/pos' + }, { + type: 'dynamo', + url: 'sc_deep_impact/earth/flyby1/orb' + }, { + type: 'dynamo', + url: 'sc_deep_impact/earth/flyby2/orb' + }, { + type: 'dynamo', + url: 'sc_deep_impact/earth/flyby3/orb' + }, { + type: 'dynamo', + url: 'sc_deep_impact/103p_hartley_2/pos' + }, { + // Backup for when quat dynamo doesn't cover. + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }, { + type: 'dynamo', + url: 'sc_deep_impact/quat' + }] + }, + sc_deep_impact_impactor: { + groups: ['small body spacecraft', 'comet spacecraft', '9p_tempel_1', 'sc_deep_impact', 'spacecraft'], + occlusionRadius: 0.001, + extentsRadius: 0.00100, + label: 'Deep Impact Impactor', + parents: [ + [158829812.068274, 'sc_deep_impact'], + [173642464.18400002, '9p_tempel_1'], + [173727938.18158135, ''] + ], + trail: { + length: 27830.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_deep_impact_impactor/deep_impact_impactor.gltf', + rotate: [ + { y: -90 } + ] + }, + controllers: [{ + type: 'custom', + func: (entity) => { + // There are spice kernels for the impactor, but they don't release or impact at the right locations. + // So we use a keyframe controller here. + const keyframeController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.KeyframeController); + keyframeController.addPositionKeyframe(173642464.18400002, // Release from Deep Impact + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.000713, -0.000055, 0), + 'sc_deep_impact', undefined, + 'sc_deep_impact'); + keyframeController.addPositionKeyframe(173656621.40411958, // Push away from Deep Impact + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-123095.24746842826, -48294.70341251187, 61743.99881253781), + 'sc_deep_impact', 173642464.18400002); + keyframeController.addPositionKeyframe(173727938.18158135, // Impact + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(1.580046751199936, 3.178179950746365, -0.628457454223176)); + return keyframeController; + } + }, { + // Start it off with the right direction. + type: 'fixed', + position: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.000713, -0.000055, 0), + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity, + relativeToEntity: 'sc_deep_impact', + coverage: [158829812.068274, 173642464.18400002] + }, { + // The quat dynamo doesn't quite reach the impact (short 10 seconds) so fix the orientation as a backup. + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.9060465048532422, 0.3173702681972099, 0.2649483984949708, 0.09032269948692226), + coverage: [173642464.18400002, Number.POSITIVE_INFINITY] + }, { + type: 'dynamo', + url: 'sc_deep_impact_impactor/quat', + coverage: [173642464.18400002, Number.POSITIVE_INFINITY] + }] + }, + sc_deep_impact_impactor_impact_site: { + groups: ['small body sites', 'comet sites', '9p_tempel_1', 'sc_deep_impact', 'sc_deep_impact_impactor', 'sites'], + radius: 0.001, + label: 'Deep Impact Impactor Impact Site', + parents: [ + [173727938.18158135, '9p_tempel_1'] + ], + controllers: [{ + type: 'fixed', + position: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(3.1153282512332603, -1.2860729555237982, -1.277920399403075), + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity, + relativeToEntity: '9p_tempel_1', + coverage: [173727938.18158135, Number.POSITIVE_INFINITY] + }] + }, + sc_deep_space_1: { + groups: ['small body spacecraft', 'asteroid spacecraft', '9969_braille', 'spacecraft'], + occlusionRadius: 0.00125, + extentsRadius: 0.005000, + label: 'Deep Space 1', + parents: [ + [-37470248, 'earth'], + [-36628312, 'sun'], + [-13523799, '9969_braille'], + [-13496699, 'sun'], + [54458637, '19p_borrelly'], + [54476825, 'sun'], + [61977664.184, ''] + ], + trail: { + length: 40845609.0, + lengthCoverages: [ + [27100, -13523799, -13496699], + [18188, 54458637, 54476825] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_deep_space_1/deep_space_1.gltf', + rotate: [ + { x: 90 }, + { z: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_deep_space_1/earth/orb' + }, { + type: 'dynamo', + url: 'sc_deep_space_1/sun/orb' + }, { + type: 'dynamo', + url: 'sc_deep_space_1/9969_braille/pos' + }, { + type: 'dynamo', + url: 'sc_deep_space_1/19p_borrelly/pos' + }, { + type: 'align', + primary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis, + target: 'earth' + }, + secondary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg, + target: 'sun' + } + }, { + type: 'dynamo', + url: 'sc_deep_space_1/quat' + }] + }, + sc_near_shoemaker: { + groups: ['small body spacecraft', 'asteroid spacecraft', '253_mathilde', '433_eros', 'spacecraft'], + occlusionRadius: 0.002, + extentsRadius: 0.0034000, + label: 'NEAR', + parents: [ + [-122129937, 'sun'], + [-61397606, 'earth'], + [-60793811, 'sun'], + [-79403925, '253_mathilde'], + [-79210250, 'sun'], + [-8425610, '433_eros'], + [36675809.3654, ''] + ], + trail: { + length: 63919069.0, + lengthCoverages: [ + [400000, -8425610, 35279032.137], + [0, 35279032.137, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_near_shoemaker/near.gltf', + rotate: [ + { x: 90 }, + { z: 135 } + ] + }, + controllers: [{ + type: 'custom', + func: (entity) => { + // Add an OE controller because the dynamo doesn't go back to launch. + // This data was calculated by the computeOrbit function in Pioneer Play. + const oeController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.OrbitalElementsController); + const oe = new pioneer__WEBPACK_IMPORTED_MODULE_2__.OrbitalElements(); + oe.eccentricity = 0.3722732412046076; + oe.epoch = -122129937; + oe.semiMajorAxis = 235420679.8644008; + oe.orbitOrientation.set(0.25408339907533106, 0.05463135384055627, -0.18986948069810847, 0.9467875272685549); + oe.meanAngularMotion = 1.0085301888805118e-7; + oe.meanAnomalyAtEpoch = -0.005941352116228519; + oeController.addOrbitalElements(-122129937, oe); + oeController.addOrbitalElements(-113227200, oe); + oeController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(-122129937, -113227200)); + return oeController; + } + }, { + type: 'dynamo', + url: 'sc_near_shoemaker/sun/orb' + }, { + type: 'dynamo', + url: 'sc_near_shoemaker/earth/flyby/orb' + }, { + type: 'dynamo', + url: 'sc_near_shoemaker/253_mathilde/pos' + }, { + type: 'dynamo', + url: 'sc_near_shoemaker/433_eros/orb' + }, { + // Cover the launch period. + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.5052018803124495, -0.11842169431143575, 0.7652511949887616, -0.3809697770341459), + coverage: [-122129937, -121953528.049046] + }, { + type: 'dynamo', + url: 'sc_near_shoemaker/quat' + }, { + // Add a fixed controller for after it lands. + type: 'fixed', + position: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.930389249841349, 4.935129554115763, -4.002004469114965), + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.11222410400554989, 0.7066112547219852, -0.6897721372150081, 0.11099857612696495), + coverage: [35279032.137, 36675809.3654] + }, { + // Get the landing fixed coverage coords in the J2000 frame. + type: 'rotateByEntityOrientation', + coverage: [35279032.137, 36675809.3654] + }] + }, + sc_near_shoemaker_landing_site: { + groups: ['433_eros', 'sc_near_shoemaker', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'NEAR Shoemaker Landing Site', + parents: [ + [36675809.3654, '433_eros'] + ], + controllers: [{ + type: 'fixed', + position: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.930389249841349, 4.935129554115763, -4.002004469114965), + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.11222410400554989, 0.7066112547219852, -0.6897721372150081, 0.11099857612696495), + relativeToEntity: '433_eros', + coverage: [36675809.3654, Number.POSITIVE_INFINITY] + }] + }, + sc_lucy: { + groups: ['small body spacecraft', 'asteroid spacecraft', '52246_donaldjohanson', '3548_eurybates', '15094_polymele', '11351_leucus', '21900_orus', '617_patroclus', 'menoetius', 'spacecraft'], + occlusionRadius: 0.002, + extentsRadius: 0.007125, + label: 'Lucy', + parents: [ + [687656642.763, 'earth'], + [687915086, 'sun'], + [718960993, 'earth'], + [719531941, 'sun'], + [787134972, 'earth'], + [787532222, 'sun'], + [798252820, '52246_donaldjohanson'], + [798584539, 'sun'], + [870652086, '3548_eurybates'], + [872642047, 'sun'], + [872642047, '15094_polymele'], + [875308504, 'sun'], + [891166024, '11351_leucus'], + [894761809, 'sun'], + [909384911, '21900_orus'], + [912190135, 'sun'], + [977590306, 'earth'], + [978108682, 'sun'], + [1046169596, '617_patroclus_barycenter'], + [1047892376, 'sun'] + ], + dependents: [ + '152830_dinkinesh' + ], + trail: { + length: 63919069.0, + lengthCoverages: [ + [719531941 - 718960993, 718960993, 719531941], + [787532222 - 787134972, 787134972, 787532222], + [798584539 - 798252820, 798252820, 798584539], + [872642047 - 870652086, 870652086, 872642047], + [875308504 - 872642047, 872642047, 875308504], + [894761809 - 891166024, 891166024, 894761809], + [912190135 - 909384911, 909384911, 912190135], + [978108682 - 977590306, 977590306, 978108682], + [1047892376 - 1046169596, 1046169596, 1047892376] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_lucy/lucy.gltf', + rotate: [ + { x: 90 }, + { z: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_lucy/earth/launch/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }, { + type: 'dynamo', + url: 'sc_lucy/sun/orb' + }, { + type: 'dynamo', + url: 'sc_lucy/earth/flyby1/orb' + }, { + type: 'dynamo', + url: 'sc_lucy/earth/flyby2/orb' + }, { + type: 'dynamo', + url: 'sc_lucy/52246_donaldjohanson/pos' + }, { + type: 'dynamo', + url: 'sc_lucy/3548_eurybates/pos' + }, { + type: 'dynamo', + url: 'sc_lucy/15094_polymele/pos' + }, { + type: 'dynamo', + url: 'sc_lucy/11351_leucus/pos' + }, { + type: 'dynamo', + url: 'sc_lucy/21900_orus/pos' + }, { + type: 'dynamo', + url: 'sc_lucy/earth/flyby3/orb' + }, { + type: 'dynamo', + url: 'sc_lucy/617_patroclus/pos' + }, { + type: 'align', + primary: { + type: 'point', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis, + target: 'earth' + }, + secondary: { + type: 'align', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis, + target: 'sun', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + } + }, { + type: 'dynamo', + url: 'sc_lucy/quat' + }] + }, + sc_new_horizons: { + groups: ['small body spacecraft', 'dwarf planet spacecraft', 'TNO spacecraft', '134340_pluto', '486958_arrokoth', 'spacecraft'], + occlusionRadius: 0.00135, + extentsRadius: 0.0026, + label: 'New Horizons', + parents: [ + [190972278.33046317, 'earth'], + [191055829, 'sun'], + [225619606, 'jupiter'], + [226100665, 'sun'], + [490130161, '134340_pluto'], + [490167848, 'sun'], + [598753684, '486958_arrokoth'], + [600203601, 'sun'] + ], + trail: { + length: 60 * 60 * 24 * 365 * 3 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_new_horizons/new_horizons.gltf', + rotate: [ + { y: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_new_horizons/earth/orb' + }, { + type: 'dynamo', + url: 'sc_new_horizons/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_new_horizons/jupiter/orb' + }, { + type: 'dynamo', + url: 'sc_new_horizons/sun/2/orb' + }, { + type: 'dynamo', + url: 'sc_new_horizons/pluto/orb' + }, { + type: 'dynamo', + url: 'sc_new_horizons/sun/3/pos' + }, { + type: 'dynamo', + url: 'sc_new_horizons/mu69/pos' + }, { + type: 'dynamo', + url: 'sc_new_horizons/sun/4/pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis + } + }, { + type: 'dynamo', + url: 'sc_new_horizons/ori/1' + }, { + type: 'dynamo', + url: 'sc_new_horizons/ori/2' + }] + }, + sc_rosetta: { + groups: ['small body spacecraft', 'comet spacecraft', '67p_churyumov_gerasimenko', 'spacecraft'], + occlusionRadius: 0.001400, + extentsRadius: 0.016000, + label: 'Rosetta', + parents: [ + [131491581.583, 'earth'], + [131901500, 'sun'], + [162704887, 'earth'], + [163831232, 'sun'], + [225623375, 'mars'], + [225657862, 'sun'], + [248111015, 'earth'], + [248475560, 'sun'], + [311055929, 'earth'], + [311664877, 'sun'], + [452394238, '67p_churyumov_gerasimenko'], + [528503957.968, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_rosetta/rosettaPhilae.gltf', + rotate: [ + { x: 180 }, + { z: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_rosetta/earth/launch/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity + }, { + type: 'dynamo', + url: 'sc_rosetta/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_rosetta/earth/flyby1/orb' + }, { + type: 'dynamo', + url: 'sc_rosetta/sun/2/orb' + }, { + type: 'dynamo', + url: 'sc_rosetta/mars/flyby/orb' + }, { + type: 'dynamo', + url: 'sc_rosetta/sun/3/orb' + }, { + type: 'dynamo', + url: 'sc_rosetta/earth/flyby2/orb' + }, { + type: 'dynamo', + url: 'sc_rosetta/sun/4/orb' + }, { + type: 'dynamo', + url: 'sc_rosetta/earth/flyby3/orb' + }, { + type: 'dynamo', + url: 'sc_rosetta/sun/5/orb' + }, { + type: 'dynamo', + url: 'sc_rosetta/67p_churyumov_gerasimenko/pos' + }, { + type: 'dynamo', + url: 'sc_rosetta/ori' + }, { + type: 'coverage', + coverage: [469053367.183, Number.POSITIVE_INFINITY], + enter: (entity) => { + const modelComponent = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + if (modelComponent !== null) { + modelComponent.setHiddenObject('Philae', true); + // modelComponent.setHiddenObject('foil_gold_h', true); + } + }, + exit: (entity) => { + const modelComponent = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + if (modelComponent !== null) { + modelComponent.setHiddenObject('Philae', false); + // modelComponent.setHiddenObject('foil_gold_h', false); + } + } + }, { + type: 'custom', + func: (entity) => { + const solarPanelAlignLeft = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + solarPanelAlignLeft.setJoint('panels_01'); + solarPanelAlignLeft.setSecondaryAlignType('point'); + solarPanelAlignLeft.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis); + solarPanelAlignLeft.setSecondaryTargetEntity('sun'); + return solarPanelAlignLeft; + } + }, { + type: 'custom', + func: (entity) => { + const solarPanelAlignRight = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + solarPanelAlignRight.setJoint('panels_02'); + solarPanelAlignRight.setSecondaryAlignType('point'); + solarPanelAlignRight.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis); + solarPanelAlignRight.setSecondaryTargetEntity('sun'); + return solarPanelAlignRight; + } + }] + }, + sc_rosetta_impact_site: { + groups: ['small body sites', 'comet sites', '67p_churyumov_gerasimenko', 'sc_rosetta', 'sites'], + radius: 0.001, + label: 'Rosetta Impact Site', + parents: [ + [528503957.968, '67p_churyumov_gerasimenko'] + ], + controllers: [{ + type: 'fixed', + position: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(1.7309310500292525, 0.3509303067271947, 1.1641920075039298), + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity, + relativeToEntity: '67p_churyumov_gerasimenko', + coverage: [528503957.968, Number.POSITIVE_INFINITY] + }] + }, + sc_osiris_rex: { + groups: ['small body spacecraft', 'asteroid spacecraft', '101955_bennu', 'spacecraft'], + occlusionRadius: 0.001600, + extentsRadius: 0.005, + label: 'OSIRIS-REx', + parents: [ + [526676400, 'earth'], + [527025408, 'sun'], + [558938468, 'earth'], + [559919190, 'sun'], + [591770603, '101955_bennu'], + [674049669, 'sun'], + [748358886, 'earth'], + [749140122, 'sun'] + ], + dependents: ['sc_osiris_rex_src', '99942_apophis'], // These aren't parents and so they are named here. + trail: { + length: 102742.5, + lengthCoverages: [ + [10000000, Number.NEGATIVE_INFINITY, 599748661], + [672000.0, 599748661, 668095733], + [10000000, 668095733, Number.POSITIVE_INFINITY] + ] + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_osiris_rex_v2/osiris_rex_articulated_panels.gltf', + rotate: [ + { x: 90 } + ], + shadowEntities: ['bennu'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_osiris_rex/earth/launch/orb' + }, { + type: 'dynamo', + url: 'sc_osiris_rex/sun/1/orb' + }, { + type: 'dynamo', + url: 'sc_osiris_rex/earth/flyby/orb' + }, { + type: 'dynamo', + url: 'sc_osiris_rex/sun/2/orb' + }, { + type: 'dynamo', + url: 'sc_osiris_rex/bennu/pos' + }, { + type: 'dynamo', + url: 'sc_osiris_rex/sun/3/orb' + }, { + type: 'dynamo', + url: 'sc_osiris_rex/earth/sample_return/orb' + }, { + type: 'dynamo', + url: 'sc_osiris_rex/sun/4/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', // Orientated so that the SRC will come off at the right orientation. + axis: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.175109477645991, 0.45028151394683397, 0.8755473882299549) + }, + secondary: { + type: 'align', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis + }, + coverage: [658200668.0606446, Number.POSITIVE_INFINITY] + }, { + type: 'dynamo', + url: 'sc_osiris_rex/ori' + }, { + // For the animations, used "The OSIRIS-REx Spacecraft and the Touch and Go Sample Acquisition Mechanism", Kyle Brown 2020. + type: 'custom', + func: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeSubobjectVisibleAnimation(model, 'Tagsam_housing_cover', true, [ + [593036911, false] // Head cover jettisoned. + ]); + } + }, { + type: 'custom', + func: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model, 'Tagsam_rod_bottom', 'z', [ + [595442726, 0], // First extending. + [595442726 + 1 * 180, -2.51758508612], + [595442726 + 2 * 180, -2.51758508612], // Folds back after first extending. + [595442726 + 3 * 180, 0], + [656502686 - 220 * 60, 0], // At T-220m it unfurls. + [656502686 - 220 * 60 + 360, -3.71758508612], + [656502686 + 2 * 60 + 90, -3.71758508612], // At T+2m it parks. + [656502686 + 2 * 60 + 90 + 180, 0], + [656502686 + 10 * 24 * 3600 + 0 * 180, 0], // It stores the head in the SRC module. + [656502686 + 10 * 24 * 3600 + 2 * 180, -2.73771997401], + [656502686 + 10 * 24 * 3600 + 4 * 180, 0] + ]); + } + }, { + type: 'custom', + func: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model, 'Tagsam_rod_top', 'z', [ + [593728111, 0], // Frangibolts fired and TAGSAM is unlocked. + [593728111 + 2, 0.15], + [595442726, 0.15], // First extending. + [595442726 + 1 * 180, 2.73247002363], + [595442726 + 2 * 180, 2.73247002363], // Folds back after first extending. + [595442726 + 3 * 180, 0.15], + [656502686 - 220 * 60, 0.15], // At T-220m it unfurls. + [656502686 - 220 * 60 + 360, 3.73247002363], + [656502686 + 2 * 60 + 90, 3.73247002363], // At T+2m it parks. + [656502686 + 2 * 60 + 90 + 180, 0.15], + [656502686 + 10 * 24 * 3600 + 0 * 180, 0.15], // It stores the head in the SRC module. + [656502686 + 10 * 24 * 3600 + 1 * 180, 1.16136826422], + [656502686 + 10 * 24 * 3600 + 2 * 180, 0.509601235], + [656502686 + 10 * 24 * 3600 + 3 * 180, 1.16136826422], + [656502686 + 10 * 24 * 3600 + 4 * 180, 0.15] + ]); + } + }, { + type: 'custom', + func: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model, 'tagsam_head', 'z', [ + [595442726 + 1 * 180, 0], // First extending. + [595442726 + 1.5 * 180, 1.57079632679], // Folds back after first extending. + [595442726 + 2 * 180, 1.57079632679], + [656502686 - 220 * 60, 0], // At T-220m it unfurls. + [656502686 - 220 * 60 + 90, 1.57079632679], + [656502686 + 2 * 60, 1.57079632679], // At T+2m it parks. + [656502686 + 2 * 60 + 90, 0], + [656502686 + 10 * 24 * 3600, 0], // It stores the head in the SRC module. + [656502686 + 10 * 24 * 3600 + 360, 1.01463145268] + ]); + } + }, { + type: 'custom', + func: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeSubobjectVisibleAnimation(model, 'tagsam_head', true, [ + [656502686 + 10 * 24 * 3600 + 360, false] // At T+10d, the head is stowed. We don't have the SRC stowage piece, so the head will just disappear. + ]); + } + }, { + type: 'custom', + func: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model, 'Gimbal_Base_Right', 'z', [ + [656501483 + 0 * 60, -70 * Math.PI / 180], + [656501483 + 2 * 60, 0], + [656503242 + 0 * 60, 0], + [656503242 + 2 * 180, -70 * Math.PI / 180] + ]); + } + }, { + type: 'custom', + func: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model, 'Gimbal_Base_Left', 'z', [ + [656501483 + 0 * 60, -70 * Math.PI / 180], + [656501483 + 2 * 60, 0], + [656503242 + 0 * 60, 0], + [656503242 + 2 * 180, -70 * Math.PI / 180] + ]); + } + }, { + type: 'custom', + func: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model, 'Gimbal_Pivot_Right', 'x', [ + [656501483 + 2 * 60, 0], + [656501483 + 4 * 60, 38 * Math.PI / 180], + [656503242, 38 * Math.PI / 180], + [656503242 + 2 * 60, 0] + ]); + } + }, { + type: 'custom', + func: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model, 'Gimbal_Pivot_Left', 'x', [ + [656501483 + 2 * 60, 0], + [656501483 + 4 * 60, -38 * Math.PI / 180], + [656503242, -38 * Math.PI / 180], + [656503242 + 2 * 60, 0] + ]); + } + }, { + type: 'custom', + func: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeSubobjectVisibleAnimation(model, 'heatshield', true, [ + [748824183.985732, false] // At this time, the SRC is released. + ]); + } + }] + }, + sc_osiris_rex_src: { + groups: ['small body spacecraft', 'asteroid spacecraft', '101955_bennu', 'sample return capsule'], + occlusionRadius: 0.0008, + extentsRadius: 0.0005, + label: 'OSIRIS-REx SRC', + parents: [ + [748824183.985732, 'sc_osiris_rex'], + [748832190, 'earth'], + [748839215, ''] + ], + dependents: ['sc_osiris_rex'], + trail: { + length: 360 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_osiris_rex_v2/src/osiris_rex_heatshield.gltf', + rotate: [ + { x: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_osiris_rex_src/sc_osiris_rex' + }, { + type: 'dynamo', + url: 'sc_osiris_rex_src/earth' + }, { + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(-0.7795827954678449, -0.23701239922750972, 0.5441503490850964, -0.19994045416955505) + }, { + type: 'coverage', + coverage: [748838642, 748839373], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(true); + } + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(false); + } + } + }, { + type: 'custom', + func: (entity) => { + const translate = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TranslateController); + translate.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 0, 0.0012)); + translate.setRelativeToOrientation(true); + return translate; + }, + coverage: [748824183.985732, 748839215] + }], + postCreateFunction: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0, 0, -0.0012)); + } + }, + sc_philae: { + groups: ['small body spacecraft', 'comet spacecraft', '67p_churyumov_gerasimenko', 'spacecraft', 'landers'], + occlusionRadius: 0.0006, + extentsRadius: 0.001, + label: 'Philae', + parents: [ + [469053367.183, '67p_churyumov_gerasimenko'], + [469078512.324, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_philae/philae.gltf', + rotate: [ + { x: 180 }, + { z: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_philae/67p_churyumov_gerasimenko/pos' + }, { + // The orientation of Rosetta when it is detached. + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.05763938670269045, 0.04093459828351704, 0.6750586755218195, 0.7343690110337115) + }, { + type: 'custom', + func: (entity) => { + // Get the lander's origin and model aligned with the spacecraft when they separate. + const originOffset = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.0021658104318583687, 0.0011575046500869896, 0.00011875498849156656); + const modelOffset = new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.00147, 0, 0); + const translateController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TranslateController); + translateController.setTranslation(originOffset); + // Also set the model's translation, so everything aligns. + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + model.setTranslation(modelOffset); + return translateController; + }, + coverage: [469053367.183, 469078512.324] + }] + }, + sc_philae_landing_site: { + groups: ['small body sites', 'comet sites', '67p_churyumov_gerasimenko', 'sc_philae', 'sites'], + radius: 0.001, + systemRadius: 200, + label: 'Philae Landing Site', + parents: [ + [469078512.324, '67p_churyumov_gerasimenko'] + ], + controllers: [{ + type: 'fixed', + position: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(2.4452763955965984, -0.12110982508097201, -0.36032099522959377), + orientation: pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity, + relativeToEntity: '67p_churyumov_gerasimenko', + coverage: [469078512.324, Number.POSITIVE_INFINITY] + }] + }, + sc_psyche: { + groups: ['small body spacecraft', 'asteroid spacecraft', '16_psyche', 'spacecraft'], + occlusionRadius: 0.0031, + extentsRadius: 0.025, + label: 'Psyche', + parents: [ + [750482453, 'earth'], + [750686758, 'sun'], + [831828698, 'mars'], + [832302380, 'sun'], + [931665741, '16_psyche'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_psyche/psyche.gltf', + rotate: [ + { y: -90 }, + { x: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_psyche/earth/orb' + }, { + type: 'dynamo', + url: 'sc_psyche/sun/orb' + }, { + type: 'dynamo', + url: 'sc_psyche/mars/orb' + }, { + type: 'dynamo', + url: 'sc_psyche/16_psyche/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg + } + }, { + type: 'custom', + func: (entity) => { + const solarPanelAlignLeft = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + solarPanelAlignLeft.setJoint('ArrayGimbleLeft'); + solarPanelAlignLeft.setSecondaryAlignType('point'); + solarPanelAlignLeft.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis); + solarPanelAlignLeft.setSecondaryTargetEntity('sun'); + return solarPanelAlignLeft; + } + }, { + type: 'custom', + func: (entity) => { + const solarPanelAlignRight = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController); + solarPanelAlignRight.setJoint('ArrayGimbleRight'); + solarPanelAlignRight.setSecondaryAlignType('point'); + solarPanelAlignRight.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis); + solarPanelAlignRight.setSecondaryTargetEntity('sun'); + return solarPanelAlignRight; + } + }] + }, + sc_stardust: { + groups: ['small body spacecraft', 'comet spacecraft', '81p_wild_2', '9p_tempel_1', 'spacecraft'], + occlusionRadius: 0.00065, + extentsRadius: 0.003000, + label: 'Stardust', + parents: [ + [-28304869.3, 'earth'], + [-28038699, 'sun'], + [32627842, 'earth'], + [33120541, 'sun'], + [89379733, '5535_annefrank'], + [89550209, 'sun'], + [126009572, '81p_wild_2'], + [126678668, 'sun'], + [190336290, 'earth'], + [190866114, 'sun'], + [284944970, 'earth'], + [285742028, 'sun'], + [350896766, '9p_tempel_1'], + [351068113, 'sun'], + [354279666, ''] + ], + trail: { + length: 62659492.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_stardust/stardust_articulated.gltf', + shadowEntities: ['earth'], + rotate: [ + { x: 90 }, + { z: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_stardust/earth/launch/orb' + }, { + type: 'dynamo', + url: 'sc_stardust/sun/orb' + }, { + type: 'dynamo', + url: 'sc_stardust/earth/flyby1/orb' + }, { + type: 'dynamo', + url: 'sc_stardust/5535_annefrank/pos' + }, { + type: 'dynamo', + url: 'sc_stardust/81p_wild_2/pos' + }, { + type: 'dynamo', + url: 'sc_stardust/earth/flyby2/orb' + }, { + type: 'dynamo', + url: 'sc_stardust/earth/flyby3/orb' + }, { + type: 'dynamo', + url: 'sc_stardust/9p_tempel_1/pos' + }, { + type: 'dynamo', + url: 'sc_stardust/quat' + }, { + // Orientation dynamo doesn't quite reach to the end. + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.382740492391079, -0.1080542417135509, -0.5511677923678098, -0.7335175941913997), + coverage: [351017063, 354279666] + }, { + // Hide the SRC when it is released. + type: 'coverage', + coverage: [190576755.185 - 64.40161622339717, Number.POSITIVE_INFINITY], + enter: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + for (const object of ['Stardust_capsule', 'Stardust_tex_01_c', 'Stardust_tex_02_c', 'Stardust_tex_03_c', 'Stardust_tex_02_c2', 'Stardust_Sample_Collection1']) { + model.setHiddenObject(object, true); + } + }, + exit: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + for (const object of ['Stardust_capsule', 'Stardust_tex_01_c', 'Stardust_tex_02_c', 'Stardust_tex_03_c', 'Stardust_tex_02_c2', 'Stardust_Sample_Collection1']) { + model.setHiddenObject(object, false); + } + } + }], + postCreateFunction: (entity) => { + const model = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent); + const stardustAnimation = (/** @type {number} */angle, /** @type {number} */timeOffset, /** @type {number} */duration) => { + return /** @type {[number, number][]} */([ + [4449664 + timeOffset, angle], + [4449664 + timeOffset + duration, 0], + [10411264 - timeOffset - duration, 0], + [10411264 - timeOffset, angle], + [81864064 + timeOffset, angle], + [81864064 + timeOffset + duration, 0], + [92664064 - timeOffset - duration, 0], + [92664064 - timeOffset, angle], + [125496064 + timeOffset, angle], + [125496064 + timeOffset + duration, 0], + [126363664 - timeOffset - duration, 0], + [126363664 - timeOffset, angle] + ]); + }; + _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model, 'Stardust_capsule', 'x', stardustAnimation(1.481785, 0, 600)); + _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model, 'Stardust_Sample_Collection1', 'x', stardustAnimation(-Math.PI, 610, 300)); + _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model, 'Stardust_Sample_Collection2', 'x', stardustAnimation(-Math.PI, 920, 300)); + } + }, + sc_stardust_src: { + groups: ['small body spacecraft', 'comet spacecraft', '81p_wild_2', 'earth', 'spacecraft'], + occlusionRadius: 0.0004, + extentsRadius: 0.0008, + label: 'Stardust SRC', + parents: [ + [190576690.7833838, 'sc_stardust'], + [190576755.185, 'earth'], + [190591985.184, ''] + ], + trail: { + length: 14547.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_stardust_src/stardust_capsule.gltf', + shadowEntities: ['earth'], + rotate: [ + { x: 90 }, + { z: 90 } + ] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_stardust_src/earth/pos' + }, { + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.5761056269233067, 0.6860897901682099, 0.2627910947477326, 0.3582233199772653) + }, { + // Make the SRC trail relative to earth orientation. + type: 'coverage', + coverage: [190591100, Number.POSITIVE_INFINITY], + enter: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(true); + trail.setStartTime(1600); + } + }, + exit: (entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TrailComponent); + if (trail !== null) { + trail.setRelativeToEntityOrientation(false); + trail.setStartTime(18000); + } + } + }, { + // The spice kernels for the SRC don't release at the right position, so we use a keyframe controller to fill the gap. + type: 'custom', + func: (entity) => { + const keyframeControllerRelease = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.KeyframeController); + keyframeControllerRelease.addPositionKeyframe(190576755.185 - 64.40161622339717, // Release + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.0010057, 0, 0.0001569), + 'sc_stardust', undefined, + 'sc_stardust', undefined); + keyframeControllerRelease.addPositionKeyframe(190576755.185, // Dynamo starts + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.016734488308429718, -0.019199222326278687, -0.00404781848192215), + 'sc_stardust'); + return keyframeControllerRelease; + } + }, { + // The spice kernels for the SRC don't land correctly, + // so we use a keyframe controller to fill the gap. + type: 'custom', + func: (entity) => { + const keyframeControllerLand = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.KeyframeController); + keyframeControllerLand.addPositionKeyframe(190591163, // Spice doesn't look as good after this point. + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-1979.4577357598625, -4478.591383446022, 4136.322858267745), + 'earth' + ); + keyframeControllerLand.addPositionKeyframe(190591445.184, // Starts more gentle descent with parachute. + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-1947.8360605285134, -4491.082890234251, 4123.1018367103425), + 'earth' + ); + keyframeControllerLand.addPositionKeyframe(190591985.184, // Lands + new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-1918.7633689113482, -4478.864184129612, 4103.897124245734), + 'earth' + ); + return keyframeControllerLand; + } + }, { + // Get the landing animation above into the J2000 frame. + type: 'rotateByEntityOrientation', + coverage: [190591163, 190591985.184] + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/solar_spacecraft.js": +/*!***********************************************************!*\ + !*** ../pioneer/scripts/src/entities/solar_spacecraft.js ***! + \***********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + sc_biosentinel: { + groups: ['sun', 'spacecraft'], + occlusionRadius: 0.0002, + extentsRadius: 0.0005, + label: 'BioSentinel', + parents: [ + [721866289, 'earth'], + [722273637, 'moon'], + [722923565, 'sun'] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_biosentinel/biosentinel.gltf', + shadowEntities: ['moon'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_biosentinel/earth/orb' + }, { + type: 'dynamo', + url: 'sc_biosentinel/moon/orb' + }, { + type: 'dynamo', + url: 'sc_biosentinel/sun/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + }, + secondary: { + type: 'align', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + } + }] + }, + sc_kepler_space_telescope: { + groups: ['sun', 'spacecraft', 'telescope'], + occlusionRadius: 0.002350, + extentsRadius: 0.00400, + label: 'Kepler', + parents: [ + [289679042.1855, 'earth'], + [290348743, 'sun'], + [595512069.183, ''] + ], + trail: { + length: 32190048 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_kepler/Kepler.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_kepler/earth/orb' + }, { + type: 'dynamo', + url: 'sc_kepler/sun/orb' + }, { + type: 'align', + primary: { + type: 'align', + target: 'sun', + // This number is from 290.666... RA 44.5 DEC, the center of the Kepler cone. + targetAxis: new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.25176480336, -0.66735243742, 0.7009092643), + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + }, + secondary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg + } + }] + }, + sc_mariner_2: { + groups: ['sun', 'spacecraft'], + occlusionRadius: 0.002, + extentsRadius: 0.0025000, + label: 'Mariner 2', + parents: [ + [-1178599240.703784, 'sun'], + [409233667.18358755, ''] + ], + trail: { + length: 29411352.0 + }, + controllers: [{ + type: 'animdata', + url: 'sc_mariner_2', + dataType: 'pos' + }] + }, + sc_parker_solar_probe: { + groups: ['sun', 'spacecraft'], + occlusionRadius: 0.0015, + extentsRadius: 0.003, + label: 'Parker Solar Probe', + parents: [ + [587333783.3431, 'earth'], + [587454078, 'sun'] + ], + trail: { + length: 12942631.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_parker_solar_probe/PSP.gltf' + }, + controllers: [{ + type: 'dynamo', + url: 'sc_parker_solar_probe/earth/orb' + }, { + type: 'dynamo', + url: 'sc_parker_solar_probe/sun/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + } + }] + }, + sc_spitzer: { + groups: ['sun', 'spacecraft'], + occlusionRadius: 0.0085, + extentsRadius: 0.004, + label: 'Spitzer', + parents: [ + [115064804, 'earth'], + [115493678, 'sun'], + [633614469, ''] + ], + trail: { + length: 32167331.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_spitzer/SPITZER.gltf', + rotate: [ + { z: -90 }, + { x: -90 } + ], + shadowEntities: ['venus', 'mercury'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_spitzer/earth/orb' + }, { + type: 'dynamo', + url: 'sc_spitzer/sun/orb' + }, { + type: 'fixed', + orientation: new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.5258297992951877, 0.8139480432783324, -0.1400557906856776, -0.20341086625833524), + coverage: [115064804, 174548493] + }, { + type: 'dynamo', + url: 'sc_spitzer/quat' + }] + }, + sc_stereo_ahead: { + groups: ['sun', 'spacecraft'], + occlusionRadius: 0.003, + extentsRadius: 0.003000, + label: 'STEREO Ahead', + parents: [ + [215097110, 'earth'], + [221418192, 'sun'] + ], + trail: { + length: 29809031.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_stereo_ahead/stereo_a.gltf', + rotate: [ + { x: 90 } + ], + shadowEntities: ['venus', 'mercury'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_stereo_ahead/earth/orb' + }, { + type: 'dynamo', + url: 'sc_stereo_ahead/sun/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_stereo_ahead', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg + } + }] + }, + sc_stereo_behind: { + groups: ['sun', 'spacecraft'], + occlusionRadius: 0.003, + extentsRadius: 0.003000, + label: 'STEREO Behind', + parents: [ + [215097110, 'earth'], + [224468337, 'sun'], + [527860868.182, ''] + ], + trail: { + length: 33473699.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_stereo_behind/stereo_b.gltf', + rotate: [ + { x: 90 } + ], + shadowEntities: ['venus', 'mercury'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_stereo_behind/earth/orb' + }, { + type: 'dynamo', + url: 'sc_stereo_behind/sun/orb' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_stereo_behind', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg + } + }] + }, + sc_ulysses: { + groups: ['sun', 'spacecraft'], + occlusionRadius: 0.002, + extentsRadius: 0.002, + label: 'Ulysses', + parents: [ + [-291488100, 'sun'], + [268142464.18410408, ''] + ], + trail: { + length: 140294739.0 + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_ulysses/ulysses.gltf', + shadowEntities: ['venus', 'mercury'] + }, + controllers: [{ + type: 'animdata', + url: 'sc_ulysses', + dataType: 'pos' + }, { + type: 'align', + primary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis + }, + secondary: { + type: 'velocity', + target: 'sc_ulysses', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg + } + }] + }, + sc_wmap: { + groups: ['sun', 'spacecraft'], + occlusionRadius: 0.0026, + extentsRadius: 0.0026, + label: 'WMAP', + parents: [ + [339422466.184, 'sun'], + [360158466.184, ''] + ], + trail: { + length: 60 * 60 * 24 * 365 + }, + controllers: [{ + type: 'animdata', + url: 'sc_wmap', + dataType: 'pos' + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/uranus_major_moons.js": +/*!*************************************************************!*\ + !*** ../pioneer/scripts/src/entities/uranus_major_moons.js ***! + \*************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/** @module pioneer-scripts */ + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + ariel: { + groups: ['uranus', 'moons', 'major'], + radius: 578.9, + label: 'Ariel', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + spheroid: { + equatorialRadius: 578.9, + polarRadius: 578.9, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'ariel/color_$SIZE_$FACE.png', + sizes: [4, 512] + } + }, + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'ariel/uranus/orb' + }, { + type: 'dynamo', + url: 'ariel/ori' + }] + }, + miranda: { + groups: ['uranus', 'moons', 'major'], + radius: 235.8, + label: 'Miranda', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + spheroid: { + equatorialRadius: 235.8, + polarRadius: 235.8, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'miranda/color_$SIZE_$FACE.png', + sizes: [4, 256] + } + }, + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'miranda/uranus/orb' + }, { + type: 'dynamo', + url: 'miranda/ori' + }] + }, + oberon: { + groups: ['uranus', 'moons', 'major'], + radius: 761.4, + label: 'Oberon', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + spheroid: { + equatorialRadius: 761.4, + polarRadius: 761.4, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'oberon/color_$SIZE_$FACE.png', + sizes: [4, 512] + } + }, + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'oberon/uranus/orb' + }, { + type: 'dynamo', + url: 'oberon/ori' + }] + }, + titania: { + groups: ['uranus', 'moons', 'major'], + radius: 788.4, + label: 'Titania', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + spheroid: { + equatorialRadius: 788.4, + polarRadius: 788.4, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'titania/color_$SIZE_$FACE.png', + sizes: [4, 512] + } + }, + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'titania/uranus/orb' + }, { + type: 'dynamo', + url: 'titania/ori' + }] + }, + umbriel: { + groups: ['uranus', 'moons', 'major'], + radius: 584.7, + label: 'Umbriel', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + spheroid: { + equatorialRadius: 584.7, + polarRadius: 584.7, + planetographic: false + }, + spheroidLOD: { + features: ['shadowEntities'], + textures: { + color: { + url: 'umbriel/color_$SIZE_$FACE.png', + sizes: [4, 256] + } + }, + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'umbriel/uranus/orb' + }, { + type: 'dynamo', + url: 'umbriel/ori' + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/uranus_minor_moons.js": +/*!*************************************************************!*\ + !*** ../pioneer/scripts/src/entities/uranus_minor_moons.js ***! + \*************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + belinda: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 45.0, + label: 'Belinda', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [45, 45, 45], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'belinda/uranus/orb' + }, { + type: 'dynamo', + url: 'belinda/ori' + }] + }, + bianca: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 25.7, + label: 'Bianca', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [25.7, 25.7, 25.7], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'bianca/uranus/orb' + }, { + type: 'dynamo', + url: 'bianca/ori' + }] + }, + caliban: { + groups: ['uranus', 'moons', 'minor', 'irregular'], + radius: 36, + label: 'Caliban', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [36, 36, 36], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'caliban/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + cordelia: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 20.1, + label: 'Cordelia', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [20.1, 20.1, 20.1], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'cordelia/uranus/orb' + }, { + type: 'dynamo', + url: 'cordelia/ori' + }] + }, + cressida: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 39.8, + label: 'Cressida', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [39.8, 39.8, 39.8], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'cressida/uranus/orb' + }, { + type: 'dynamo', + url: 'cressida/ori' + }] + }, + cupid: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 9.0, + label: 'Cupid', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [9, 9, 9], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'cupid/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + desdemona: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 32.0, + label: 'Desdemona', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [32, 32, 32], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'desdemona/uranus/orb' + }, { + type: 'dynamo', + url: 'desdemona/ori' + }] + }, + ferdinand: { + groups: ['uranus', 'moons', 'minor', 'irregular'], + radius: 10, + label: 'Ferdinand', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [10, 10, 10], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'ferdinand/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + francisco: { + groups: ['uranus', 'moons', 'minor', 'irregular'], + radius: 11, + label: 'Francisco', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [11, 11, 11], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'francisco/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + juliet: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 46.8, + label: 'Juliet', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [46.8, 46.8, 46.8], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'juliet/uranus/orb' + }, { + type: 'dynamo', + url: 'juliet/ori' + }] + }, + mab: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 12.5, + label: 'Mab', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [12.5, 12.5, 12.5], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'mab/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + margaret: { + groups: ['uranus', 'moons', 'minor', 'irregular'], + radius: 10, + label: 'Margaret', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [10, 10, 10], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'margaret/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + ophelia: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 22.4, + label: 'Ophelia', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [22.4, 22.4, 22.4], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'ophelia/uranus/orb' + }, { + type: 'dynamo', + url: 'ophelia/ori' + }] + }, + perdita: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 15.0, + label: 'Perdita', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [15, 15, 15], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'perdita/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + portia: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 67.6, + label: 'Portia', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [67.6, 67.6, 67.6], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'portia/uranus/orb' + }, { + type: 'dynamo', + url: 'portia/ori' + }] + }, + prospero: { + groups: ['uranus', 'moons', 'minor', 'irregular'], + radius: 25, + label: 'Prospero', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [25, 25, 25], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'prospero/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + puck: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 81.0, + label: 'Puck', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [81, 81, 81], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'puck/uranus/orb' + }, { + type: 'dynamo', + url: 'puck/ori' + }] + }, + rosalind: { + groups: ['uranus', 'moons', 'minor', 'inner'], + radius: 36.0, + label: 'Rosalind', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [36, 36, 36], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'rosalind/uranus/orb' + }, { + type: 'dynamo', + url: 'rosalind/ori' + }] + }, + setebos: { + groups: ['uranus', 'moons', 'minor', 'irregular'], + radius: 24, + label: 'Setebos', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [24, 24, 24], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'setebos/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + stephano: { + groups: ['uranus', 'moons', 'minor', 'irregular'], + radius: 16, + label: 'Stephano', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf', + scale: [16, 16, 16], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'stephano/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + sycorax: { + groups: ['uranus', 'moons', 'minor', 'irregular'], + radius: 82, + label: 'Sycorax', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf', + scale: [82, 82, 82], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'sycorax/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + }, + trinculo: { + groups: ['uranus', 'moons', 'minor', 'irregular'], + radius: 9, + label: 'Trinculo', + parents: [ + [Number.NEGATIVE_INFINITY, 'uranus'] + ], + trail: { + length: undefined, + color: [0.67, 0.92, 1.00, 0.7] + }, + model: { + url: '$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf', + scale: [9, 9, 9], + shadowEntities: ['uranus'] + }, + controllers: [{ + type: 'dynamo', + url: 'trinculo/uranus/orb' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entities/venus_spacecraft.js": +/*!***********************************************************!*\ + !*** ../pioneer/scripts/src/entities/venus_spacecraft.js ***! + \***********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + + +_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ + sc_magellan: { + groups: ['venus', 'spacecraft'], + occlusionRadius: 0.003200, + extentsRadius: 0.006000, + label: 'Magellan', + parents: [ + [-336388283.36, 'sun'], + [-296448521.457, 'venus'], + [-164631538.81763855, ''] + ], + trail: { + length: undefined + }, + model: { + url: '$STATIC_ASSETS_URL/models/sc_magellan/magellan.gltf', + shadowEntities: ['venus'] + }, + controllers: [{ + type: 'dynamo', + url: 'sc_magellan/venus/orb' + }, { + type: 'custom', + func: (entity) => { + // Add the controller for going around sun from earth to venus. + const oeCruiseController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController); + const oeCruise = new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements(); + oeCruise.epoch = -336394683.816; + oeCruise.eccentricity = 0.1791852824104108; + oeCruise.semiMajorAxis = 128280596.63956015; + oeCruise.meanAngularMotion = 2.5073465306679634e-7; + oeCruise.meanAnomalyAtEpoch = 2.9229288382327625; + oeCruise.orbitOrientation.set(0.8728453580255966, 0.1876084386162498, -0.08948587100888229, 0.4415159494547423); + oeCruiseController.addOrbitalElements(-336388283.360, oeCruise); + oeCruiseController.addOrbitalElements(-296448521.457, oeCruise); + return oeCruiseController; + } + }, { + type: 'custom', + func: (entity) => { + // Add the controller for the venus orbital insertion and first few orbits that aren't covered by spice. + const oeVOIController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController); + // Orbital insertion with hyperbolic eccentricity. + const oeVOI = new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements(); + oeVOI.epoch = -296448521.457; + oeVOI.eccentricity = 1.272922970547487; + oeVOI.semiMajorAxis = 23358.593430196037; + oeVOI.meanAngularMotion = 0.00015965302516479147; + oeVOI.meanAnomalyAtEpoch = -6.138103356108873; + oeVOI.orbitOrientation.set(-0.49933963770188916, 0.11817755769547109, 0.7262027627540558, -0.45751889408554064); + oeVOIController.addOrbitalElements(-296448521.457, oeVOI); + oeVOIController.addOrbitalElements(-296410230.351, oeVOI); + // Extra orbits from Aug 10 to Aug 16 to connect to the start of the spice/dynamo. + const oeVOI2 = new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements(); + oeVOI2.epoch = -295884037.7511; + oeVOI2.eccentricity = 0.39186818222106645; + oeVOI2.semiMajorAxis = 10434.012201911135; + oeVOI2.meanAngularMotion = 0.000534773863104956; + oeVOI2.meanAnomalyAtEpoch = -1.5165416917234864; + oeVOI2.orbitOrientation.set(-0.4665778554219434, 0.18802595119032475, 0.7217932088991018, -0.47535871728198204); + oeVOIController.addOrbitalElements(-296410230.351, oeVOI2); + oeVOIController.addOrbitalElements(-295884037.7511, oeVOI2); + return oeVOIController; + } + }, { + type: 'align', + primary: { + type: 'point', + target: 'earth', + axis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis + }, + secondary: { + type: 'align', + axis: new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-Math.sqrt(0.5), Math.sqrt(0.5), 0), + target: 'venus', + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg + } + }] + }, + sc_venus_express: { + groups: ['venus', 'spacecraft'], + occlusionRadius: 0.0009, + extentsRadius: 0.0040, + label: 'Venus Express', + parents: [ + [184784702, 'earth'], + [185369766, 'sun'], + [197902579, 'venus'], + [473341201, ''] + ], + trail: { + length: 779592.165087551 + }, + controllers: [{ + type: 'dynamo', + url: 'sc_venus_express/earth' + }, { + type: 'dynamo', + url: 'sc_venus_express/sun' + }, { + type: 'dynamo', + url: 'sc_venus_express/venus' + }, { + type: 'fixed', + orientation: pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity + }, { + type: 'dynamo', + url: 'sc_venus_express/quat' + }] + } +}); + + +/***/ }), + +/***/ "../pioneer/scripts/src/entity.js": +/*!****************************************!*\ + !*** ../pioneer/scripts/src/entity.js ***! + \****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Entity": function() { return /* binding */ Entity; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * @typedef Options + * @property {string[]} [groups] + * @property {string} [label] + * @property {string} [labelFadeEntity] - The entity that when this gets close to it, the label fades. + * @property {number} [occlusionRadius] + * @property {number} [extentsRadius] + * @property {number} [radius] - This applies to occlusion and extents radii. + * @property {number} [systemRadius] - The radius within which all children reside. + * @property {[number, string][]} parents + * @property {string[]} [dependents] + * @property {string} [lightSource] + * @property {TrailOptions} [trail] + * @property {SpheroidOptions} [spheroid] + * @property {SpheroidLODOptions} [spheroidLOD] + * @property {CMTSOptions} [cmts] + * @property {ModelOptions} [model] + * @property {CometOptions} [comet] + * @property {ControllersOptions[]} [controllers] + * @property {(entity: Pioneer.Entity, extraOptions?: ExtraOptions) => void} [postCreateFunction] + */ + +/** + * @typedef ExtraOptions + * @property {string} [namePrefix] - A prefix that will be prepended to the name of the entity. + * @property {string} [nameSuffix] - A suffix that will be appended to the name of the entity. + * @property {boolean} [milkyWaySprite] - Whether or not to use the milky way sprite. + * @property {boolean} [skybox] - A skybox that is used instead of the stars. + * @property {number} [skyboxResolution] - The resolution of the skybox. + * @property {boolean} [starfield] - A starfield that is used instead of the skybox. + * @property {boolean} [heliosphere] - Whether or not the sun has a heliosphere. + * @property {boolean} [clouds] - Whether the earth has clouds or not. + * @private + */ + +/** + * @typedef {FixedOptions | SpinOptions | DynamoOptions | AnimdataOptions | AlignOptions | RotateByEntityOrientation | CoverageOptions | CustomControllerOptions | OrbitalElementsOptions} ControllersOptions + */ + +/** + * @typedef TrailOptions + * @property {string} [name] + * @property {number | undefined} length + * @property {[number, number, number, number]} [color] + * @property {string} [relativeTo] + * @property {[number, number, number][]} [lengthCoverages] + */ + +/** + * @typedef SpheroidOptions + * @property {string} [name] + * @property {number} equatorialRadius + * @property {number} polarRadius + * @property {boolean} planetographic + */ + +/** + * @typedef SpheroidLODOptions + * @property {string} [name] + * @property {string[]} [features] + * @property {Object.} [textures] + * @property {string[]} [shadowEntities] + */ + +/** + * @typedef SpheroidTextureOptions + * @property {string} url + * @property {number[]} sizes + */ + +/** + * @typedef CMTSOptions + * @property {string} [name] + * @property {Object.} textures + * @property {string[]} [shadowEntities] + * @property {number} [maxLevel] + */ + +/** + * @typedef ModelOptions + * @property {string} [name] + * @property {string} url + * @property {ModelRotateOptions[]} [rotate] + * @property {[number, number, number] | number} [scale] + * @property {string[]} [shadowEntities] + * @property {ModelEnvironmentMapOptions} [environmentMap] + * @property {boolean} [useCompressedTextures] + */ + +/** + * @typedef ModelRotateOptions + * @property {number} [x] + * @property {number} [y] + * @property {number} [z] + */ + +/** + * @typedef ModelEnvironmentMapOptions + * @property {string} [cubemap] + * @property {string} [cylindrical] + */ + +/** + * @typedef CometOptions + * @property {string} [name] + * @property {number} [timeLength] + */ + +/** + * @typedef FixedOptions + * @property {'fixed'} type + * @property {string} [name] + * @property {Pioneer.Vector3} [position] + * @property {Pioneer.Quaternion} [orientation] + * @property {string} [relativeToEntity] + * @property {Pioneer.LatLonAlt} [llaOnSpheroid] + * @property {string} [llaOnSpheroidEntity] + * @property {[number, number]} [coverage] + */ + +/** + * @typedef SpinOptions + * @property {'spin'} type + * @property {string} [name] + * @property {Pioneer.Vector3} axis + * @property {boolean} [axisInFrameSpace] + * @property {number} periodInHours + * @property {number} [relativeToTime] + * @property {[number, number]} [coverage] + */ + +/** + * @typedef DynamoOptions + * @property {'dynamo'} type + * @property {string} [name] + * @property {string} url + * @property {boolean} [parentIsBarycenter] + * @property {boolean} [customUrl] + * @property {[number, number]} [coverage] + */ + +/** + * @typedef AnimdataOptions + * @property {'animdata'} type + * @property {string} [name] + * @property {string} url + * @property {string} dataType + * @property {[number, number]} [coverage] + */ + +/** + * @typedef AlignOptions + * @property {'align'} type + * @property {string} [name] + * @property {AlignAxisOptions} primary + * @property {AlignAxisOptions} [secondary] + * @property {[number, number]} [coverage] + */ + +/** + * @typedef AlignAxisOptions + * @property {string} type + * @property {string} target + * @property {Pioneer.Vector3} axis + * @property {Pioneer.Vector3} [targetAxis] + */ + +/** + * @typedef RotateByEntityOrientation + * @property {'rotateByEntityOrientation'} type + * @property {string} [name] + * @property {string} [entityForOrientation] + * @property {boolean} [rotatingOrientation] + * @property {boolean} [rotatingPosition] + * @property {[number, number]} [coverage] + */ + +/** + * @typedef OrbitalElementsOptions + * @property {'orbitalElements'} type + * @property {string} [name] + * @property {number} [epoch] + * @property {number} eccentricity Can be calculated from `e = 1 - 2 / (apoapsis / periapsis + 1)`. + * @property {number} semiMajorAxis Can be calculated from `a = periapsis / (1 - e)`. In km. + * @property {number} meanAngularMotion Can be calculated from `2 * PI / period`. In rad / s. + * @property {number} meanAnomalyAtEpoch The mean angle at the epoch time. In rad. + * @property {Pioneer.Quaternion} [orbitOrientation] + * @property {number} [inclination] + * @property {number} [longitudeOfAscendingNode] + * @property {number} [argumentOfPeriapsis] + * @property {[number, number]} [coverage] + */ + +/** + * @typedef CoverageOptions + * @property {'coverage'} type + * @property {string} [name] + * @property {[number, number]} coverage + * @property {(entity: Pioneer.Entity) => void} [enter] + * @property {(entity: Pioneer.Entity) => void} [exit] + * @property {(entity: Pioneer.Entity) => void} [update] + * @property {number} [updateInterval] + */ + +/** + * @typedef CustomControllerOptions + * @property {'custom'} type + * @property {(entity: Pioneer.Entity) => Pioneer.BaseController} func + * @property {[number, number]} [coverage] + */ + +/** + * Helpful functions for creating entities. + * @hideconstructor + */ +class Entity { + /** + * Every script that imports this needs to register its "entity name -> options" object so that the create script can use it. + * @param {Object} entities + */ + static register(entities) { + for (const name in entities) { + if (Object.prototype.hasOwnProperty.call(entities, name)) { + this._entities.set(name, entities[name]); + } + } + } + + /** + * Creates an entity. + * @param {string} name + * @param {Pioneer.Scene} scene + * @param {ExtraOptions} [extraOptions] + * @returns {Pioneer.Entity} + */ + static create(name, scene, extraOptions) { + // Get the options for the entity's name. + const options = Entity._entities.get(name); + if (options === undefined) { + throw new Error('Could not find the options for the entity with name ' + name); + } + + return this.createFromOptions(name, options, scene, extraOptions); + } + + /** + * Create an entity from the given options. + * @param {string} name + * @param {Options} options + * @param {Pioneer.Scene} scene + * @param {ExtraOptions} [extraOptions] + * @returns {Pioneer.Entity} + */ + static createFromOptions(name, options, scene, extraOptions) { + // Create the actual name given the prefix and suffix options. + let actualName = name; + if (extraOptions) { + if (extraOptions.namePrefix) { + actualName = extraOptions.namePrefix + actualName; + } + if (extraOptions.nameSuffix) { + actualName = actualName + extraOptions.nameSuffix; + } + } + + // Check if entity already exists. + let entity = scene.getEntity(actualName); + if (entity !== null) { + return entity; + } + + // Create the entity. + entity = scene.addEntity(actualName); + + // Process the options. + try { + if (options.radius) { + entity.setOcclusionRadius(options.radius); + entity.setExtentsRadius(options.radius); + } + if (options.occlusionRadius) { + entity.setOcclusionRadius(options.occlusionRadius); + } + if (options.extentsRadius) { + entity.setExtentsRadius(options.extentsRadius); + } + + // Add the parenting table. + for (const [startTime, parentName] of options.parents) { + entity.addParentingTableEntry(startTime, parentName); + } + + if (options.label) { + const component = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.DivComponent); + const div = component.getDiv(); + div.innerHTML = options.label; + div.className = 'pioneer-label-div'; + } + + if (options.labelFadeEntity) { + const divComponent = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.DivComponent); + if (divComponent === null) { + throw new Error('There is no label.'); + } + divComponent.setFadeWhenCloseToEntity(options.labelFadeEntity); + } + + if (options.trail) { + const component = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.TrailComponent, options.trail.name); + component.setStartTime(options.trail.length); + if (options.trail.color) { + component.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(options.trail.color[0], options.trail.color[1], options.trail.color[2], options.trail.color[3])); + } + else { + component.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 0.5)); + } + if (options.trail.relativeTo) { + component.setRelativeToEntity(options.trail.relativeTo); + } + if (options.trail.lengthCoverages) { + const trailLength = options.trail.length; + for (let i = 0, l = options.trail.lengthCoverages.length; i < l; i++) { + const lengthCoverage = options.trail.lengthCoverages[i]; + const coverageController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CoverageController, `trail_length_coverage.${i}`, entity.getController(0) ?? undefined); + coverageController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(lengthCoverage[1], lengthCoverage[2])); + coverageController.setEnterFunction((entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.TrailComponent); + if (trail !== null) { + trail.setStartTime(lengthCoverage[0]); + } + }); + coverageController.setExitFunction((entity) => { + const trail = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.TrailComponent); + if (trail !== null) { + trail.setStartTime(trailLength); + } + }); + } + } + } + + if (options.spheroid) { + const component = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent, options.spheroid.name); + component.setEquatorialRadius(options.spheroid.equatorialRadius); + component.setPolarRadius(options.spheroid.polarRadius); + component.setPlanetographic(options.spheroid.planetographic); + } + + if (options.spheroidLOD) { + const component = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidLODComponent, options.spheroidLOD.name ?? 'basic'); + if (options.spheroidLOD.features) { + for (let i = 0, l = options.spheroidLOD.features.length; i < l; i++) { + component.setFeature(options.spheroidLOD.features[i], true); + } + } + if (options.spheroidLOD.textures) { + component.setMapping('cube'); + for (const name in options.spheroidLOD.textures) { + component.setTexture(name, '$STATIC_ASSETS_URL/maps/' + options.spheroidLOD.textures[name].url, options.spheroidLOD.textures[name].sizes); + } + } + if (options.spheroidLOD.shadowEntities) { + component.setShadowEntities(options.spheroidLOD.shadowEntities); + } + } + + if (options.cmts) { + const component = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CMTSComponent, options.cmts.name); + if (options.cmts.textures) { + for (const name in options.cmts.textures) { + const url = options.cmts.textures[name]; + component.setBaseUrl(name, url); + } + component.setMaxLevel(options.cmts.maxLevel || 0); + } + if (options.cmts.shadowEntities) { + component.setShadowEntities(options.cmts.shadowEntities); + } + } + + if (options.model) { + const component = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent, options.model.name); + component.setUrl(options.model.url); + if (options.model.rotate) { + const rotation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + rotation.set(1, 0, 0, 0); + for (let i = 0, l = options.model.rotate.length; i < l; i++) { + let axis; + let angle; + const rotate = options.model.rotate[i]; + if (rotate.x !== undefined) { + axis = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(1, 0, 0); + angle = rotate.x; + } + else if (rotate.y !== undefined) { + axis = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 1, 0); + angle = rotate.y; + } + else if (rotate.z !== undefined) { + axis = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0, 0, 1); + angle = rotate.z; + } + else { + throw new Error('Invalid model rotate axis.'); + } + angle = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(angle); + const r = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + r.setFromAxisAngle(axis, angle); + rotation.mult(r, rotation); + } + component.setRotation(rotation); + } + if (options.model.scale) { + const scale = options.model.scale; + if (Array.isArray(scale)) { + component.setScale(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(scale[0], scale[1], scale[2])); + } + else { + component.setScale(scale); + } + } + if (options.model.useCompressedTextures === true) { + component.setUseCompressedTextures(true); + } + if (options.model.shadowEntities) { + component.setShadowEntities(options.model.shadowEntities); + } + + if (options.model.environmentMap) { + if (options.model.environmentMap.cubemap) { + component.setEnvironmentCubemapUrl(options.model.environmentMap.cubemap); + component.setEnvironmentCylindricalUrl(''); + } + else if (options.model.environmentMap.cylindrical) { + component.setEnvironmentCylindricalUrl(options.model.environmentMap.cylindrical); + component.setEnvironmentCubemapUrl(''); + } + } + } + + if (options.comet) { + const dustTail = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CometTailComponent, options.comet.name); + if (options.comet.timeLength !== undefined) { + dustTail.setTimeLength(options.comet.timeLength); + } + dustTail.setLightSource('sun'); + + const gasTail = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CometTailComponent); + gasTail.setTimeLength(dustTail.getTimeLength() * 0.5); + gasTail.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(0.214, 0.235, 0.371, 0.5)); + gasTail.setStarAccelerationMultiplier(10.0); + gasTail.setLightSource('sun'); + + const coma = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CometTailComponent); + // coma.setTimeLength(dustTail.getTimeLength() * 0.1); + coma.setStarAccelerationMultiplier(0); + coma.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1, 1, 1, 10)); + coma.setNumberOfParticles(1); + coma.setLightSource('sun'); + } + + if (options.controllers) { + for (let i = 0, l = options.controllers.length; i < l; i++) { + const controllerOptions = options.controllers[i]; + const type = controllerOptions.type; + let controller; + if (type === 'fixed') { + controller = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.FixedController, controllerOptions.name); + if (controllerOptions.position) { + controller.setPosition(controllerOptions.position); + } + if (controllerOptions.orientation) { + controller.setOrientation(controllerOptions.orientation); + } + if (controllerOptions.relativeToEntity) { + // Add a rotate by parent orientation to get the fixed position in the J2000 frame. + const rotateByEntityOrientationController = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.RotateByEntityOrientationController); + rotateByEntityOrientationController.setEntityForOrientation(controllerOptions.relativeToEntity); + if (controllerOptions.coverage && controllerOptions.coverage.length === 2) { + rotateByEntityOrientationController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(controllerOptions.coverage[0], controllerOptions.coverage[1])); + } + } + if (controllerOptions.llaOnSpheroid) { + const parentName = controllerOptions.llaOnSpheroidEntity ?? options.parents[0][1]; + const parent = scene.getEntity(parentName); + if (parent !== null) { + const spheroid = parent.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent); + if (spheroid === null) { + throw new Error('Missing spheroid component.'); + } + if (controllerOptions.coverage && controllerOptions.coverage.length === 2) { + controller.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(controllerOptions.coverage[0], controllerOptions.coverage[1])); + } + // Get the xyz from the lla and set the position. + const position = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(); + spheroid.xyzFromLLA(position, controllerOptions.llaOnSpheroid); + controller.setPosition(position); + // Get the ori from the lla and set the orientation. + const orientation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(); + spheroid.orientationFromLLA(orientation, controllerOptions.llaOnSpheroid); + controller.setOrientation(orientation); + // Add a rotate by parent orientation to get it in the J2000 frame. + const rotateByEntityOrientation = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.RotateByEntityOrientationController); + if (controllerOptions.coverage && controllerOptions.coverage.length === 2) { + rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(controllerOptions.coverage[0], controllerOptions.coverage[1])); + } + const groundClamp = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.GroundClampController); + groundClamp.setGroundComponentRef(parentName, 'cmts'); + if (controllerOptions.coverage && controllerOptions.coverage.length === 2) { + groundClamp.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(controllerOptions.coverage[0], controllerOptions.coverage[1])); + } + } + } + } + else if (type === 'dynamo') { + controller = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.DynamoController, controllerOptions.name); + if (!controllerOptions.customUrl) { + controller.setBaseUrl('$DYNAMIC_ASSETS_URL/dynamo/' + controllerOptions.url); + } + else { + controller.setBaseUrl(controllerOptions.url); + } + if (controllerOptions.parentIsBarycenter) { + controller.setHeaderValue('body', 1); + } + } + else if (type === 'animdata') { + controller = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.AnimdataController, controllerOptions.name); + controller.setBaseUrlAndStateType('$ANIMDATA_URL/' + controllerOptions.url, controllerOptions.dataType); + } + else if (type === 'align') { + controller = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.AlignController, controllerOptions.name); + controller.setPrimaryAlignType(controllerOptions.primary.type); + controller.setPrimaryTargetEntity(controllerOptions.primary.target); + controller.setPrimaryAxis(controllerOptions.primary.axis); + if (controllerOptions.primary.targetAxis) { + controller.setPrimaryTargetAxis(controllerOptions.primary.targetAxis); + } + if (controllerOptions.secondary) { + controller.setSecondaryAlignType(controllerOptions.secondary.type); + controller.setSecondaryTargetEntity(controllerOptions.secondary.target); + controller.setSecondaryAxis(controllerOptions.secondary.axis); + if (controllerOptions.secondary.targetAxis) { + controller.setSecondaryTargetAxis(controllerOptions.secondary.targetAxis); + } + } + } + else if (type === 'spin') { + controller = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpinController, controllerOptions.name); + controller.setAxis(controllerOptions.axis, controllerOptions.axisInFrameSpace ?? true); + controller.setRate(pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi / (controllerOptions.periodInHours * 3600)); + if (controllerOptions.relativeToTime !== undefined) { + controller.setReferenceTime(controllerOptions.relativeToTime); + } + } + else if (type === 'rotateByEntityOrientation') { + controller = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.RotateByEntityOrientationController, controllerOptions.name); + if (controllerOptions.entityForOrientation) { + controller.setEntityForOrientation(controllerOptions.entityForOrientation); + } + if (controllerOptions.rotatingOrientation !== undefined) { + controller.setRotatingOrientation(controllerOptions.rotatingOrientation); + } + if (controllerOptions.rotatingPosition !== undefined) { + controller.setRotatingPosition(controllerOptions.rotatingPosition); + } + } + else if (type === 'orbitalElements') { + controller = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitalElementsController, controllerOptions.name); + const epoch = controllerOptions.epoch ?? 0; + const orbitalElements = new pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements(); + orbitalElements.epoch = epoch; + orbitalElements.eccentricity = controllerOptions.eccentricity; + orbitalElements.semiMajorAxis = controllerOptions.semiMajorAxis; + orbitalElements.meanAngularMotion = controllerOptions.meanAngularMotion; + orbitalElements.meanAnomalyAtEpoch = controllerOptions.meanAnomalyAtEpoch; + if (controllerOptions.orbitOrientation !== undefined) { + orbitalElements.orbitOrientation.copy(controllerOptions.orbitOrientation); + } + else { + if (controllerOptions.inclination === undefined || controllerOptions.longitudeOfAscendingNode === undefined || controllerOptions.argumentOfPeriapsis === undefined) { + throw new Error('Either orbitOrientation or all of inclination, longitudeOfAscendingNode, and argumentOfPeriapsis must be defined.'); + } + orbitalElements.setOrbitOrientationFromElements(controllerOptions.inclination, controllerOptions.longitudeOfAscendingNode, controllerOptions.argumentOfPeriapsis); + } + controller.addOrbitalElements(epoch, orbitalElements); + } + else if (type === 'coverage') { + controller = entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CoverageController, controllerOptions.name); + controller.setEnterFunction(controllerOptions.enter); + controller.setExitFunction(controllerOptions.exit); + controller.setUpdateFunction(controllerOptions.update); + if (controllerOptions.updateInterval !== undefined) { + controller.setUpdateInterval(controllerOptions.updateInterval); + } + } + else if (type === 'custom') { + controller = controllerOptions.func(entity); + } + else { + throw new Error(`The type "${type}" is unknown.`); + } + if (controllerOptions.coverage && controllerOptions.coverage.length === 2) { + controller.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(controllerOptions.coverage[0], controllerOptions.coverage[1])); + } + } + } + + if (options.postCreateFunction) { + options.postCreateFunction(entity, extraOptions); + } + } + catch (error) { + if (entity !== null) { + scene.removeEntity(entity); + } + if (error instanceof Error) { + error.message = `While creating "${actualName}": ${error.message}`; + } + throw error; + } + + return entity; + } + + /** + * Gets the entity options that are used to create the entity. + * @param {string} name + * @returns {Options | undefined} + */ + static getEntityOptions(name) { + return Entity._entities.get(name); + } + + /** + * Gets a list of all entity names that are within a given set of groups, which is a comma-separated list of groups that each entity must include. + * @param {string} groups + * @returns {Set} + */ + static getEntityNamesInGroup(groups) { + const matchingEntityNames = new Set(); + if (groups !== '') { + const groupsArray = groups.split(',').map((group) => { + return group.trim(); + }); + for (const [name, options] of Entity._entities) { + const entityGroups = options.groups; + if (!entityGroups) { // Entity has has no group. + continue; + } + let matches = true; + for (const group of groupsArray) { + if (!entityGroups.includes(group)) { + matches = false; + } + } + if (!matches) { + continue; + } + matchingEntityNames.add(name); + } + } + else { + for (const name of Entity._entities.keys()) { + matchingEntityNames.add(name); + } + } + return matchingEntityNames; + } + + /** + * Gets a list of all groups that exist within the entities. + * @returns {Set} + */ + static getGroups() { + const groups = new Set(); + for (const options of this._entities.values()) { + const entityGroups = options.groups; + if (entityGroups !== undefined) { + for (let i = 0; i < entityGroups.length; i++) { + groups.add(entityGroups[i]); + } + } + } + return groups; + } + + /** + * Create all of the entities that belong to a group. + * @param {string} groups - A comma-separated list of groups that each entity must include. + * @param {Pioneer.Scene} scene + * @param {ExtraOptions} [extraOptions] + */ + static createGroup(groups, scene, extraOptions) { + const matchingEntityNames = this.getEntityNamesInGroup(groups); + for (const entityName of matchingEntityNames) { + this.create(entityName, scene, extraOptions); + } + } +} + +/** + * @type {Map} + */ +Entity._entities = new Map(); + + +/***/ }), + +/***/ "../pioneer/scripts/src/features.js": +/*!******************************************!*\ + !*** ../pioneer/scripts/src/features.js ***! + \******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Features": function() { return /* binding */ Features; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./entity */ "../pioneer/scripts/src/entity.js"); + + + +/** + * Functions for enabling and disabling special features on entities. + */ +class Features { + /** + * Enables or disables the featureType of the entityName. + * @param {Pioneer.Scene} scene + * @param {string} entityName + * @param {string} featureType + * @param {boolean} enable + */ + static setEnabled(scene, entityName, featureType, enable) { + const featureSetEnabledMap = entityFeatureSetEnabledMap[entityName]; + if (!featureSetEnabledMap) { + throw new Error(`Attempted to access unavailable feature ${featureType} for ${entityName}.`); + } + const setEnabledFunction = featureSetEnabledMap[featureType]; + if (!setEnabledFunction) { + throw new Error(`Attempted to access unavailable feature ${featureType} for ${entityName}.`); + } + setEnabledFunction(scene, enable); + } + + /** + * Returns true if the featureType of the entityName is enabled. + * @param {Pioneer.Scene} scene + * @param {string} entityName + * @param {string} featureType + * @returns {boolean} + */ + static isEnabled(scene, entityName, featureType) { + const featureIsEnabledMap = entityFeatureIsEnabledMap[entityName]; + if (!featureIsEnabledMap) { + throw new Error(`Attempted to access unavailable feature ${featureType} for ${entityName}.`); + } + const isEnabledFunction = featureIsEnabledMap[featureType]; + if (!isEnabledFunction) { + throw new Error(`Attempted to access unavailable feature ${featureType} for ${entityName}.`); + } + return isEnabledFunction(scene); + } + + /** + * Enables or disables Jupiter's auroras. + * @param {Pioneer.Scene} scene + * @param {boolean} enable + */ + static setEnabledJupiterAuroras(scene, enable) { + if (enable) { + Features._createJupiterModelComponent(scene, 'auroras', 'auroras'); + } + else if (enable === false) { + scene.getEntity('jupiter').removeComponent('auroras'); + } + } + + /** + * Returns true if Jupiter's auroras are enabled. + * @param {Pioneer.Scene} scene + * @returns {boolean} + */ + static isEnabledJupiterAuroras(scene) { + return scene.getEntity('jupiter').getComponent('auroras') !== null; + } + + /** + * Enables or disables Jupiter's magnetosphere. + * @param {Pioneer.Scene} scene + * @param {boolean} enable + */ + static setEnabledJupiterMagnetosphere(scene, enable) { + if (enable) { + Features._createJupiterModelComponent(scene, 'magnetosphere', 'magnetosphere'); + } + else { + scene.getEntity('jupiter').removeComponent('magnetosphere'); + } + } + + /** + * Returns true if Jupiter's magnetosphere is enabled. + * @param {Pioneer.Scene} scene + * @returns {boolean} + */ + static isEnabledJupiterMagnetosphere(scene) { + return scene.getEntity('jupiter').getComponent('magnetosphere') !== null; + } + + /** + * Enables or disables Jupiter's radiation belt. + * @param {Pioneer.Scene} scene + * @param {boolean} enable + */ + static setEnabledJupiterRadiationBelt(scene, enable) { + if (enable) { + Features._createJupiterModelComponent(scene, 'radiation_belt_1', 'radbelt1'); + Features._createJupiterModelComponent(scene, 'radiation_belt_2', 'radbelt2'); + Features._createJupiterModelComponent(scene, 'radiation_belt_3', 'radbelt3'); + Features._createJupiterModelComponent(scene, 'radiation_belt_4', 'radbelt4'); + } + else { + const entity = scene.getEntity('jupiter'); + entity.removeComponent('radiation_belt_1'); + entity.removeComponent('radiation_belt_2'); + entity.removeComponent('radiation_belt_3'); + entity.removeComponent('radiation_belt_4'); + } + } + + /** + * Returns true if Jupiter's radiation belt is enabled. + * @param {Pioneer.Scene} scene + * @returns {boolean} + */ + static isEnabledJupiterRadiationBelt(scene) { + const entity = scene.getEntity('jupiter'); + return entity.getComponent('radiation_belt_1') !== null + && entity.getComponent('radiation_belt_2') !== null + && entity.getComponent('radiation_belt_3') !== null + && entity.getComponent('radiation_belt_4') !== null; + } + + /** + * Enables or disables Saturn's magnetosphere. + * @param {Pioneer.Scene} scene + * @param {boolean} enable + */ + static setEnabledSaturnMagnetosphere(scene, enable) { + if (enable) { + _entity__WEBPACK_IMPORTED_MODULE_1__.Entity.createFromOptions('saturn_magnetosphere', { + radius: 5027500, + parents: [ + [Number.NEGATIVE_INFINITY, 'saturn'] + ], + model: { + url: '$STATIC_ASSETS_URL/models/saturn/magnetosphere/saturn_magnetosphere.gltf', + scale: 1078.27002124, + rotate: [ + { x: 90 } + ] + }, + controllers: [{ + type: 'fixed', + position: pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero + }, { + type: 'align', + primary: { + type: 'align', + target: 'saturn', + axis: pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis, + targetAxis: pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis + }, + secondary: { + type: 'point', + target: 'sun', + axis: pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis + } + }], + postCreateFunction: (entity) => { + entity.setCanOcclude(false); + const thinModel = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent); + thinModel.setUrl('$STATIC_ASSETS_URL/models/saturn/magnetosphere_thin/saturn_magnetosphere_thin.gltf'); + thinModel.setScale(1078.27002124); + thinModel.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(Math.sqrt(0.5), Math.sqrt(0.5), 0, 0)); + thinModel.setPixelRadiusVisibleInterval(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(4000, Number.POSITIVE_INFINITY)); + thinModel.setResourcesLoadedCallback(() => { + thinModel.getThreeJsObjects()[0].renderOrder = -1; + }); + const thickModel = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent); + thickModel.setPixelRadiusVisibleInterval(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(0, 4000)); + thickModel.setResourcesLoadedCallback(() => { + thickModel.getThreeJsObjects()[0].renderOrder = -1; + }); + } + }, scene); + } + else { + scene.removeEntity('saturn_magnetosphere'); + } + } + + /** + * Returns true if Saturn's magnetosphere is enabled. + * @param {Pioneer.Scene} scene + * @returns {boolean} + */ + static isEnabledSaturnMagnetosphere(scene) { + return scene.getEntity('saturn_magnetosphere') !== null; + } + + /** + * Creates a Jupiter model. Returns the component created. + * @param {Pioneer.Scene} scene - the scene where the entity is. + * @param {string} name - the folder and component name. + * @param {string} fileName - the name of the file inbetween the jupiter_ and .gltf. + * @private + */ + static _createJupiterModelComponent(scene, name, fileName) { + const entity = scene.getEntity('jupiter'); + const model = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent, name); + model.setUrl(`$STATIC_ASSETS_URL/models/${'jupiter'}/${name}/${'jupiter'}_${fileName}.gltf`); + // Scale it, since the gltf uses a 100 km polar diameter model. + model.setScale(1337.08); + // Rotate the model to be in the right orientation. + const rotation1 = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(Math.SQRT1_2, Math.SQRT1_2, 0, 0); // 90 degrees around x-axis + const rotation2 = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(Math.SQRT1_2, 0, 0, Math.SQRT1_2); // 90 degrees around z-axis + rotation1.mult(rotation2, rotation1); + model.setRotation(rotation1); + } +} + +/** + * A entityName to featureType to setEnabled function map. + * @type {Record void>>} + * @private + */ +const entityFeatureSetEnabledMap = { + jupiter: { + auroras: Features.setEnabledJupiterAuroras, + magnetosphere: Features.setEnabledJupiterMagnetosphere, + radiationBelt: Features.setEnabledJupiterRadiationBelt + }, + saturn: { + magnetosphere: Features.setEnabledSaturnMagnetosphere + } +}; + +/** + * A entityName to featureType to isEnabled function map. + * @type {Record boolean>>} + * @private + */ +const entityFeatureIsEnabledMap = { + jupiter: { + auroras: Features.isEnabledJupiterAuroras, + magnetosphere: Features.isEnabledJupiterMagnetosphere, + radiationBelt: Features.isEnabledJupiterRadiationBelt + }, + saturn: { + magnetosphere: Features.isEnabledSaturnMagnetosphere + } +}; + + +/***/ }), + +/***/ "../pioneer/scripts/src/index.js": +/*!***************************************!*\ + !*** ../pioneer/scripts/src/index.js ***! + \***************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Cameras": function() { return /* reexport safe */ _cameras__WEBPACK_IMPORTED_MODULE_0__.Cameras; }, +/* harmony export */ "DateTime": function() { return /* reexport safe */ _date_time__WEBPACK_IMPORTED_MODULE_1__.DateTime; }, +/* harmony export */ "Entity": function() { return /* reexport safe */ _entity__WEBPACK_IMPORTED_MODULE_2__.Entity; }, +/* harmony export */ "Features": function() { return /* reexport safe */ _features__WEBPACK_IMPORTED_MODULE_3__.Features; }, +/* harmony export */ "Mapping": function() { return /* reexport safe */ _mapping__WEBPACK_IMPORTED_MODULE_4__.Mapping; }, +/* harmony export */ "Parenting": function() { return /* reexport safe */ _parenting__WEBPACK_IMPORTED_MODULE_5__.Parenting; }, +/* harmony export */ "Placemarks": function() { return /* reexport safe */ _placemarks__WEBPACK_IMPORTED_MODULE_6__.Placemarks; }, +/* harmony export */ "SceneHelpers": function() { return /* reexport safe */ _scene_helpers__WEBPACK_IMPORTED_MODULE_7__.SceneHelpers; }, +/* harmony export */ "Transitions": function() { return /* reexport safe */ _transitions__WEBPACK_IMPORTED_MODULE_8__.Transitions; }, +/* harmony export */ "AnnulusComponent": function() { return /* reexport safe */ _components_annulus_component__WEBPACK_IMPORTED_MODULE_9__.AnnulusComponent; }, +/* harmony export */ "CelestialGridComponent": function() { return /* reexport safe */ _components_celestial_grid_component__WEBPACK_IMPORTED_MODULE_10__.CelestialGridComponent; }, +/* harmony export */ "ConstellationsComponent": function() { return /* reexport safe */ _components_constellations_component__WEBPACK_IMPORTED_MODULE_11__.ConstellationsComponent; }, +/* harmony export */ "DiscGridComponent": function() { return /* reexport safe */ _components_disc_grid_component__WEBPACK_IMPORTED_MODULE_12__.DiscGridComponent; }, +/* harmony export */ "ShadowConeComponent": function() { return /* reexport safe */ _components_shadow_cone_component__WEBPACK_IMPORTED_MODULE_13__.ShadowConeComponent; }, +/* harmony export */ "OrbitLineComponent": function() { return /* reexport safe */ _components_orbit_line_component__WEBPACK_IMPORTED_MODULE_14__.OrbitLineComponent; }, +/* harmony export */ "TorusComponent": function() { return /* reexport safe */ _components_torus_component__WEBPACK_IMPORTED_MODULE_15__.TorusComponent; }, +/* harmony export */ "WMTSComponent": function() { return /* reexport safe */ _components_wmts_component__WEBPACK_IMPORTED_MODULE_16__.WMTSComponent; }, +/* harmony export */ "KeyframePointingController": function() { return /* reexport safe */ _controllers_keyframe_pointing_controller__WEBPACK_IMPORTED_MODULE_17__.KeyframePointingController; }, +/* harmony export */ "KeyframeSpinController": function() { return /* reexport safe */ _controllers_keyframe_spin_controller__WEBPACK_IMPORTED_MODULE_18__.KeyframeSpinController; }, +/* harmony export */ "PositionSumController": function() { return /* reexport safe */ _controllers_position_sum_controller__WEBPACK_IMPORTED_MODULE_19__.PositionSumController; }, +/* harmony export */ "ZoomFitController": function() { return /* reexport safe */ _controllers_zoom_fit_controller__WEBPACK_IMPORTED_MODULE_20__.ZoomFitController; } +/* harmony export */ }); +/* harmony import */ var _cameras__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./cameras */ "../pioneer/scripts/src/cameras.js"); +/* harmony import */ var _date_time__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./date_time */ "../pioneer/scripts/src/date_time.js"); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var _features__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./features */ "../pioneer/scripts/src/features.js"); +/* harmony import */ var _mapping__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./mapping */ "../pioneer/scripts/src/mapping.js"); +/* harmony import */ var _parenting__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./parenting */ "../pioneer/scripts/src/parenting.js"); +/* harmony import */ var _placemarks__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./placemarks */ "../pioneer/scripts/src/placemarks.js"); +/* harmony import */ var _scene_helpers__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./scene_helpers */ "../pioneer/scripts/src/scene_helpers.js"); +/* harmony import */ var _transitions__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./transitions */ "../pioneer/scripts/src/transitions.js"); +/* harmony import */ var _components_annulus_component__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/annulus_component */ "../pioneer/scripts/src/components/annulus_component.js"); +/* harmony import */ var _components_celestial_grid_component__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/celestial_grid_component */ "../pioneer/scripts/src/components/celestial_grid_component.js"); +/* harmony import */ var _components_constellations_component__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./components/constellations_component */ "../pioneer/scripts/src/components/constellations_component.js"); +/* harmony import */ var _components_disc_grid_component__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/disc_grid_component */ "../pioneer/scripts/src/components/disc_grid_component.js"); +/* harmony import */ var _components_shadow_cone_component__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./components/shadow_cone_component */ "../pioneer/scripts/src/components/shadow_cone_component.js"); +/* harmony import */ var _components_orbit_line_component__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./components/orbit_line_component */ "../pioneer/scripts/src/components/orbit_line_component.js"); +/* harmony import */ var _components_torus_component__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./components/torus_component */ "../pioneer/scripts/src/components/torus_component.js"); +/* harmony import */ var _components_wmts_component__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./components/wmts_component */ "../pioneer/scripts/src/components/wmts_component.js"); +/* harmony import */ var _controllers_keyframe_pointing_controller__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./controllers/keyframe_pointing_controller */ "../pioneer/scripts/src/controllers/keyframe_pointing_controller.js"); +/* harmony import */ var _controllers_keyframe_spin_controller__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./controllers/keyframe_spin_controller */ "../pioneer/scripts/src/controllers/keyframe_spin_controller.js"); +/* harmony import */ var _controllers_position_sum_controller__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./controllers/position_sum_controller */ "../pioneer/scripts/src/controllers/position_sum_controller.js"); +/* harmony import */ var _controllers_zoom_fit_controller__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./controllers/zoom_fit_controller */ "../pioneer/scripts/src/controllers/zoom_fit_controller.js"); +/* harmony import */ var _entities_planets_and_stars__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./entities/planets_and_stars */ "../pioneer/scripts/src/entities/planets_and_stars.js"); +/* harmony import */ var _entities_minor_planets__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./entities/minor_planets */ "../pioneer/scripts/src/entities/minor_planets.js"); +/* harmony import */ var _entities_comets__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./entities/comets */ "../pioneer/scripts/src/entities/comets.js"); +/* harmony import */ var _entities_earth_moon__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./entities/earth_moon */ "../pioneer/scripts/src/entities/earth_moon.js"); +/* harmony import */ var _entities_jupiter_regular_moons__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./entities/jupiter_regular_moons */ "../pioneer/scripts/src/entities/jupiter_regular_moons.js"); +/* harmony import */ var _entities_jupiter_irregular_moons__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./entities/jupiter_irregular_moons */ "../pioneer/scripts/src/entities/jupiter_irregular_moons.js"); +/* harmony import */ var _entities_mars_moons__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./entities/mars_moons */ "../pioneer/scripts/src/entities/mars_moons.js"); +/* harmony import */ var _entities_neptune_moons__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./entities/neptune_moons */ "../pioneer/scripts/src/entities/neptune_moons.js"); +/* harmony import */ var _entities_saturn_major_moons__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./entities/saturn_major_moons */ "../pioneer/scripts/src/entities/saturn_major_moons.js"); +/* harmony import */ var _entities_saturn_minor_moons__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./entities/saturn_minor_moons */ "../pioneer/scripts/src/entities/saturn_minor_moons.js"); +/* harmony import */ var _entities_uranus_major_moons__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./entities/uranus_major_moons */ "../pioneer/scripts/src/entities/uranus_major_moons.js"); +/* harmony import */ var _entities_uranus_minor_moons__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./entities/uranus_minor_moons */ "../pioneer/scripts/src/entities/uranus_minor_moons.js"); +/* harmony import */ var _entities_earth_spacecraft__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./entities/earth_spacecraft */ "../pioneer/scripts/src/entities/earth_spacecraft.js"); +/* harmony import */ var _entities_lunar_spacecraft__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./entities/lunar_spacecraft */ "../pioneer/scripts/src/entities/lunar_spacecraft.js"); +/* harmony import */ var _entities_mars_spacecraft__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./entities/mars_spacecraft */ "../pioneer/scripts/src/entities/mars_spacecraft.js"); +/* harmony import */ var _entities_mercury_spacecraft__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./entities/mercury_spacecraft */ "../pioneer/scripts/src/entities/mercury_spacecraft.js"); +/* harmony import */ var _entities_outer_planet_spacecraft__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./entities/outer_planet_spacecraft */ "../pioneer/scripts/src/entities/outer_planet_spacecraft.js"); +/* harmony import */ var _entities_small_body_spacecraft__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./entities/small_body_spacecraft */ "../pioneer/scripts/src/entities/small_body_spacecraft.js"); +/* harmony import */ var _entities_solar_spacecraft__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! ./entities/solar_spacecraft */ "../pioneer/scripts/src/entities/solar_spacecraft.js"); +/* harmony import */ var _entities_venus_spacecraft__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! ./entities/venus_spacecraft */ "../pioneer/scripts/src/entities/venus_spacecraft.js"); +/* harmony import */ var _entities_comparison__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! ./entities/comparison */ "../pioneer/scripts/src/entities/comparison.js"); +/** + * Interface to export classes from modules. + */ + + + + + + + + + + +// Components + + + + + + + + + +// Controllers + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/***/ }), + +/***/ "../pioneer/scripts/src/mapping.js": +/*!*****************************************!*\ + !*** ../pioneer/scripts/src/mapping.js ***! + \*****************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Mapping": function() { return /* binding */ Mapping; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); + + +/** + * Functions for enabling and disabling special features on entities. + */ +class Mapping { + /** + * Gets all possible mapping types for a given entity. + * @param {string} entityName + * @returns string[] + */ + static getTypes(entityName) { + return Mapping._types[entityName] ?? []; + } + + /** + * Sets the entity to use the mapping given by the type. + * @param {Pioneer.Scene} scene + * @param {string} entityName + * @param {string} type + */ + static async set(scene, entityName, type) { + // Enable the type and wait for it to be loaded. + await Mapping.setEnabled(scene, entityName, type, true); + // Disable all of the other non-matching types, including basic. + for (const otherType of Mapping.getTypes(entityName)) { + if (otherType !== type) { + Mapping.setEnabled(scene, entityName, otherType, false); + } + } + if (type !== 'basic') { + Mapping.setEnabled(scene, entityName, 'basic', false); + } + } + + /** + * Enables or disables the given type. Used as a mapping from the 'type' to actual functions. + * @param {Pioneer.Scene} scene + * @param {string} entityName + * @param {string} type + * @param {boolean} enabled + * @private + */ + static async setEnabled(scene, entityName, type, enabled) { + if (type === 'basic') { + Mapping.setBasic(scene, entityName, enabled); + } + else if (type.startsWith('cmts')) { + await Mapping.setCMTS(scene, entityName, type, enabled); + } + else { + throw new Error(`Invalid type ${type}.`); + } + } + + /** + * Sets the entity to use the basic spheroidLOD. + * @param {Pioneer.Scene} scene + * @param {string} entityName + * @param {boolean} enabled + * @returns {Promise} + * @private + */ + static async setBasic(scene, entityName, enabled) { + const entity = scene.getEntity(entityName); + if (entity === null) { + throw new Error(`No entity named '${entityName}' exists.`); + } + const spheroidLOD = entity.getComponent('basic'); + if (spheroidLOD === null || spheroidLOD.getType() !== 'spheroidLOD') { + throw new Error(`The entity '${entityName}' does not have a spheroidLOD named 'basic'.`); + } + spheroidLOD.setEnabled(enabled); + if (enabled) { + // Make it invisible, load it, and make it visible. + spheroidLOD.setVisible(false); + await spheroidLOD.getLoadedPromise(); + spheroidLOD.setVisible(true); + } + } + + /** + * Sets the entity to use CMTS. + * @param {Pioneer.Scene} scene + * @param {string} entityName + * @param {string} type + * @param {boolean} enabled + * @returns {Promise} + * @private + */ + static async setCMTS(scene, entityName, type, enabled) { + const entity = scene.getEntity(entityName); + if (entity === null) { + throw new Error(`No entity named '${entityName}' exists.`); + } + if (enabled && !entity.get('cmts')) { + const cmts = entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CMTSComponent, type); + if (entityName === 'mars') { + // Set the base urls. + cmts.setBaseUrl('color', '$DYNAMIC_ASSETS_URL/cmts/1/' + entityName + '/color'); + cmts.setBaseUrl('height', '$DYNAMIC_ASSETS_URL/cmts/1/' + entityName + '/height'); + // Set the tile offsets for certain sites. + cmts.addTileOffset(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(700.6128653358727, 3140.020080650305, 1073.622947405036), 1, 12, 1585, 2747, 1592, 2752); // M20 + cmts.addTileOffset(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(-2489.8644947661123, 2286.2056005322775, -271.3458260440484), 2, 12, 158, 1811, 169, 1825); // MSL + cmts.addTileOffset(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(-2432.935716315694, 2349.9743692542434, 267.129381207100), 2, 9, 8, 284, 8, 284); // InSight + } + else if (entityName === 'moon') { + // Set the base urls. + cmts.setBaseUrl('color', '$DYNAMIC_ASSETS_URL/cmts/' + entityName + '/color'); + cmts.setBaseUrl('normal', '$DYNAMIC_ASSETS_URL/cmts/' + entityName + '/normal'); + cmts.setBaseUrl('height', '$DYNAMIC_ASSETS_URL/cmts/' + entityName + '/height'); + } + // Make it invisible, load it, and make it visible. + cmts.setVisible(false); + await cmts.getLoadedPromise(); + await cmts.getTilesLoadedPromise(); + cmts.setVisible(true); + } + else if (!enabled && entity.get('cmts')) { + entity.removeComponent(entity.getComponentByType('cmts')); + } + } + + /** + * @type {Object} + * @private + */ + static _types = { + mars: ['cmts'] + }; +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/parenting.js": +/*!*******************************************!*\ + !*** ../pioneer/scripts/src/parenting.js ***! + \*******************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Parenting": function() { return /* binding */ Parenting; } +/* harmony export */ }); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./entity */ "../pioneer/scripts/src/entity.js"); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); + + + +/** + * Parenting helper functions. + */ +class Parenting { + + /** + * Gets the parent of the entity at the given time. + * @param {string} entityName + * @param {number} time + * @returns {string} + */ + static getParentOfEntity(entityName, time) { + const entityOptions = _entity__WEBPACK_IMPORTED_MODULE_0__.Entity.getEntityOptions(entityName); + if (entityOptions === undefined) { + throw new Error(`There are no entity options for ${entityName}.`); + } + const parents = entityOptions.parents; + const index = pioneer__WEBPACK_IMPORTED_MODULE_1__.Sort.getIndex(time, parents, isStartTimeLessThanTime); + + if (index < parents.length && time === parents[index][0]) { + return parents[index][1]; + } + else if (index > 0) { + return parents[index - 1][1]; + } + else { + return ''; + } + } + + /** + * Gets all of the ancestors of an entity for all times. + * @param {string} entityName - The name of the entity. + * @returns {Set} + */ + static getAllAncestorsOfEntity(entityName) { + const parents = new Set(); + this._getAllAncestorsOfEntityRecursed(entityName, parents); + return parents; + } + + /** + * Gets all of the ancestors of an entity for all times. + * @param {string} entityName - The name of the entity. + * @param {Set} parents - The parents set that will be added to. + * @private + */ + static _getAllAncestorsOfEntityRecursed(entityName, parents) { + const entityOptions = _entity__WEBPACK_IMPORTED_MODULE_0__.Entity.getEntityOptions(entityName); + if (entityOptions === undefined || entityOptions.parents === undefined) { + return; + } + const parentTable = entityOptions.parents; + for (const parentEntry of parentTable) { + const parentName = parentEntry[1]; + if (!parents.has(parentName)) { + parents.add(parentName); + this._getAllAncestorsOfEntityRecursed(parentName, parents); + } + } + } +} + +/** + * Returns true if a < b. + * @param {[number, string]} a + * @param {number} b + */ +function isStartTimeLessThanTime(a, b) { + return a[0] < b; +} + + +/***/ }), + +/***/ "../pioneer/scripts/src/placemarks.js": +/*!********************************************!*\ + !*** ../pioneer/scripts/src/placemarks.js ***! + \********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Placemarks": function() { return /* binding */ Placemarks; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * Helpful functions for placing markers on a spheroid. + * @hideconstructor + */ +class Placemarks { + /** + * Adds a placemark on an entity and returns it. + * @param {string} name - The name of the placemark entity. + * @param {string} label - The label to be displayed. + * @param {Pioneer.Entity} body - The entity on which the placemark will go. + * @param {number} latInDeg - The latitude in degrees. + * @param {number} lonInDeg - The longitude in degrees. + * @param {number} altitudeInKm - The altitude in km. + * @param {boolean} useOrientation - If true, orients the placemark entity to be along the east and north axes. + * @returns {Pioneer.Entity} + */ + static addPlacemark(name, label, body, latInDeg, lonInDeg, altitudeInKm, useOrientation = false) { + const placemark = body.getScene().addEntity(name); + placemark.setParent(body); + placemark.setCanOcclude(false); + placemark.setExtentsRadius(1); + + const divComponent = placemark.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.DivComponent); + divComponent.setAlignment(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(0.5, 0.5)); + divComponent.getDiv().innerHTML = label; + + placemark.addController('fixed'); + placemark.addController('rotateByEntityOrientation'); + + this.updateLLA(placemark, latInDeg, lonInDeg, altitudeInKm, useOrientation); + + return placemark; + } + + /** + * Updates a placemark with a new location. + * @param {Pioneer.Entity} placemark - The placemark to change. + * @param {number} latInDeg - The latitude in degrees. + * @param {number} lonInDeg - The longitude in degrees. + * @param {number} altitudeInKm - The altitude in km. + * @param {boolean} useOrientation - If true, orients the placemark entity to be along the east and north axes. + */ + static updateLLA(placemark, latInDeg, lonInDeg, altitudeInKm, useOrientation = false) { + const body = placemark.getParent(); + const fixedController = placemark.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.FixedController); + const spheroidComponent = body.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent); + if (fixedController === null || spheroidComponent === null) { + throw new Error('No fixed controller and/or spheroid component.'); + } + + const lla = pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + const markPos = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + + // Update the position using the given lat, lon, alt, and the spheroid. + lla.set(pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(latInDeg), pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(lonInDeg), altitudeInKm); + spheroidComponent.xyzFromLLA(markPos, lla); + fixedController.setPosition(markPos); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(markPos); + + // If we're setting the orientation, use the east and north of the location on the spheroid. + if (useOrientation) { + const markOri = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + const east = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const north = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + spheroidComponent.eastFromLLA(east, lla); + spheroidComponent.northFromLLA(north, lla); + markOri.setFromAxes(east, north, undefined); + fixedController.setOrientation(markOri); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(east); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(north); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(markOri); + } + + pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + } +}; + + +/***/ }), + +/***/ "../pioneer/scripts/src/scene_helpers.js": +/*!***********************************************!*\ + !*** ../pioneer/scripts/src/scene_helpers.js ***! + \***********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "SceneHelpers": function() { return /* binding */ SceneHelpers; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/* harmony import */ var _entity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./entity */ "../pioneer/scripts/src/entity.js"); +/** @module pioneer-scripts */ + + + +/** + * Helpful utilities for scenes. + * @hideconstructor + */ +class SceneHelpers { + /** + * The transformation from EclipJ2000 (a SPICE frame) to J2000 coordinates. This is the tilt from the equator to the ecliptic. + * @returns {Pioneer.Quaternion} + */ + static getEclipJ2000ToJ2000Rotation() { + return this.eclipJ2000ToJ2000Rotation; + } + + /** + * This returns a promise that resolves when all of the entities in `entityNames` have non-NaN positions and orientations. + * For entities that aren't covered in the current time, they count as immediately valid. + * @param {Pioneer.Scene} scene - the scene where the entities are + * @param {string[]} entityNames - the set of names of entities to be checked + * @param {number} [time] - an optional time to use + * @param {number} [timeout = 5.0] - the number of seconds to wait until the promise is rejected + * @param {number} [frequency = 0.030] - the number of seconds to wait before checking the positions and orientations again + * @returns {Promise} + */ + static async waitTillEntitiesInPlace(scene, entityNames, time = undefined, timeout = 5.0, frequency = 0.030) { + // Get the set of entities from the set of entity names. + const entities = /** @type {Set} */(new Set()); + for (const entityName of entityNames) { + const entity = scene.getEntity(entityName); + if (entity === null) { + throw new Error('Entity "' + entityName + '" not added yet. Use Entity.create to add the entity.'); + } + entities.add(entity); + } + + // Wait on the promises of all controllers of every entity. + const controllerPromises = []; + for (const entity of entities) { + for (let i = 0; i < entity.getNumControllers(); i++) { + controllerPromises.push(entity.getController(i).getLoadedPromise()); + } + } + await Promise.all(controllerPromises); + + // If there was no time, set it to the current time. + if (time === undefined) { + time = scene.getEngine().getTime(); + } + + // Check the entities' positions and orientations every `frequency` seconds. + return new Promise((resolve, reject) => { + let timeSoFar = 0; + const intervalCheck = setInterval(() => { + // Check each entity in the list to see if is either not covered or has valid position and orientation. + // If so, remove it from the list. + const position = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const orientation = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + for (const entity of entities) { + const isInCoverage = entity.getPositionCoverage().contains(time); + entity.getPositionAtTime(position, time); + entity.getOrientationAtTime(orientation, time); + const inPlace = !position.isNaN() && !orientation.isNaN(); + if (!isInCoverage || inPlace) { + entities.delete(entity); + } + } + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + // If there are no more entities in the list, resolve. + if (entities.size === 0) { + clearInterval(intervalCheck); + resolve(); + } + // If we've hit the timeout, reject. + timeSoFar += frequency; + if (timeSoFar >= timeout) { + clearInterval(intervalCheck); + let entitiesAsString = ''; + for (const entity of entities) { + if (entitiesAsString !== '') { + entitiesAsString += ', '; + } + entitiesAsString += '\'' + entity.getName() + '\''; + } + reject(new Error('Timed out (' + timeout + ' seconds) while waiting for entities to be in place. The remaining entities were [' + entitiesAsString + '].')); + } + }, frequency * 1000.0); + }).then(() => scene.getEngine().waitUntilNextFrame()); + } + + /** + * Converts a lat, lon, alt into an xyz, with the xyz in either the standard J2000 or entity frame. + * @param {Pioneer.Vector3} out + * @param {Pioneer.Entity} entity + * @param {Pioneer.LatLonAlt} lla + * @param {boolean} inEntityFrame + */ + static llaToXYZ(out, entity, lla, inEntityFrame) { + const spheroid = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent); + if (spheroid !== null) { + spheroid.xyzFromLLA(out, lla); + if (!inEntityFrame) { + out.rotate(entity.getOrientation(), out); + } + } + } + + /** + * Converts an xyz to a lat, lon, alt, with the xyz in either the standard J2000 or entity frame. + * @param {Pioneer.LatLonAlt} out + * @param {Pioneer.Entity} entity + * @param {Pioneer.Vector3} xyz + * @param {boolean} inEntityFrame + */ + static xyzToLLA(out, entity, xyz, inEntityFrame) { + const spheroid = entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent); + if (spheroid !== null) { + const xyzInFrame = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (inEntityFrame) { + xyzInFrame.copy(xyz); + } + else { + xyzInFrame.rotateInverse(entity.getOrientation(), xyz); + } + spheroid.llaFromXYZ(out, xyzInFrame); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(xyzInFrame); + } + } + + /** + * Gets all of the other entities that the named entity is dependent upon, including all ancestors. + * @param {string} entityName - The name of the entity. + * @returns {Set} + */ + static getDependentEntities(entityName) { + const others = /** @type {Set} */(new Set()); + this._getDependentEntitiesRecursed(entityName, others); + others.delete(entityName); + return others; + } + + /** + * Recursive function for getDependentEntities(). + * @param {string} entityName - The name of the entity. + * @param {Set} others - The parents set that will be added to. + * @private + */ + static _getDependentEntitiesRecursed(entityName, others) { + const entityOptions = _entity__WEBPACK_IMPORTED_MODULE_1__.Entity.getEntityOptions(entityName); + if (entityOptions === undefined) { + return; + } + const otherEntityNames = /** @type {Set} */(new Set()); + // Get all parents. + const parentTable = entityOptions.parents; + for (const parentEntry of parentTable) { + if (parentEntry[1] !== '') { + otherEntityNames.add(parentEntry[1]); + } + } + // Check for other relations. + if (entityOptions.lightSource !== undefined) { + otherEntityNames.add(entityOptions.lightSource); + } + if (entityOptions.trail !== undefined && entityOptions.trail.relativeTo !== undefined) { + otherEntityNames.add(entityOptions.trail.relativeTo); + } + for (let i = 0, l = entityOptions.controllers.length; i < l; i++) { + const controllerOptions = entityOptions.controllers[i]; + if (controllerOptions.type === 'align') { + if (controllerOptions.primary.target !== undefined) { + otherEntityNames.add(controllerOptions.primary.target); + } + if (controllerOptions.secondary !== undefined && controllerOptions.secondary.target !== undefined) { + otherEntityNames.add(controllerOptions.secondary.target); + } + } + } + if (entityOptions.labelFadeEntity) { + otherEntityNames.add(entityOptions.labelFadeEntity); + } + // Go through any other dependent entities. + if (entityOptions.dependents) { + for (let i = 0, l = entityOptions.dependents.length; i < l; i++) { + otherEntityNames.add(entityOptions.dependents[i]); + } + } + // Go through each entity found and recursively get its dependencies. + for (const otherEntityName of otherEntityNames) { + if (!others.has(otherEntityName)) { + others.add(otherEntityName); + this._getDependentEntitiesRecursed(otherEntityName, others); + } + } + } +} + +SceneHelpers.eclipJ2000ToJ2000Rotation = new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(0.9791532214288992, 0.2031230389823101, 0, 0); +SceneHelpers.eclipJ2000ToJ2000Rotation.freeze(); + + +/***/ }), + +/***/ "../pioneer/scripts/src/transitions.js": +/*!*********************************************!*\ + !*** ../pioneer/scripts/src/transitions.js ***! + \*********************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Transitions": function() { return /* binding */ Transitions; } +/* harmony export */ }); +/* harmony import */ var pioneer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pioneer */ "../pioneer/engine/src/index.js"); +/** @module pioneer-scripts */ + + +/** + * Helpful custom transition functions to use with the Transition controller. + * @hideconstructor + */ +class Transitions { + /** + * A function which the transition controller will use that will jump from one position on a sphere to another position. + * It uses the z-axis for rotation. For how it works, see the bottom of the file. + * To use this function, do `transitionController.setTransitionFunction(jumpToLocationOnSphere.bind(undefined, 5, 1e4, true, earth))`. + * @param {number} jumpFactor - The height at which the camera will "bounce". A good number is 5. + * @param {number} radius - The "ground" radius to use when calculating the jump. + * @param {boolean} useNorthPole - The camera will use the north pole when rotating around its parent. + * @param {Pioneer.Entity} sphereEntity - The entity to use as the sphere and north pole reference. If undefined, the camera entity's parent is used. + * @param {Pioneer.Entity} cameraEntity - The camera entity. + * @param {Pioneer.Vector3} initialPosition - The initial position of the camera. + * @param {Pioneer.Vector3} finalPosition - The final position of the camera. + * @param {Pioneer.Quaternion} initialOrientation - The initial orientation of the camera. + * @param {Pioneer.Quaternion} finalOrientation - The final orientation of the camera. + * @param {number} u - The lerp parameter. + */ + static jumpToLocationOnSphere(jumpFactor, radius, useNorthPole, sphereEntity, cameraEntity, initialPosition, finalPosition, initialOrientation, finalOrientation, u) { + // If the jump factor is zero, it won't work, so make it a very small number. + if (jumpFactor <= 0) { + jumpFactor = 0.001; + } + + // Make the transition a little bit smoother. + u = Transitions.easeInOut(u); + + // Get the radius of the parent of the camera entity. + if (sphereEntity === undefined) { + sphereEntity = cameraEntity.getParent(); + } + + // Make the initial and final position relative to the sphere entity. + const initialPositionRel = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const finalPositionRel = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (cameraEntity.getParent() !== null) { + cameraEntity.getParent().getPositionRelativeToEntity(initialPositionRel, initialPosition, sphereEntity); + cameraEntity.getParent().getPositionRelativeToEntity(finalPositionRel, finalPosition, sphereEntity); + } + else { + initialPositionRel.copy(initialPosition); + finalPositionRel.copy(finalPosition); + } + + // Get the radial variables that will be used in the calculations. + const r0 = initialPositionRel.magnitude() - radius; // The radial distance of the initial position. + const r1 = finalPositionRel.magnitude() - radius; // The radial distance of the final position. + + // Get the axis that will be used in both north pole and no-up transitions. + const axisVec = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + if (useNorthPole && sphereEntity) { + sphereEntity.getOrientation().getAxis(axisVec, 2); + } + else { + axisVec.cross(initialPositionRel, finalPositionRel); + } + axisVec.normalize(axisVec); + if (axisVec.isZero()) { + axisVec.set(0, 0, 1); + } + + // Get the angular distance between the points. + let a0 = 0; + // Get the p0 and p1 coordinates as (lon, lat, alt), but as a Vector3. + const p0 = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const p1 = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const frame = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + frame.setFromAxis(axisVec, 2); + p0.rotateInverse(frame, initialPositionRel); + p1.rotateInverse(frame, finalPositionRel); + // Get the lla0 and lla1 coordinates from the p0 and p1. + const lla0 = pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + const lla1 = pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLLAFromXYZOnSphere(lla0, p0, 0); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLLAFromXYZOnSphere(lla1, p1, 0); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(p1); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(p0); + // Get the a0 value that will be used in the _jumpOnCircle function. + // It's a distance value based on the latitude and longitude. + let lon0 = lla0.lon * Math.cos(lla0.lat); + let lon1 = lla1.lon * Math.cos(lla1.lat); + if (lon0 + Math.PI < lon1) { + lon0 += 2.0 * Math.PI; + } + if (lon1 + Math.PI < lon0) { + lon1 += 2.0 * Math.PI; + } + a0 = radius * jumpFactor * Math.sqrt((lon1 - lon0) * (lon1 - lon0) + (lla1.lat - lla0.lat) * (lla1.lat - lla0.lat)); + + // Call the _jumpOnCircle function to get the a and r values used to set the new position. + const p = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get(); + Transitions._jumpOnCircle(p, a0, r0, r1, u); + const a = p.x; + const r = p.y; + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(p); + + // Get the new position based on the new r and a. + const newPosition = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + newPosition.normalize(initialPositionRel); + newPosition.mult(newPosition, r + radius); + const lla = pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get(); + // Get a lerp value f of the angular distance. + let f; + if (a0 !== 0) { + f = (a0 - a) / a0; + } + else { + f = 0; + } + // Get the new lat, lon, alt position. + lla.lat = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(lla0.lat, lla1.lat, f); + lla.lon = pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerpAngle(lla0.lon, lla1.lon, f); + lla.alt = r; + // Convert it to the x, y, z position. + pioneer__WEBPACK_IMPORTED_MODULE_0__.Geometry.getXYZFromLLAOnSphere(newPosition, lla, radius); + newPosition.rotate(frame, newPosition); + pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla); + pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla0); + pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla1); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(frame); + + // Set the position. + if (newPosition.isNaN()) { + newPosition.copy(finalPositionRel); + } + if (cameraEntity.getParent() !== null) { + sphereEntity.getPositionRelativeToEntity(newPosition, newPosition, cameraEntity.getParent()); + } + cameraEntity.setPosition(newPosition); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(axisVec); + + // Make the camera always look at the parent, up aligned with the north pole axis or camera axis. + const position = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + sphereEntity.getPositionRelativeToEntity(position, pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero, cameraEntity); + position.normalize(position); + const up = pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get(); + const orientation = pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get(); + if (useNorthPole) { + sphereEntity.getOrientation().getAxis(up, 2); + } + else { + orientation.slerp(initialOrientation, finalOrientation, u); + orientation.getAxis(up, 2); + } + up.setNormalTo(position, up); + orientation.setFromAxes(undefined, position, up); + cameraEntity.setOrientation(orientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(up); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(initialPositionRel); + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(finalPositionRel); + } + + /** + * Does a quadratic ease-in and ease-out of the u parameter. + * @param {number} u + * @returns {number} + */ + static easeInOut(u) { + const sq = u * u; + return sq / (2 * (sq - u) + 1); + } + + /** + * Given two coordinates p0 = (a0, r0) and p1 = (0, r1), and a lerp value u, return a new coordinate (a, r) along the jump path. + * @param {Pioneer.Vector2} out - The result vector, x = a, y = r. + * @param {number} a0 - The initial angular distance. + * @param {number} r0 - The initial radial distance. + * @param {number} r1 - The final radial distance. + * @param {number} u - The lerp value. + * @private + */ + static _jumpOnCircle(out, a0, r0, r1, u) { + // If the angle is not 0... + let r = 0; // The radial distance to set. + let a = 0; // The angular distance to set. + if (Math.abs(a0 / (r1 - r0)) > 1e-6) { + // Get the center angular coordinate. + const aC = (r1 - r0) / -a0 * (r1 + r0) / 2 + a0 / 2; + // Get the angle between aC-a0 and aC-a1 + const anglep1pcp0pc = Math.sign(a0) * Math.acos((r0 * r1 + (a0 - aC) * (-aC)) / Math.sqrt(r0 * r0 + (a0 - aC) * (a0 - aC)) / Math.sqrt(r1 * r1 + aC * aC)); + // Get the cos and sin values of u, scaled so that 0 is at p0 and 1 is at p1. + const cosU = Math.cos(u * anglep1pcp0pc); + const sinU = Math.sin(u * anglep1pcp0pc); + // Calculate the new p value, going along the circle. + r = (a0 - aC) * sinU + r0 * cosU; + a = aC + (a0 - aC) * cosU - r0 * sinU; + } + // If the angle is 0, just lerp the radial and angular distance. + else { + r = u * r1 + (1 - u) * r0; + a = (1 - u) * a0; + } + // Make it exact at the end to fix precision errors. + if (u === 1) { + r = r1; + a = 0; + } + out.set(a, r); + } +} + +/* Notes on how _jumpOnCircle works. + +The radius of the parent of the camera is R. +The initial and final positions are mapped onto cartesian plane: + The x-axis is the angular distance between them. + The y-axis is the radial distances of the points. + The initial position p0 is at coordinates (a0, r0). + The final position p1 is at coordinates (0, r1). +A line segment l is drawn from p0 to p1, and the midpoint on that line is pM. +A line lP starting from pM and perpendicular to l is drawn. +The point at which lP intersects the x-axis is pC, with coordinates (aC, 0). +A circle O is formed, with center at pC and two points on the circle, p0 and p1. +The circle O is the path along which the camera will travel. +The jumpFactor * R of the entity is multiplied to stretch out the coordinates system horizontally. + +*/ + + +/***/ }), + +//JSON Modules + +/***/ "./src/configs/scene_info.json": +/*!*************************************!*\ + !*** ./src/configs/scene_info.json ***! + \*************************************/ +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse('{\ + "zoomMax":12000000000,\ + "dynamicEntityGroups":[\ + "spacecraft"\ + ],\ + "staticEntityGroups":[\ + "moons",\ + "stars",\ + "planets",\ + "dwarf planets"\ + ],\ + "staticEntities":[\ + "moon",\ + "sc_osiris_rex",\ + "sc_lucy",\ + "sc_psyche",\ + "sc_deep_impact",\ + "sc_deep_impact_impactor",\ + "sc_deep_space_1",\ + "sc_near_shoemaker",\ + "sc_stardust",\ + "sc_stardust_src",\ + "sc_dawn",\ + "sc_rosetta",\ + "sc_galileo",\ + "sc_philae",\ + "sc_dart",\ + "sc_new_horizons",\ + "sc_chandra"\ + ],\ + "title":{\ + "prefix":"Eyes on Asteroids",\ + "suffix":"NASA/JPL"\ + }\ +}'); + +/***/ }), + +/***/ "./src/configs/story_info.json": +/*!*************************************!*\ + !*** ./src/configs/story_info.json ***! + \*************************************/ +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse('[{"title":"Asteroids 101","path":"asteroids_101","questions":["What are asteroids?","What does this app show me?"]},{"title":"Close Approaches","path":"asteroids_close_approach","questions":["What is a close approach?","Are we in danger of impact?"]},{"title":"Missions","path":"asteroids_missions","questions":["Can we visit an asteroid?","What can missions achieve?"]}]'); + +/***/ }), + +/***/ "./src/configs/time_info.json": +/*!************************************!*\ + !*** ./src/configs/time_info.json ***! + \************************************/ +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse('{"limits":{"min":"1990-01-01T00:00:00Z","max":"2034-01-01T00:00:00Z"}}'); + +/***/ }), + +/***/ "./src/configs/view_info.json": +/*!************************************!*\ + !*** ./src/configs/view_info.json ***! + \************************************/ +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse('[\ + {\ + "class":"HomeView",\ + "name":"home",\ + "components":[\ + "breadcrumb",\ + "clock",\ + "clockShortcut"\ + ]\ + },\ + {\ + "class":"AsteroidView",\ + "name":"asteroid",\ + "components":[\ + "breadcrumb",\ + "clock",\ + "clockShortcut",\ + "asteroidPanel",\ + "loadIcon"\ + ]\ + },\ + {\ + "class":"WatchView",\ + "name":"watch",\ + "components":[\ + "watchPanel",\ + "breadcrumb",\ + "clock",\ + "clockShortcut"\ + ]\ + },\ + {\ + "class":"MissionView",\ + "name":"mission",\ + "components":[\ + "breadcrumb",\ + "clock",\ + "clockShortcut",\ + "missionPanel",\ + "loadIcon"\ + ]\ + },\ + {\ + "class":"FollowingView",\ + "name":"following",\ + "components":[\ + "breadcrumb",\ + "clock",\ + "clockShortcut",\ + "followingPanel",\ + "loadIcon",\ + "definitionOverlay"\ + ]\ + },\ + {\ + "class":"StoryView",\ + "name":"story",\ + "components":[\ + "clock",\ + "breadcrumb",\ + "story",\ + "overlay",\ + "definitionOverlay"\ + ]\ + }\ +]'); + +/***/ }), + +/***/ "./src/data/definitions.json": +/*!***********************************!*\ + !*** ./src/data/definitions.json ***! + \***********************************/ +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse('{"asteroid":{"title":"Asteroid","html":"

      Sometimes called minor planets, asteroids are rocky, airless remnants left over from the early formation of our solar system about 4.6 billion years ago.

      Most of this ancient space rubble can be found orbiting the Sun between Mars and Jupiter within the main asteroid belt.

      Unlike comets, asteroids remain solid under extreme temperatures; this is due to their formation in the high heat, high density center of the solar nebula.

      Deep Dive into Asteroids 101
      ","related":["comet"]},"comet":{"title":"Comet","html":"

      Comets are frozen leftovers from the formation of the solar system composed of dust, rock, and ice. They range from a few kilometers, to hundreds of kilometers wide.

      As they orbit closer to the Sun, they heat up and spew gases and dust into a glowing head that can be larger than a planet. This material forms a tail that stretches millions of kilometers.

      Unlike asteroids, comets formed in areas of the solar nebula where it was cold enough for water and gases to freeze. Consequently, they are larger and rarer than asteroids, and tend to originate in the far reaches of the solar system.

      ","related":["asteroid"]},"neo":{"title":"NEO","html":"
      Near-Earth object

      A near-Earth object is any small solar system body whose orbit brings it within a certain distance of Earth. This distance is defined by having the closest approach to the sun, the perihelion, be within 1.3 AU

      A sub-category of the NEO is the PHO.

      ","related":["perihelion","au","pho"]},"pho":{"title":"PHO","html":"
      Potentially Hazardous Object

      To be defined as potentially hazardous, an object must be:

      • Larger than 150 meters (almost 500 feet), roughly twice as big as the Statue of Liberty is tall.
      • Approach Earth\'s orbit to within about 7.5 million kilometers (4.6 million miles). This can also be expressed as having a MOID of less than 0.05 AU (within 19.5 LDs).

      PHOs can be both asteroids and comets, but the vast majority are asteroids. Learn more about the PHO, Apophis below.

      Deep Dive into Close Approaches
      ","related":["asteroid","comet","moid","au","ld"]},"aphelion":{"title":"Aphelion","html":"

      The aphelion is the point in the orbit of an object at which it is farthest from the sun.

      The opposite case is called the perihelion.

      ","related":["perihelion"]},"perihelion":{"title":"Perihelion","html":"

      The perihelion is the point in the orbit of an object at which it is closest to the sun.

      The opposite case is called the aphelion.

      ","related":["aphelion"]},"moid":{"title":"MOID","html":"
      Minimum Orbit Intersection Distance

      The MOID is the minimum distance between the orbits of two objects. It indicates the closest possible approach of two objects to each other.

      For Earth, an object with a MOID of less than or equal to 0.05 AU is considered a possible Potentially Hazardous Object if it\'s large enough.

      ","related":["au","pho"]},"oumuamua":{"title":"Oumuamua","html":"
      First interstellar object

      Discovered on October 19, 2017, Oumuamua is unlike any asteroid previously observed.

      Although we don’t have a picture, its unusually shiny surface reflects sunlight with a variation factor of 10. This suggest a severely elongated shape, 5 to 10 times larger than its width. Along with its rapid speed and high eccentricity, it was determined to be of interstellar origin.

      Passing Earth on October 14, 2017 at approximately 0.1618 AU, Oumuamua is now exiting our solar system, unlikely to ever return.

      ","related":["au"]},"au":{"title":"AU","html":"
      Astronomical Unit

      An AU is defined as exactly 92,955,807.273 miles (149,597,871 kilometers), or roughly the distance between the Earth and the Sun.

      Jupiter orbits at about 5.2 times the Sun-Earth distance, so Jupiter’s distance from the Sun can be expressed as 5.2 AU.

      1 AU is equivalent to 389,174 LDs.

      ","related":["moid","ld"]},"ld":{"title":"LD","html":"
      Lunar Distance

      A lunar distance is defined exactly as 384,398 kilometers (238,854 miles); the average distance between the centers of the Earth and the Moon.

      More technically, it\'s the length of the semi-major axis of the geocentric lunar orbit.

      1 LD is equivalent to about 0.00257 AU.

      ","related":["au"]}}'); + +/***/ }), + +/***/ "./src/data/heroes.json": +/*!******************************!*\ + !*** ./src/data/heroes.json ***! + \******************************/ +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse('{"99942_apophis":{"stats":{"discovery":"

      Discovered on June 19, 2004 at the Kitt Peak National Observatory in Arizona.

      ","rotation":30.4},"approach":{"fact":"

      On April 13, 2029, the asteroid Apophis will pass less than 23,239 miles (37,399 kilometers) from our planet’s surface – just outside the distance of geosynchronous satellites, and closer to Earth than any similarly sized PHO in recorded history. At that time, Apophis will be visible to observers on the ground in the Eastern Hemisphere without the aid of a telescope or binoculars.

      "}},"4_vesta":{"stats":{"discovery":"

      One of the largest and earliest known asteroids, Vesta was discovered on March 29th, 1807, and was visited by the Dawn mission in 2011.

      ","rotation":5.342}},"433_eros":{"stats":{"discovery":"

      Discovered on August 13th, 1898, Eros was the first near-Earth Object (NEO) ever found, and the first asteroid ever orbited by a spacecraft, NEAR-Shoemaker.

      ","rotation":5.27},"approach":{"fact":"

      Eros will approach Earth within 0.39765 AU on November 30th, 2025.

      "}},"951_gaspra":{"stats":{"discovery":"

      Discovered in 1916, Gaspra is the first asteroid to be closely approached by a spacecraft, which was Galileo in 1991.

      ","rotation":7.042}},"243_ida":{"stats":{"discovery":"

      Discovered in 1884, Ida was visited by the Galileo spacecraft in August of 1993.

      ","rotation":4.634}},"81p_wild_2":{"stats":{"discovery":"

      This comet was discovered on January 6th, 1978, and was visited by the Stardust mission in January of 2004.

      "}},"9p_tempel_1":{"stats":{"discovery":"

      Discovered in 1867, comet Tempel 1 was the target of the Deep Impact mission, which physically collided with the comet on July 4th, 2005.

      ","rotation":40.7}},"21_lutetia":{"stats":{"discovery":"

      Discovered in 1852, the asteroid was visited by the European space probe Rosetta in July of 2010.

      ","rotation":8.1655}},"67p_churyumov_gerasimenko":{"stats":{"discovery":"

      Discovered in 1969, this comet was the first to be landed upon by a robotic mission from Earth, the European Space Agency\'s Rosetta mission. The Philae lander touched down in November of 2014.

      ","rotation":12.76},"approach":{"fact":"

      The comet approached Earth within 0.418 AU on November 12th, 2021, and then will approach again in November of 2034 at a distance of 0.4523 AU.

      "}},"1_ceres":{"stats":{"discovery":"

      Discovered in January of 1801, Ceres was the first asteroid ever found, though it was initially classified as a planet. It remained an asteroid until 2006, when it was reclassified as a dwarf planet.

      ","rotation":9.0741}},"101955_bennu":{"stats":{"discovery":"

      Discovered in September of 1999, Bennu was the subject of the OSIRIS-REx mission, which touched down on the asteroid and collected a sample of the surface on October 20th, 2020. OSIRIS-REx departed Bennu in 2021, and delivered the capsule with pieces of the asteroid to Earth on September 24, 2023.

      ","rotation":4.296},"approach":{"fact":"

      Bennu is a PHO, and will have multiple close approaches with Earth over time. The next close approach will be in 2023, at a distance of 0.497 AU

      "}},"103p_hartley_2":{"stats":{"discovery":"

      Discovered in 1986, Comet Hartley 2 was the target of the Deep Impact/EPOXI mission, which flew by in November of 2010.

      ","rotation":18.1},"approach":{"fact":"

      103p/Hartley 2 is classified as an NEO, and will approach Earth within 0.3826 AU on September 26th, 2023.

      "}},"25143_itokawa":{"stats":{"discovery":"

      Discovered in 1998, Itokawa was the first asteroid to be the target of a sample return mission. The Japanese space probe Hayabusa took a sample from the comet in November of 2005.

      ","rotation":12.132},"approach":{"fact":"

      Itokawa is classified as a PHO, and will next approach the Earth on March 6th, 2030, at a distance of 0.376 AU.

      "}},"16_psyche":{"stats":{"discovery":"

      Discovered in 1852, the Psyche asteroid is the subject of the upcoming Psyche mission which will launch no earlier than 2023.

      ","rotation":4.196}},"65803_didymos":{"stats":{"discovery":"

      Discovered in 1996, Didymos is part of a binary asteroid system with its smaller partner, Dimorphos. The DART mission targeted this system, successfully crashing a probe into Dimorphos on September 26th, 2022.

      ","rotation":2.2593},"approach":{"fact":"

      Didymos is a PHO, and approached Earth at a distance of 0.07123 AU on October 4th, 2022.

      "}},"dimorphos":{"stats":{"discovery":"

      First observed in 2003 (7 years after the discovery of Didymos), Dimorphos is the smaller twin of the Didymos binary asteroid system. The DART mission intentionally crashed into Dimorphos on September 26th, 2022, and successfully altered its orbit.

      ","rotation":11.92},"approach":{"fact":"

      Dimorphos and its binary system are classifed as a PHO, and approached Earth at a distance of 0.07123 AU on October 4th, 2022.

      "}},"52246_donaldjohanson":{"stats":{"discovery":"

      Discovered in 1981, and named after the paleoanthropologist who discovered the \\"Lucy\\" fossil, this will be the second small body that the Lucy mission will encounter in 2025.

      ","rotation":252}},"3548_eurybates":{"stats":{"discovery":"

      Discovered in 1973, Eurybates is the first Trojan Asteroid that the Lucy mission will visit in August of 2027. It has a small satellite named Queta.

      ","rotation":8.7}},"15094_polymele":{"stats":{"discovery":"

      Discovered in 1999, Polymele is a Trojan Asteroid that will be visited by the Lucy mission in September of 2027.

      ","rotation":5.86}},"11351_leucus":{"stats":{"discovery":"

      Discovered in 1997, Leucus is a Trojan Asteroid that will be visited by the Lucy mission in April of 2028.

      ","rotation":445.73}},"21900_orus":{"stats":{"discovery":"

      Discovered in 1999, Orus is a Trojan Asteroid that will be visited by the Lucy mission in November of 2028.

      ","rotation":13.45}},"617_patroclus":{"stats":{"discovery":"

      Discovered in 1906, Patroclus is a Trojan Asteroid that will be visited by the Lucy mission in 2033. In 2001, Patroclus was found to be part of a binary asteroid system with its smaller twin, named Menoetius.

      ","rotation":102.8}},"19p_borrelly":{"stats":{"discovery":"

      Discovered in 1904, comet Borrelly was the target of the Deep Space 1 mission, which flew by in September of 2001.

      "}},"5535_annefrank":{"stats":{"discovery":"

      Discovered in 1942, the main belt asteroid 5535 Annefrank was used as a practice flyby target by the Stardust mission on November 2nd, 2002.

      ","rotation":15.12}},"9969_braille":{"stats":{"discovery":"

      Discovered in 1992, Braille was visited by the Deep Space 1 mission on July 29th, 1999. The spacecraft passed within 26 km (16 miles) of the asteroid, which was the closest asteroid flyby ever at that time.

      ","rotation":226.4}},"162173_ryugu":{"stats":{"discovery":"

      Discovered in 1999, Ryugu was the target of the Hayabusa2 mission, which orbited the asteroid for a year and a half, landed small rovers on it, and collected samples that were returned to Earth in December of 2020.

      ","rotation":7.63},"approach":{"fact":"

      Ryugu is a PHO, and will next approach Earth at a distance of 0.373 AUs on June 3rd, 2025.

      "}},"152830_dinkinesh":{"stats":{"discovery":"

      Discovered in 1999, Dinkinesh will be the Lucy mission\'s first flyby target in early November of 2023. It will become the smallest main-belt asteroid ever visited.

      "}},"73p_schwassmann_wachmann_3":{"stats":{"discovery":"

      Discovered in 1930, 73P/Schwassmann-Wachmann 3 is a periodic comet that began to disintegrate as it approached the sun in 1995. Initially, it split into four distinct fragments, but later further split into more than sixty pieces.

      "},"category":"Comet","id":"73p_schwassmann_wachmann_3","iauName":"73P/Schwassmann Wachmann 3","displayName":"Schwassmann Wachmann 3"}}'); + +/***/ }), + +/***/ "./src/data/stories/story_list.json": +/*!******************************************!*\ + !*** ./src/data/stories/story_list.json ***! + \******************************************/ +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse('{"stories":{"asteroids_101":{"id":"asteroids_101","title":"Asteroids 101"},"asteroids_close_approach":{"id":"asteroids_close_approach","title":"What is a Close Approach?"},"asteroids_missions":{"id":"asteroids_missions","title":"Asteroid and Comet Missions"}},"external":{},"featured":[]}'); + +/***/ }), + +/***/ "./src/data/tutorials.json": +/*!*********************************!*\ + !*** ./src/data/tutorials.json ***! + \*********************************/ +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse('[{"id":"intro","title":"Welcome to
      Eyes on Asteroids!","description":"You are looking at a real-time visualization of every known asteroid or comet that is classified as a Near-Earth Object (NEO).
      With asteroids represented as blue points, and comets as white points, our database is updated daily to give you approximately {{getNeoTotal}} NEOs (and counting). Additionally, you can explore most of NASA\'s asteroid and comet missions (past and present), from Galileo, to Lucy and DART.","extra":"
      Extra fact:

      Farther from Earth, the full asteroid belt contains over a million members, with the majority lying between Mars and Jupiter.

      "},{"id":"nav3d","title":"Navigate 3D like an Expert","description":{"touch":"One finger controls your orbit in all directions. Pinch zoom for close inspection, large-scale overviews, and everything in-between.","desktop":"Left mouse click-and-drag controls your orbit in all directions. Scroll zoom for close inspection, macro overviews, and everything in-between."},"extra":{"desktop":"
      Secret tip:

      Use the \'A\', \'S\', \'D\', \'W\', \'Z\', and \'C\' keys only if you\'re a true expert. Hold the \'shift\' key to move even faster.

      "},"targetSelector":"#pioneer","mask":{"xSizeMult":0.6,"ySizeMult":0.25}},{"id":"labels","title":"Info on the Fly","description":"Select any label or icon in the 3D screen to fly to it and bring up an information panel.","extra":"
      Don\'t get lost:

      The top-left NASA logo or \'See all asteroids\' button will always take you back home.

      ","targetSelector":"#pioneer","mask":{"xSizeMult":0.6,"ySizeMult":0.25}},{"id":"time","title":"From 1990 to 2033
      You Control Time.","description":"Drag the time slider left to go backwards, or right to go forwards in time. The LIVE button will always return you to the present time.","extra":"
      A little trick:

      To go even faster, zoom out and try again.

      ","targetSelector":"#time-slider-container"},{"id":"learn","title":"Learn by Scrolling","description":"Select \'Learn\' to access three different scrollable stories about asteroids and comets, including a tour through NASA\'s historic missions.","targetSelector":"nav.navigation div:nth-child(1).clickable button","mask":{"xSizeMult":0.7,"ySizeMult":0.7}},{"id":"watch","title":"Keep an Eye Out!","description":"Select the \'Asteroid Watch\' option to see the next five closest approaches to Earth, complete with a countdown.","extra":"
      Hint:

      Don\'t forget to play with that time slider!

      ","targetSelector":"nav.navigation div:nth-child(2).clickable button","mask":{"xSizeMult":0.7,"ySizeMult":0.7}},{"id":"filters","title":"Filter your View","description":"Select \'Filters\' to see just the comets, or just the asteroids, or just the Potentially Hazardous Objects (PHOs).","targetSelector":"nav.navigation div:nth-child(3).clickable button","mask":{"xSizeMult":0.7,"ySizeMult":0.7}},{"id":"search","title":"Looking for Something?","description":"Type it in the search bar to look through our entire NEO database.","targetSelector":".search>span.icon-search","mask":{"xSizeMult":0.5,"ySizeMult":0.5}},{"id":"settings","title":"Fine Tuning","description":"Use the settings menu to toggle display layers, incrementally zoom, change the lighting when the sun is not enough, and go full-screen.","alternateDescription":"Use the settings menu to toggle display layers, incrementally zoom, and change the lighting when the sun is not enough.","extra":"
      Just in case:

      The info icon will take you back here if you ever need a recap.

      ","targetSelector":"div.settings","mask":{"xSizeMult":0.5}},{"id":"complete","title":"Dare Mighty Things","description":"You are now armed with all the knowledge to explore Eyes on Asteroids like a pro. Happy Learning!","extra":"
      One last secret:

      Watch out for any underlined text; it may lead you down a rabbit hole of space knowledge...

      "}]'); + +/***/ }), + +/***/ "../eyes/src/data/entity_info.json": +/*!*****************************************!*\ + !*** ../eyes/src/data/entity_info.json ***! + !*** copied to ./entity_info.json ***! + \*****************************************/ +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse('{"observable_universe":{"id":"observable_universe","displayName":"Observable universe","category":"Universe","searchable":false},"milky_way":{"id":"milky_way","displayName":"Milky way","category":"Galaxy","searchable":false},"sun":{"id":"sun","iauName":"Sun","category":"Star","subcategory":"Yellow Dwarf Star","planeEntity":"earth","keywords":["star","solar system"]},"mercury":{"id":"mercury","iauName":"Mercury","category":"Planet","subcategory":"Terrestrial","keywords":["terrestrial planet","solar system","planets"]},"venus":{"id":"venus","iauName":"Venus","category":"Planet","subcategory":"Terrestrial","keywords":["terrestrial planet","solar system","planets"]},"earth":{"id":"earth","iauName":"Earth","category":"Planet","subcategory":"Terrestrial","hasMoons":true,"planeEntity":"moon","keywords":["terrestrial planet","solar system","planets"]},"mars":{"id":"mars","iauName":"Mars","category":"Planet","subcategory":"Terrestrial","hasMoons":true,"keywords":["terrestrial planet","solar system","planets"]},"jupiter":{"id":"jupiter","iauName":"Jupiter","category":"Planet","subcategory":"Gas Giant","hasMoons":true,"keywords":["gas giant","solar system","planets"]},"saturn":{"id":"saturn","iauName":"Saturn","category":"Planet","subcategory":"Gas Giant","hasMoons":true,"keywords":["gas giant","solar system","planets"]},"neptune":{"id":"neptune","iauName":"Neptune","category":"Planet","subcategory":"Ice Giant","hasMoons":true,"keywords":["ice giant","solar system","planets"]},"uranus":{"id":"uranus","iauName":"Uranus","category":"Planet","subcategory":"Ice Giant","hasMoons":true,"keywords":["gas giant","solar system","planets","1781"]},"134340_pluto":{"id":"134340_pluto","iauName":"134340 Pluto","displayName":"Pluto","category":"Dwarf Planet","keywords":["dwarf planet","solar system","dwarf planet","trans-neptunian object","plutoid","kuiper belt object","plutino","synchronous","1930"]},"134340_pluto_barycenter":{"id":"134340_pluto_barycenter","displayName":"Pluto system","hasMoons":true,"comparisonFeature":false,"category":"Dwarf Planet","subcategory":"Barycenter","planeEntity":"134340_pluto","forceVisibleEntities":["134340_pluto"],"keywords":["barycenter"]},"617_patroclus_barycenter":{"id":"617_patroclus_barycenter","displayName":"Patroclus barycenter","category":"Asteroid","subcategory":"Barycenter","comparisonFeature":false,"forceVisibleEntities":["617_patroclus","menoetius"]},"21_lutetia":{"id":"21_lutetia","iauName":"21 Lutetia","displayName":"Lutetia","category":"Asteroid","keywords":["asteroid","asteroids","Rosetta"]},"253_mathilde":{"id":"253_mathilde","iauName":"253 Mathilde","displayName":"Mathilde","category":"Asteroid","keywords":["asteroid","asteroids"]},"11351_leucus":{"id":"11351_leucus","iauName":"11351 Leucus","displayName":"Leucus","category":"Asteroid","keywords":["asteroid","asteroids"]},"15094_polymele":{"id":"15094_polymele","iauName":"15094 Polymele","displayName":"Polymele","category":"Asteroid","keywords":["asteroid","asteroids"]},"21900_orus":{"id":"21900_orus","iauName":"21900 Orus","displayName":"Orus","category":"Asteroid","keywords":["asteroid","asteroids"]},"3548_eurybates":{"id":"3548_eurybates","iauName":"3548 Eurybates","displayName":"Eurybates","category":"Asteroid","keywords":["asteroid","asteroids"]},"5535_annefrank":{"id":"5535_annefrank","iauName":"5535 Annefrank","displayName":"Annefrank","category":"Asteroid","keywords":["asteroid","asteroids"]},"52246_donaldjohanson":{"id":"52246_donaldjohanson","iauName":"52246 Donaldjohanson","displayName":"Donaldjohanson","category":"Asteroid","keywords":["asteroid","asteroids"]},"617_patroclus":{"id":"617_patroclus","iauName":"617 Patroclus","displayName":"Patroclus","category":"Asteroid","keywords":["asteroid","asteroids"]},"951_gaspra":{"id":"951_gaspra","iauName":"951 Gaspra","displayName":"Gaspra","category":"Asteroid","keywords":["asteroid","asteroids"]},"2867_steins":{"id":"2867_steins","iauName":"2867 Steins","displayName":"Steins","category":"Asteroid","keywords":["asteroid","asteroids"]},"ariel":{"id":"ariel","iauName":"Ariel","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","uranus","moons","prograde","synchronous","1851"]},"90377_sedna":{"id":"90377_sedna","iauName":"90377 Sedna","displayName":"Sedna","category":"Dwarf Planet","keywords":["dwarf planet","asteroids"]},"99942_apophis":{"id":"99942_apophis","iauName":"99942 Apophis","displayName":"Apophis","category":"Asteroid","keywords":["asteroid","asteroids"]},"486958_arrokoth":{"id":"486958_arrokoth","iauName":"486958 Arrokoth","displayName":"Arrokoth","category":"Asteroid","subcategory":"Kuiper Belt Object","keywords":["mu69","asteroid","asteroids","tno","cubewano","distant minor planet","pt1","1110113y","ultima thule","2014","kuiper belt object"]},"101955_bennu":{"id":"101955_bennu","iauName":"101955 Bennu","displayName":"Bennu","category":"Asteroid","subcategory":"B-Type Asteroid","keywords":["asteroid","asteroids","apollo","neo","pha","1999 rq36","1999","b-type"]},"152830_dinkinesh":{"id":"152830_dinkinesh","iauName":"152830 Dinkinesh","displayName":"Dinkinesh","category":"Asteroid","keywords":["asteroid","asteroids"]},"16_psyche":{"id":"16_psyche","iauName":"16 Psyche","displayName":"16 Psyche","category":"Asteroid","subcategory":"M-Type Asteroid","keywords":["asteroid","asteroids","m-type"]},"1_ceres":{"id":"1_ceres","iauName":"1 Ceres","displayName":"Ceres","category":"Dwarf Planet","keywords":["dwarf planet","asteroids","asteroid belt","a899 of","1943 xb","1801"]},"2_pallas":{"id":"2_pallas","iauName":"2 Pallas","displayName":"Pallas","category":"Asteroid","keywords":["asteroid","asteroids"]},"3_juno":{"id":"3_juno","iauName":"3 Juno","displayName":"Juno","category":"Asteroid","keywords":["asteroid","asteroids"]},"216_kleopatra":{"id":"216_kleopatra","iauName":"216 Kleopatra","displayName":"Kleopatra","category":"Asteroid","keywords":["asteroid","asteroids"]},"243_ida":{"id":"243_ida","iauName":"243 Ida","displayName":"Ida","category":"Asteroid","keywords":["asteroid","asteroids"],"hasMoons":true},"1566_icarus":{"id":"1566_icarus","iauName":"1566 Icarus","displayName":"Icarus","category":"Asteroid","keywords":["asteroid","asteroids"]},"1620_geographos":{"id":"1620_geographos","iauName":"1620 Geographos","displayName":"Geographos","category":"Asteroid","keywords":["asteroid","asteroids"]},"1862_apollo":{"id":"1862_apollo","iauName":"1862 Apollo","displayName":"Apollo","category":"Asteroid","keywords":["asteroid","asteroids"]},"1981_midas":{"id":"1981_midas","iauName":"1981 Midas","displayName":"Midas","category":"Asteroid","keywords":["asteroid","asteroids"]},"2063_bacchus":{"id":"2063_bacchus","iauName":"2063 Bacchus","displayName":"Bacchus","category":"Asteroid","keywords":["asteroid","asteroids"]},"2101_adonis":{"id":"2101_adonis","iauName":"2101 Adonis","displayName":"Adonis","category":"Asteroid","keywords":["asteroid","asteroids"]},"2102_tantalus":{"id":"2102_tantalus","iauName":"2102 Tantalus","displayName":"Tantalus","category":"Asteroid","keywords":["asteroid","asteroids"]},"2135_aristaeus":{"id":"2135_aristaeus","iauName":"2135 Aristaeus","displayName":"Aristaeus","category":"Asteroid","keywords":["asteroid","asteroids"]},"2340_hathor":{"id":"2340_hathor","iauName":"2340 Hathor","displayName":"Hathor","category":"Asteroid","keywords":["asteroid","asteroids"]},"3122_florence":{"id":"3122_florence","iauName":"3122 Florence","displayName":"Florence","category":"Asteroid","keywords":["asteroid","asteroids"]},"3200_phaethon":{"id":"3200_phaethon","iauName":"3200 Phaethon","displayName":"Phaethon","category":"Asteroid","keywords":["asteroid","asteroids"]},"3362_khufu":{"id":"3362_khufu","iauName":"3362 Khufu","displayName":"Khufu","category":"Asteroid","keywords":["asteroid","asteroids"]},"4015_wilson-harrington":{"id":"4015_wilson-harrington","iauName":"4015 Wilson-Harrington","displayName":"Wilson-Harrington","category":"Asteroid","keywords":["asteroid","asteroids"]},"4179_toutatis":{"id":"4179_toutatis","iauName":"4179 Toutatis","displayName":"Toutatis","category":"Asteroid","keywords":["asteroid","asteroids"]},"4183_cuno":{"id":"4183_cuno","iauName":"4183 Cuno","displayName":"Cuno","category":"Asteroid","keywords":["asteroid","asteroids"]},"4450_pan":{"id":"4450_pan","iauName":"4450 Pan","displayName":"Pan","category":"Asteroid","keywords":["asteroid","asteroids","minor moon","saturn"]},"4486_mithra":{"id":"4486_mithra","iauName":"4486 Mithra","displayName":"Mithra","category":"Asteroid","keywords":["asteroid","asteroids"]},"4769_castalia":{"id":"4769_castalia","iauName":"4769 Castalia","displayName":"Castalia","category":"Asteroid","keywords":["asteroid","asteroids"]},"5011_ptah":{"id":"5011_ptah","iauName":"5011 Ptah","displayName":"Ptah","category":"Asteroid","keywords":["asteroid","asteroids"]},"6239_minos":{"id":"6239_minos","iauName":"6239 Minos","displayName":"Minos","category":"Asteroid","keywords":["asteroid","asteroids"]},"6489_golevka":{"id":"6489_golevka","iauName":"6489 Golevka","displayName":"Golevka","category":"Asteroid","keywords":["asteroid","asteroids"]},"9969_braille":{"id":"9969_braille","iauName":"9969 Braille","displayName":"Braille","category":"Asteroid","keywords":["asteroid","asteroids"]},"12923_zephyr":{"id":"12923_zephyr","iauName":"12923 Zephyr","displayName":"Zephyr","category":"Asteroid","keywords":["asteroid","asteroids"]},"14827_hypnos":{"id":"14827_hypnos","iauName":"14827 Hypnos","displayName":"Hypnos","category":"Asteroid","keywords":["asteroid","asteroids"]},"25143_itokawa":{"id":"25143_itokawa","iauName":"25143 Itokawa","displayName":"Itokawa","category":"Asteroid","keywords":["asteroid","asteroids"]},"37655_illapa":{"id":"37655_illapa","iauName":"37655 Illapa","displayName":"Illapa","category":"Asteroid","keywords":["asteroid","asteroids"]},"65803_didymos":{"id":"65803_didymos","iauName":"65803 Didymos","displayName":"Didymos","category":"Asteroid","keywords":["asteroid","asteroids"],"hasMoons":true},"69230_hermes":{"id":"69230_hermes","iauName":"69230 Hermes","displayName":"Hermes","category":"Asteroid","keywords":["asteroid","asteroids"]},"136199_eris":{"id":"136199_eris","iauName":"136199 Eris","displayName":"Eris","category":"Dwarf Planet","keywords":["asteroid","asteroids","dwarf planet","tno","plutoid","sdo","binary","dysnomia","2005"]},"136108_haumea":{"id":"136108_haumea","iauName":"136108 Haumea","displayName":"Haumea","category":"Dwarf Planet","keywords":["asteroid","asteroids","dwarf planet","plutoid","tno","cubewano","trinary","2003 el61","2004"],"hasMoons":true},"136472_makemake":{"id":"136472_makemake","iauName":"136472 Makemake","displayName":"Makemake","category":"Dwarf Planet","keywords":["asteroid","asteroids","dwarf planet","cubewano","scattered-near","kuiper belt","2005 fy9","2005"]},"162173_ryugu":{"id":"162173_ryugu","iauName":"162173 Ryugu","displayName":"Ryugu","category":"Asteroid","keywords":["asteroid","asteroids","neo","pha","b-type","c-type"]},"4_vesta":{"id":"4_vesta","iauName":"4 Vesta","displayName":"Vesta","category":"Asteroid","subcategory":"Protoplanet","keywords":["asteroid","asteroids","main belt","vesta family","1807","protoplanet"]},"433_eros":{"id":"433_eros","iauName":"433 Eros","displayName":"Eros","category":"Asteroid","subcategory":"S-Type Asteroid","keywords":["asteroid","asteroids","neo","1898","prograde"]},"callisto":{"id":"callisto","iauName":"Callisto","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","jupiter","moons","main group","galilean moons","prograde","synchronous","1610"]},"sc_chandra":{"id":"sc_chandra","iauName":"Chandra X-ray Observatory","category":"Spacecraft","subcategory":"Orbiter","keywords":["telescope","orbiter","earth","Columbia","X-ray","astrophysics"]},"charon":{"id":"charon","iauName":"Charon","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","pluto","moons","prograde","synchronous","1978"]},"67p_churyumov_gerasimenko":{"id":"67p_churyumov_gerasimenko","iauName":"67P/Churyumov-Gerasimenko","displayName":"67P/Churyumov-Gerasimenko","category":"Comet","subcategory":"Short-Period Comet","keywords":["comet","comets","jupiter-family","1969 r1","1969 iv","1969h","1975 p1","1976 vii","1975i","1982 viii","1982f","1989 vi","1988i","1969","chury","short-period"]},"1p_halley":{"id":"1p_halley","iauName":"1P/Halley","displayName":"Halley","category":"Comet","subcategory":"Short-Period Comet","keywords":["comet","comets","short-period","1p/halley"]},"103p_hartley_2":{"id":"103p_hartley_2","iauName":"103P/Hartley","displayName":"Hartley 2","category":"Comet","keywords":["comet"]},"1i_oumuamua":{"id":"1i_oumuamua","iauName":"1I/\'Oumuamua","displayName":"Oumuamua","category":"Comet","keywords":["comet","comets","1i/oumuamua"]},"9p_tempel_1":{"id":"9p_tempel_1","iauName":"9P/Tempel 1","displayName":"Tempel 1","category":"Comet","subcategory":"Jupiter-Family Comet","keywords":["comet","comets","periodic","jupiter-family","9p/tempel","1867"]},"19p_borrelly":{"id":"19p_borrelly","iauName":"19P/Borrelly","displayName":"Borrelly","category":"Comet","subcategory":"Jupiter-Family Comet","keywords":["comet","comets","periodic","jupiter-family","19p/borrelly","Deep Space 1"]},"81p_wild_2":{"id":"81p_wild_2","iauName":"81P/Wild 2","displayName":"Wild 2","category":"Comet","subcategory":"Short-Period Comet","keywords":["comet","comets","81p/wild","1978 xi","1984 xiv","1990 xxviii","1978"]},"adrastea":{"id":"adrastea","iauName":"Adrastea","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"aegaeon":{"id":"aegaeon","iauName":"Aegaeon","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"aegir":{"id":"aegir","iauName":"Aegir","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"aitne":{"id":"aitne","iauName":"Aitne","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"albiorix":{"id":"albiorix","iauName":"Albiorix","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"amalthea":{"id":"amalthea","iauName":"Amalthea","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"ananke":{"id":"ananke","iauName":"Ananke","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"anthe":{"id":"anthe","iauName":"Anthe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"aoede":{"id":"aoede","iauName":"Aoede","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"arche":{"id":"arche","iauName":"Arche","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"atlas":{"id":"atlas","iauName":"Atlas","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"autonoe":{"id":"autonoe","iauName":"Autonoe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"bebhionn":{"id":"bebhionn","iauName":"Bebhionn","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"belinda":{"id":"belinda","iauName":"Belinda","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"bergelmir":{"id":"bergelmir","iauName":"Bergelmir","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"bestla":{"id":"bestla","iauName":"Bestla","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"bianca":{"id":"bianca","iauName":"Bianca","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"c_2010_x1":{"id":"c_2010_x1","iauName":"C/2010 X1","displayName":"Elenin","category":"Comet","keywords":["comet"]},"c_2012_s1":{"id":"c_2012_s1","iauName":"C/2012 S1","displayName":"ISON","category":"Comet","keywords":["comet"]},"caliban":{"id":"caliban","iauName":"Caliban","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"callirrhoe":{"id":"callirrhoe","iauName":"Callirrhoe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"calypso":{"id":"calypso","iauName":"Calypso","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"carme":{"id":"carme","iauName":"Carme","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"carpo":{"id":"carpo","iauName":"Carpo","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"chaldene":{"id":"chaldene","iauName":"Chaldene","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"cordelia":{"id":"cordelia","iauName":"Cordelia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"cressida":{"id":"cressida","iauName":"Cressida","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"cupid":{"id":"cupid","iauName":"Cupid","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"cyllene":{"id":"cyllene","iauName":"Cyllene","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"dactyl":{"id":"dactyl","iauName":"243 Ida I Dactyl","displayName":"Dactyl","category":"Moon","subcategory":"Major Moon","keywords":["asteroid","minor moon","ida"]},"daphnis":{"id":"daphnis","iauName":"Daphnis","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"deimos":{"id":"deimos","iauName":"Deimos","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","mars","moons","synchronous","1877"]},"desdemona":{"id":"desdemona","iauName":"Desdemona","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"despina":{"id":"despina","iauName":"Despina","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"dia":{"id":"dia","iauName":"Dia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"dimorphos":{"id":"dimorphos","iauName":"Dimorphos","category":"Moon","subcategory":"Major Moon","keywords":["minor moon","solar system","65803 Didymos","asteroid"]},"dione":{"id":"dione","iauName":"Dione","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","inner moons","prograde","synchronous","1684"]},"sc_dscovr":{"id":"sc_dscovr","iauName":"DSCOVR","category":"Spacecraft","subcategory":"Orbiter","keywords":["earth","orbiter","Deep Space Climate Observatory"]},"eirene":{"id":"eirene","iauName":"Eirene","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"elara":{"id":"elara","iauName":"Elara","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"enceladus":{"id":"enceladus","iauName":"Enceladus","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","inner moons","prograde","synchronous","1789"]},"epimetheus":{"id":"epimetheus","iauName":"Epimetheus","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"erinome":{"id":"erinome","iauName":"Erinome","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"erriapus":{"id":"erriapus","iauName":"Erriapus","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"ersa":{"id":"ersa","iauName":"Ersa","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"euanthe":{"id":"euanthe","iauName":"Euanthe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"eukelade":{"id":"eukelade","iauName":"Eukelade","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"eupheme":{"id":"eupheme","iauName":"Eupheme","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"euporie":{"id":"euporie","iauName":"Euporie","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"europa":{"id":"europa","iauName":"Europa","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","jupiter","moons","main group","galilean moons","prograde","synchronous","1610"],"ignoreDependentWhenUnloading":["sc_juno"]},"eurydome":{"id":"eurydome","iauName":"Eurydome","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"farbauti":{"id":"farbauti","iauName":"Farbauti","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"fenrir":{"id":"fenrir","iauName":"Fenrir","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"galatea":{"id":"galatea","iauName":"Galatea","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"ganymede":{"id":"ganymede","iauName":"Ganymede","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","jupiter","moons","main group","galilean moons","prograde","synchronous","1610"],"ignoreDependentWhenUnloading":["sc_juno"]},"greip":{"id":"greip","iauName":"Greip","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"c_1995_o1":{"id":"c_1995_o1","iauName":"C/1995 O1","displayName":"Hale-Bopp","category":"Comet","subcategory":"Long-Period Comet","keywords":["comet","solar system","The Great Comet of 1997","C/1995 O1","1995"]},"ferdinand":{"id":"ferdinand","iauName":"Ferdinand","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"fornjot":{"id":"fornjot","iauName":"Fornjot","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"francisco":{"id":"francisco","iauName":"Francisco","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"halimede":{"id":"halimede","iauName":"Halimede","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"harpalyke":{"id":"harpalyke","iauName":"Harpalyke","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"hati":{"id":"hati","iauName":"Hati","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"hegemone":{"id":"hegemone","iauName":"Hegemone","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"helene":{"id":"helene","iauName":"Helene","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"helike":{"id":"helike","iauName":"Helike","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"hermippe":{"id":"hermippe","iauName":"Hermippe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"herse":{"id":"herse","iauName":"Herse","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"hiiaka":{"id":"hiiaka","iauName":"Hi\'iaka","displayName":"Hi\'iaka","category":"Moon","subcategory":"Major Moon","keywords":["asteroid","minor moon","haumea"]},"himalia":{"id":"himalia","iauName":"Himalia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"hippocamp":{"id":"hippocamp","iauName":"Hippocamp","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"hydra":{"id":"hydra","iauName":"Hydra","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","pluto","moons","outer moons"]},"hyperion":{"id":"hyperion","iauName":"Hyperion","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","outer moons","prograde","1848"]},"hyrrokkin":{"id":"hyrrokkin","iauName":"Hyrrokkin","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"iapetus":{"id":"iapetus","iauName":"Iapetus","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","outer moons","prograde","synchronous","1671"]},"io":{"id":"io","iauName":"Io","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","jupiter","moons","main group","galilean moons","prograde","synchronous","1610"],"ignoreDependentWhenUnloading":["sc_juno"]},"ijiraq":{"id":"ijiraq","iauName":"Ijiraq","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"iocaste":{"id":"iocaste","iauName":"Iocaste","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"isonoe":{"id":"isonoe","iauName":"Isonoe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"janus":{"id":"janus","iauName":"Janus","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"jarnsaxa":{"id":"jarnsaxa","iauName":"Jarnsaxa","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"juliet":{"id":"juliet","iauName":"Juliet","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"jupiter_li":{"id":"jupiter_li","iauName":"Jupiter LI","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lii":{"id":"jupiter_lii","iauName":"Jupiter LII","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_liv":{"id":"jupiter_liv","iauName":"Jupiter LIV","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lix":{"id":"jupiter_lix","iauName":"Jupiter LIX","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lv":{"id":"jupiter_lv","iauName":"Jupiter LV","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lvi":{"id":"jupiter_lvi","iauName":"Jupiter LVI","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxi":{"id":"jupiter_lxi","iauName":"Jupiter LXI","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxiii":{"id":"jupiter_lxiii","iauName":"Jupiter LXIII","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxiv":{"id":"jupiter_lxiv","iauName":"Jupiter LXIV","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxix":{"id":"jupiter_lxix","iauName":"Jupiter LXIX","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxvi":{"id":"jupiter_lxvi","iauName":"Jupiter LXVI","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxvii":{"id":"jupiter_lxvii","iauName":"Jupiter LXVI","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxviii":{"id":"jupiter_lxviii","iauName":"Jupiter LXVIII","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxx":{"id":"jupiter_lxx","iauName":"Jupiter LXX","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxxii":{"id":"jupiter_lxxii","iauName":"Jupiter LXXII","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"kale":{"id":"kale","iauName":"Kale","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"kallichore":{"id":"kallichore","iauName":"Kallichore","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"kalyke":{"id":"kalyke","iauName":"Kalyke","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"kari":{"id":"kari","iauName":"Kari","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"kerberos":{"id":"kerberos","iauName":"Kerberos","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","pluto","moons"]},"kiviuq":{"id":"kiviuq","iauName":"Kiviuq","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"kore":{"id":"kore","iauName":"Kore","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"laomedeia":{"id":"laomedeia","iauName":"Laomedeia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"larissa":{"id":"larissa","iauName":"Larissa","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"leda":{"id":"leda","iauName":"Leda","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"loge":{"id":"loge","iauName":"Loge","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"lysithea":{"id":"lysithea","iauName":"Lysithea","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"mab":{"id":"mab","iauName":"Mab","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"margaret":{"id":"margaret","iauName":"Margaret","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"megaclite":{"id":"megaclite","iauName":"Megaclite","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons","jupiter xix","S/2000 J 8"]},"menoetius":{"id":"menoetius","iauName":"Menoetius","displayName":"Menoetius","category":"Asteroid","keywords":["asteroid","asteroids","solar system","617 Patroclus"]},"methone":{"id":"methone","iauName":"Methone","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"metis":{"id":"metis","iauName":"Metis","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"mimas":{"id":"mimas","iauName":"Mimas","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","inner moons","prograde","synchronous","1789","death star"]},"miranda":{"id":"miranda","iauName":"Miranda","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","uranus","moons","prograde","synchronous","1948"]},"mneme":{"id":"mneme","iauName":"Mneme","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"moon":{"id":"moon","iauName":"Moon","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","earth","moons","synchronous"]},"mundilfari":{"id":"mundilfari","iauName":"Mundilfari","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"naiad":{"id":"naiad","iauName":"Naiad","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"namaka":{"id":"namaka","iauName":"Namaka","displayName":"Namaka","category":"Moon","subcategory":"Major Moon","keywords":["asteroid","minor moon","haumea"]},"narvi":{"id":"narvi","iauName":"Narvi","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"nix":{"id":"nix","iauName":"Nix","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","pluto","moons"]},"nereid":{"id":"nereid","iauName":"Nereid","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons","irregular moons","prograde","1949"]},"neso":{"id":"neso","iauName":"Neso","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"oberon":{"id":"oberon","iauName":"Oberon","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","uranus","moons","prograde","synchronous","1787"]},"ophelia":{"id":"ophelia","iauName":"Ophelia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"orthosie":{"id":"orthosie","iauName":"Orthosie","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"paaliaq":{"id":"paaliaq","iauName":"Paaliaq","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"pallene":{"id":"pallene","iauName":"Pallene","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"pan":{"id":"pan","iauName":"Pan","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"pandia":{"id":"pandia","iauName":"Pandia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"pandora":{"id":"pandora","iauName":"Pandora","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"pasiphae":{"id":"pasiphae","iauName":"Pasiphae","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"pasithee":{"id":"pasithee","iauName":"Pasithee","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"perdita":{"id":"perdita","iauName":"Perdita","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"philophrosyne":{"id":"philophrosyne","iauName":"Philophrosyne","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"phobos":{"id":"phobos","iauName":"Phobos","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","mars","moons","synchronous","1877"]},"phoebe":{"id":"phoebe","iauName":"Phoebe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","norse group","retrograde","1899"]},"polydeuces":{"id":"polydeuces","iauName":"Polydeuces","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"portia":{"id":"portia","iauName":"Portia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"praxidike":{"id":"praxidike","iauName":"Praxidike","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"prometheus":{"id":"prometheus","iauName":"Prometheus","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"prospero":{"id":"prospero","iauName":"Prospero","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"proteus":{"id":"proteus","iauName":"Proteus","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons","regular moons","prograde","synchronous","1989"]},"psamathe":{"id":"psamathe","iauName":"Psamathe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"puck":{"id":"puck","iauName":"Puck","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"rhea":{"id":"rhea","iauName":"Rhea","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","outer moons","prograde","synchronous","1672"]},"rosalind":{"id":"rosalind","iauName":"Rosalind","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"s_2003_j_10":{"id":"s_2003_j_10","iauName":"S/2003 J 10","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_12":{"id":"s_2003_j_12","iauName":"S/2003 J 12","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_16":{"id":"s_2003_j_16","iauName":"S/2003 J 16","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_2":{"id":"s_2003_j_2","iauName":"S/2003 J 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_23":{"id":"s_2003_j_23","iauName":"S/2003 J 23","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_24":{"id":"s_2003_j_24","iauName":"S/2003 J 24","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_4":{"id":"s_2003_j_4","iauName":"S/2003 J 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_9":{"id":"s_2003_j_9","iauName":"S/2003 J 9","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2004_s_7":{"id":"s_2004_s_7","iauName":"S/2004 S 7","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_12":{"id":"s_2004_s_12","iauName":"S/2004 S 12","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_13":{"id":"s_2004_s_13","iauName":"S/2004 S 13","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_17":{"id":"s_2004_s_17","iauName":"S/2004 S 17","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_21":{"id":"s_2004_s_21","iauName":"S/2004 S 21","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_24":{"id":"s_2004_s_24","iauName":"S/2004 S 24","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_28":{"id":"s_2004_s_28","iauName":"S/2004 S 28","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_31":{"id":"s_2004_s_31","iauName":"S/2004 S 31","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_36":{"id":"s_2004_s_36","iauName":"S/2004 S 36","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_37":{"id":"s_2004_s_37","iauName":"S/2004 S 37","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_39":{"id":"s_2004_s_39","iauName":"S/2004 S 39","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_40":{"id":"s_2004_s_40","iauName":"S/2004 S 40","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_41":{"id":"s_2004_s_41","iauName":"S/2004 S 41","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_42":{"id":"s_2004_s_42","iauName":"S/2004 S 42","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_43":{"id":"s_2004_s_43","iauName":"S/2004 S 43","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_44":{"id":"s_2004_s_44","iauName":"S/2004 S 44","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_45":{"id":"s_2004_s_45","iauName":"S/2004 S 45","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_46":{"id":"s_2004_s_46","iauName":"S/2004 S 46","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_47":{"id":"s_2004_s_47","iauName":"S/2004 S 47","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_48":{"id":"s_2004_s_48","iauName":"S/2004 S 48","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_49":{"id":"s_2004_s_49","iauName":"S/2004 S 49","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_50":{"id":"s_2004_s_50","iauName":"S/2004 S 50","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_51":{"id":"s_2004_s_51","iauName":"S/2004 S 51","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_52":{"id":"s_2004_s_52","iauName":"S/2004 S 52","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_53":{"id":"s_2004_s_53","iauName":"S/2004 S 53","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2005_s_4":{"id":"s_2005_s_4","iauName":"S/2005 S 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2005_s_5":{"id":"s_2005_s_5","iauName":"S/2005 S 5","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_1":{"id":"s_2006_s_1","iauName":"S/2006 S 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_10":{"id":"s_2006_s_10","iauName":"S/2006 S 10","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_11":{"id":"s_2006_s_11","iauName":"S/2006 S 11","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_12":{"id":"s_2006_s_12","iauName":"S/2006 S 12","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_13":{"id":"s_2006_s_13","iauName":"S/2006 S 13","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_14":{"id":"s_2006_s_14","iauName":"S/2006 S 14","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_15":{"id":"s_2006_s_15","iauName":"S/2006 S 15","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_16":{"id":"s_2006_s_16","iauName":"S/2006 S 16","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_17":{"id":"s_2006_s_17","iauName":"S/2006 S 17","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_18":{"id":"s_2006_s_18","iauName":"S/2006 S 18","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_19":{"id":"s_2006_s_19","iauName":"S/2006 S 19","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_20":{"id":"s_2006_s_20","iauName":"S/2006 S 20","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_3":{"id":"s_2006_s_3","iauName":"S/2006 S 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_9":{"id":"s_2006_s_9","iauName":"S/2006 S 9","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_2":{"id":"s_2007_s_2","iauName":"S/2007 S 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_3":{"id":"s_2007_s_3","iauName":"S/2007 S 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_5":{"id":"s_2007_s_5","iauName":"S/2007 S 5","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_6":{"id":"s_2007_s_6","iauName":"S/2007 S 6","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_7":{"id":"s_2007_s_7","iauName":"S/2007 S 7","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_8":{"id":"s_2007_s_8","iauName":"S/2007 S 8","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_9":{"id":"s_2007_s_9","iauName":"S/2007 S 9","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2009_s_1":{"id":"s_2009_s_1","iauName":"S/2009 S 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2011_j_3":{"id":"s_2011_j_3","iauName":"S/2011 J 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2016_j_3":{"id":"s_2016_j_3","iauName":"S/2016 J 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2016_j_4":{"id":"s_2016_j_4","iauName":"S/2016 J 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2018_j_2":{"id":"s_2018_j_2","iauName":"S/2018 J 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2018_j_3":{"id":"s_2018_j_3","iauName":"S/2018 J 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2018_j_4":{"id":"s_2018_j_4","iauName":"S/2018 J 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2019_s_1":{"id":"s_2019_s_1","iauName":"S/2019 S 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_10":{"id":"s_2019_s_10","iauName":"S/2019 S 10","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_11":{"id":"s_2019_s_11","iauName":"S/2019 S 11","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_12":{"id":"s_2019_s_12","iauName":"S/2019 S 12","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_13":{"id":"s_2019_s_13","iauName":"S/2019 S 13","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_14":{"id":"s_2019_s_14","iauName":"S/2019 S 14","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_15":{"id":"s_2019_s_15","iauName":"S/2019 S 15","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_16":{"id":"s_2019_s_16","iauName":"S/2019 S 16","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_17":{"id":"s_2019_s_17","iauName":"S/2019 S 17","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_18":{"id":"s_2019_s_18","iauName":"S/2019 S 18","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_19":{"id":"s_2019_s_19","iauName":"S/2019 S 19","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_2":{"id":"s_2019_s_2","iauName":"S/2019 S 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_20":{"id":"s_2019_s_20","iauName":"S/2019 S 20","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_21":{"id":"s_2019_s_21","iauName":"S/2019 S 21","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_3":{"id":"s_2019_s_3","iauName":"S/2019 S 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_4":{"id":"s_2019_s_4","iauName":"S/2019 S 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_5":{"id":"s_2019_s_5","iauName":"S/2019 S 5","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_6":{"id":"s_2019_s_6","iauName":"S/2019 S 6","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_7":{"id":"s_2019_s_7","iauName":"S/2019 S 7","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_8":{"id":"s_2019_s_8","iauName":"S/2019 S 8","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_9":{"id":"s_2019_s_9","iauName":"S/2019 S 9","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_1":{"id":"s_2020_s_1","iauName":"S/2020 S 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_10":{"id":"s_2020_s_10","iauName":"S/2020 S 10","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_2":{"id":"s_2020_s_2","iauName":"S/2020 S 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_3":{"id":"s_2020_s_3","iauName":"S/2020 S 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_4":{"id":"s_2020_s_4","iauName":"S/2020 S 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_5":{"id":"s_2020_s_5","iauName":"S/2020 S 5","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_6":{"id":"s_2020_s_6","iauName":"S/2020 S 6","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_7":{"id":"s_2020_s_7","iauName":"S/2020 S 7","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_8":{"id":"s_2020_s_8","iauName":"S/2020 S 8","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_9":{"id":"s_2020_s_9","iauName":"S/2020 S 9","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2021_j_1":{"id":"s_2021_j_1","iauName":"S/2021 J 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2021_j_2":{"id":"s_2021_j_2","iauName":"S/2021 J 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2021_j_3":{"id":"s_2021_j_3","iauName":"S/2021 J 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2021_j_4":{"id":"s_2021_j_4","iauName":"S/2021 J 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2021_j_5":{"id":"s_2021_j_5","iauName":"S/2021 J 5","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2021_j_6":{"id":"s_2021_j_6","iauName":"S/2021 J 6","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2022_j_1":{"id":"s_2022_j_1","iauName":"S/2022 J 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2022_j_2":{"id":"s_2022_j_2","iauName":"S/2022 J 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2022_j_3":{"id":"s_2022_j_3","iauName":"S/2022 J 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"sao":{"id":"sao","iauName":"Sao","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"gridr":{"id":"gridr","iauName":"Gridr","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S20","saturn liv"]},"angrboda":{"id":"angrboda","iauName":"Angrboda","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S22","saturn lv"]},"skrymir":{"id":"skrymir","iauName":"Skrymir","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S23","saturn lvi"]},"gerd":{"id":"gerd","iauName":"Gerd","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S25","saturn lvii"]},"saturn_lviii":{"id":"saturn_lviii","iauName":"Saturn LVIII","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"eggther":{"id":"eggther","iauName":"Eggther","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S27","saturn lix"]},"saturn_lx":{"id":"saturn_lx","iauName":"Saturn LX","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"beli":{"id":"beli","iauName":"Beli","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S30","saturn lxi"]},"gunnlod":{"id":"gunnlod","iauName":"Gunnlod","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S32","saturn lxii"]},"thiazzi":{"id":"thiazzi","iauName":"Thiazzi","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S33","saturn lxiii"]},"saturn_lxiv":{"id":"saturn_lxiv","iauName":"Saturn LXIV","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"alvaldi":{"id":"alvaldi","iauName":"Alvaldi","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S35","saturn lxv"]},"geirrod":{"id":"geirrod","iauName":"Geirrod","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S38","saturn lxvi"]},"setebos":{"id":"setebos","iauName":"Setebos","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"siarnaq":{"id":"siarnaq","iauName":"Siarnaq","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"sinope":{"id":"sinope","iauName":"Sinope","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"skathi":{"id":"skathi","iauName":"Skathi","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"skoll":{"id":"skoll","iauName":"Skoll","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"sponde":{"id":"sponde","iauName":"Sponde","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"stephano":{"id":"stephano","iauName":"Stephano","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"styx":{"id":"styx","iauName":"Styx","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","pluto","moons"]},"surtur":{"id":"surtur","iauName":"Surtur","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"suttungr":{"id":"suttungr","iauName":"Suttungr","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"sycorax":{"id":"sycorax","iauName":"Sycorax","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"tarqeq":{"id":"tarqeq","iauName":"Tarqeq","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"tarvos":{"id":"tarvos","iauName":"Tarvos","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"taygete":{"id":"taygete","iauName":"Taygete","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"telesto":{"id":"telesto","iauName":"Telesto","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"tethys":{"id":"tethys","iauName":"Tethys","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","inner moons","prograde","synchronous","1684"]},"thalassa":{"id":"thalassa","iauName":"Thalassa","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"thebe":{"id":"thebe","iauName":"Thebe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"thelxinoe":{"id":"thelxinoe","iauName":"Thelxinoe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"themisto":{"id":"themisto","iauName":"Themisto","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"thrymr":{"id":"thrymr","iauName":"Thrymr","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"thyone":{"id":"thyone","iauName":"Thyone","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"titan":{"id":"titan","iauName":"Titan","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","outer moons","prograde","synchronous","1655"]},"titania":{"id":"titania","iauName":"Titania","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","uranus","moons","prograde","synchronous","1787"]},"trinculo":{"id":"trinculo","iauName":"Trinculo","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"triton":{"id":"triton","iauName":"Triton","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","neptune","moons","irregular moons","retrograde","synchronous","1846"]},"umbriel":{"id":"umbriel","iauName":"Umbriel","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","uranus","moons","prograde","synchronous","1851"]},"ymir":{"id":"ymir","iauName":"Ymir","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"sc_ace":{"id":"sc_ace","iauName":"ACE","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_acrimsat":{"id":"sc_acrimsat","iauName":"ACRIMSAT","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_acs3":{"id":"sc_acs3","iauName":"ACS3","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"],"disabled":true},"sc_aqua":{"id":"sc_aqua","iauName":"Aqua","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_artemis_1":{"id":"sc_artemis_1","iauName":"Artemis I","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_aura":{"id":"sc_aura","iauName":"Aura","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_biosentinel":{"id":"sc_biosentinel","iauName":"BioSentinel","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_calipso":{"id":"sc_calipso","iauName":"CALIPSO","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_capstone":{"id":"sc_capstone","iauName":"CAPSTONE","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_cassini":{"id":"sc_cassini","iauName":"Cassini","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","saturn"],"hasEvents":true},"sc_clementine":{"id":"sc_clementine","iauName":"Clementine","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_cloudsat":{"id":"sc_cloudsat","iauName":"CloudSat","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_cluster_ii_fm5":{"id":"sc_cluster_ii_fm5","iauName":"Rumba","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_cluster_ii_fm6":{"id":"sc_cluster_ii_fm6","iauName":"Salsa","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_cluster_ii_fm7":{"id":"sc_cluster_ii_fm7","iauName":"Samba","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_cluster_ii_fm8":{"id":"sc_cluster_ii_fm8","iauName":"Tango","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_1":{"id":"sc_cygnss_1","iauName":"CYGNSS 1","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_2":{"id":"sc_cygnss_2","iauName":"CYGNSS 2","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_3":{"id":"sc_cygnss_3","iauName":"CYGNSS 3","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_4":{"id":"sc_cygnss_4","iauName":"CYGNSS 4","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_5":{"id":"sc_cygnss_5","iauName":"CYGNSS 5","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_6":{"id":"sc_cygnss_6","iauName":"CYGNSS 6","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_7":{"id":"sc_cygnss_7","iauName":"CYGNSS 7","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_8":{"id":"sc_cygnss_8","iauName":"CYGNSS 8","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_dart":{"id":"sc_dart","iauName":"DART","category":"Spacecraft","subcategory":"Impactor","altName":"boom","keywords":["spacecraft","65803_didymos","dimorphos","asteroid"],"hasEvents":true},"sc_dawn":{"id":"sc_dawn","iauName":"Dawn","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","vesta","ceres","small body mission"],"related":{"asteroid":["4_vesta","1_ceres"]},"hasEvents":true},"sc_deep_impact":{"id":"sc_deep_impact","iauName":"Deep Impact","category":"Spacecraft","subcategory":"Flyby","altName":"DI","keywords":["spacecraft","tempel 1","small body mission"],"related":{"comet":["9p_temp_1"]},"hasEvents":true},"sc_deep_impact_impactor":{"id":"sc_deep_impact_impactor","iauName":"Deep Impact Impactor","category":"Spacecraft","subcategory":"Impactor","altName":"DII","keywords":["spacecraft","tempel 1","small body mission"],"related":{"comet":["9p_temp_1"]},"hasEvents":true},"sc_deep_impact_impactor_impact_site":{"id":"sc_deep_impact_impactor_impact_site","displayName":"Deep Impact Impactor Impact Site","category":"Landing site","comparisonFeature":false},"sc_deep_space_1":{"id":"sc_deep_space_1","iauName":"Deep Space 1","category":"Spacecraft","subcategory":"Flyby","altName":"DS1","keywords":["spacecraft","9660 Braille","19p/Borrelly","small body mission"],"related":{"asteroid":["9969_braille"],"comet":["19p_borrelly"]},"hasEvents":true},"sc_eo_1":{"id":"sc_eo_1","iauName":"EO-1","category":"Spacecraft","subcategory":"Orbiter","altName":"Earth Observing-1","keywords":["spacecraft","earth","orbiter"]},"sc_euclid":{"id":"sc_euclid","iauName":"Euclid","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","telescope"],"disabled":false},"sc_europa_clipper":{"id":"sc_europa_clipper","iauName":"Europa Clipper","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","europa"]},"sc_explorer_1":{"id":"sc_explorer_1","iauName":"Explorer 1","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_galileo":{"id":"sc_galileo","iauName":"Galileo","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","outer planet mission","orbiter","jupiter"],"hasEvents":true},"sc_galileo_probe":{"id":"sc_galileo_probe","iauName":"Galileo Probe","category":"Spacecraft","subcategory":"Lander","keywords":["spacecraft","outer planet mission","orbiter","jupiter"],"hasEvents":true},"sc_geotail":{"id":"sc_geotail","iauName":"Geotail","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_gpm":{"id":"sc_gpm","iauName":"GPM","category":"Spacecraft","subcategory":"Orbiter","altName":"Global Precipitation Measurement","keywords":["spacecraft","earth","orbiter"]},"sc_grace_1":{"id":"sc_grace_1","iauName":"GRACE-1","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_grace_2":{"id":"sc_grace_2","iauName":"GRACE-2","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_grace_fo1":{"id":"sc_grace_fo1","iauName":"GRACE-FO1","category":"Spacecraft","subcategory":"Orbiter","altName":"GRACE Follow-On","keywords":["spacecraft","earth","orbiter"]},"sc_grace_fo2":{"id":"sc_grace_fo2","iauName":"GRACE-FO2","category":"Spacecraft","subcategory":"Orbiter","altName":"GRACE Follow-On","keywords":["spacecraft","earth","orbiter"]},"sc_grail_a":{"id":"sc_grail_a","iauName":"GRAIL A","category":"Spacecraft","subcategory":"Orbiter","altName":"Ebb","keywords":["spacecraft","moon","orbiter","ebb"]},"sc_grail_b":{"id":"sc_grail_b","iauName":"GRAIL B","category":"Spacecraft","subcategory":"Orbiter","altName":"Flow","keywords":["spacecraft","moon","orbiter","flow"]},"sc_grifex":{"id":"sc_grifex","iauName":"GRIFEX","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_hubble_space_telescope":{"id":"sc_hubble_space_telescope","iauName":"Hubble Space Telescope","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","telescope","1990"]},"sc_huygens":{"id":"sc_huygens","iauName":"Huygens","category":"Spacecraft","subcategory":"Lander","keywords":["spacecraft","titan","cassini","lander"],"hasEvents":true},"sc_ibex":{"id":"sc_ibex","iauName":"IBEX","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_icesat_2":{"id":"sc_icesat_2","iauName":"ICESat-2","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_image":{"id":"sc_image","iauName":"IMAGE","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_insight":{"id":"sc_insight","iauName":"InSight","category":"Spacecraft","subcategory":"Lander","keywords":["spacecraft","mars","lander","seismic","2018"],"landingDate":"2018-11-26T19:45:00"},"sc_ipex":{"id":"sc_ipex","iauName":"IPEX","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_isas":{"id":"sc_isas","iauName":"ISAS","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_iss":{"id":"sc_iss","iauName":"International Space Station","category":"Spacecraft","subcategory":"Orbiter","altName":"ISS","keywords":["iss","international","international space","station","earth","orbiter","1998","emit","ecostress","oco-3"],"customDistance":0.1},"sc_iss_ecostress":{"id":"sc_iss_ecostress","iauName":"ECOSTRESS","category":"Instrument","cameraOptions":{"forwardVector":"-y-axis"},"comparisonFeature":false,"keywords":["spacecraft","earth","iss","orbiter"]},"sc_iss_emit":{"id":"sc_iss_emit","iauName":"EMIT","category":"Instrument","cameraOptions":{"forwardVector":"y-axis","distance":0.006},"comparisonFeature":false,"altName":"Earth Surface Mineral Dust Source Investigation","keywords":["spacecraft","earth","iss","orbiter"]},"sc_iss_oco_3":{"id":"sc_iss_oco_3","iauName":"OCO-3","category":"Instrument","cameraOptions":{"forwardVector":"-y-axis"},"comparisonFeature":false,"altName":"Orbiting Carbon Observatory 3","keywords":["spacecraft","earth","iss","orbiter"]},"sc_iss_rapidscat":{"id":"sc_iss_rapidscat","iauName":"RapidScat","category":"Instrument","cameraOptions":{"upVector":"-y-axis","forwardVector":"x-axis","distance":0.007},"comparisonFeature":false,"keywords":["spacecraft","earth","iss","orbiter"]},"sc_ixpe":{"id":"sc_ixpe","iauName":"IXPE","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","telescope","2021","x-ray","imaging x-ray polarimetry explorer","cosmic x-rays"]},"sc_jason_1":{"id":"sc_jason_1","iauName":"Jason-1","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_jason_2":{"id":"sc_jason_2","iauName":"Jason-2/OSTM","category":"Spacecraft","subcategory":"Orbiter","altName":"OSTM","keywords":["spacecraft","earth","orbiter","jason-2"]},"sc_jason_3":{"id":"sc_jason_3","iauName":"Jason-3","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_juice":{"id":"sc_juice","iauName":"Juice","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","jupiter","orbiter"]},"sc_juno":{"id":"sc_juno","iauName":"Juno","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","jupiter","orbiter","gravity","magnetic field","atmosphere","junocam","bruh","2011"],"customDistance":0.04,"hasEvents":true},"sc_jwst":{"id":"sc_jwst","iauName":"James Webb Space Telescope","category":"Spacecraft","subcategory":"Orbiter","altName":"James Webb Space Telescope","keywords":["spacecraft","earth","orbiter","telescope","jwst"],"hasEvents":true},"sc_kepler_space_telescope":{"id":"sc_kepler_space_telescope","iauName":"Kepler","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","telescope"]},"sc_ladee":{"id":"sc_ladee","iauName":"LADEE","category":"Spacecraft","subcategory":"Orbiter","altName":"Lunar Atmosphere and Dust Environment Explorer","keywords":["spacecraft","moon","orbiter"]},"sc_landsat_7":{"id":"sc_landsat_7","iauName":"Landsat 7","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_landsat_8":{"id":"sc_landsat_8","iauName":"Landsat 8","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_landsat_9":{"id":"sc_landsat_9","iauName":"Landsat 9","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_lcross":{"id":"sc_lcross","iauName":"LCROSS","category":"Spacecraft","subcategory":"Orbiter","altName":"Lunar Crater Observation and Sensing Satellite","keywords":["spacecraft","moon","orbiter"],"hasEvents":true},"sc_lucy":{"id":"sc_lucy","iauName":"Lucy","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"],"hasEvents":true},"sc_lunar_flashlight":{"id":"sc_lunar_flashlight","iauName":"Lunar Flashlight","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_lunar_icecube":{"id":"sc_lunar_icecube","iauName":"Lunar IceCube","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_lunar_prospector":{"id":"sc_lunar_prospector","iauName":"Lunar Prospector","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_lunar_reconnaissance_orbiter":{"id":"sc_lunar_reconnaissance_orbiter","iauName":"Lunar Reconnaissance Orbiter","category":"Spacecraft","subcategory":"Orbiter","altName":"LRO","keywords":["spacecraft","moon","orbiter","lro","temperature","imaging","albedo","polar","2009"]},"sc_lunar_trailblazer":{"id":"sc_lunar_trailblazer","iauName":"Lunar Trailblazer","category":"Spacecraft","subcategory":"Orbiter","altName":"","keywords":["spacecraft","moon","orbiter","lunar","trailblazer","water"],"disabled":true},"sc_lunir":{"id":"sc_lunir","iauName":"Lunar Reconnaissance Orbiter","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter","artemis"],"disabled":true},"sc_magellan":{"id":"sc_magellan","iauName":"Magellan","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","inner planet mission","venus"]},"sc_marco_a":{"id":"sc_marco_a","iauName":"MarCO A","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","insight","cubesat"]},"sc_marco_b":{"id":"sc_marco_b","iauName":"MarCO B","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","insight","cubesat"]},"sc_mars_2020":{"id":"sc_mars_2020","iauName":"Mars 2020 (Perseverance)","category":"Spacecraft","subcategory":"Rover","altName":"Percy","keywords":["spacecraft","mars","lander","rover","perseverance","mars 2020","mars2020","m2020"],"landingDate":"2021-02-18T20:55:00"},"sc_mars_2020_landing_site":{"id":"sc_mars_2020_landing_site","displayName":"Perseverance Rover landing site","category":"Landing site","comparisonFeature":false},"sc_mars_exploration_rover_1_landing_site":{"id":"sc_mars_exploration_rover_1_landing_site","displayName":"Opportunity Rover landing site","category":"Landing site","comparisonFeature":false},"sc_mars_exploration_rover_1":{"id":"sc_mars_exploration_rover_1","iauName":"Mars Exploration Rover B (Opportunity)","displayName":"Opportunity","category":"Spacecraft","subcategory":"Rover","keywords":["spacecraft","mars","lander","rover","opportunity","meridiani planum","2003","MER-B","MER-1","mer b"],"landingDate":"2004-01-25T04:54:00"},"sc_mars_exploration_rover_2_landing_site":{"id":"sc_mars_exploration_rover_2_landing_site","displayName":"Spirit Rover landing site","category":"Landing site","comparisonFeature":false},"sc_mars_exploration_rover_2":{"id":"sc_mars_exploration_rover_2","iauName":"Mars Exploration Rover A (Spirit)","displayName":"Spirit","category":"Spacecraft","subcategory":"Rover","keywords":["spacecraft","mars","lander","rover","spirit","MER-A","MER-2","mer a"],"landingDate":"2004-01-25T04:54:00"},"sc_mars_express":{"id":"sc_mars_express","iauName":"Mars Express","category":"Spacecraft","subcategory":"Orbiter","altName":"MEX","keywords":["spacecraft","mars","orbiter","water","geology","atmosphere","surface","relay","2003"]},"sc_mars_global_surveyor":{"id":"sc_mars_global_surveyor","iauName":"Mars Global Surveyor","category":"Spacecraft","subcategory":"Orbiter","altName":"MGS","keywords":["spacecraft","mars","MGS"]},"sc_mars_odyssey":{"id":"sc_mars_odyssey","iauName":"Mars Odyssey","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","mars","orbiter","elements","minerals","hydrogen","water","polar","radiation","relay","2001"]},"sc_mars_reconnaissance_orbiter":{"id":"sc_mars_reconnaissance_orbiter","iauName":"Mars Reconnaissance Orbiter","category":"Spacecraft","subcategory":"Orbiter","altName":"MRO","keywords":["spacecraft","mars","orbiter","mro","water","dust","atmosphere","relay","2005"]},"sc_mars_science_laboratory_landing_site":{"id":"sc_mars_science_laboratory_landing_site","displayName":"Curiosity Rover landing site","category":"Landing site","comparisonFeature":false},"sc_mars_science_laboratory":{"id":"sc_mars_science_laboratory","iauName":"Mars Science Laboratory (Curiosity)","displayName":"Mars Science Laboratory (Curiosity)","category":"Spacecraft","subcategory":"Rover","altName":"MSL","keywords":["spacecraft","mars","lander","rover","msl","curiosity","microbes","habitability","2011"],"landingDate":"2012-08-06T05:32:00"},"sc_maven":{"id":"sc_maven","iauName":"MAVEN","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","mars","orbiter","atmosphere","ionosphere","solar wind","relay","2013"]},"sc_messenger":{"id":"sc_messenger","iauName":"MESSENGER","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","mercury","orbiter"]},"sc_messenger_impact_site":{"id":"sc_messenger_impact_site","displayName":"MESSENGER Impact Site","category":"Landing site","comparisonFeature":false},"sc_mcubed_2":{"id":"sc_mcubed_2","iauName":"M-Cubed 2","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_mms_1":{"id":"sc_mms_1","iauName":"MMS 1","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_mms_2":{"id":"sc_mms_2","iauName":"MMS 2","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_mms_3":{"id":"sc_mms_3","iauName":"MMS 3","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_mms_4":{"id":"sc_mms_4","iauName":"MMS 4","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_near_shoemaker":{"id":"sc_near_shoemaker","iauName":"NEAR Shoemaker","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","eros","orbiter"],"related":{"asteroid":["433_eros"]},"hasEvents":true},"sc_new_horizons":{"id":"sc_new_horizons","iauName":"New Horizons","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","pluto","flyby","imager","spectrometer","ultraviolet","solar wind","extended mission","2006"],"hasEvents":true},"sc_nustar":{"id":"sc_nustar","iauName":"NuSTAR","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","telescope","X-ray","astrophysics"]},"sc_oco_2":{"id":"sc_oco_2","iauName":"OCO-2","category":"Spacecraft","subcategory":"Orbiter","altName":"Orbiting Carbon Observatory 2","keywords":["spacecraft","earth","orbiter"]},"sc_osiris_rex":{"id":"sc_osiris_rex","iauName":"OSIRIS-APEX","category":"Spacecraft","subcategory":"Orbiter","altName":"ORX","keywords":["spacecraft","bennu","apex","osiris-apex","lander","sample return","asteroids","chemistry","mineralogy","2016"],"related":{"asteroid":["101955_bennu","99942_apophis"]},"hasEvents":true},"sc_osiris_rex_src":{"id":"sc_osiris_rex_src","iauName":"OSIRIS-REx Sample Return Capsule","category":"Spacecraft","subcategory":"Flyby","altName":"ORX SRC","keywords":["spacecraft","Bennu","orbiter","sc_osiris_rex","SRC","sample return"],"related":{"asteroid":["101955_bennu"]},"hasEvents":true},"sc_pace":{"id":"sc_pace","iauName":"PACE","altName":"Plankton, Aerosol, Cloud, ocean Ecosystem","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_parker_solar_probe":{"id":"sc_parker_solar_probe","iauName":"Parker Solar Probe","category":"Spacecraft","subcategory":"Orbiter","altName":"PSP","keywords":["spacecraft","psp"]},"sc_philae":{"id":"sc_philae","iauName":"Philae","category":"Spacecraft","subcategory":"Lander","keywords":["spacecraft","67P/Churyumov-Gerasimenko","lander","Rosetta"],"related":{"comet":["67p_churyumov_gerasimenko"]},"hasEvents":true},"sc_phoenix":{"id":"sc_phoenix","iauName":"Phoenix","category":"Spacecraft","subcategory":"Lander","altName":"PHX","keywords":["spacecraft","mars","lander"],"landingDate":"2008-05-25T23:53:44"},"sc_phoenix_landing_site":{"id":"sc_phoenix_landing_site","displayName":"Phoenix landing site","category":"Landing site","comparisonFeature":false},"sc_pioneer_10":{"id":"sc_pioneer_10","iauName":"Pioneer 10","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","jupiter","callisto","ganymede","europa","io","flyby","outer planets","interstellar","1972"],"hasEvents":true},"sc_pioneer_11":{"id":"sc_pioneer_11","iauName":"Pioneer 11","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","jupiter","callisto","ganymede","io","europa","amalthea","saturn","iapetus","phoebe","hyperion","epimetheus","atlas","dione","mimas","janus","tethys","enceladus","calypso","rhea","titan","flyby","magnetic field","solar wind","outer planets","interstellar","1973"],"hasEvents":true},"sc_polar":{"id":"sc_polar","iauName":"Polar","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_prefire_1":{"id":"sc_prefire_1","iauName":"PREFIRE-1","category":"Spacecraft","subcategory":"Orbiter","constellation":"PREFIRE","keywords":["spacecraft","earth","orbiter"]},"sc_prefire_2":{"id":"sc_prefire_2","iauName":"PREFIRE-2","category":"Spacecraft","subcategory":"Orbiter","constellation":"PREFIRE","keywords":["spacecraft","earth","orbiter"]},"sc_psyche":{"id":"sc_psyche","iauName":"Psyche","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","16 Psyche","orbiter"],"related":{"asteroid":["16_psyche"]},"hasEvents":true},"sc_quikscat":{"id":"sc_quikscat","iauName":"QuikSCAT","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_raincube":{"id":"sc_raincube","iauName":"RainCube","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","cubesat"]},"sc_rbsp_a":{"id":"sc_rbsp_a","iauName":"Van Allen Probe A","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_rbsp_b":{"id":"sc_rbsp_b","iauName":"Van Allen Probe B","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_sac_d":{"id":"sc_sac_d","iauName":"Aquarius","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_rosetta":{"id":"sc_rosetta","iauName":"Rosetta","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","small body mission","67P/Churyumov-Gerasimenko"],"related":{"comet":["67p_churyumov_gerasimenko"]},"hasEvents":true},"sc_sdo":{"id":"sc_sdo","iauName":"Solar Dynamics Observatory","category":"Spacecraft","subcategory":"Orbiter","altName":"SDO","keywords":["spacecraft","earth","orbiter"]},"sc_sentinel_6":{"id":"sc_sentinel_6","iauName":"Sentinel-6 Michael Freilich","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","2020","sea level","jason","jason-cs","copernicus","topex/poseidon"]},"sc_smap":{"id":"sc_smap","iauName":"SMAP","category":"Spacecraft","subcategory":"Orbiter","altName":"Soil Moisture Active Passive","keywords":["spacecraft","earth","orbiter"]},"sc_soho":{"id":"sc_soho","iauName":"SOHO","category":"Spacecraft","subcategory":"Orbiter","altName":"Solar and Heliospheric Observatory","keywords":["spacecraft","sun","orbiter"]},"sc_sorce":{"id":"sc_sorce","iauName":"SORCE","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_spitzer":{"id":"sc_spitzer","iauName":"Spitzer Space Telescope","category":"Spacecraft","subcategory":"Orbiter","altName":"SIRTF","keywords":["spacecraft","sun","orbiter","sirtf","space infrared telescope facility","spitzer space telescope","2003"]},"sc_stardust":{"id":"sc_stardust","iauName":"Stardust","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","Wild-2","orbiter"],"related":{"comet":["81p_wild_2"]},"hasEvents":true},"sc_stardust_src":{"id":"sc_stardust_src","iauName":"Stardust Sample Return Capsule","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","Wild-2","orbiter"],"related":{"comet":["81p_wild_2"]}},"sc_starling_1":{"id":"sc_starling_1","iauName":"Starling-1","category":"Spacecraft","subcategory":"Orbiter","constellation":"STARLING","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_starling_2":{"id":"sc_starling_2","iauName":"Starling-2","category":"Spacecraft","subcategory":"Orbiter","constellation":"STARLING","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_starling_3":{"id":"sc_starling_3","iauName":"Starling-3","category":"Spacecraft","subcategory":"Orbiter","constellation":"STARLING","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_starling_4":{"id":"sc_starling_4","iauName":"Starling-4","category":"Spacecraft","subcategory":"Orbiter","constellation":"STARLING","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_stereo_ahead":{"id":"sc_stereo_ahead","iauName":"STEREO Ahead","category":"Spacecraft","subcategory":"Orbiter","altName":"STA","keywords":["spacecraft","sun","orbiter","solar terrestrial relations observatory","stereoscopic","coronal mass ejections","cme","2006"]},"sc_stereo_behind":{"id":"sc_stereo_behind","iauName":"STEREO Behind","category":"Spacecraft","subcategory":"Orbiter","altName":"STB","keywords":["spacecraft","sun","orbiter","solar terrestrial relations observatory","stereoscopic","coronal mass ejections","cme","2006"]},"sc_tdrs_3":{"id":"sc_tdrs_3","iauName":"TDRS-3","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_5":{"id":"sc_tdrs_5","iauName":"TDRS-5","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_6":{"id":"sc_tdrs_6","iauName":"TDRS-6","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_7":{"id":"sc_tdrs_7","iauName":"TDRS-7","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_8":{"id":"sc_tdrs_8","iauName":"TDRS-8","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_9":{"id":"sc_tdrs_9","iauName":"TDRS-9","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_10":{"id":"sc_tdrs_10","iauName":"TDRS-10","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_11":{"id":"sc_tdrs_11","iauName":"TDRS-11","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_12":{"id":"sc_tdrs_12","iauName":"TDRS-12","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_13":{"id":"sc_tdrs_13","iauName":"TDRS-13","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_suomi_npp":{"id":"sc_suomi_npp","iauName":"Suomi NPP","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_swot":{"id":"sc_swot","iauName":"SWOT","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_tempo":{"id":"sc_tempo","iauName":"TEMPO","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_terra":{"id":"sc_terra","iauName":"Terra","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_tess":{"id":"sc_tess","iauName":"TESS","category":"Spacecraft","subcategory":"Orbiter","altName":"Transiting Exoplanet Survey Satellite","keywords":["spacecraft","earth","telescope","transiting exoplanet survey satellite","orbiter","2018","exoplanets"]},"sc_themis_a":{"id":"sc_themis_a","iauName":"THEMIS-A","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_themis_b":{"id":"sc_themis_b","iauName":"ARTEMIS P1","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_themis_c":{"id":"sc_themis_c","iauName":"ARTEMIS P2","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_themis_d":{"id":"sc_themis_d","iauName":"THEMIS-D","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_themis_e":{"id":"sc_themis_e","iauName":"THEMIS-E","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_trace_gas_orbiter":{"id":"sc_trace_gas_orbiter","iauName":"Trace Gas Orbiter","category":"Spacecraft","subcategory":"Orbiter","altName":"TGO","keywords":["spacecraft","mars","orbiter","tgo","atmosphere","relay","2016"]},"sc_trmm":{"id":"sc_trmm","iauName":"TRMM","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_tropics_03":{"id":"sc_tropics_03","iauName":"TROPICS-03","category":"Spacecraft","subcategory":"Orbiter","constellation":"TROPICS","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_tropics_05":{"id":"sc_tropics_05","iauName":"TROPICS-05","category":"Spacecraft","subcategory":"Orbiter","constellation":"TROPICS","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_tropics_06":{"id":"sc_tropics_06","iauName":"TROPICS-06","category":"Spacecraft","subcategory":"Orbiter","constellation":"TROPICS","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_tropics_07":{"id":"sc_tropics_07","iauName":"TROPICS-07","category":"Spacecraft","subcategory":"Orbiter","constellation":"TROPICS","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_tropics_01":{"id":"sc_tropics_01","iauName":"TROPICS-01","category":"Spacecraft","subcategory":"Orbiter","constellation":"TROPICS","keywords":["spacecraft","earth","orbiter","tropics pathfinder","pathfinder"],"disabled":false},"sc_ulysses":{"id":"sc_ulysses","iauName":"Ulysses","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","sun","orbiter"]},"sc_voyager_1":{"id":"sc_voyager_1","iauName":"Voyager 1","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","jupiter","saturn","flyby","imaging","vger","radio science","infrared","ultraviolet","magnetometer","plasma","1977"],"hasEvents":true},"sc_voyager_2":{"id":"sc_voyager_2","iauName":"Voyager 2","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","jupiter","saturn","uranus","vger","neptune","flyby","imaging","radio science","infrared","ultraviolet","magnetometer","plasma","1977"],"hasEvents":true},"sc_wind":{"id":"sc_wind","iauName":"WIND","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","solar wind","earth","orbiter"]},"valetudo":{"id":"valetudo","iauName":"Valetudo","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"scientist":{"id":"scientist","displayName":"Scientist","category":"Human","searchable":false},"school_bus":{"id":"school_bus","displayName":"School Bus","category":"Vehicle","searchable":false},"rose_bowl":{"id":"rose_bowl","displayName":"Stadium","category":"Building","searchable":false}}'); + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ id: moduleId, +/******/ loaded: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = __webpack_modules__; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/chunk loaded */ +/******/ !function() { +/******/ var deferred = []; +/******/ __webpack_require__.O = function(result, chunkIds, fn, priority) { +/******/ if(chunkIds) { +/******/ priority = priority || 0; +/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; +/******/ deferred[i] = [chunkIds, fn, priority]; +/******/ return; +/******/ } +/******/ var notFulfilled = Infinity; +/******/ for (var i = 0; i < deferred.length; i++) { +/******/ var chunkIds = deferred[i][0]; +/******/ var fn = deferred[i][1]; +/******/ var priority = deferred[i][2]; +/******/ var fulfilled = true; +/******/ for (var j = 0; j < chunkIds.length; j++) { +/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) { +/******/ chunkIds.splice(j--, 1); +/******/ } else { +/******/ fulfilled = false; +/******/ if(priority < notFulfilled) notFulfilled = priority; +/******/ } +/******/ } +/******/ if(fulfilled) { +/******/ deferred.splice(i--, 1) +/******/ var r = fn(); +/******/ if (r !== undefined) result = r; +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/compat get default export */ +/******/ !function() { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function() { return module['default']; } : +/******/ function() { return module; }; +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ !function() { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = function(exports, definition) { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/global */ +/******/ !function() { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ }(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ !function() { +/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } +/******/ }(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ !function() { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/node module decorator */ +/******/ !function() { +/******/ __webpack_require__.nmd = function(module) { +/******/ module.paths = []; +/******/ if (!module.children) module.children = []; +/******/ return module; +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/jsonp chunk loading */ +/******/ !function() { +/******/ // no baseURI +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ "main": 0 +/******/ }; +/******/ +/******/ // no chunk on demand loading +/******/ +/******/ // no prefetching +/******/ +/******/ // no preloaded +/******/ +/******/ // no HMR +/******/ +/******/ // no HMR manifest +/******/ +/******/ __webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; }; +/******/ +/******/ // install a JSONP callback for chunk loading +/******/ var webpackJsonpCallback = function(parentChunkLoadingFunction, data) { +/******/ var chunkIds = data[0]; +/******/ var moreModules = data[1]; +/******/ var runtime = data[2]; +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ installedChunks[chunkId][0](); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ return __webpack_require__.O(result); +/******/ } +/******/ +/******/ var chunkLoadingGlobal = self["webpackChunkasteroids"] = self["webpackChunkasteroids"] || []; +/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); +/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); +/******/ }(); +/******/ +/************************************************************************/ +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module depends on other loaded chunks and execution need to be delayed +/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["vendors"], function() { return __webpack_require__("./src/app.js"); }) +/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); +/******/ +/******/ })() +; +//# sourceMappingURL=app.js.map \ No newline at end of file diff --git a/experiences/asteroids/web/assets/default/fonts/DMMono-Italic.woff b/experiences/asteroids/web/assets/default/fonts/DMMono-Italic.woff new file mode 100644 index 0000000..d9ed85b Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/DMMono-Italic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/DMMono-Light.woff b/experiences/asteroids/web/assets/default/fonts/DMMono-Light.woff new file mode 100644 index 0000000..f35d327 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/DMMono-Light.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/DMMono-LightItalic.woff b/experiences/asteroids/web/assets/default/fonts/DMMono-LightItalic.woff new file mode 100644 index 0000000..9e6df20 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/DMMono-LightItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/DMMono-Medium.woff b/experiences/asteroids/web/assets/default/fonts/DMMono-Medium.woff new file mode 100644 index 0000000..5ea142d Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/DMMono-Medium.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/DMMono-MediumItalic.woff b/experiences/asteroids/web/assets/default/fonts/DMMono-MediumItalic.woff new file mode 100644 index 0000000..1a058f2 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/DMMono-MediumItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/DMMono-Regular.woff b/experiences/asteroids/web/assets/default/fonts/DMMono-Regular.woff new file mode 100644 index 0000000..fec1940 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/DMMono-Regular.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Inter-Bold.woff b/experiences/asteroids/web/assets/default/fonts/Inter-Bold.woff new file mode 100644 index 0000000..80f70f0 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Inter-Bold.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Inter-Bold.woff2 b/experiences/asteroids/web/assets/default/fonts/Inter-Bold.woff2 new file mode 100644 index 0000000..622e5f1 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Inter-Bold.woff2 differ diff --git a/experiences/asteroids/web/assets/default/fonts/Inter-Light.woff b/experiences/asteroids/web/assets/default/fonts/Inter-Light.woff new file mode 100644 index 0000000..0df2bc7 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Inter-Light.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Inter-Light.woff2 b/experiences/asteroids/web/assets/default/fonts/Inter-Light.woff2 new file mode 100644 index 0000000..b09ea9d Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Inter-Light.woff2 differ diff --git a/experiences/asteroids/web/assets/default/fonts/Inter-Regular.woff b/experiences/asteroids/web/assets/default/fonts/Inter-Regular.woff new file mode 100644 index 0000000..7cb4990 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Inter-Regular.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Inter-Regular.woff2 b/experiences/asteroids/web/assets/default/fonts/Inter-Regular.woff2 new file mode 100644 index 0000000..66691b8 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Inter-Regular.woff2 differ diff --git a/experiences/asteroids/web/assets/default/fonts/Inter-SemiBold.woff b/experiences/asteroids/web/assets/default/fonts/Inter-SemiBold.woff new file mode 100644 index 0000000..490bd9d Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Inter-SemiBold.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Inter-SemiBold.woff2 b/experiences/asteroids/web/assets/default/fonts/Inter-SemiBold.woff2 new file mode 100644 index 0000000..9fd7726 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Inter-SemiBold.woff2 differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-Black.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-Black.woff new file mode 100644 index 0000000..0b4022d Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-Black.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-BlackItalic.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-BlackItalic.woff new file mode 100644 index 0000000..470b7e6 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-BlackItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-Bold.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-Bold.woff new file mode 100644 index 0000000..8538378 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-Bold.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-BoldItalic.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-BoldItalic.woff new file mode 100644 index 0000000..377c991 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-BoldItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraBold.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraBold.woff new file mode 100644 index 0000000..fc98683 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraBold.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraBoldItalic.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraBoldItalic.woff new file mode 100644 index 0000000..7039b62 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraBoldItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraLight.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraLight.woff new file mode 100644 index 0000000..7e5c31e Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraLight.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraLightItalic.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraLightItalic.woff new file mode 100644 index 0000000..da2929c Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-ExtraLightItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-Light.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-Light.woff new file mode 100644 index 0000000..f3a84ef Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-Light.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-LightItalic.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-LightItalic.woff new file mode 100644 index 0000000..ee72f2c Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-LightItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-Medium.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-Medium.woff new file mode 100644 index 0000000..cd3c1ab Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-Medium.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-MediumItalic.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-MediumItalic.woff new file mode 100644 index 0000000..814a9d5 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-MediumItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-Regular.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-Regular.woff new file mode 100644 index 0000000..6aa4dba Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-Regular.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-RegularItalic.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-RegularItalic.woff new file mode 100644 index 0000000..019578a Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-RegularItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-SemiBold.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-SemiBold.woff new file mode 100644 index 0000000..ca2edb0 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-SemiBold.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-SemiBoldItalic.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-SemiBoldItalic.woff new file mode 100644 index 0000000..3c6a03b Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-SemiBoldItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-Thin.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-Thin.woff new file mode 100644 index 0000000..40341f4 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-Thin.woff differ diff --git a/experiences/asteroids/web/assets/default/fonts/Metropolis-ThinItalic.woff b/experiences/asteroids/web/assets/default/fonts/Metropolis-ThinItalic.woff new file mode 100644 index 0000000..8943df9 Binary files /dev/null and b/experiences/asteroids/web/assets/default/fonts/Metropolis-ThinItalic.woff differ diff --git a/experiences/asteroids/web/assets/default/svg/crosshair.svg b/experiences/asteroids/web/assets/default/svg/crosshair.svg new file mode 100644 index 0000000..66ab913 --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/crosshair.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/experiences/asteroids/web/assets/default/svg/cubemap.svg b/experiences/asteroids/web/assets/default/svg/cubemap.svg new file mode 100644 index 0000000..fee5596 --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/cubemap.svg @@ -0,0 +1,45 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/experiences/asteroids/web/assets/default/svg/finger.svg b/experiences/asteroids/web/assets/default/svg/finger.svg new file mode 100644 index 0000000..57fccc7 --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/finger.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/experiences/asteroids/web/assets/default/svg/help_icon.svg b/experiences/asteroids/web/assets/default/svg/help_icon.svg new file mode 100644 index 0000000..4c5b117 --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/help_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/experiences/asteroids/web/assets/default/svg/icon_clock.svg b/experiences/asteroids/web/assets/default/svg/icon_clock.svg new file mode 100644 index 0000000..0fb8734 --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/icon_clock.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/experiences/asteroids/web/assets/default/svg/learn.svg b/experiences/asteroids/web/assets/default/svg/learn.svg new file mode 100644 index 0000000..6384219 --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/learn.svg @@ -0,0 +1,3 @@ + + + diff --git a/experiences/asteroids/web/assets/default/svg/locked.svg b/experiences/asteroids/web/assets/default/svg/locked.svg new file mode 100644 index 0000000..ecfc356 --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/locked.svg @@ -0,0 +1,3 @@ + + + diff --git a/experiences/asteroids/web/assets/default/svg/nasa_logo.svg b/experiences/asteroids/web/assets/default/svg/nasa_logo.svg new file mode 100644 index 0000000..0c358c6 --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/nasa_logo.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/experiences/asteroids/web/assets/default/svg/share_arrow.svg b/experiences/asteroids/web/assets/default/svg/share_arrow.svg new file mode 100644 index 0000000..a25b0bb --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/share_arrow.svg @@ -0,0 +1 @@ + diff --git a/experiences/asteroids/web/assets/default/svg/sprite.svg b/experiences/asteroids/web/assets/default/svg/sprite.svg new file mode 100644 index 0000000..1681a1b --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/sprite.svg @@ -0,0 +1,422 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/experiences/asteroids/web/assets/default/svg/time_slider_lines.svg b/experiences/asteroids/web/assets/default/svg/time_slider_lines.svg new file mode 100644 index 0000000..aeef229 --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/time_slider_lines.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/experiences/asteroids/web/assets/default/svg/timeline_bg.svg b/experiences/asteroids/web/assets/default/svg/timeline_bg.svg new file mode 100644 index 0000000..dd761e1 --- /dev/null +++ b/experiences/asteroids/web/assets/default/svg/timeline_bg.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/experiences/asteroids/web/assets/fonts/Mamam.woff b/experiences/asteroids/web/assets/fonts/Mamam.woff new file mode 100644 index 0000000..2e8fb93 Binary files /dev/null and b/experiences/asteroids/web/assets/fonts/Mamam.woff differ diff --git a/experiences/asteroids/web/assets/images/outterAsteroidBelt.png b/experiences/asteroids/web/assets/images/outterAsteroidBelt.png new file mode 100644 index 0000000..3626727 Binary files /dev/null and b/experiences/asteroids/web/assets/images/outterAsteroidBelt.png differ diff --git a/experiences/asteroids/web/assets/svg/arrow_next.svg b/experiences/asteroids/web/assets/svg/arrow_next.svg new file mode 100644 index 0000000..7d10d45 --- /dev/null +++ b/experiences/asteroids/web/assets/svg/arrow_next.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/experiences/asteroids/web/assets/svg/arrow_prev.svg b/experiences/asteroids/web/assets/svg/arrow_prev.svg new file mode 100644 index 0000000..88c55a7 --- /dev/null +++ b/experiences/asteroids/web/assets/svg/arrow_prev.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/experiences/asteroids/web/assets/svg/asteroid.svg b/experiences/asteroids/web/assets/svg/asteroid.svg new file mode 100644 index 0000000..a36bc81 --- /dev/null +++ b/experiences/asteroids/web/assets/svg/asteroid.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/experiences/asteroids/web/assets/svg/circuit_brain.svg b/experiences/asteroids/web/assets/svg/circuit_brain.svg new file mode 100644 index 0000000..230933b --- /dev/null +++ b/experiences/asteroids/web/assets/svg/circuit_brain.svg @@ -0,0 +1,3 @@ + + + diff --git a/experiences/asteroids/web/assets/svg/comet.svg b/experiences/asteroids/web/assets/svg/comet.svg new file mode 100644 index 0000000..30a0727 --- /dev/null +++ b/experiences/asteroids/web/assets/svg/comet.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/experiences/asteroids/web/assets/svg/filter_inactive.svg b/experiences/asteroids/web/assets/svg/filter_inactive.svg new file mode 100644 index 0000000..5a6abe8 --- /dev/null +++ b/experiences/asteroids/web/assets/svg/filter_inactive.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/experiences/asteroids/web/assets/svg/icon_clock.svg b/experiences/asteroids/web/assets/svg/icon_clock.svg new file mode 100644 index 0000000..e4303b8 --- /dev/null +++ b/experiences/asteroids/web/assets/svg/icon_clock.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/experiences/asteroids/web/assets/svg/mobile_arrow.svg b/experiences/asteroids/web/assets/svg/mobile_arrow.svg new file mode 100644 index 0000000..ee7ead4 --- /dev/null +++ b/experiences/asteroids/web/assets/svg/mobile_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/experiences/asteroids/web/assets/svg/oumuamua.svg b/experiences/asteroids/web/assets/svg/oumuamua.svg new file mode 100644 index 0000000..3f2270e --- /dev/null +++ b/experiences/asteroids/web/assets/svg/oumuamua.svg @@ -0,0 +1 @@ + diff --git a/experiences/asteroids/web/assets/svg/rock.svg b/experiences/asteroids/web/assets/svg/rock.svg new file mode 100644 index 0000000..126c7b6 --- /dev/null +++ b/experiences/asteroids/web/assets/svg/rock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/experiences/asteroids/web/assets/svg/ruler.svg b/experiences/asteroids/web/assets/svg/ruler.svg new file mode 100644 index 0000000..c603802 --- /dev/null +++ b/experiences/asteroids/web/assets/svg/ruler.svg @@ -0,0 +1,3 @@ + + + diff --git a/experiences/asteroids/web/assets/svg/spacecraft.svg b/experiences/asteroids/web/assets/svg/spacecraft.svg new file mode 100644 index 0000000..6e9b101 --- /dev/null +++ b/experiences/asteroids/web/assets/svg/spacecraft.svg @@ -0,0 +1,3 @@ + + + diff --git a/experiences/asteroids/web/config.js b/experiences/asteroids/web/config.js new file mode 100644 index 0000000..fa9da68 --- /dev/null +++ b/experiences/asteroids/web/config.js @@ -0,0 +1,5 @@ +window.config = { + staticAssetsUrl: 'https://eyes.nasa.gov/assets/static', + dynamicAssetsUrl: 'https://eyes.nasa.gov/assets/dynamic', + animdataUrl: 'https://eyes.nasa.gov/server/spice' +}; diff --git a/experiences/asteroids/web/events/sc_cassini/all_events.json b/experiences/asteroids/web/events/sc_cassini/all_events.json new file mode 100644 index 0000000..15579c2 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/all_events.json @@ -0,0 +1,1356 @@ +{ + "launch": { + "id": "launch", + "title": "Cassini Launch", + "start": "1997-10-15T09:26:00", + "end": "1997-10-16T09:26:00", + "target": "earth", + "distance": 0.05, + "rate": 60 + }, + "jupiter_flyby": { + "id": "jupiter_flyby", + "title": "Jupiter Flyby", + "start": "2000-12-27T01:24:00", + "end": "2001-01-02T10:15:00", + "target": "jupiter", + "rate": 3600, + "distance": 0.05, + "horizontalOffset": 10, + "verticalOffset": 5 + }, + "saturn_orbit_insertion": { + "id": "saturn_orbit_insertion", + "title": "Saturn Orbit Insertion", + "start": "2004-06-30T12:38:22.5279", + "end": "2004-07-03T02:38:22.5279", + "target": "saturn", + "distance": 0.05, + "rate": 3000, + "horizontalOffset": -6 + }, + "descent_to_titan": { + "id": "descent_to_titan", + "title": "Descent to Titan", + "start": "2005-01-13T11:00:00", + "end": "2005-01-14T11:25:00", + "target": "sc_huygens", + "rate": 3600, + "distance": 0.07, + "horizontalOffset": -10 + }, + "closest_enceladus_flyby": { + "id": "closest_enceladus_flyby", + "title": "Closest Enceladus Flyby", + "start": "2008-10-09T19:03:00", + "end": "2008-10-09T23:35:00", + "target": "enceladus", + "rate": 15, + "distance": 0.07, + "horizontalOffset": 15 + }, + "grand_finale": { + "id": "grand_finale", + "title": "The Grand Finale", + "start": "2017-04-26T08:15:00", + "end": "2017-09-15T11:55:46", + "target": "saturn", + "rate": 60, + "distance": 0.1 + }, + "earth_flyby": { + "id": "earth_flyby", + "title": "Earth Flyby", + "start": "1999-08-18T00:40:25.8842", + "end": "1999-08-19T03:28:25", + "target": "earth", + "rate": 600, + "distance": 0.05, + "horizontalOffset": -6 + }, + "venus_flyby_1": { + "id": "venus_flyby_1", + "title": "First Venus Flyby", + "start": "1998-04-26T06:45:40", + "end": "1998-04-27T20:14:40", + "target": "venus", + "rate": 2500, + "distance": 0.05, + "horizontalOffset": -5 + }, + "huygens": { + "id": "huygens", + "title": "Huygens Deployment", + "start": "2004-12-25T01:59:53", + "end": "2004-12-25T02:46:00", + "target": "sc_huygens", + "distance": 0.03 + }, + "enceladus_discovery": { + "id": "enceladus_discovery", + "title": "Discovery at Enceladus", + "start": "2005-02-17T02:15:00", + "end": "2005-02-17T05:30:00", + "target": "enceladus", + "distance": 0.05, + "rate": 300, + "horizontalOffset": -5 + }, + "titan_n_lake": { + "id": "titan_n_lake", + "title": "Titan Northern Lakes", + "start": "2006-07-21T20:44:00", + "end": "2006-07-22T01:11:00", + "target": "titan", + "template": "titan_flybys.json", + "rate": 230, + "horizontalOffset": -7, + "verticalOffset": 7 + }, + "backlit_saturn": { + "id": "backlit_saturn", + "title": "Backlit Saturn", + "start": "2006-09-08T12:00:00", + "end": "2006-09-15T18:20:00", + "target": "saturn" + }, + "wave_saturn": { + "id": "wave_saturn", + "title": "The Wave at Saturn", + "start": "2013-07-19T21:27:00", + "end": "2013-07-19T21:55:00", + "target": "saturn", + "distance": 0.05, + "rate": 200 + }, + "first_ring_plane_crossing": { + "id": "first_ring_plane_crossing", + "title": "First Ring Plane Crossing", + "start": "2017-04-26T08:30:35", + "target": "saturn", + "distance": 1.0, + "rate": 100 + }, + "final_transmission": { + "id": "final_transmission", + "title": "The Final Transmission", + "start": "2017-09-15T07:01:45", + "end": "2017-09-15T11:55:46", + "target": "saturn", + "rate": 200, + "distance": 0.06 + }, + "phoebe_p-1": { + "id": "phoebe_p-1", + "title": "Phoebe flyby #1", + "start": "2004-06-11T18:50:00", + "target": "phoebe", + "template": "phoebe_flybys.json", + "horizontalOffset": -5 + }, + "titan_t-a": { + "id": "titan_t-a", + "title": "Titan flyby #1", + "start": "2004-10-26T14:30:05", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-b": { + "id": "titan_t-b", + "title": "Titan flyby #2", + "start": "2004-12-13T10:38:15", + "target": "titan", + "template": "titan_flybys.json" + }, + "iapetus_i-0": { + "id": "iapetus_i-0", + "title": "Iapetus flyby #1", + "start": "2004-12-31T14:00", + "target": "iapetus", + "template": "iapetus_flybys.json", + "distance": 0.05, + "horizontalOffset": -10, + "rate": 600 + }, + "titan_t-3": { + "id": "titan_t-3", + "title": "Titan flyby #3", + "start": "2005-02-15T06:00:00", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-0": { + "id": "enceladus_e-0", + "title": "Enceladus flyby #1", + "start": "2005-02-17T02:15:00", + "target": "enceladus", + "template": "enceladus_flybys.json", + "distance": 0.05, + "rate": 300, + "horizontalOffset": -5 + }, + "enceladus_e-1": { + "id": "enceladus_e-1", + "title": "Enceladus flyby #2", + "start": "2005-03-09T09:00:02", + "target": "enceladus", + "template": "enceladus_flybys.json", + "distance": 0.05, + "rate": 25, + "horizontalOffset": -5 + }, + "titan_t-4": { + "id": "titan_t-4", + "title": "Titan flyby #4", + "start": "2005-03-31T18:54:16", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-5": { + "id": "titan_t-5", + "title": "Titan flyby #5", + "start": "2005-04-16T18:28:16", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-2": { + "id": "enceladus_e-2", + "title": "Enceladus flyby #3", + "start": "2005-07-14T19:47:21", + "target": "enceladus", + "template": "enceladus_flybys.json", + "distance": 0.05, + "rate": 20, + "horizontalOffset": 8 + }, + "titan_t-6": { + "id": "titan_t-6", + "title": "Titan flyby #6", + "start": "2005-08-22T07:30:37", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-7": { + "id": "titan_t-7", + "title": "Titan flyby #7", + "start": "2005-09-07T07:23:57", + "target": "titan", + "template": "titan_flybys.json" + }, + "tethys_te-1": { + "id": "tethys_te-1", + "title": "Tethys flyby", + "start": "2005-09-24T02:28:19", + "target": "tethys", + "template": "tethys_flybys.json", + "distance": 0.05, + "rate": 23, + "horizontalOffset": -7 + }, + "hyperion_h-1": { + "id": "hyperion_h-1", + "title": "Hyperion flyby", + "start": "2005-09-26T02:15:46", + "target": "hyperion", + "template": "hyperion_flybys.json", + "distance": 0.05, + "rate": 15, + "horizontalOffset": -8 + }, + "dione_d-1": { + "id": "dione_d-1", + "title": "Dione flyby #1", + "start": "2005-10-11T17:35:00", + "target": "dione", + "template": "dione_flybys.json", + "horizontalOffset": -8, + "verticalOffset": -8 + }, + "titan_t-8": { + "id": "titan_t-8", + "title": "Titan flyby #8", + "start": "2005-10-28T03:21:24", + "target": "titan", + "template": "titan_flybys.json" + }, + "rhea_r-1": { + "id": "rhea_r-1", + "title": "Rhea flyby #1", + "start": "2005-11-26T22:15:06", + "target": "rhea", + "template": "rhea_flybys.json" + }, + "titan_t-9": { + "id": "titan_t-9", + "title": "Titan flyby #9", + "start": "2005-12-26T17:48:25", + "target": "titan", + "template": "titan_flybys.json", + "horizontalOffset": -8 + }, + "titan_t-10": { + "id": "titan_t-10", + "title": "Titan flyby #10", + "start": "2006-01-15T10:36:26", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-11": { + "id": "titan_t-11", + "title": "Titan flyby #11", + "start": "2006-02-27T07:35:17", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-12": { + "id": "titan_t-12", + "title": "Titan flyby #12", + "start": "2006-03-18T23:03:00", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-13": { + "id": "titan_t-13", + "title": "Titan flyby #13", + "start": "2006-04-30T20:10:13", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-14": { + "id": "titan_t-14", + "title": "Titan flyby #14", + "start": "2006-05-20T11:18:10", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-15": { + "id": "titan_t-15", + "title": "Titan flyby #15", + "start": "2006-07-02T08:18:46", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-16": { + "id": "titan_t-16", + "title": "Titan flyby #16", + "start": "2006-07-21T20:44:25", + "target": "titan", + "template": "titan_flybys.json", + "rate": 230, + "horizontalOffset": -7, + "verticalOffset": 7 + }, + "titan_t-17": { + "id": "titan_t-17", + "title": "Titan flyby #17", + "start": "2006-09-07T19:35:50", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-18": { + "id": "titan_t-18", + "title": "Titan flyby #18", + "start": "2006-09-23T18:25:49", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-19": { + "id": "titan_t-19", + "title": "Titan flyby #19", + "start": "2006-10-09T16:49:07", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-20": { + "id": "titan_t-20", + "title": "Titan flyby #20", + "start": "2006-10-25T15:17:06", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-21": { + "id": "titan_t-21", + "title": "Titan flyby #21", + "start": "2006-12-12T11:08:25", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-22": { + "id": "titan_t-22", + "title": "Titan flyby #22", + "start": "2006-12-28T09:28:21", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-23": { + "id": "titan_t-23", + "title": "Titan flyby #23", + "start": "2007-01-13T08:00:31", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-24": { + "id": "titan_t-24", + "title": "Titan flyby #24", + "start": "2007-01-29T06:32:54", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-25": { + "id": "titan_t-25", + "title": "Titan flyby #25", + "start": "2007-02-22T02:44:24", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-26": { + "id": "titan_t-26", + "title": "Titan flyby #26", + "start": "2007-03-10T01:20:00", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-27": { + "id": "titan_t-27", + "title": "Titan flyby #27", + "start": "2007-03-25T23:23:27", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-28": { + "id": "titan_t-28", + "title": "Titan flyby #28", + "start": "2007-04-10T22:25:59", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-29": { + "id": "titan_t-29", + "title": "Titan flyby #29", + "start": "2007-04-26T21:00:57", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-30": { + "id": "titan_t-30", + "title": "Titan flyby #30", + "start": "2007-05-12T19:32:57", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-31": { + "id": "titan_t-31", + "title": "Titan flyby #31", + "start": "2007-05-28T18:12:55", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-32": { + "id": "titan_t-32", + "title": "Titan flyby #32", + "start": "2007-06-13T17:15:10", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-33": { + "id": "titan_t-33", + "title": "Titan flyby #33", + "start": "2007-06-29T16:31:45", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-34": { + "id": "titan_t-34", + "title": "Titan flyby #34", + "start": "2007-07-19T00:35:19", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-35": { + "id": "titan_t-35", + "title": "Titan flyby #35", + "start": "2007-08-31T06:00:35", + "target": "titan", + "template": "titan_flybys.json" + }, + "iapetus_i-1": { + "id": "iapetus_i-1", + "title": "Iapetus flyby #2", + "start": "2007-09-10T13:13:48", + "target": "iapetus", + "template": "iapetus_flybys.json", + "rate": 60, + "distance": 0.05, + "horizontalOffset": -10 + }, + "titan_t-36": { + "id": "titan_t-36", + "title": "Titan flyby #36", + "start": "2007-10-02T04:06:42", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-37": { + "id": "titan_t-37", + "title": "Titan flyby #37", + "start": "2007-11-19T00:16:24", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-38": { + "id": "titan_t-38", + "title": "Titan flyby #38", + "start": "2007-12-04T23:31:49", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-39": { + "id": "titan_t-39", + "title": "Titan flyby #39", + "start": "2007-12-20T22:32:54", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-40": { + "id": "titan_t-40", + "title": "Titan flyby #40", + "start": "2008-01-05T21:00:19", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-41": { + "id": "titan_t-41", + "title": "Titan flyby #41", + "start": "2008-02-22T17:00:06", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-3": { + "id": "enceladus_e-3", + "title": "Enceladus flyby #4", + "start": "2008-03-12T18:55:11", + "target": "enceladus", + "template": "enceladus_flybys.json", + "horizontalOffset": -20, + "distance": 0.05 + }, + "titan_t-42": { + "id": "titan_t-42", + "title": "Titan flyby #42", + "start": "2008-03-25T13:52:48", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-43": { + "id": "titan_t-43", + "title": "Titan flyby #43", + "start": "2008-05-12T09:30:57", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-44": { + "id": "titan_t-44", + "title": "Titan flyby #44", + "start": "2008-05-28T07:46:31", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-45": { + "id": "titan_t-45", + "title": "Titan flyby #45", + "start": "2008-07-31T01:44:10", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-4": { + "id": "enceladus_e-4", + "title": "Enceladus flyby #5", + "start": "2008-08-11T21:04:18", + "target": "enceladus", + "template": "enceladus_flybys.json", + "rate": 15, + "distance": 0.07, + "horizontalOffset": 15 + }, + "enceladus_e-5": { + "id": "enceladus_e-5", + "title": "Enceladus flyby #6", + "start": "2008-10-09T19:01:00", + "target": "enceladus", + "template": "enceladus_flybys.json", + "rate": 15, + "distance": 0.07, + "horizontalOffset": 15 + }, + "enceladus_e-6": { + "id": "enceladus_e-6", + "title": "Enceladus flyby #7", + "start": "2008-10-31T17:05:00", + "target": "enceladus", + "template": "enceladus_flybys.json", + "rate": 30, + "distance": 0.07, + "horizontalOffset": 15 + }, + "titan_t-46": { + "id": "titan_t-46", + "title": "Titan flyby #46", + "start": "2008-11-03T17:02:22", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-47": { + "id": "titan_t-47", + "title": "Titan flyby #47", + "start": "2008-11-19T15:23:27", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-48": { + "id": "titan_t-48", + "title": "Titan flyby #48", + "start": "2008-12-05T13:53:44", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-49": { + "id": "titan_t-49", + "title": "Titan flyby #49", + "start": "2008-12-21T12:28:52", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-50": { + "id": "titan_t-50", + "title": "Titan flyby #50", + "start": "2009-02-07T08:21:51", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-51": { + "id": "titan_t-51", + "title": "Titan flyby #51", + "start": "2009-03-27T04:05:35", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-52": { + "id": "titan_t-52", + "title": "Titan flyby #52", + "start": "2009-04-04T01:07:46", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-53": { + "id": "titan_t-53", + "title": "Titan flyby #53", + "start": "2009-04-19T23:45:45", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-54": { + "id": "titan_t-54", + "title": "Titan flyby #54", + "start": "2009-05-05T22:16:14", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-55": { + "id": "titan_t-55", + "title": "Titan flyby #55", + "start": "2009-05-21T20:55:41", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-56": { + "id": "titan_t-56", + "title": "Titan flyby #56", + "start": "2009-06-06T19:20:00", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-57": { + "id": "titan_t-57", + "title": "Titan flyby #57", + "start": "2009-06-22T18:00:34", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-58": { + "id": "titan_t-58", + "title": "Titan flyby #58", + "start": "2009-07-08T16:35:02", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-59": { + "id": "titan_t-59", + "title": "Titan flyby #59", + "start": "2009-07-24T15:06:03", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-60": { + "id": "titan_t-60", + "title": "Titan flyby #60", + "start": "2009-08-09T13:33:53", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-61": { + "id": "titan_t-61", + "title": "Titan flyby #61", + "start": "2009-08-25T12:20:38", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-62": { + "id": "titan_t-62", + "title": "Titan flyby #62", + "start": "2009-10-12T08:09:24", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-7": { + "id": "enceladus_e-7", + "title": "Enceladus flyby #8", + "start": "2009-11-02T07:35:44", + "target": "enceladus", + "template": "enceladus_flybys.json" + }, + "enceladus_e-8": { + "id": "enceladus_e-8", + "title": "Enceladus flyby #9", + "start": "2009-11-21T01:58:56", + "target": "enceladus", + "template": "enceladus_flybys.json", + "horizontalOffset": -10 + }, + "titan_t-63": { + "id": "titan_t-63", + "title": "Titan flyby #63", + "start": "2009-12-12T00:23:13", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-64": { + "id": "titan_t-64", + "title": "Titan flyby #64", + "start": "2009-12-27T23:47:58", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-65": { + "id": "titan_t-65", + "title": "Titan flyby #65", + "start": "2010-01-12T22:38:35", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-66": { + "id": "titan_t-66", + "title": "Titan flyby #66", + "start": "2010-01-28T21:34:49", + "target": "titan", + "template": "titan_flybys.json" + }, + "rhea_r-2": { + "id": "rhea_r-2", + "title": "Rhea flyby #2", + "start": "2010-03-02T17:24:35", + "target": "rhea", + "template": "rhea_flybys.json" + }, + "titan_t-67": { + "id": "titan_t-67", + "title": "Titan flyby #67", + "start": "2010-04-05T15:00:53", + "target": "titan", + "template": "titan_flybys.json" + }, + "dione_d-2": { + "id": "dione_d-2", + "title": "Dione flyby #2", + "start": "2010-04-07T05:04:10", + "target": "dione", + "template": "dione_flybys.json" + }, + "enceladus_e-9": { + "id": "enceladus_e-9", + "title": "Enceladus flyby #10", + "start": "2010-04-28T00:00:00", + "target": "enceladus", + "template": "enceladus_flybys.json", + "horizontalOffset": -7 + }, + "enceladus_e-10": { + "id": "enceladus_e-10", + "title": "Enceladus flyby #11", + "start": "2010-05-18T05:39:40", + "target": "enceladus", + "template": "enceladus_flybys.json", + "horizontalOffset": 6 + }, + "titan_t-68": { + "id": "titan_t-68", + "title": "Titan flyby #68", + "start": "2010-05-20T02:47:19", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-69": { + "id": "titan_t-69", + "title": "Titan flyby #69", + "start": "2010-06-05T01:47:26", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-70": { + "id": "titan_t-70", + "title": "Titan flyby #70", + "start": "2010-06-21T01:00:42", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-71": { + "id": "titan_t-71", + "title": "Titan flyby #71", + "start": "2010-07-06T23:49:44", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-11": { + "id": "enceladus_e-11", + "title": "Enceladus flyby #12", + "start": "2010-08-13T22:10:51", + "target": "enceladus", + "template": "enceladus_flybys.json", + "horizontalOffset": 8 + }, + "titan_t-72": { + "id": "titan_t-72", + "title": "Titan flyby #72", + "start": "2010-09-24T17:50:40", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-73": { + "id": "titan_t-73", + "title": "Titan flyby #73", + "start": "2010-11-11T13:00:00", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-12": { + "id": "enceladus_e-12", + "title": "Enceladus flyby #13", + "start": "2010-11-30T11:45:59", + "target": "enceladus", + "template": "enceladus_flybys.json" + }, + "enceladus_e-13": { + "id": "enceladus_e-13", + "title": "Enceladus flyby #14", + "start": "2010-12-21T01:00:27", + "target": "enceladus", + "template": "enceladus_flybys.json", + "horizontalOffset": -6 + }, + "rhea_r-3": { + "id": "rhea_r-3", + "title": "Rhea flyby #3", + "start": "2011-01-11T04:40:24", + "target": "rhea", + "template": "rhea_flybys.json" + }, + "titan_t-74": { + "id": "titan_t-74", + "title": "Titan flyby #74", + "start": "2011-02-18T15:27:11", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-75": { + "id": "titan_t-75", + "title": "Titan flyby #75", + "start": "2011-04-19T04:18:38", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-76": { + "id": "titan_t-76", + "title": "Titan flyby #76", + "start": "2011-05-08T22:10:43", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-77": { + "id": "titan_t-77", + "title": "Titan flyby #77", + "start": "2011-06-20T17:52:00", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-78": { + "id": "titan_t-78", + "title": "Titan flyby #78", + "start": "2011-09-12T02:05:06", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-14": { + "id": "enceladus_e-14", + "title": "Enceladus flyby #15", + "start": "2011-10-01T13:48:26", + "target": "enceladus", + "template": "enceladus_flybys.json", + "rate": 20 + }, + "enceladus_e-15": { + "id": "enceladus_e-15", + "title": "Enceladus flyby #16", + "start": "2011-10-19T09:13:12", + "target": "enceladus", + "template": "enceladus_flybys.json" + }, + "enceladus_e-16": { + "id": "enceladus_e-16", + "title": "Enceladus flyby #17", + "start": "2011-11-06T04:45:53", + "target": "enceladus", + "template": "enceladus_flybys.json", + "horizontalOffset": 5 + }, + "dione_d-3": { + "id": "dione_d-3", + "title": "Dione flyby #3", + "start": "2011-12-12T09:30:23", + "target": "dione", + "template": "dione_flybys.json", + "rate": 40 + }, + "titan_t-79": { + "id": "titan_t-79", + "title": "Titan flyby #79", + "start": "2011-12-13T19:24:23", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-80": { + "id": "titan_t-80", + "title": "Titan flyby #80", + "start": "2012-01-02T14:26:38", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-81": { + "id": "titan_t-81", + "title": "Titan flyby #81", + "start": "2012-01-30T13:08:48", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-82": { + "id": "titan_t-82", + "title": "Titan flyby #82", + "start": "2012-02-19T08:08:16", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-17": { + "id": "enceladus_e-17", + "title": "Enceladus flyby #18", + "start": "2012-03-27T18:24:09", + "target": "enceladus", + "template": "enceladus_flybys.json", + "rate": 20 + }, + "enceladus_e-18": { + "id": "enceladus_e-18", + "title": "Enceladus flyby #19", + "start": "2012-04-14T13:54:38", + "target": "enceladus", + "template": "enceladus_flybys.json", + "rate": 20, + "horizontalOffset": 5 + }, + "enceladus_e-19": { + "id": "enceladus_e-19", + "title": "Enceladus flyby #20", + "start": "2012-05-02T09:24:29", + "target": "enceladus", + "template": "enceladus_flybys.json", + "rate": 20, + "horizontalOffset": -9 + }, + "titan_t-83": { + "id": "titan_t-83", + "title": "Titan flyby #83", + "start": "2012-05-22T00:36:10", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-84": { + "id": "titan_t-84", + "title": "Titan flyby #84", + "start": "2012-06-06T23:37:20", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-85": { + "id": "titan_t-85", + "title": "Titan flyby #85", + "start": "2012-07-24T19:35:06", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-86": { + "id": "titan_t-86", + "title": "Titan flyby #86", + "start": "2012-09-26T14:03:38", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-87": { + "id": "titan_t-87", + "title": "Titan flyby #87", + "start": "2012-11-13T09:56:07", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-88": { + "id": "titan_t-88", + "title": "Titan flyby #88", + "start": "2012-11-29T08:25:58", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-89": { + "id": "titan_t-89", + "title": "Titan flyby #89", + "start": "2013-02-17T01:24:34", + "target": "titan", + "template": "titan_flybys.json" + }, + "rhea_r-4": { + "id": "rhea_r-4", + "title": "Rhea flyby #4", + "start": "2013-03-09T18:00:25", + "target": "rhea", + "template": "rhea_flybys.json", + "rate": 30, + "horizontalOffset": 12 + }, + "titan_t-90": { + "id": "titan_t-90", + "title": "Titan flyby #90", + "start": "2013-04-05T21:08:30", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-91": { + "id": "titan_t-91", + "title": "Titan flyby #91", + "start": "2013-05-23T17:00:54", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-92": { + "id": "titan_t-92", + "title": "Titan flyby #92", + "start": "2013-07-10T12:42:47", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-93": { + "id": "titan_t-93", + "title": "Titan flyby #93", + "start": "2013-07-26T11:20:21", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-94": { + "id": "titan_t-94", + "title": "Titan flyby #94", + "start": "2013-09-12T07:05:55", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-95": { + "id": "titan_t-95", + "title": "Titan flyby #95", + "start": "2013-10-14T04:22:27", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-96": { + "id": "titan_t-96", + "title": "Titan flyby #96", + "start": "2013-12-01T00:00:18", + "target": "titan", + "template": "titan_flybys.json", + "verticalOffset": -10 + }, + "titan_t-97": { + "id": "titan_t-97", + "title": "Titan flyby #97", + "start": "2014-01-01T21:25:41", + "target": "titan", + "template": "titan_flybys.json", + "horizontalOffset": 10 + }, + "titan_t-98": { + "id": "titan_t-98", + "title": "Titan flyby #98", + "start": "2014-02-02T18:37:38", + "target": "titan", + "template": "titan_flybys.json", + "horizontalOffset": 12 + }, + "titan_t-99": { + "id": "titan_t-99", + "title": "Titan flyby #99", + "start": "2014-03-06T15:47:47", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-100": { + "id": "titan_t-100", + "title": "Titan flyby #100", + "start": "2014-04-07T13:06:13", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-101": { + "id": "titan_t-101", + "title": "Titan flyby #101", + "start": "2014-05-17T15:25:14", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-102": { + "id": "titan_t-102", + "title": "Titan flyby #102", + "start": "2014-06-18T12:53:24", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-103": { + "id": "titan_t-103", + "title": "Titan flyby #103", + "start": "2014-07-20T10:00:57", + "target": "titan", + "template": "titan_flybys.json", + "horizontalOffset": 9 + }, + "titan_t-104": { + "id": "titan_t-104", + "title": "Titan flyby #104", + "start": "2014-08-21T07:32:08", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-105": { + "id": "titan_t-105", + "title": "Titan flyby #105", + "start": "2014-09-22T04:48:18", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-106": { + "id": "titan_t-106", + "title": "Titan flyby #106", + "start": "2014-10-24T02:05:30", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-107": { + "id": "titan_t-107", + "title": "Titan flyby #107", + "start": "2014-12-10T21:52:34", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-108": { + "id": "titan_t-108", + "title": "Titan flyby #108", + "start": "2015-01-11T19:16:35", + "target": "titan", + "template": "titan_flybys.json", + "horizontalOffset": -8 + }, + "titan_t-109": { + "id": "titan_t-109", + "title": "Titan flyby #109", + "start": "2015-02-12T16:30:04", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-110": { + "id": "titan_t-110", + "title": "Titan flyby #110", + "start": "2015-03-16T13:55:48", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-111": { + "id": "titan_t-111", + "title": "Titan flyby #111", + "start": "2015-05-07T22:14:22", + "target": "titan", + "template": "titan_flybys.json", + "verticalOffset": -10 + }, + "dione_d-4": { + "id": "dione_d-4", + "title": "Dione flyby #4", + "start": "2015-06-16T19:53:51", + "target": "dione", + "template": "dione_flybys.json", + "rate": 40 + }, + "titan_t-112": { + "id": "titan_t-112", + "title": "Titan flyby #112", + "start": "2015-07-07T07:38:49", + "target": "titan", + "template": "titan_flybys.json" + }, + "dione_d-5": { + "id": "dione_d-5", + "title": "Dione flyby #5", + "start": "2015-08-17T18:17:25", + "target": "dione", + "template": "dione_flybys.json", + "rate": 35, + "horizontalOffset": 8 + }, + "titan_t-113": { + "id": "titan_t-113", + "title": "Titan flyby #113", + "start": "2015-09-28T21:04:12", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-20": { + "id": "enceladus_e-20", + "title": "Enceladus flyby #21", + "start": "2015-10-14T10:30:29", + "target": "enceladus", + "template": "enceladus_flybys.json", + "distance": 0.035, + "rate": 18, + "horizontalOffset": 6 + }, + "enceladus_e-21": { + "id": "enceladus_e-21", + "title": "Enceladus flyby #22", + "start": "2015-10-28T15:18:41", + "target": "enceladus", + "template": "enceladus_flybys.json", + "distance": 0.035, + "rate": 7 + }, + "titan_t-114": { + "id": "titan_t-114", + "title": "Titan flyby #114", + "start": "2015-11-13T05:06:30", + "target": "titan", + "template": "titan_flybys.json" + }, + "enceladus_e-22": { + "id": "enceladus_e-22", + "title": "Enceladus flyby #23", + "start": "2015-12-19T17:42:16", + "target": "enceladus", + "template": "enceladus_flybys.json", + "rate": 15, + "horizontalOffset": 10 + }, + "titan_t-115": { + "id": "titan_t-115", + "title": "Titan flyby #115", + "start": "2016-01-16T01:44:23", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-116": { + "id": "titan_t-116", + "title": "Titan flyby #116", + "start": "2016-02-01T00:20:04", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-117": { + "id": "titan_t-117", + "title": "Titan flyby #117", + "start": "2016-02-16T23:16:40", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-118": { + "id": "titan_t-118", + "title": "Titan flyby #118", + "start": "2016-04-04T19:05:42", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-119": { + "id": "titan_t-119", + "title": "Titan flyby #119", + "start": "2016-05-06T16:12:35", + "target": "titan", + "template": "titan_flybys.json", + "horizontalOffset": -8 + }, + "titan_t-120": { + "id": "titan_t-120", + "title": "Titan flyby #120", + "start": "2016-06-07T13:22:17", + "target": "titan", + "template": "titan_flybys.json", + "horizontalOffset": 8 + }, + "titan_t-121": { + "id": "titan_t-121", + "title": "Titan flyby #121", + "start": "2016-07-25T09:24:22", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-122": { + "id": "titan_t-122", + "title": "Titan flyby #122", + "start": "2016-08-10T07:56:53", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-123": { + "id": "titan_t-123", + "title": "Titan flyby #123", + "start": "2016-09-27T03:41:58", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-124": { + "id": "titan_t-124", + "title": "Titan flyby #124", + "start": "2016-11-13T23:17:55", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-125": { + "id": "titan_t-125", + "title": "Titan flyby #125", + "start": "2016-11-29T21:35:31", + "target": "titan", + "template": "titan_flybys.json" + }, + "titan_t-126": { + "id": "titan_t-126", + "title": "Titan flyby #126", + "start": "2017-04-22T05:30:06", + "target": "titan", + "template": "titan_flybys.json" + } +} diff --git a/experiences/asteroids/web/events/sc_cassini/backlit_saturn.json b/experiences/asteroids/web/events/sc_cassini/backlit_saturn.json new file mode 100644 index 0000000..2cbf710 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/backlit_saturn.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "Cassini discovered a never-before-seen ring with the help of a rare point of view in 2006.", + "more": "Cassini saw some new rings and other features of the Saturn system in 2006, thanks to some unusual geometry. Because of the ever-changing shape and position of the spacecraft's orbit around Saturn, Cassini has at times been in Saturn's shadow. Astronomers call such an event a \"solar occultation\" because, from Cassini's point of view, the sun is occulted - or hidden - behind Saturn. Such events reveal features of the Saturn system that are at other times difficult to see. It's a bit like the difference between standing on a stage with a spotlight on your face versus standing in the wings of the stage. Dust particles floating in the spotlight's beam are, of course, much easier to spot from the wings where the source of light isn't shining at your eyes. Usually an occultation lasts about an hour, but on Sept. 17, 2006, Cassini experienced a 12-hour occultation - the longest of the mission at that point - during which the spacecraft discovered a faint ring outward of the bright main rings, and inward of the G and E rings. The observation also allowed the spacecraft to image the entire E ring at once for the first time, revealing unexpected details there." + }, + "related": ["saturn"] +} diff --git a/experiences/asteroids/web/events/sc_cassini/closest_enceladus_flyby.json b/experiences/asteroids/web/events/sc_cassini/closest_enceladus_flyby.json new file mode 100644 index 0000000..1227478 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/closest_enceladus_flyby.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "In 2008, Cassini flew through Enceladus' plume nearer to the moon's surface than ever before.", + "more": "By summer of 2008, Cassini had flown by the little moon Enceladus four times, starting at a distance of 783 miles (1,260 kilometers) and getting closer in each flyby. In March, the spacecraft passed within just 29 miles (47 kilometers) of Enceladus. Scientists now knew that the jets producing the plume over the moon's south polar region were made up mostly of water vapor and water ice. They also knew that the material spraying out of Enceladus was the source of most of the ions in Saturn's magnetosphere (excited atoms of oxygen in particular). But much remained unknown. The mission was scheduled to end in July, but Cassini's first mission extension gave the spacecraft two more years and six more Enceladus flybys. The first of the six flybys happened in August, and was nearly the same distance as the March flyby. But in October, the spacecraft nearly halved that distance, flying just 16 miles (25 kilometers) from Enceladus' surface. The bold flyby yielded new hints about the icy moon's active surface, as well as how the plume causes Saturn's magnetosphere to slow, locally, as it sweeps over Enceladus. This was the closest moon flyby of the entire mission, although closest approach was not over the plume region (Cassini flew deeper into the plume on October 28, 2015)." + }, + "related": ["enceladus"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_cassini/descent_to_titan.json b/experiences/asteroids/web/events/sc_cassini/descent_to_titan.json new file mode 100644 index 0000000..0197106 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/descent_to_titan.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "On Jan. 14, 2005, the Huygens probe parachuted through Titan's atmosphere and landed on the moon's surface.", + "more": "After detaching from Cassini, the European Space Agency's Huygens probe coasted for about three weeks. Then, on Jan. 14, 2005, Huygens descended through the dense atmosphere of Titan, Saturn's largest moon for about two and a half hours. Titan is the only moon in the solar system with a thick atmosphere and open bodies of liquid on its surface. Huygens was about 9 feet (2.7 meters) wide and weighed roughly 700 pounds (318 kilograms). The probe slowed itself once it was in Titan's atmosphere, at first using a heat shield, and then using a series of three parachutes.\nDuring and after descent, Huygens studied the temperatures, pressures, and composition of Titan's atmosphere, and collected images of the surface. When Huygens safely touched down on the surface of Titan, it became the first probe to land on a world in the outer solar system. The probe survived more than an hour on Titan's surface and continued to transmit its observations to Cassini until its batteries died. Cassini write-protected the data until it had transmitted it back to Earth 16 times, to ensure scientists had a complete and accurate copy of the data." + }, + "related": ["titan"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_cassini/dione_flybys.json b/experiences/asteroids/web/events/sc_cassini/dione_flybys.json new file mode 100644 index 0000000..8471c48 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/dione_flybys.json @@ -0,0 +1,9 @@ +{ + "description": { + "blurb": "Cassini performed five flybys of Dione within a few hundred miles to study the moon closely.", + "more": "About 700 miles (1,100 kilometers) in diameter, Dione orbits Saturn once every 2.7 days at almost the same distance that Earth's moon orbits around our planet. Dione's density is 1.48 times that of liquid water, suggesting that about a third of Dione is made up of a dense core (probably silicate rock) with the remainder of its composition being ice. At Dione's average temperature of minus 121 degrees Fahrenheit (minus 186 degrees Celsius or 87 Kelvin), ice is hard as rock. Ice particles as fine as smoke constantly bombard Dione from Saturn's E ring, which is produced by the jets of icy material spraying from Enceladus. So while Enceladus is less than half the diameter of Dione, the smaller moon is altering the surface of the larger moon, painting it with fresh ice dust." + }, + "related": ["dione", "sc_cassini"], + "rate": 60, + "distance": 0.035 +} diff --git a/experiences/asteroids/web/events/sc_cassini/earth_flyby.json b/experiences/asteroids/web/events/sc_cassini/earth_flyby.json new file mode 100644 index 0000000..d0fb50b --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/earth_flyby.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "After two Venus flybys, Cassini gained a third speed boost by flying by Earth in 1999 for a gravity assist.", + "more": "After leaving Earth and orbiting the sun twice to perform a pair of Venus gravity assist flybys, Cassini came back, flying past Earth on Aug. 18, 1999. The flyby boosted Cassini's speed by 12,000 miles per hour (5.5 kilometers per second), and the spacecraft got within 719 miles (1,157 kilometers) of Earth, making it visible at night from some islands in the South Pacific. Nine of Cassini's 12 instruments were active when the spacecraft flew through the Earth-moon system, primarily for calibration purposes. At the time of the flyby, Cassini had traveled more than 1 billion miles (about 1.6 billion kilometers) since its 1997 launch." + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_cassini/enceladus_discovery.json b/experiences/asteroids/web/events/sc_cassini/enceladus_discovery.json new file mode 100644 index 0000000..4288895 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/enceladus_discovery.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "In 2005, Cassini's instruments found the first hints of a global subsurface water ocean in the moon Enceladus.", + "more": "In February 2005, Cassini made its first close flyby of Enceladus, one of Saturn's several dozen moons, and the mission's scientists were in for a surprise. As Cassini passed within 725 miles (1,167 kilometers) of the 300-mile (500-kilometer) wide Enceladus, the spacecraft's magnetometer detected a localized bending of Saturn's magnetic field in the space above the icy moon -- almost like it had an atmosphere. This was the first clue that Enceladus was much more than just a cratered ball of ice. Over the following couple of encounters with Enceladus, scientists realized that the magnetometer data had revealed not an atmosphere, but a plume of ice particles and gas over Enceladus' south polar region. Observations by several of Cassini's other instruments over the following months and years led Cassini scientists to conclude that the plume is produced by jets that spray out through cracks in Enceladus' ice shell, and that the water originates from a global ocean of salty water whose seafloor might have hydrothermal vents. Thanks to Cassini, Enceladus has become one of the prime targets in the quest to find environments beyond Earth where life might have evolved." + }, + "related": ["enceladus"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_cassini/enceladus_flybys.json b/experiences/asteroids/web/events/sc_cassini/enceladus_flybys.json new file mode 100644 index 0000000..67c9d5a --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/enceladus_flybys.json @@ -0,0 +1,10 @@ +{ + "description": { + "blurb": "Cassini's Enceladus flybys have altered perceptions about where to search for habitable worlds.", + "more": "The Saturn system is nearly 10 times farther from the sun than Earth is, so Saturn's sixth-largest moon Enceladus receives only about one-hundredth the sunlight that Earth receives. Since Enceladus is so small -- only about 300 miles (about 500 kilometers) in diameter -- the tiny moon should have cooled long ago, causing its internal ocean to freeze. In all, scientists had every reason to expect Enceladus to be frozen solid. But Cassini found it to be otherwise. Cassini's 23 flybys of Enceladus first revealed a bending of Saturn's magnetic field near the tiny moon, as if it had an atmosphere. The bending was caused by a plume of gas and particles above the moon's south polar region. In subsequent flybys, Cassini found that the plume was produced by water jets spraying from enormous fractures that run across the moon's southern surface. Cassini also found that the particles in the plume were water ice with a surprising amount of salt, and then gravitational measurements indicated that the jets are supplied by a global subsurface ocean. Tiny silica grains, also found in the plume, suggest that Enceladus' ocean likely contains hydrothermal vents - one of the places scientists suspect life could have begun on Earth" + }, + "related": ["enceladus", "sc_cassini"], + "layers": true, + "rate": 30, + "distance": 0.035 +} diff --git a/experiences/asteroids/web/events/sc_cassini/final_transmission.json b/experiences/asteroids/web/events/sc_cassini/final_transmission.json new file mode 100644 index 0000000..11c4538 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/final_transmission.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "This view shows a visualization of Cassini's final transmission to Earth as the spacecraft approached its demise.", + "more": "In its final orbit Cassini swung over Saturn's northern hemisphere, then down diagonally across the face of Saturn (from Earth's point of view). The signal traveled at light speed, but Saturn is nearly a billion miles from Earth. So while the signal appears slow from this point of view, it is in fact traveling as fast as nature allows. On Cassini's final plunge into the atmosphere, the spacecraft transmitted its observations toward Earth in real time until Saturn's atmosphere overpowered its stabilizing thrusters. Shortly after that, 19 years and 11 months after launching from Earth, Cassini burned up in Saturn's atmosphere becoming part of the planet itself. Light-speed travel time from Saturn to Earth is nearly an hour and a half, so by the time the last wiggle of Cassini's radio signal reached Earth, the spacecraft will have been gone for more than an hour. The final transmission arrived on Earth around 7:55 a.m. Eastern time (4:45 a.m. Pacific) on Sept. 15, 2017. At that point Cassini's signal went silent, ending a 20-year mission and closing a remarkable chapter in the exploration of our solar system." + }, + "related": ["saturn"] +} diff --git a/experiences/asteroids/web/events/sc_cassini/first_ring_plane_crossing.json b/experiences/asteroids/web/events/sc_cassini/first_ring_plane_crossing.json new file mode 100644 index 0000000..c7bde55 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/first_ring_plane_crossing.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "This was Cassini's first visit to this unexplored region of the Saturn system.", + "more": "From a great distance, Saturn's rings appear as if their borders are sharply defined. But the space beyond the apparent borders of the rings is not completely empty. When Cassini raced through the 1,500-mile (2,400-kilometer) space between Saturn and its rings during its 22 Grand Finale orbits, the spacecraft was traveling at tens of thousands of miles per hour, and a single unseen ring particle the size of a BB can damage the spacecraft. So to protect Cassini during its first crossing through that gap (as well as four other grand finale passes), the spacecraft was instructed to reorient itself so that its big dish - the high-gain antenna - was facing toward the direction Cassini is moving, like a snowplow. The team calls this orientation \"high-gain to ram.\" The high-gain antenna's radius extends almost exactly the same distance from the center of the spacecraft as most of Cassini's instruments. So the orientation should at least help reduce the hazard of ring particles striking more sensitive hardware, while a few pits in the antenna itself won't likely inhibit the spacecraft's ability to communicate with Earth." + }, + "related": ["saturn"] +} diff --git a/experiences/asteroids/web/events/sc_cassini/grand_finale.json b/experiences/asteroids/web/events/sc_cassini/grand_finale.json new file mode 100644 index 0000000..17d000f --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/grand_finale.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "Cassini's Grand Finale was like a whole new mission.", + "more": "When Cassini launched, Earthlings hadn't decided the spacecraft's ultimate fate. They considered eventually leaving Saturn to go study another of the other outer planets, but after Cassini reached Saturn, scientists began thinking that the moon Enceladus (and possibly even Titan) might be habitable for some form of life. So before Cassini completely runs out of propellant, engineers set it on a course to responsibly dispose of it in Saturn's atmosphere. They did this while they still had control of the spacecraft in order to prevent Cassini from accidentally colliding with either of those moons. Cassini's fateful plunge came with an enormous perk. The trajectory that led up to the end of mission carried it through a place where no spacecraft had ever been. Starting April 22, 2017, Cassini began its Grand Finale - a series of 22 daring dives through the 1,500-mile (2,400-kilometer) gap between the planet and the inner edge of the rings to collect incredibly rich and valuable information that the mission's original planners might never have imagined. On the final five Grand Finale orbits, Cassini dipped down and directly sampled Saturn's upper atmosphere. And on Cassini's final plunge into the atmosphere, the spacecraft transmitted its observations toward Earth in real time, until Saturn's atmosphere overpowered the spacecraft's thrusters. Shortly after that, 19 years and 11 months after launching from Earth, Cassini burned up in Saturn's upper atmosphere, becoming part of the planet itself." + }, + "related": ["saturn"] +} diff --git a/experiences/asteroids/web/events/sc_cassini/huygens.json b/experiences/asteroids/web/events/sc_cassini/huygens.json new file mode 100644 index 0000000..e07d435 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/huygens.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "The Huygens probe detached from Cassini on Dec. 24, 2004, bound for Saturn's largest moon Titan.", + "more": "After riding along with the Cassini spacecraft for nearly seven years from Earth to Saturn, the European Space Agency's Huygens probe detached from Cassini on Dec. 24, 2004. Before separation, Cassini turned so that Huygens was oriented in the attitude needed for atmospheric entry at Titan. Cassini spun the disk-like probe up to about seven revolutions per minute to stabilize Huygens for its three-week journey to Titan, and then released it at a separation velocity of about a foot per second. Cassini later fired its propulsion system to change trajectories so that it wouldn't follow Huygens to Titan's surface." + }, + "related": ["titan"] +} diff --git a/experiences/asteroids/web/events/sc_cassini/hyperion_flybys.json b/experiences/asteroids/web/events/sc_cassini/hyperion_flybys.json new file mode 100644 index 0000000..592b103 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/hyperion_flybys.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "Cassini found that Saturn's sponge-looking moon Hyperion is the only known world aside from Earth's moon to have a statically charged surface.", + "more": "The largest of Saturn's irregular, nonspherical moons, Hyperion is 255 miles (410 kilometers) long and shaped like a potato. Its odd shape leads scientists to believe it may be a remnant of a larger moon that was destroyed by a collision. Cassini scientists think that Hyperion's unusual appearance may be due to the moon's unusually low density for such a large object, giving it weak surface gravity and high porosity. When other objects strike Hyperion, the moon's weak gravity, and correspondingly low escape velocity, means that what little ejecta is produced has a good chance of escaping the moon altogether. That results in less impact ejecta ending up on the moon's surface, so the original shapes of craters are preserved and sharp rather than being subdued and softened by falling ejecta." + }, + "related": ["hyperion", "sc_cassini"] +} diff --git a/experiences/asteroids/web/events/sc_cassini/iapetus_flybys.json b/experiences/asteroids/web/events/sc_cassini/iapetus_flybys.json new file mode 100644 index 0000000..0981888 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/iapetus_flybys.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "Giovanni Cassini, the spacecraft's namesake, noted the two-toned brightness pattern of Iapetus in 1671, but until the Cassini spacecraft flew by, the cause of the coloring was a mystery.", + "more": "Saturn's third largest moon Iapetus is about 900 miles (1,500 kilometers) in diameter and orbits 2,213,000 miles (3,561,000 kilometers) from Saturn. With a density only 1.2 times that of liquid water, Iapetus may be, like Rhea, three-quarters ice and one-quarter rock. Cassini solved the centuries-old puzzle about why Iapetus has one snow-white hemisphere while the other is nearly as dark as charcoal. Iapetus is tidally locked, so one side always faces the direction in which it's orbiting. It turns out that dark material falls on Iapetus' leading side. The dark dust is from Saturn's distant moon Phoebe, and Iapetus is flying through that debris. The dark material coats the leading side of Iapetus, causing ice there to sublimate, or turn to gas, as the surface warms. This vapor then refreezes on the moon's opposite side as bright, white ice." + }, + "related": ["iapetus", "sc_cassini"] +} diff --git a/experiences/asteroids/web/events/sc_cassini/jupiter_flyby.json b/experiences/asteroids/web/events/sc_cassini/jupiter_flyby.json new file mode 100644 index 0000000..542b93b --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/jupiter_flyby.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "On Dec. 30, 2000, Cassini flew past Jupiter for a gravity assist, and to test its software and instruments.", + "more": "After two Venus flybys and one Earth flyby, Cassini then flew past Jupiter on Dec. 30, 2000. The previous three flybys were all within several hundred miles of the planets' surfaces, but Cassini flew by Jupiter at a distance of about 6 million miles (9.7 million kilometers) from the planet's cloud-tops. The Galileo spacecraft, which launched in 1989, was orbiting Jupiter at the time. With Cassini passing by, scientists were able to spend several months studying the Jovian system up close with two spacecraft at the same time, which had never been done before. The Jupiter gravity assist provided Cassini with a speed boost of more than 4,000 miles per hour (about 2 kilometers per second)." + }, + "related": ["jupiter"] +} diff --git a/experiences/asteroids/web/events/sc_cassini/launch.json b/experiences/asteroids/web/events/sc_cassini/launch.json new file mode 100644 index 0000000..d064364 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/launch.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "The Cassini spacecraft launched Oct. 15, 1997 atop a Titan IVB/Centaur rocket.", + "more": "At 4:43 a.m. EDT on Oct. 15, 1997, a Titan IVB/Centaur rocket, powered by two solid rocket motors, lifted off from Launch Complex 40 in Cape Canaveral, Florida, carrying NASA's Cassini spacecraft and the European Space Agency's Huygens probe.\nAbout two minutes into flight, the Titan first stage engine ignited, and a few seconds later the expended solid rocket motors detached and fell away. Three and a half minutes into flight, at an altitude of 363,000 feet (110,600 meters), the payload fairing (a.k.a. nose-cone) split and fell away. Just past five minutes after liftoff, the Titan first stage detached and fell away, and the second stage ignited to burn for about four minutes. About nine minutes after liftoff, the Titan second stage detached, clearing the way for the Centaur upper stage, which then executed two burns - the first to get Cassini-Huygens into Earth orbit, and the second to leave Earth for its interplanetary journey. Cassini-Huygens then detached from the Centaur stage and traveled for nearly seven years, flying by Venus twice, Earth once, and Jupiter once, before entering orbit around Saturn on July 1, 2004." + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_cassini/phoebe_flybys.json b/experiences/asteroids/web/events/sc_cassini/phoebe_flybys.json new file mode 100644 index 0000000..aa0e57e --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/phoebe_flybys.json @@ -0,0 +1,9 @@ +{ + "description": { + "blurb": "Cassini's trajectory to Saturn and time of arrival were specifically chosen to permit a close flyby of the moon Phoebe.", + "more": "Phoebe was Cassini's gateway to Saturn. When the spacecraft reached the Saturn system in 2004, Phoebe was the first moon it encountered. Scientists suspect that, unlike most of Saturn's moons, Phoebe didn't form around Saturn. A roughly spherical moon, Phoebe is about 130 miles (210 kilometers) in diameter and rotates on its axis every nine hours. Phoebe also takes 1.5 Earth years to orbit Saturn once because it's about 8 million miles (13 million kilometers) from its planet -- almost four times the distance from Saturn than Phoebe's nearest neighbor Iapetus. Phoebe and Iapetus are the only major moons in the Saturn system that do not orbit near Saturn's equatorial plane. Phoebe's irregular, elliptical orbit is highly inclined with respect to Saturn's equator and is also retrograde, meaning it goes around Saturn in the opposite direction than most other moons. Its backward orbit, along with being far darker than most of Saturn's moons, suggest Phoebe most likely came from much farther out in the solar system, in the Kuiper Belt region beyond Neptune. It likely passed too close to Saturn, whose gravity captured the dark, cratered world and placed it in its unusual orbit." + }, + "related": ["phoebe", "sc_cassini"], + "rate": 90, + "distance": 0.05 +} diff --git a/experiences/asteroids/web/events/sc_cassini/rhea_flybys.json b/experiences/asteroids/web/events/sc_cassini/rhea_flybys.json new file mode 100644 index 0000000..366a13c --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/rhea_flybys.json @@ -0,0 +1,9 @@ +{ + "description": { + "blurb": "Cassini visited Saturn's moon Rhea four times, finding it similar to Dione and Tethys, but with important exceptions.", + "more": "At 950 miles (about 1,500 kilometers) in diameter, Rhea is Saturn's second largest moon. It is heavily cratered, cold, and airless like sister moons Dione and Tethys. Rhea's surface temperatures are also similar to Dione and Tethys, at roughly minus 281 degrees Fahrenheit (minus 174 degrees Celsius) in sunlit areas and minus 364 degrees Fahrenheit (minus 220 degrees Celsius) in shaded areas. At 327,500 miles (527,000 kilometers) from Saturn, Rhea orbits farther from the planet than Dione and Tethys and does not receive ample tidal variation from Saturn to cause internal heating, which may be why Dione and Tethys have more areas of smooth plains than Rhea. The plains are probably areas where liquid water reached the surface and settled in depressions such as craters, forming flat surfaces before refreezing and erasing older craters." + }, + "related": ["rhea", "sc_cassini"], + "rate": 60, + "distance": 0.035 +} diff --git a/experiences/asteroids/web/events/sc_cassini/saturn_orbit_insertion.json b/experiences/asteroids/web/events/sc_cassini/saturn_orbit_insertion.json new file mode 100644 index 0000000..4a45005 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/saturn_orbit_insertion.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "On July 1, 2004, Cassini became the first spacecraft in history to enter Saturn orbit.", + "more": "At 7:10 p.m. EDT on June 30, 2004, Cassini turned so that its high-gain antenna could shield the rest of the spacecraft from particles as it passed through Saturn's ring plane. The spacecraft then turned again and began a main engine burn at 10:36 p.m. EDT to slow the spacecraft enough to be captured in Saturn orbit. The burn lasted 96 minutes, ending at 12:12 a.m. EDT on July 1. Cassini's first orbit was several months long, but later in the mission some orbits were as short as a week. At the time of Saturn Orbit Insertion, the mission was scheduled to end on July 1, 2008, after four years and 75 orbits. But two mission extensions stretched Cassini's time orbiting Saturn out to Sept. 15, 2017, or about 13 years and 294 orbits. The unprecedented length of time at Saturn has allowed scientists to make unexpected observations, and to study how Saturn, its rings, and its moons change over Saturn's seasons, each of which lasts more than seven Earth years." + }, + "related": ["saturn"] +} diff --git a/experiences/asteroids/web/events/sc_cassini/tethys_flybys.json b/experiences/asteroids/web/events/sc_cassini/tethys_flybys.json new file mode 100644 index 0000000..0166c55 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/tethys_flybys.json @@ -0,0 +1,9 @@ +{ + "description": { + "blurb": "When Cassini flew by Tethys, scientists discovered that its surface had strange red streaks, which remain unexplained.", + "more": "Tethys is about 660 miles (about 1,500 kilometers) across and it orbits about 183,000 miles (295,000 kilometers) from Saturn, taking 45.3 hours to circle the planet. The moon is tidally locked - the same side always faces toward Saturn. Cassini found mysterious red streaks running across the moon's surface. they were unseen until a Cassini scientist observed the moon in infrared wavelengths of light. The streaks look as if someone dragged a red crayon across a golf ball, and they don't appear to be related to any physical features of the moon's surface, such as valleys or fractures. They go up mountains and down into craters. If the red streaks are coming from fractures, then the fractures are too small to see at the resolution of Cassini's instruments. Further, the streaks seem to be only in the moon's north, not in the south, and scientists don't yet understand why." + }, + "related": ["tethys", "sc_cassini"], + "rate": 60, + "distance": 0.045 +} diff --git a/experiences/asteroids/web/events/sc_cassini/titan_flybys.json b/experiences/asteroids/web/events/sc_cassini/titan_flybys.json new file mode 100644 index 0000000..2437403 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/titan_flybys.json @@ -0,0 +1,10 @@ +{ + "description": { + "blurb": "Through close flybys of Saturn's largest moon Titan, Cassini revealed the moon's surface and discovered liquid lakes and seas there.", + "more": "Cassini performed 127 flybys of Titan, one of the mission's highest-priority science targets. These flybys gave scientists their first views of Titan's surface. In the Earth-like world's northern regions, Cassini found seas roughly the size of the U.S. Great Lakes but full of nearly-pure liquid methane. Cassini data also suggest that below Titan's water-ice crust is likely a global liquid water ocean. In addition to providing the first close study of the hazy moon, Cassini's Titan flybys provided the trajectory changes that allowed the spacecraft to change course to achieve amazing observations of other features of the Saturn system. Cassini's navigation team describes Titan as the engine of the mission; because a single flyby of Titan at an altitude of 620 miles (about 1,000 kilometers) gives Cassini a change in velocity equivalent to one-third of Cassini's total propellant at launch. In all, Titan flybys have provided Cassini with more than 30 times the velocity change that it could have achieved by propellant alone." + }, + "related": ["titan", "sc_cassini"], + "layers": true, + "rate": 100, + "distance": 0.035 +} diff --git a/experiences/asteroids/web/events/sc_cassini/titan_n_lake.json b/experiences/asteroids/web/events/sc_cassini/titan_n_lake.json new file mode 100644 index 0000000..b4aaa30 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/titan_n_lake.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "In July 2006, Cassini's radar instrument detected lakes on the surface of Titan.", + "more": "Scientists had long suspected that Saturn's largest moon, Titan, has liquid lakes of hydrocarbons on its surface. But its atmosphere filled with a smoggy haze of suspended hydrocarbons that make the surface difficult to observe from space with imaging instruments that use visible wavelengths of light. During a flyby on July 22, 2006, however, Cassini observed Titan with its radar instrument, which can see through the moon's haze and create images from radar signals reflected off the moon's surface. The instrument found lakes in Titan's higher latitudes ranging from 0.6 miles (about a kilometer) wide to about 20 miles (32 kilometers) wide. Subsequent flybys with the radar instrument found a collection of seas equal in size and depth to the Great Lakes of North America. Titan's lakes and seas are thought to be made of almost pure methane and ethane, and they are the only known large bodies of liquid on any world in our solar system other than Earth." + }, + "related": ["titan"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_cassini/venus_flyby_1.json b/experiences/asteroids/web/events/sc_cassini/venus_flyby_1.json new file mode 100644 index 0000000..4500fa2 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/venus_flyby_1.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "In 1998, Cassini performed the first of two Venus flybys that provided the spacecraft with speed boosts.", + "more": "Interplanetary missions often use gravity assists to gain speed and reach their destinations more quickly. On April 26, 1998, Cassini flew by Venus at an altitude of 209 miles (336 kilometers), followed by a second flyby on June 24, 1999, at an altitude of 387 miles (623 kilometers). The spacecraft approached the planet from behind, traveling in the same direction Venus moves through its solar orbit. The nearer Cassini got to Venus, the more the spacecraft and the planet pulled on one another gravitationally. The spacecraft sped up and the planet slowed down, but because the spacecraft's mass is miniscule relative to Venus, the planet slowed by an immeasurably small amount, while the spacecraft sped up enormously. Cassini later performed a gravity assist with Earth, and then Jupiter. The flybys provided Cassini with so much velocity that it arrived at Saturn years earlier than it would have without the gravity assists. The first Venus flyby alone boosted Cassini's speed by 15,000 miles per hour (about 6 kilometers per second)." + }, + "related": ["venus"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_cassini/wave_saturn.json b/experiences/asteroids/web/events/sc_cassini/wave_saturn.json new file mode 100644 index 0000000..20e5849 --- /dev/null +++ b/experiences/asteroids/web/events/sc_cassini/wave_saturn.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "In 2013, members of the public were invited to wave toward Saturn while Cassini took an image of the planet that included Earth.", + "more": "Other spacecraft had previously taken pictures of Earth from the outer solar system - perhaps most famously, Voyager 1's \"Pale Blue Dot\"; - and on July 19, 2013, early in the afternoon (PDT), Cassini did the same. But this was the first time the public was notified beforehand that a spacecraft was taking such an image, and they were encouraged to wave at Saturn for the picture. In a way, it was the grandest and most distant selfie to date. Because Cassini was nearly 900 million miles (1.5 billion kilometers) from Earth at the time, the Earth-moon system is barely a speck in the resulting image, which was combined with 140 other images Cassini took from within Saturn's shadow to create a mosaic of the planet and its rings. The mosaic was intended to help scientists learn more about the fainter rings encircling Saturn, and it did. But it also is one of the most iconic images of the Cassini mission. The processed mosaic includes planets Venus and Mars, Saturn's largest moon Titan, Enceladus in the ring it produces, several other Saturnian moons -- and the entirety of humanity." + }, + "related": ["saturn"] +} diff --git a/experiences/asteroids/web/events/sc_dart/all_events.json b/experiences/asteroids/web/events/sc_dart/all_events.json new file mode 100644 index 0000000..2593d35 --- /dev/null +++ b/experiences/asteroids/web/events/sc_dart/all_events.json @@ -0,0 +1,19 @@ +{ + "launch": { + "id": "launch", + "title": "DART Launch", + "start": "2021-11-24T07:53:19Z", + "target": "earth", + "distance": 0.2, + "rate": 60 + }, + "dimorphos_impact": { + "id": "dimorphos_impact", + "title": "Impact with Dimorphos", + "start": "2022-09-26T23:14:08", + "target": "dimorphos", + "distance": 0.04, + "verticalOffset": 3, + "visual": true + } +} diff --git a/experiences/asteroids/web/events/sc_dart/dimorphos_impact.json b/experiences/asteroids/web/events/sc_dart/dimorphos_impact.json new file mode 100644 index 0000000..5ef93ec --- /dev/null +++ b/experiences/asteroids/web/events/sc_dart/dimorphos_impact.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "The DART spacecraft will impact Dimorphos nearly head-on, shortening the time it takes the small asteroid moonlet to orbit Didymos by several minutes. The impulse of energy that DART delivers to the Didymos binary asteroid system is low and cannot disrupt the asteroid, and Didymos's orbit does not intersect Earth's at any point in current predictions. Furthermore, the change in Dimorphos's orbit is designed to bring its orbit closer to Didymos. The DART mission is a demonstration of capability to respond to a potential asteroid impact threat, should one ever be discovered." + }, + "related": ["65803_didymos", "dimorphos"] +} diff --git a/experiences/asteroids/web/events/sc_dart/launch.json b/experiences/asteroids/web/events/sc_dart/launch.json new file mode 100644 index 0000000..7b6bf35 --- /dev/null +++ b/experiences/asteroids/web/events/sc_dart/launch.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "On November 24th, 2021, the DART mission launched from Vandenberg Space Force Base aboard a Falcon 9 rocket." + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_dawn/all_events.json b/experiences/asteroids/web/events/sc_dawn/all_events.json new file mode 100644 index 0000000..83b5a30 --- /dev/null +++ b/experiences/asteroids/web/events/sc_dawn/all_events.json @@ -0,0 +1,64 @@ +{ + "launch": { + "id": "launch", + "title": "Dawn Launch", + "start": "2007-09-27T13:15:00", + "target": "earth", + "rate": 60, + "distance": 0.1 + }, + "mars_flyby": { + "id": "mars_flyby", + "title": "Mars flyby", + "start": "2009-02-17T16:00:00", + "target": "mars", + "rate": 3000, + "distance": 0.05 + }, + "vesta_arrival": { + "id": "vesta_arrival", + "title": "Dawn Arrives at Vesta", + "start": "2011-07-16T00:26:00", + "target": "4_vesta", + "rate": 3000, + "distance": 0.05, + "horizontalOffset": 5 + }, + "vesta_orbit": { + "id": "vesta_orbit", + "title": "Dawn Orbits Vesta", + "start": "2012-02-05T09:00:00", + "target": "4_vesta", + "rate": 30, + "distance": 0.1, + "visual": true + }, + "vesta_departure": { + "id": "vesta_departure", + "title": "Departure from Vesta", + "start": "2012-09-04T16:00:00", + "rate": 10000, + "distance": 0.1, + "target": "4_vesta" + }, + "ceres_arrival": { + "id": "ceres_arrival", + "title": "Arrival at Ceres", + "start": "2015-03-06T22:00:00", + "target": "1_ceres", + "rate": 3000, + "distance": 0.05, + "horizontalOffset": 5, + "verticalOffset": 3 + }, + "ceres_orbit": { + "id": "ceres_orbit", + "title": "Dawn Orbits Ceres", + "start": "2016-03-05T22:00:00", + "target": "1_ceres", + "rate": 100, + "distance": 700.0, + "horizontalOffset": 10, + "visual": true + } +} diff --git a/experiences/asteroids/web/events/sc_dawn/ceres_arrival.json b/experiences/asteroids/web/events/sc_dawn/ceres_arrival.json new file mode 100644 index 0000000..69c403e --- /dev/null +++ b/experiences/asteroids/web/events/sc_dawn/ceres_arrival.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "After a journey of two and a half years, Dawn arrived at the dwarf planet Ceres on March 6th, 2015, becoming the first mission in history to study a dwarf planet at close range, beating the New Horizons mission to Pluto by only four months. The spacecraft is still in orbit around Ceres to this day, but ran out of fuel in 2018, triggering the formal end of the mission. It is estimated that the spacecraft will orbit for another twenty years, eventually impacting the surface of Ceres. The spacecraft made many discoveries about Ceres that will be studied for decades to come." + }, + "related": ["1_ceres"] +} diff --git a/experiences/asteroids/web/events/sc_dawn/ceres_orbit.json b/experiences/asteroids/web/events/sc_dawn/ceres_orbit.json new file mode 100644 index 0000000..94fdb94 --- /dev/null +++ b/experiences/asteroids/web/events/sc_dawn/ceres_orbit.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "Dawn executed a number of different orbits around Ceres in order to accomplish several scientific goals, including the Low Altitude Mapping Orbit, which allowed the spacecraft to study the composition of the surface of Ceres from just 375 kilometers(233 miles) away." + }, + "related": ["1_ceres"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_dawn/launch.json b/experiences/asteroids/web/events/sc_dawn/launch.json new file mode 100644 index 0000000..4c3d568 --- /dev/null +++ b/experiences/asteroids/web/events/sc_dawn/launch.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "On September 27th, 2007, the Dawn mission launched from Cape Canaveral aboard a Delta II rocket." + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_dawn/mars_flyby.json b/experiences/asteroids/web/events/sc_dawn/mars_flyby.json new file mode 100644 index 0000000..a48e248 --- /dev/null +++ b/experiences/asteroids/web/events/sc_dawn/mars_flyby.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "The Dawn mission used Mars as a gravity \"slingshot\" in February of 2009, approaching within 550 kilometers of the surface of Mars in order to change her trajectory and pick up extra speed for the journey to the asteroid Vesta." + }, + "related": ["mars"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_dawn/vesta_arrival.json b/experiences/asteroids/web/events/sc_dawn/vesta_arrival.json new file mode 100644 index 0000000..834cbde --- /dev/null +++ b/experiences/asteroids/web/events/sc_dawn/vesta_arrival.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On July 16th, 2011, the Dawn spacecraft was captured by Vesta's gravity and entered orbit. Dawn would stay in orbit around Vesta for over a year, mapping the asteroid and collecting data for the purpose of evaluating the conditions of the early formation of the solar system. Dawn was the first mission to orbit an object in the main asteroid belt." + }, + "related": ["4_vesta"] +} diff --git a/experiences/asteroids/web/events/sc_dawn/vesta_departure.json b/experiences/asteroids/web/events/sc_dawn/vesta_departure.json new file mode 100644 index 0000000..07232d8 --- /dev/null +++ b/experiences/asteroids/web/events/sc_dawn/vesta_departure.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "On December 4th, 2012, Dawn escaped from the gravity of Vesta. The next port of call would be Ceres, a dwarf planet and the largest object in the main asteroid belt." + }, + "related": ["4_vesta"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_dawn/vesta_orbit.json b/experiences/asteroids/web/events/sc_dawn/vesta_orbit.json new file mode 100644 index 0000000..b489501 --- /dev/null +++ b/experiences/asteroids/web/events/sc_dawn/vesta_orbit.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "On July 16th, 2011, the Dawn spacecraft was captured by Vesta's gravity and entered orbit. The spacecraft would subsequently lower its orbit twice. Starting at 2,750 km (1,710 mi) above Vesta, the spacecraft later assumed a 12.3-hour high-altitude mapping orbit at 680 km (420 mi) on September 27, 2011, and finally entered a 4.3-hour low-altitude mapping orbit at 210 km(130 mi) on December 8th, 2011." + }, + "related": ["4_vesta"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_deep_impact/all_events.json b/experiences/asteroids/web/events/sc_deep_impact/all_events.json new file mode 100644 index 0000000..7b5fda1 --- /dev/null +++ b/experiences/asteroids/web/events/sc_deep_impact/all_events.json @@ -0,0 +1,30 @@ +{ + "launch": { + "id": "launch", + "title": "Deep Impact Launch", + "start": "2005-01-12T19:23:00", + "target": "earth", + "rate": 300, + "distance": 0.05, + "horizontalOffset": 5 + }, + "impactor_separation": { + "id": "impactor_separation", + "title": "Impactor Probe Separation", + "start": "2005-07-03T05:59:55", + "target": "sc_deep_impact_impactor", + "verticalOffset": 5, + "horizontalOffset": 5, + "distance": 0.017, + "visual": true + }, + "hartley_flyby": { + "id": "hartley_flyby", + "title": "A Visit to Comet 103P/Hartley", + "start": "2010-11-04T14:00:00", + "target": "103p_hartley_2", + "distance": 0.05, + "horizontalOffset": 2, + "visual": true + } +} diff --git a/experiences/asteroids/web/events/sc_deep_impact/hartley_flyby.json b/experiences/asteroids/web/events/sc_deep_impact/hartley_flyby.json new file mode 100644 index 0000000..0b25009 --- /dev/null +++ b/experiences/asteroids/web/events/sc_deep_impact/hartley_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "Although Deep Impact’s primary mission was over, because the flyby vehicle still had plenty of propellant, on July 3, 2007, NASA approved a new supplemental mission for Deep Impact, known as EPOXI. The spacecraft was eventually redirected towards Comet Hartley 2, also known as 103P/Hartley. On November 4th, 2010, the spacecraft conducted its flyby of the target at a range of about 430 miles (694 kilometers), taking many highly detailed images of the comet. After this encounter, the mission focused on studying other comets from further distances before communication was lost in August of 2013." + }, + "related": ["103p_hartley_2"] +} diff --git a/experiences/asteroids/web/events/sc_deep_impact/impact.json b/experiences/asteroids/web/events/sc_deep_impact/impact.json new file mode 100644 index 0000000..e8c7230 --- /dev/null +++ b/experiences/asteroids/web/events/sc_deep_impact/impact.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On the 4th of July, 2005, the 820 pound (372 kilogram) impactor probe crashed into Comet Tempel 1 at a relative velocity of 23,000 mph (37,000 kph). A camera on the impactor took pictures all the way until three seconds before impact and transmitted them safely to Deep Impact. The impact generated an explosion the equivalent of 4.7 tons of TNT and a crater estimated to be about 490 feet (150 meters) in diameter. Minutes after the impact, the flyby probe passed the nucleus at a range of about 310 miles (500 kilometers) and took images of the crater (although it was obscured by the dust cloud), ejecta plume, and the entire nucleus." + }, + "related": ["9p_tempel_1"] +} diff --git a/experiences/asteroids/web/events/sc_deep_impact/impactor_separation.json b/experiences/asteroids/web/events/sc_deep_impact/impactor_separation.json new file mode 100644 index 0000000..e6177e4 --- /dev/null +++ b/experiences/asteroids/web/events/sc_deep_impact/impactor_separation.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On July 3rd, 2005, the Deep Impact spacecraft released its Impactor probe, which was about the size of a washing machine. The probe was placed on a collision course with the rapidly approaching comet Tempel 1." + }, + "related": ["9p_tempel_1"] +} diff --git a/experiences/asteroids/web/events/sc_deep_impact/launch.json b/experiences/asteroids/web/events/sc_deep_impact/launch.json new file mode 100644 index 0000000..35be6e5 --- /dev/null +++ b/experiences/asteroids/web/events/sc_deep_impact/launch.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "The Deep Impact mission launched on January 12th, 2005, with the spectacular goal of impacting a comet with an impactor probe and flying through the subsequent debris field to study the interior composition of Comet Tempel 1." + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_deep_impact_impactor/all_events.json b/experiences/asteroids/web/events/sc_deep_impact_impactor/all_events.json new file mode 100644 index 0000000..5c8a6d8 --- /dev/null +++ b/experiences/asteroids/web/events/sc_deep_impact_impactor/all_events.json @@ -0,0 +1,21 @@ +{ + "impact": { + "id": "impact", + "title": "Impact on Tempel 1", + "start": "2005-07-04T05:44:20", + "target": "9p_tempel_1", + "distance": 0.02, + "horizontalOffset": 3, + "visual": true + }, + "impactor_separation": { + "id": "impactor_separation", + "title": "Impactor Probe Separation", + "start": "2005-07-03T05:59:56", + "target": "sc_deep_impact", + "distance": 0.01, + "horizontalOffset": 10, + "verticalOffset": 10, + "visual": true + } +} diff --git a/experiences/asteroids/web/events/sc_deep_impact_impactor/impact.json b/experiences/asteroids/web/events/sc_deep_impact_impactor/impact.json new file mode 100644 index 0000000..e8c7230 --- /dev/null +++ b/experiences/asteroids/web/events/sc_deep_impact_impactor/impact.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On the 4th of July, 2005, the 820 pound (372 kilogram) impactor probe crashed into Comet Tempel 1 at a relative velocity of 23,000 mph (37,000 kph). A camera on the impactor took pictures all the way until three seconds before impact and transmitted them safely to Deep Impact. The impact generated an explosion the equivalent of 4.7 tons of TNT and a crater estimated to be about 490 feet (150 meters) in diameter. Minutes after the impact, the flyby probe passed the nucleus at a range of about 310 miles (500 kilometers) and took images of the crater (although it was obscured by the dust cloud), ejecta plume, and the entire nucleus." + }, + "related": ["9p_tempel_1"] +} diff --git a/experiences/asteroids/web/events/sc_deep_impact_impactor/impactor_separation.json b/experiences/asteroids/web/events/sc_deep_impact_impactor/impactor_separation.json new file mode 100644 index 0000000..e6177e4 --- /dev/null +++ b/experiences/asteroids/web/events/sc_deep_impact_impactor/impactor_separation.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On July 3rd, 2005, the Deep Impact spacecraft released its Impactor probe, which was about the size of a washing machine. The probe was placed on a collision course with the rapidly approaching comet Tempel 1." + }, + "related": ["9p_tempel_1"] +} diff --git a/experiences/asteroids/web/events/sc_deep_space_1/all_events.json b/experiences/asteroids/web/events/sc_deep_space_1/all_events.json new file mode 100644 index 0000000..31b3425 --- /dev/null +++ b/experiences/asteroids/web/events/sc_deep_space_1/all_events.json @@ -0,0 +1,9 @@ +{ + "borrelly_flyby": { + "id": "borrelly_flyby", + "title": "A Visit to Comet 19P/Borrelly", + "start": "2001-09-22T22:29:33", + "target": "19p_borrelly", + "visual": true + } +} diff --git a/experiences/asteroids/web/events/sc_deep_space_1/borrelly_flyby.json b/experiences/asteroids/web/events/sc_deep_space_1/borrelly_flyby.json new file mode 100644 index 0000000..7e5c0e6 --- /dev/null +++ b/experiences/asteroids/web/events/sc_deep_space_1/borrelly_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On September 22, 2001, Deep Space 1 entered the coma of Comet Borrelly, making its closest approach of about 1,350 miles (2,171 kilometers) to the nucleus at 22:29:33 UT. Traveling at about 10 miles per second (16.58 kilometers per second) relative to the nucleus at the time, it returned some of the best images of a comet to date, as well as other significant data." + }, + "related": ["19p_borrelly"] +} diff --git a/experiences/asteroids/web/events/sc_galileo/all_events.json b/experiences/asteroids/web/events/sc_galileo/all_events.json new file mode 100644 index 0000000..75e6a14 --- /dev/null +++ b/experiences/asteroids/web/events/sc_galileo/all_events.json @@ -0,0 +1,55 @@ +{ + "launch": { + "id": "launch", + "title": "Galileo Launch", + "start": "1989-10-18T13:28:44", + "target": "earth", + "rate": 300, + "distance": 0.05 + }, + "gaspra_flyby": { + "id": "gaspra_flyby", + "title": "A Visit to Gaspra", + "start": "1991-10-29T22:16:00", + "target": "951_gaspra", + "distance": 0.06, + "rate": 1, + "horizontalOffset": -8, + "visual": true + }, + "ida_flyby": { + "id": "ida_flyby", + "title": "A Flyby of Ida", + "start": "1993-08-28T16:50:29", + "target": "243_ida", + "distance": 0.1, + "rate": 15, + "horizontalOffset": 8, + "visual": true + }, + "probe_deploy": { + "id": "probe_deploy", + "title": "Atmospheric Probe Released", + "start": "1995-07-13T05:29:57", + "target": "sc_galileo_probe", + "distance": 0.03 + }, + "jupiter_arrival": { + "id": "jupiter_arrival", + "title": "Arrival at Jupiter and Orbit Insertion", + "start": "1995-12-07T17:36:00", + "target": "jupiter", + "distance": 0.04, + "rate": 1 + }, + "end_of_mission": { + "id": "end_of_mission", + "title": "Galileo enters Jupiter's Atmosphere", + "start": "2003-09-21T18:22:00", + "target": "jupiter", + "rate": 60, + "distance": 0.15, + "horizontalOffset": 10 + } + +} diff --git a/experiences/asteroids/web/events/sc_galileo/end_of_mission.json b/experiences/asteroids/web/events/sc_galileo/end_of_mission.json new file mode 100644 index 0000000..a7f1e22 --- /dev/null +++ b/experiences/asteroids/web/events/sc_galileo/end_of_mission.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": " After 34 Jupiter orbits and 35 flybys of the moons of Jupiter, and many important scientific discoveries, the Galileo spacecraft was intentionally sent into the atmosphere of Jupiter to end the mission. Once a spacecraft loses power, it could stay in orbit around Jupiter, but there is a danger of impacting one of the Jovian moons over time. The spacecraft could potentially be contaminated with microbes from Earth, so to protect the moons from a possible contamination event years later, Galileo was sent directly into Jupiter to be vaporized in the intense heat and pressure of Jupiter, like the Galileo probe was years before. Galileo entered Jupiter's atmosphere on September 21st, 2003." + }, + "related": ["sc_galileo_probe"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_galileo/gaspra_flyby.json b/experiences/asteroids/web/events/sc_galileo/gaspra_flyby.json new file mode 100644 index 0000000..f01d181 --- /dev/null +++ b/experiences/asteroids/web/events/sc_galileo/gaspra_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "After a flyby of Venus and two flybys of Earth, the Galileo mission became the first spacecraft to closely approach an asteroid, a flyby by Gaspra on October 29th, 1991." + }, + "related": ["951_gaspra"] +} diff --git a/experiences/asteroids/web/events/sc_galileo/ida_flyby.json b/experiences/asteroids/web/events/sc_galileo/ida_flyby.json new file mode 100644 index 0000000..cf9125e --- /dev/null +++ b/experiences/asteroids/web/events/sc_galileo/ida_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On a second pass through the asteroid belt, Galileo discovered a miniature moon orbiting asteroid Ida. This tiny body was named Dactyl." + }, + "related": ["243_ida","dactyl"] +} diff --git a/experiences/asteroids/web/events/sc_galileo/jupiter_arrival.json b/experiences/asteroids/web/events/sc_galileo/jupiter_arrival.json new file mode 100644 index 0000000..43b9717 --- /dev/null +++ b/experiences/asteroids/web/events/sc_galileo/jupiter_arrival.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "On July 7th, 1995, Galileo arrived at Jupiter. To get into orbit, the spacecraft had to use its main engine. An error could send Galileo sailing past the planet, and there was just one chance to get it right. After hours of anxious waiting, mission controllers confirmed that the spacecraft was safely in orbit; Galileo was alive and well and had begun its primary mission. That very day, the spacecraft made close flybys of both Europa and Io." + }, + "related": ["sc_galileo"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_galileo/launch.json b/experiences/asteroids/web/events/sc_galileo/launch.json new file mode 100644 index 0000000..92b5f5e --- /dev/null +++ b/experiences/asteroids/web/events/sc_galileo/launch.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "The Galileo mission launched on October 18th, 1989, from the Space Shuttle Atlantis, which was already in orbit around the Earth. The mission sought to become the first spacecraft to enter orbit around Jupiter, and also the first to send a probe down into the atmosphere. The journey to Jupiter took six years." + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_galileo/probe_deploy.json b/experiences/asteroids/web/events/sc_galileo/probe_deploy.json new file mode 100644 index 0000000..0266e97 --- /dev/null +++ b/experiences/asteroids/web/events/sc_galileo/probe_deploy.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On July 13th, 1995, the Galileo probe detached and began her journey. It would be another five months before the probe arrived at Jupiter and entered the planet itself." + }, + "related": ["jupiter"] +} diff --git a/experiences/asteroids/web/events/sc_galileo_probe/all_events.json b/experiences/asteroids/web/events/sc_galileo_probe/all_events.json new file mode 100644 index 0000000..29fdef8 --- /dev/null +++ b/experiences/asteroids/web/events/sc_galileo_probe/all_events.json @@ -0,0 +1,19 @@ +{ + "probe_entry": { + "id": "probe_entry", + "title": "Descent into Jupiter", + "start": "1995-12-07T06:00:00", + "target": "jupiter", + "distance": 0.03, + "rate": 3000, + "horizontalOffset": 10 + }, + "probe": { + "id": "probe", + "title": "Atmospheric Probe Deployment", + "start": "1995-07-13T05:29:55", + "target": "sc_galileo", + "distance": 0.02, + "rate": 1 + } +} diff --git a/experiences/asteroids/web/events/sc_galileo_probe/probe.json b/experiences/asteroids/web/events/sc_galileo_probe/probe.json new file mode 100644 index 0000000..b0ce71f --- /dev/null +++ b/experiences/asteroids/web/events/sc_galileo_probe/probe.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On July 13th, 1995, the Galileo probe detached and began her journey. It would be another five months before the probe arrived at Jupiter and entered the planet itself." + }, + "related": ["jupiter"] +} diff --git a/experiences/asteroids/web/events/sc_galileo_probe/probe_entry.json b/experiences/asteroids/web/events/sc_galileo_probe/probe_entry.json new file mode 100644 index 0000000..8fa213c --- /dev/null +++ b/experiences/asteroids/web/events/sc_galileo_probe/probe_entry.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": " On December 7th, 1995, the probe sliced into Jupiter's atmosphere at 106,000 mph (47 kilometers per second). It slowed, released its parachute, and dropped its heat shield. As the probe descended through 95 miles (153 kilometers) of the top layers of the atmosphere, it collected 58 minutes of data on the local weather. The data were sent to the spacecraft overhead, then transmitted back to Earth. It appeared that Jupiter's atmosphere is drier than had been previously thought. Measurements from the probe showed few clouds, and lightning only in the distance. It was only later that we discovered that the probe had entered an area called a \"hot spot.\" Towards the end of the 58-minute descent, the probe measured winds of 450 mph (724 kilometers per hour)—stronger than anything on Earth. The probe was finally melted and vaporized by the intense heat of the atmosphere." + }, + "related": ["jupiter", "sc_galileo"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_huygens/all_events.json b/experiences/asteroids/web/events/sc_huygens/all_events.json new file mode 100644 index 0000000..975023f --- /dev/null +++ b/experiences/asteroids/web/events/sc_huygens/all_events.json @@ -0,0 +1,21 @@ +{ + "descent_to_titan": { + "id": "descent_to_titan", + "title": "Descent to Titan", + "start": "2005-01-13T09:00:00", + "end": "2005-01-14T11:25:00", + "target": "titan", + "distance": 0.03, + "rate": 3600, + "horizontalOffset": -6 + }, + "huygens": { + "id": "huygens", + "title": "Huygens Deployment", + "start": "2004-12-25T01:46:00", + "end": "2004-12-25T02:46:00", + "target": "sc_cassini", + "distance": 0.02, + "rate": 1 + } +} diff --git a/experiences/asteroids/web/events/sc_huygens/descent_to_titan.json b/experiences/asteroids/web/events/sc_huygens/descent_to_titan.json new file mode 100644 index 0000000..0197106 --- /dev/null +++ b/experiences/asteroids/web/events/sc_huygens/descent_to_titan.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "On Jan. 14, 2005, the Huygens probe parachuted through Titan's atmosphere and landed on the moon's surface.", + "more": "After detaching from Cassini, the European Space Agency's Huygens probe coasted for about three weeks. Then, on Jan. 14, 2005, Huygens descended through the dense atmosphere of Titan, Saturn's largest moon for about two and a half hours. Titan is the only moon in the solar system with a thick atmosphere and open bodies of liquid on its surface. Huygens was about 9 feet (2.7 meters) wide and weighed roughly 700 pounds (318 kilograms). The probe slowed itself once it was in Titan's atmosphere, at first using a heat shield, and then using a series of three parachutes.\nDuring and after descent, Huygens studied the temperatures, pressures, and composition of Titan's atmosphere, and collected images of the surface. When Huygens safely touched down on the surface of Titan, it became the first probe to land on a world in the outer solar system. The probe survived more than an hour on Titan's surface and continued to transmit its observations to Cassini until its batteries died. Cassini write-protected the data until it had transmitted it back to Earth 16 times, to ensure scientists had a complete and accurate copy of the data." + }, + "related": ["titan"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_huygens/huygens.json b/experiences/asteroids/web/events/sc_huygens/huygens.json new file mode 100644 index 0000000..e07d435 --- /dev/null +++ b/experiences/asteroids/web/events/sc_huygens/huygens.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "The Huygens probe detached from Cassini on Dec. 24, 2004, bound for Saturn's largest moon Titan.", + "more": "After riding along with the Cassini spacecraft for nearly seven years from Earth to Saturn, the European Space Agency's Huygens probe detached from Cassini on Dec. 24, 2004. Before separation, Cassini turned so that Huygens was oriented in the attitude needed for atmospheric entry at Titan. Cassini spun the disk-like probe up to about seven revolutions per minute to stabilize Huygens for its three-week journey to Titan, and then released it at a separation velocity of about a foot per second. Cassini later fired its propulsion system to change trajectories so that it wouldn't follow Huygens to Titan's surface." + }, + "related": ["titan"] +} diff --git a/experiences/asteroids/web/events/sc_juno/all_events.json b/experiences/asteroids/web/events/sc_juno/all_events.json new file mode 100644 index 0000000..02769b0 --- /dev/null +++ b/experiences/asteroids/web/events/sc_juno/all_events.json @@ -0,0 +1,46 @@ +{ + "launch": { + "id": "launch", + "title": "Juno Launch", + "start": "2011-08-05T17:24:00", + "target": "earth", + "distance": 0.07, + "rate": 5, + "horizontalOffset": -25 + }, + "earth_flyby": { + "id": "earth_flyby", + "title": "Earth Flyby", + "start": "2013-10-09T16:55:00", + "target": "earth", + "distance": 0.2, + "rate": 300, + "horizontalOffset": 5 + }, + "deep_space_manuevers": { + "id": "deep_space_manuevers", + "title": "Deep Space Maneuvers", + "start": "2012-08-30T22:30:00" + }, + "jupiter_orbit_insertion": { + "id": "jupiter_orbit_insertion", + "title": "Jupiter Orbit Insertion", + "start": "2016-07-04T14:30:00", + "end": "2016-07-05T04:45:00", + "target": "jupiter", + "distance": 0.1, + "rate": 1500, + "horizontalOffset": 1 + }, + "joi_burn": { + "id": "joi_burn", + "title": "Jupiter Orbit Insertion Burn", + "start": "2016-07-05T02:29:50", + "end": "2016-07-05T03:05:00", + "target": "jupiter", + "distance": 0.05, + "rate": 5, + "verticalOffset": -50, + "horizontalOffset": 5 + } +} diff --git a/experiences/asteroids/web/events/sc_juno/deep_space_manuevers.json b/experiences/asteroids/web/events/sc_juno/deep_space_manuevers.json new file mode 100644 index 0000000..36bb06d --- /dev/null +++ b/experiences/asteroids/web/events/sc_juno/deep_space_manuevers.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "Juno performed two deep space manuevers, on August 30th and September 14th of 2012.", + "more": "The deep space manuevers are designed to pick up speed, in order to slingshot around the Earth in October of 2013 at an even faster rate. This enables the spacecraft to make it to Jupiter without needing too much fuel. The DSMs feature the use of the main engine and were both roughly 30-minutes long." + }, + "related": ["sc_juno"] +} diff --git a/experiences/asteroids/web/events/sc_juno/earth_flyby.json b/experiences/asteroids/web/events/sc_juno/earth_flyby.json new file mode 100644 index 0000000..2bca0e8 --- /dev/null +++ b/experiences/asteroids/web/events/sc_juno/earth_flyby.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "The Earth flyby occurs as the spacecraft is completing one elliptical orbit around the sun.", + "more": "It will boost Juno's velocity by 16,330 miles per hour (about 7.3 kilometers per second), placing the spacecraft on its final trajectory for Jupiter. Closest approach to Earth occurs on Oct. 9, 2013, at an altitude of 310 miles (500 kilometers). The exact time of closest approach will vary by about eight hours on this date, depending on launch date. During the flyby, Juno will pass behind Earth as seen from the sun, causing an interval when Earth blocks the sun's rays from reaching the spacecraft's solar panels. The time in eclipse is about 20 minutes, and represents the only time after Launch Phase when Juno will not receive direct sunlight." + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_juno/joi_burn.json b/experiences/asteroids/web/events/sc_juno/joi_burn.json new file mode 100644 index 0000000..1011ce6 --- /dev/null +++ b/experiences/asteroids/web/events/sc_juno/joi_burn.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "In order to be captured by Jupiter's gravity and enter a stable orbit around Jupiter, the Juno spacecraft performed a 35 minute burn of the main engine.", + "more": "The engine burn is a do-or-die moment. If the main engine does not burn long enough, the spacecraft doesn’t slow down enough to go into orbit around Jupiter. Had that happened, Juno would have passed right by the planet and entered into its own long orbit around the sun, and probably never see Jupiter again. The burn was successful and Juno entered a 53.5 day orbit around Jupiter" + }, + "related": ["jupiter"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_juno/jupiter_orbit_insertion.json b/experiences/asteroids/web/events/sc_juno/jupiter_orbit_insertion.json new file mode 100644 index 0000000..ccec474 --- /dev/null +++ b/experiences/asteroids/web/events/sc_juno/jupiter_orbit_insertion.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "Jupiter Orbit Insertion, or JOI, lasts from July 1st until one hour after the insertion maneuver, or until July 5th, 2016, at 03:30 UTC.", + "more": "This phase was extremely critical: it was the transition from flying through space to orbiting another planet. This was accomplished by slowing down the spacecraft by performing a main engine burn for 35 minutes when the spacecraft is at its closest approach to Jupiter. This slowdown allowed the craft to be captured by Jupiter's gravity, which means the spacecraft can then begin to settle into a final orbit. The settling process takes a long time; the next two orbits took 53.5 days each. The spacecraft was supposed to settle into its planned 14-day orbits after that, but a problem with the engine meant that Juno reamained in the 53.5 day orbits rather than risking another engine burn." + }, + "related": ["jupiter"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_juno/launch.json b/experiences/asteroids/web/events/sc_juno/launch.json new file mode 100644 index 0000000..21e7e22 --- /dev/null +++ b/experiences/asteroids/web/events/sc_juno/launch.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "The Juno spacecraft launched aboard an Atlas V 551 rocket from Cape Canaveral, Florida, on August 5th, 2011. About 54 minutes after launch, the spacecraft separated from the Centaur and began to extend its solar panels to gather energy from the sun.", + "more": "" + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_jwst/all_events.json b/experiences/asteroids/web/events/sc_jwst/all_events.json new file mode 100644 index 0000000..e16e728 --- /dev/null +++ b/experiences/asteroids/web/events/sc_jwst/all_events.json @@ -0,0 +1,21 @@ +{ + "launch": { + "id": "launch", + "title": "JWST Launch", + "start": "2021-12-25T12:20:00", + "target": "earth", + "rate": 300, + "distance": 0.08, + "horizontalOffset": -30 + }, + "deployment_complete": { + "id": "deployment_complete", + "title": "Deployment Complete", + "start": "2022-01-08T20:00:00" + }, + "enters_L2_orbit": { + "id": "enters_L2_orbit", + "title": "Webb Begins to Orbit the Sun at Lagrange Point L2", + "start": "2022-01-24T20:00:00" + } +} diff --git a/experiences/asteroids/web/events/sc_jwst/deployment_complete.json b/experiences/asteroids/web/events/sc_jwst/deployment_complete.json new file mode 100644 index 0000000..901b088 --- /dev/null +++ b/experiences/asteroids/web/events/sc_jwst/deployment_complete.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "In an incredible feat of engineering, JWST finished deploying the solar arrays, sunshield, antenna and mirrors on January 8th, 2021.", + "more": "The deployment of the James Webb Space Telescope was possibly the most complex ever done in space, having over 300 single points of failure in the two-week process of deployment." + }, + "related": ["earth"] +} diff --git a/experiences/asteroids/web/events/sc_jwst/enters_L2_orbit.json b/experiences/asteroids/web/events/sc_jwst/enters_L2_orbit.json new file mode 100644 index 0000000..4732832 --- /dev/null +++ b/experiences/asteroids/web/events/sc_jwst/enters_L2_orbit.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "On Jan. 24, 2022, the mission team fired Webb’s thrusters and inserted the space telescope into orbit around the Sun at the second Lagrange point, or L2, its final destination, nearly 1 million miles from Earth.", + "more": "What is special about this orbit is that it lets the telescope stay in line with the Earth as it moves around the Sun. This allows the satellite's large sunshield to protect the telescope from the light and heat of the Sun and Earth (and Moon)." + }, + "related": ["earth"] +} diff --git a/experiences/asteroids/web/events/sc_jwst/launch.json b/experiences/asteroids/web/events/sc_jwst/launch.json new file mode 100644 index 0000000..538bf93 --- /dev/null +++ b/experiences/asteroids/web/events/sc_jwst/launch.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "The James Webb Space Telescope launched aboard an Ariane 5 ECA rocket from the Guiana Space Center in French Guiana on December 25th, 2021.", + "more": "" + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_lcross/all_events.json b/experiences/asteroids/web/events/sc_lcross/all_events.json new file mode 100644 index 0000000..683af72 --- /dev/null +++ b/experiences/asteroids/web/events/sc_lcross/all_events.json @@ -0,0 +1,10 @@ +{ + "lcross_impact": { + "id": "lcross_impact", + "title": "LCROSS Approaches the South Pole Impact Site", + "start": "2009-10-09T10:53:41", + "target": "moon", + "rate": 130, + "distance": 0.1 + } +} diff --git a/experiences/asteroids/web/events/sc_lcross/lcross_impact.json b/experiences/asteroids/web/events/sc_lcross/lcross_impact.json new file mode 100644 index 0000000..d8a3d17 --- /dev/null +++ b/experiences/asteroids/web/events/sc_lcross/lcross_impact.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "As the spacecraft approached the moon's south pole, the upper stage separated, and then impacted a crater in the south pole area. A plume from the upper stage crash developed as the \"Shepherding Spacecraft\" LCROSS headed toward the moon. The 880-kilogram LCROSS probe flew through the resulting plume and used its instruments to scan for water while taking photographs. Fifteen minutes after the upper stage booster's impact, the LCROSS spacecraft also crashed into the crater floor." + }, + "related": ["sc_lunar_reconnaissance_orbiter"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_lucy/all_events.json b/experiences/asteroids/web/events/sc_lucy/all_events.json new file mode 100644 index 0000000..a1e89d5 --- /dev/null +++ b/experiences/asteroids/web/events/sc_lucy/all_events.json @@ -0,0 +1,60 @@ +{ + "lucy_eurybates_flyby": { + "id": "lucy_eurybates_flyby", + "title": "Flyby of Eurybates", + "start": "2027-08-12T09:36:26", + "target": "3548_eurybates", + "distance": 0.2, + "horizontalOffset": 5, + "visual": true + }, + "lucy_donaldjohanson_flyby": { + "id": "lucy_donaldjohanson_flyby", + "title": "Flyby of Donaldjohanson", + "start": "2025-04-20T18:16:07", + "target": "52246_donaldjohanson", + "distance": 0.3 + }, + "lucy_polymele_flyby": { + "id": "lucy_polymele_flyby", + "title": "Flyby of Polymele", + "start": "2027-09-15T14:30:25", + "target": "15094_polymele", + "distance": 0.2, + "horizontalOffset": 5 + }, + "lucy_dinkinesh_flyby": { + "id": "lucy_dinkinesh_flyby", + "title": "Flyby of Dinkinesh", + "start": "2023-11-01T16:54:45", + "target": "152830_dinkinesh", + "distance": 0.2, + "horizontalOffset": 5, + "visual": true + }, + "lucy_leucus_flyby": { + "id": "lucy_leucus_flyby", + "title": "Flyby of Leucus", + "start": "2028-04-18T17:29:08", + "target": "11351_leucus", + "horizontalOffset": 5, + "distance": 0.2 + }, + "lucy_orus_flyby": { + "id": "lucy_orus_flyby", + "title": "Flyby of Orus", + "start": "2028-11-11T16:26:13", + "target": "21900_orus", + "horizontalOffset": 5, + "distance": 0.2 + }, + "lucy_patroclus_menoetius_flyby": { + "id": "lucy_patroclus_menoetius_flyby", + "title": "Flyby of Patroclus and Menoetius", + "start": "2033-03-02T14:08:49", + "target": "617_patroclus", + "horizontalOffset": 5, + "distance": 0.2, + "rate": 3 + } +} diff --git a/experiences/asteroids/web/events/sc_lucy/lucy_dinkinesh_flyby.json b/experiences/asteroids/web/events/sc_lucy/lucy_dinkinesh_flyby.json new file mode 100644 index 0000000..6668421 --- /dev/null +++ b/experiences/asteroids/web/events/sc_lucy/lucy_dinkinesh_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "Lucy's first asteroid visit was at Dinkinesh, on November 1st, 2023. While the main purpose of this encounter was as an engineering test, mission scientists were also excited for what this tiny asteroid might teach us. This was the smallest main belt asteroid ever explored." + }, + "related": ["sc_lucy"] +} diff --git a/experiences/asteroids/web/events/sc_lucy/lucy_donaldjohanson_flyby.json b/experiences/asteroids/web/events/sc_lucy/lucy_donaldjohanson_flyby.json new file mode 100644 index 0000000..8135bbf --- /dev/null +++ b/experiences/asteroids/web/events/sc_lucy/lucy_donaldjohanson_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "Named after the paleoanthropologist who discovered the \"Lucy\" fossil, this will be the first small body that the Lucy mission will encounter. This is the smallest of Lucy's targets, measuring only 4 km (2-3 miles) in diameter. While this object will mostly provide a test rehearsal for all of Lucy's instruments, it is also an interesting object itself as it has been identified as a fragment of a massive collision that occurred around 130 million years ago that produced the Erigone family of asteroids. Lucy will fly by this C-type asteroid on April 20, 2025." + }, + "related": ["sc_lucy"] +} diff --git a/experiences/asteroids/web/events/sc_lucy/lucy_eurybates_flyby.json b/experiences/asteroids/web/events/sc_lucy/lucy_eurybates_flyby.json new file mode 100644 index 0000000..ef2b2eb --- /dev/null +++ b/experiences/asteroids/web/events/sc_lucy/lucy_eurybates_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "Lucy will arrive at her first Trojan asteroid encounter in August of 2027, flying by Eurybates, Trojan asteroids are those in the swarm of asteroids both ahead of Jupiter's orbit in Lagrange point L3, and behind Jupiter's orbit in Lagrange point L4." + }, + "related": ["sc_lucy"] +} diff --git a/experiences/asteroids/web/events/sc_lucy/lucy_leucus_flyby.json b/experiences/asteroids/web/events/sc_lucy/lucy_leucus_flyby.json new file mode 100644 index 0000000..627da6f --- /dev/null +++ b/experiences/asteroids/web/events/sc_lucy/lucy_leucus_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "The Lucy mission will also fly by Leucus. This 40 km (25 mile) D-type asteroid rotates extremely slowly. Its day is 446 hours! This slow rotation period means that it will likely get hotter during the day and colder at night than the other asteroids, so by comparing it with other D-type asteroids we should learn more about the materials that make up these asteroids. Also, as it rotates its brightness as observed from Earth varies a lot, suggesting that it is quite elongated. Lucy will know for sure when it flies by on April 18, 2028." + }, + "related": ["sc_lucy"] +} diff --git a/experiences/asteroids/web/events/sc_lucy/lucy_orus_flyby.json b/experiences/asteroids/web/events/sc_lucy/lucy_orus_flyby.json new file mode 100644 index 0000000..373cda2 --- /dev/null +++ b/experiences/asteroids/web/events/sc_lucy/lucy_orus_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "The Lucy mission will fly by Orus in November of 2028. Lucy will be able to compare this larger 51 km (31.7 mile) diameter Trojan to both the smaller Leucus, which is of the same type of very dark, very red objects thought to be rich in organics and carbon, and to the similarly-sized, but different spectrally typed, Eurybates." + }, + "related": ["sc_lucy"] +} diff --git a/experiences/asteroids/web/events/sc_lucy/lucy_patroclus_menoetius_flyby.json b/experiences/asteroids/web/events/sc_lucy/lucy_patroclus_menoetius_flyby.json new file mode 100644 index 0000000..cd39bbd --- /dev/null +++ b/experiences/asteroids/web/events/sc_lucy/lucy_patroclus_menoetius_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "This asteroid will be the final encounter of Lucy's primary mission, in March of 2033. After a long journey from the Greek L4 swarm to the Trojan L5 swarm, Lucy will fly by the binary pair of asteroids (617) Patroclus and Menoetius. They are large P-type Trojans, with average diameters of 113 km and 104 km (about 70 and 65 miles), respectively. Scientists hypothesize that they may be primordial asteroids left over from the very early Solar System." + }, + "related": ["sc_lucy"] +} diff --git a/experiences/asteroids/web/events/sc_lucy/lucy_polymele_flyby.json b/experiences/asteroids/web/events/sc_lucy/lucy_polymele_flyby.json new file mode 100644 index 0000000..e72d138 --- /dev/null +++ b/experiences/asteroids/web/events/sc_lucy/lucy_polymele_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "Polymele is the smallest of Lucy's Trojan targets at 21 km (13 miles) in diameter. It is a P-type asteroid, the same type as the much larger Patroclus and Menoetius binary. This will be the first time a spacecraft has ever flown by this dark, reddish class of asteroid that is believed to be rich in organics. Scientists think that Polymele is a collisional fragment of a larger P-type asteroid, and thus it will be very interesting to compare to its larger brethren. Lucy will fly by on September 15, 2027." + }, + "related": ["sc_lucy"] +} diff --git a/experiences/asteroids/web/events/sc_near_shoemaker/all_events.json b/experiences/asteroids/web/events/sc_near_shoemaker/all_events.json new file mode 100644 index 0000000..c555223 --- /dev/null +++ b/experiences/asteroids/web/events/sc_near_shoemaker/all_events.json @@ -0,0 +1,28 @@ +{ + "eros_landing": { + "id": "eros_landing", + "title": "Landing on Asteroid Eros", + "start": "2001-02-12T19:00:00", + "target": "433_eros", + "horizontalOffset": 15, + "distance": 0.1, + "rate": 45, + "visual": true + }, + "eros_orbit": { + "id": "eros_orbit", + "title": "NEAR Shoemaker Enters Orbit Around Eros", + "start": "2000-02-14T15:33:00", + "target": "433_eros", + "rate": 200, + "visual": true + }, + "mathilde_flyby": { + "id": "mathilde_flyby", + "title": "Flyby of Asteroid Mathilde", + "start": "1997-06-27T12:55:50", + "target": "253_mathilde", + "distance": 0.07, + "horizontalOffset": 15 + } +} diff --git a/experiences/asteroids/web/events/sc_near_shoemaker/eros_landing.json b/experiences/asteroids/web/events/sc_near_shoemaker/eros_landing.json new file mode 100644 index 0000000..8ec065f --- /dev/null +++ b/experiences/asteroids/web/events/sc_near_shoemaker/eros_landing.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "Following a slow, controlled descent, during which it took 69 high-resolution photos of Eros, NEAR touched down on Eros at a gentle 4 miles per hour (6.4 kilometers per hour), just south of a saddle-shaped feature named Himeros, on February 12, 2001, at 19:44 UT, becoming the first spacecraft to ever land on an asteroid. Remarkably, the spacecraft – which was not designed as a lander – survived touchdown on the asteroid and returned valuable data for about two weeks." + }, + "related": ["sc_near_shoemaker"] +} diff --git a/experiences/asteroids/web/events/sc_near_shoemaker/eros_orbit.json b/experiences/asteroids/web/events/sc_near_shoemaker/eros_orbit.json new file mode 100644 index 0000000..267763e --- /dev/null +++ b/experiences/asteroids/web/events/sc_near_shoemaker/eros_orbit.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "After first flying by the asteroid Eros in late 1998, NEAR finally moved into orbit around Eros on February 14, 2000, roughly a year later than intended, becoming the first human-made object to orbit a minor planet. It is not a coincidence that it landed on Valentine's Day." + }, + "related": ["sc_near_shoemaker"] +} diff --git a/experiences/asteroids/web/events/sc_near_shoemaker/mathilde_flyby.json b/experiences/asteroids/web/events/sc_near_shoemaker/mathilde_flyby.json new file mode 100644 index 0000000..ee7a93a --- /dev/null +++ b/experiences/asteroids/web/events/sc_near_shoemaker/mathilde_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On the way to its primary mission, NEAR performed a 25-minute flyby of the asteroid 253 Mathilde on June 27, 1997. The closest approach was about 750 miles (1,200 kilometers) at 12:56 UT. During the encounter, the spacecraft photographed 60 percent of the minor planet from a range of 750 miles (1,200 kilometers)." + }, + "related": ["253_mathilde"] +} diff --git a/experiences/asteroids/web/events/sc_new_horizons/all_events.json b/experiences/asteroids/web/events/sc_new_horizons/all_events.json new file mode 100644 index 0000000..91d253c --- /dev/null +++ b/experiences/asteroids/web/events/sc_new_horizons/all_events.json @@ -0,0 +1,21 @@ +{ + "pluto_flyby": { + "id": "pluto_flyby", + "title": "Flyby of Pluto", + "start": "2015-07-14T10:50:00", + "target": "134340_pluto", + "distance": 0.02, + "rate": 90, + "horizontalOffset": 1, + "verticalOffset": 5 + }, + "arrokoth_flyby": { + "id": "arrokoth_flyby", + "title": "Flyby of Arrokoth", + "start": "2019-01-01T05:32:00", + "target": "486958_arrokoth", + "rate": 5, + "distance": 0.035, + "horizontalOffset": -5 + } +} diff --git a/experiences/asteroids/web/events/sc_new_horizons/arrokoth_flyby.json b/experiences/asteroids/web/events/sc_new_horizons/arrokoth_flyby.json new file mode 100644 index 0000000..60e7659 --- /dev/null +++ b/experiences/asteroids/web/events/sc_new_horizons/arrokoth_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On Jan. 1, 2019, New Horizons flew past Arrokoth, a Kuiper Belt Object that is approximately 4 billion miles (6.4 billion kilometers) from Earth, making it the farthest object ever studied in human history. Initial images hinted at a reddish, snowman-like shape, but further analysis of images taken near closest approach — New Horizons came to within just 2,200 miles (3,500 kilometers)—revealed just how unusual the object’s shape really is. At about 22 miles (35 kilometers) long, Arrokoth consists of a large, flat lobe connected to a smaller, rounder lobe. The strange shape was the biggest surprise of the flyby, somewhat resembling a red snowman. No rings or moons were spotted." + }, + "related": ["486958_arrokoth"] +} diff --git a/experiences/asteroids/web/events/sc_new_horizons/pluto_flyby.json b/experiences/asteroids/web/events/sc_new_horizons/pluto_flyby.json new file mode 100644 index 0000000..97bf58a --- /dev/null +++ b/experiences/asteroids/web/events/sc_new_horizons/pluto_flyby.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "NASA's New Horizons spacecraft is the first spacecraft to explore Pluto up close, flying by the dwarf planet and its moons on July 14, 2015. The spacecraft flew about 4,800 miles (7,800 kilometers) above the surface of Pluto. Besides collecting data on Pluto and Charon, New Horizons also observed Pluto’s other satellites, Nix, Hydra, Kerberos and Styx. Stunning photographs showed a vast heart-shaped nitrogen glacier on the surface. It’s about 600-miles wide (1,000 kilometers), undoubtedly the largest known glacier in the solar system. On Charon, images showed an enormous equatorial extension tectonic belt, suggesting a long-past water-ice ocean." + }, + "related": ["134340_pluto"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_osiris_rex/all_events.json b/experiences/asteroids/web/events/sc_osiris_rex/all_events.json new file mode 100644 index 0000000..9d3efc9 --- /dev/null +++ b/experiences/asteroids/web/events/sc_osiris_rex/all_events.json @@ -0,0 +1,44 @@ +{ + "launch": { + "id": "launch", + "title": "OSIRIS-REx Launch", + "start": "2016-09-09T06:58:51", + "end": "2016-09-10T01:00:00", + "target": "earth", + "distance": 0.05, + "rate": 600, + "horizontalOffset": 5, + "verticalOffset": 0 + }, + "bennu_arrival": { + "id": "bennu_arrival", + "title": "Arrival at Bennu", + "start": "2018-03-05T00:00:00", + "target": "101955_bennu", + "distance": 0.3, + "rate": 50000, + "horizontalOffset": 5, + "verticalOffset": 0 + }, + "sample_acquisition": { + "id": "sample_acquisition", + "title": "OSIRIS-REx Samples Bennu's Surface", + "start": "2020-10-20T21:49:00", + "target": "101955_bennu", + "distance": 0.05, + "horizontalOffset": 45, + "verticalOffset": -67, + "visual":true + }, + "sample_drop": { + "id": "sample_drop", + "title": "Sample Return Capsule Separation at Earth", + "start": "2023-09-24T10:41:52", + "end": "2023-09-24T14:43:38", + "target": "sc_osiris_rex_src", + "distance": 0.016, + "horizontalOffset": 100, + "rate": 1, + "visual":true + } +} diff --git a/experiences/asteroids/web/events/sc_osiris_rex/bennu_arrival.json b/experiences/asteroids/web/events/sc_osiris_rex/bennu_arrival.json new file mode 100644 index 0000000..e63d3ae --- /dev/null +++ b/experiences/asteroids/web/events/sc_osiris_rex/bennu_arrival.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "OSIRIS-REx arrived at Bennu on December 3rd, 2018, matching both the speed and orbit of the asteroid." + }, + "related": ["101955_bennu"] +} diff --git a/experiences/asteroids/web/events/sc_osiris_rex/launch.json b/experiences/asteroids/web/events/sc_osiris_rex/launch.json new file mode 100644 index 0000000..8bada72 --- /dev/null +++ b/experiences/asteroids/web/events/sc_osiris_rex/launch.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "OSIRIS-REx launched on September 8th, 2016 on an Atlas V 441 rocket at Cape Canaveral, Florida." + }, + "related": ["101955_bennu", "earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_osiris_rex/sample_acquisition.json b/experiences/asteroids/web/events/sc_osiris_rex/sample_acquisition.json new file mode 100644 index 0000000..5cc8613 --- /dev/null +++ b/experiences/asteroids/web/events/sc_osiris_rex/sample_acquisition.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On October 20th, 2020, the OSIRIS-REx mission successfully sampled the surface of the asteroid Bennu, collecting over 60 grams of material." + }, + "related": ["101955_bennu"] +} diff --git a/experiences/asteroids/web/events/sc_osiris_rex/sample_drop.json b/experiences/asteroids/web/events/sc_osiris_rex/sample_drop.json new file mode 100644 index 0000000..71fa4c7 --- /dev/null +++ b/experiences/asteroids/web/events/sc_osiris_rex/sample_drop.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "After almost two and a half years of travel, on September 24th, 2023, the OSIRIS-REx mission dropped the sample return capsule into the Earth's atmosphere, landing in Utah. The collected material from Bennu will then be analyzed for years." + }, + "related": ["101955_bennu","earth"] +} diff --git a/experiences/asteroids/web/events/sc_osiris_rex_src/all_events.json b/experiences/asteroids/web/events/sc_osiris_rex_src/all_events.json new file mode 100644 index 0000000..dd32e06 --- /dev/null +++ b/experiences/asteroids/web/events/sc_osiris_rex_src/all_events.json @@ -0,0 +1,13 @@ +{ + "sample_return": { + "id": "sample_return", + "title": "Sample Return Capsule Returns to Earth", + "start": "2023-09-24T14:34:00", + "target": "earth", + "distance": 4500, + "visual": true, + "horizontalOffset": 0, + "verticalOffset": 0, + "rate": 30 + } +} \ No newline at end of file diff --git a/experiences/asteroids/web/events/sc_osiris_rex_src/capsule_separation.json b/experiences/asteroids/web/events/sc_osiris_rex_src/capsule_separation.json new file mode 100644 index 0000000..813a965 --- /dev/null +++ b/experiences/asteroids/web/events/sc_osiris_rex_src/capsule_separation.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "After almost two and a half years of travel, on September 24th, 2023, the OSIRIS-REx Sample Return Capsule separated from her parent spacecraft in order to return the asteroid samples to Earth." + }, + "related": ["101955_bennu","earth"] +} diff --git a/experiences/asteroids/web/events/sc_osiris_rex_src/sample_return.json b/experiences/asteroids/web/events/sc_osiris_rex_src/sample_return.json new file mode 100644 index 0000000..58a8c87 --- /dev/null +++ b/experiences/asteroids/web/events/sc_osiris_rex_src/sample_return.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "After almost two and a half years of travel, on September 24th, 2023, the OSIRIS-REx mission dropped the sample return capsule into the Earth's atmosphere, landing in Utah. The collected material from Bennu will then be analyzed for years." + }, + "related": ["101955_bennu", "earth", "sc_osiris_rex"] +} diff --git a/experiences/asteroids/web/events/sc_philae/all_events.json b/experiences/asteroids/web/events/sc_philae/all_events.json new file mode 100644 index 0000000..9d89d58 --- /dev/null +++ b/experiences/asteroids/web/events/sc_philae/all_events.json @@ -0,0 +1,21 @@ +{ + "philae_landing": { + "id": "philae_landing", + "title": "Landing on Comet 67P", + "start": "2014-11-12T15:30:00", + "target": "67p_churyumov_gerasimenko", + "verticalOffset": -50, + "distance": 1.0, + "visual": true + }, + "philae_launch": { + "id": "philae_launch", + "title": "Philae Leaves Rosetta", + "start": "2014-11-12T08:35:15", + "target": "67p_churyumov_gerasimenko", + "distance": 0.03, + "rate": 4, + "horizontalOffset": -10, + "visual": true + } +} diff --git a/experiences/asteroids/web/events/sc_philae/philae_landing.json b/experiences/asteroids/web/events/sc_philae/philae_landing.json new file mode 100644 index 0000000..a7cdb78 --- /dev/null +++ b/experiences/asteroids/web/events/sc_philae/philae_landing.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "Philae landed on the comet at 15:34 UT, but actually bounced twice because two harpoons did not fire as intended. The lander bounced into a shadowed area, preventing the solar panels from collecting power, and the battery drained after two days. The lander collected data and did manage to send it back to Rosetta. This was the first spacecraft to ever land on a comet." + }, + "related": ["sc_rosetta"] +} diff --git a/experiences/asteroids/web/events/sc_philae/philae_launch.json b/experiences/asteroids/web/events/sc_philae/philae_launch.json new file mode 100644 index 0000000..a04a575 --- /dev/null +++ b/experiences/asteroids/web/events/sc_philae/philae_launch.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "The robotic lander Philae detatched from the Rosetta spacecraft on November 12th, 2014, initiating a seven-hour descent to the comet at a relative velocity of about 3 feet per second (1 meter per second)." + }, + "related": ["sc_rosetta"] +} diff --git a/experiences/asteroids/web/events/sc_pioneer_10/all_events.json b/experiences/asteroids/web/events/sc_pioneer_10/all_events.json new file mode 100644 index 0000000..7554710 --- /dev/null +++ b/experiences/asteroids/web/events/sc_pioneer_10/all_events.json @@ -0,0 +1,12 @@ +{ + "jupiter_flyby": { + "id": "jupiter_flyby", + "title": "Jupiter flyby", + "start": "1973-11-30T21:00:00", + "end": "1979-03-05T16:30:00", + "target": "jupiter", + "rate": 10000, + "distance": 0.06, + "horizontalOffset": -4 + } +} diff --git a/experiences/asteroids/web/events/sc_pioneer_10/jupiter_flyby.json b/experiences/asteroids/web/events/sc_pioneer_10/jupiter_flyby.json new file mode 100644 index 0000000..0f7f0d1 --- /dev/null +++ b/experiences/asteroids/web/events/sc_pioneer_10/jupiter_flyby.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "Pioneer 10’s closest approach to Jupiter was at 02:26 UT Dec. 4, 1973, when the spacecraft raced by the planet at a range of 81,000 miles (130,354 kilometers) at a velocity of approximately 78,000 miles per hour (126,000 kilometers/hour). Of the spacecraft’s 11 scientific instruments, 6 operated continuously through the encounter. The spacecraft passed by a series of Jovian moons, obtaining photos of Callisto, Ganymede, and Europa (but not of Io, as the photopolarimeter succumbed to radiation by that time). Approximately 78 minutes after the closest approach, Pioneer 10 passed behind Jupiter’s limb for a radio occultation experiment. In addition, the infrared radiometer provided further information on the planet’s atmosphere. Between November 6th and December 31st, the spacecraft took about 500 pictures of Jupiter’s atmosphere with the highest resolution of about 200 miles (320 kilometers), clearly showing such landmarks as the Great Red Spot. The Jupiter encounter was declared over Jan. 2, 1974." + }, + "related": ["sc_pioneer_11"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_pioneer_11/all_events.json b/experiences/asteroids/web/events/sc_pioneer_11/all_events.json new file mode 100644 index 0000000..630755c --- /dev/null +++ b/experiences/asteroids/web/events/sc_pioneer_11/all_events.json @@ -0,0 +1,20 @@ +{ + "jupiter_flyby": { + "id": "jupiter_flyby", + "title": "Jupiter flyby", + "start": "1974-12-01T01:00:00", + "target": "jupiter", + "rate": 10000, + "distance": 0.06, + "horizontalOffset": -4 + }, + "saturn_flyby": { + "id": "saturn_flyby", + "title": "Saturn flyby", + "start": "1979-08-30T11:00:00", + "target": "saturn", + "rate": 10000, + "distance": 0.06, + "horizontalOffset": 4 + } +} diff --git a/experiences/asteroids/web/events/sc_pioneer_11/jupiter_flyby.json b/experiences/asteroids/web/events/sc_pioneer_11/jupiter_flyby.json new file mode 100644 index 0000000..74c4cc0 --- /dev/null +++ b/experiences/asteroids/web/events/sc_pioneer_11/jupiter_flyby.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "The spacecraft’s closest approach to Jupiter occurred at 05:22 UT on Dec. 3, 1974, at a range of about 26,400 miles (42,500 kilometers) from the planet’s cloud tops, three times closer than Pioneer 10. By this time, it was traveling faster than any human-made object at the time, more than 106,000 miles per hour (171,000 kilometers per hour). Because of its high speed during the encounter, the spacecraft’s exposure to Jupiter’s radiation belts spanned a shorter time than its predecessor although it was actually closer to the planet. Pioneer 11 repeatedly crossed Jupiter’s bow shock, indicating that the Jovian magnetosphere changes its boundaries as it is buffeted by the solar wind. Besides the many images of the planet (and better pictures of the Great Red Spot), Pioneer 11 took about 200 images of the moons of Jupiter. The vehicle then used Jupiter’s massive gravitational field to swing back across the solar system to set it on a course to Saturn" + }, + "related": ["sc_pioneer_10"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_pioneer_11/saturn_flyby.json b/experiences/asteroids/web/events/sc_pioneer_11/saturn_flyby.json new file mode 100644 index 0000000..16f5958 --- /dev/null +++ b/experiences/asteroids/web/events/sc_pioneer_11/saturn_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "Pioneer 11 detected Saturn’s bow shock on Aug. 31, 1979, about 932,000 miles (1.5 million kilometers) out from the planet, thus providing the first conclusive evidence of the existence of Saturn’s magnetic field. The spacecraft crossed the planet’s ring plane beyond the outer ring at 14:36 UT Sept. 1, 1979, and then passed by the planet at 16:31 UT for a close encounter at a range of about 13,000 miles (20,900 kilometers). It was moving at a relative velocity of about 71,000 miles per hour (114,000 kilometers per hour) at the point of closest approach.During the encounter, the spacecraft took 440 images of the planetary system, with about 20 at a resolution of about 56 miles (90 kilometers). The images of Saturn’s moon Titan (at a resolution of 112 miles or 180 kilometers) showed a featureless orange fuzzy satellite. A brief burst of data on Titan indicated that the average global temperature of Titan was minus 315 degrees Fahrenheit (minus 193 degrees Celsius). Among Pioneer 11’s many discoveries were a narrow ring outside the A ring named the F ring and a new satellite 124 miles (200 kilometers) in diameter. The spacecraft recorded the planet’s overall temperature at minus 292 degrees Fahrenheit (minus 180 degrees Celsius) and photographs indicated a more featureless atmosphere than that of Jupiter. Analysis of data suggested that the planet was primarily made of liquid hydrogen." + }, + "related": ["sc_pioneer_10"] +} diff --git a/experiences/asteroids/web/events/sc_psyche/all_events.json b/experiences/asteroids/web/events/sc_psyche/all_events.json new file mode 100644 index 0000000..e848fe4 --- /dev/null +++ b/experiences/asteroids/web/events/sc_psyche/all_events.json @@ -0,0 +1,13 @@ +{ + "arrival": { + "id": "arrival", + "title": "Psyche arrives at 16 Psyche Asteroid", + "start": "2029-08-17T01:02:15", + "target": "16_psyche", + "distance": 0.085, + "visual": true, + "horizontalOffset": 0, + "verticalOffset": 0, + "rate": 1 + } +} \ No newline at end of file diff --git a/experiences/asteroids/web/events/sc_psyche/arrival.json b/experiences/asteroids/web/events/sc_psyche/arrival.json new file mode 100644 index 0000000..286d7e1 --- /dev/null +++ b/experiences/asteroids/web/events/sc_psyche/arrival.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "In August of 2029, after almost six years of travel, the Psyche mission arrives at the asteroid 16 Psyche to begin studying a new type of world. For the first time, we will examine a world made not of rock and ice, but metal." + }, + "related": ["16_psyche"] +} \ No newline at end of file diff --git a/experiences/asteroids/web/events/sc_rosetta/67p_orbit.json b/experiences/asteroids/web/events/sc_rosetta/67p_orbit.json new file mode 100644 index 0000000..7a3a845 --- /dev/null +++ b/experiences/asteroids/web/events/sc_rosetta/67p_orbit.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "In August of 2014, the Rosetta spacecraft had rendezvoused with the comet, and after a series of manuevers, became the first spacecraft to ever orbit a comet on September 10th, 2014." + }, + "related": ["67p_churyumov_gerasimenko"] +} diff --git a/experiences/asteroids/web/events/sc_rosetta/all_events.json b/experiences/asteroids/web/events/sc_rosetta/all_events.json new file mode 100644 index 0000000..99450d7 --- /dev/null +++ b/experiences/asteroids/web/events/sc_rosetta/all_events.json @@ -0,0 +1,38 @@ +{ + "philae_landing": { + "id": "philae_landing", + "title": "Landing on Comet 67P", + "start": "2014-11-12T15:33:00", + "target": "67p_churyumov_gerasimenko", + "distance": 0.1, + "horizontalOffset": -5, + "rate": 1, + "visual": true + }, + "philae_launch": { + "id": "philae_launch", + "title": "Philae Leaves Rosetta", + "start": "2014-11-12T08:35:15", + "rate": 4, + "visual": true + }, + "67p_orbit": { + "id": "67p_orbit", + "title": "Rosetta Enters Orbit Around Comet 67P", + "start": "2014-09-10T12:00:00", + "target": "67p_churyumov_gerasimenko", + "distance": 3.0, + "rate": 600, + "horizontalOffset": -5, + "visual": true + }, + "lutetia_flyby": { + "id": "lutetia_flyby", + "title": "Flyby of Asteroid Lutetia", + "start": "2010-07-10T15:45:00", + "target": "21_lutetia", + "distance": 0.1, + "horizontalOffset": -3, + "visual": true + } +} diff --git a/experiences/asteroids/web/events/sc_rosetta/lutetia_flyby.json b/experiences/asteroids/web/events/sc_rosetta/lutetia_flyby.json new file mode 100644 index 0000000..7b35b30 --- /dev/null +++ b/experiences/asteroids/web/events/sc_rosetta/lutetia_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On July 10th, 2010, the Rosetta spacecraft flew by the asteroid 21 Lutetia and captured spectacular images of about 50% of the surface." + }, + "related": ["253_mathilde"] +} diff --git a/experiences/asteroids/web/events/sc_rosetta/philae_landing.json b/experiences/asteroids/web/events/sc_rosetta/philae_landing.json new file mode 100644 index 0000000..78f2ad1 --- /dev/null +++ b/experiences/asteroids/web/events/sc_rosetta/philae_landing.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "The robotic lander Philae detatched from the Rosetta spacecraft on November 12th, 2014, initiating a seven-hour descent to the comet at a relative velocity of about 3 feet per second (1 meter per second). Philae landed on the comet at 15:34 UT, but actually bounced twice because two harpoons did not fire as intended. The lander bounced into a shadowed area, preventing the solar panels from collecting power, and the battery drained after two days. The lander collected data and did manage to send it back to Rosetta. This was the first spacecraft to ever land on a comet." + }, + "related": ["sc_rosetta"] +} diff --git a/experiences/asteroids/web/events/sc_rosetta/philae_launch.json b/experiences/asteroids/web/events/sc_rosetta/philae_launch.json new file mode 100644 index 0000000..a04a575 --- /dev/null +++ b/experiences/asteroids/web/events/sc_rosetta/philae_launch.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "The robotic lander Philae detatched from the Rosetta spacecraft on November 12th, 2014, initiating a seven-hour descent to the comet at a relative velocity of about 3 feet per second (1 meter per second)." + }, + "related": ["sc_rosetta"] +} diff --git a/experiences/asteroids/web/events/sc_stardust/all_events.json b/experiences/asteroids/web/events/sc_stardust/all_events.json new file mode 100644 index 0000000..2809896 --- /dev/null +++ b/experiences/asteroids/web/events/sc_stardust/all_events.json @@ -0,0 +1,30 @@ +{ + "wild2_flyby": { + "id": "wild2_flyby", + "title": "Flyby and Sampling of Comet Wild 2", + "start": "2004-01-02T19:22:00", + "target": "81p_wild_2", + "distance": 0.02, + "horizontalOffset": -8, + "visual": true + }, + "tempel1_flyby": { + "id": "tempel1_flyby", + "title": "Flyby of Comet Tempel 1", + "start": "2011-02-15T04:42:00", + "target": "9p_tempel_1", + "distance": 500000, + "verticalOffset": 15, + "horizontalOffset": -40, + "visual": true + }, + "collector_deployment": { + "id": "collector_deployment", + "title": "Dust Collector Deployment", + "start": "2000-02-21T23:59:31", + "target": "81p_wild_2", + "rate": 60, + "distance": 0.005, + "visual": true + } +} diff --git a/experiences/asteroids/web/events/sc_stardust/collector_deployment.json b/experiences/asteroids/web/events/sc_stardust/collector_deployment.json new file mode 100644 index 0000000..6a3129a --- /dev/null +++ b/experiences/asteroids/web/events/sc_stardust/collector_deployment.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "Insterstellar and comet dust particles were collected with a low-density microporous silica-based substance known as aerogel, attached to panels on the spacecraft to “soft-catch” and preserve the cometary materials. This is the first deployment of the dust collector." + }, + "related": ["81p_wild_2"] +} diff --git a/experiences/asteroids/web/events/sc_stardust/tempel1_flyby.json b/experiences/asteroids/web/events/sc_stardust/tempel1_flyby.json new file mode 100644 index 0000000..4dddc06 --- /dev/null +++ b/experiences/asteroids/web/events/sc_stardust/tempel1_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "Stardust, now known as Stardust/NExT, flew by Comet Tempel 1 on Feb. 15, 2011, at a range of 112 miles (181 kilometers), returning 72 images of the nucleus. Since the Deep Impact mission had been to this comet in 2005, this was the first time a comet had been revisited. It was also during this flyby that investigators were able to conclusively identify the crater caused by the Deep Impact mission’s probe." + }, + "related": ["9p_tempel_1"] +} diff --git a/experiences/asteroids/web/events/sc_stardust/wild2_flyby.json b/experiences/asteroids/web/events/sc_stardust/wild2_flyby.json new file mode 100644 index 0000000..496fd33 --- /dev/null +++ b/experiences/asteroids/web/events/sc_stardust/wild2_flyby.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "On Dec. 31, 2003, the spacecraft entered the coma of Comet Wild 2 (or 81P/Wild) with the closest encounter (at a range of 155 miles or 250 kilometers) taking place on Jan. 2, 2004. The dust sample collector, which had been deployed Dec. 24, 2003, was retracted about six hours after closest approach, stowed, and then sealed in the sample vault. The imaging system took 72 images of the comet’s nucleus." + }, + "related": ["81p_wild_2"] +} diff --git a/experiences/asteroids/web/events/sc_voyager_1/all_events.json b/experiences/asteroids/web/events/sc_voyager_1/all_events.json new file mode 100644 index 0000000..22c0375 --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_1/all_events.json @@ -0,0 +1,39 @@ +{ + "launch": { + "id": "launch", + "title": "Voyager 1 Launch", + "start": "1977-09-05T13:58:17", + "end": "1977-09-05T15:00:00", + "target": "earth", + "rate": 60, + "distance": 0.03 + }, + "jupiter": { + "id": "jupiter", + "title": "Voyager 1 at Jupiter", + "start": "1979-03-05T00:00:00", + "end": "1979-03-05T16:30:00", + "rate": 700, + "horizontalOffset": -8, + "distance": 0.08, + "target": "jupiter" + }, + "saturn": { + "id": "saturn", + "title": "Voyager 1 at Saturn", + "start": "1980-11-11T18:00:00", + "end": "1980-11-14T00:00:00", + "rate": 5000, + "horizontalOffset": -3, + "distance": 0.08, + "target": "saturn" + }, + "heliosphere": { + "id": "heliosphere", + "title": "Voyager 1 Leaves the Heliosphere", + "start": "2012-08-25T23:00:00", + "distance": 10000000000, + "target": "sun", + "horizontalOffset": 20 + } +} diff --git a/experiences/asteroids/web/events/sc_voyager_1/heliosphere.json b/experiences/asteroids/web/events/sc_voyager_1/heliosphere.json new file mode 100644 index 0000000..3fd6d55 --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_1/heliosphere.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "Scientists have three key indicators for determining whether the Voyager spacecraft have reached interstellar space.", + "more": "The three key indicators for determining whether the Voyager spacecraft have reached interstellar space are: \n 1) Outside Particles - An increase and leveling off of high-energy particles coming in from far outside our solar system. \n 2) Inside Particles - A drop to near-zero of low-energy particles that originate from inside the solar bubble. \n 3) A shift in the direction of the magnetic field or measurements of the plasma environment." + }, + "related": ["sc_voyager_1"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_voyager_1/jupiter.json b/experiences/asteroids/web/events/sc_voyager_1/jupiter.json new file mode 100644 index 0000000..5515510 --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_1/jupiter.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "Photography of Jupiter began in January 1979, when images of the brightly banded planet already exceeded the best taken from Earth. Voyager 1 completed its Jupiter encounter in early April, after taking almost 19,000 pictures and many other scientific measurements." + }, + "related": ["jupiter"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_voyager_1/launch.json b/experiences/asteroids/web/events/sc_voyager_1/launch.json new file mode 100644 index 0000000..104d13e --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_1/launch.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "On September 5th, Voyager 1 launched from Cape Canaveral aboard a Titan-Centaur rocket." + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_voyager_1/saturn.json b/experiences/asteroids/web/events/sc_voyager_1/saturn.json new file mode 100644 index 0000000..dcef850 --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_1/saturn.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "The Voyager 1 Saturn encounter occurred in November 1980. The encounter put Voyager 1 on a course to leave the solar system.", + "more": "The two Saturn encounters increased our knowledge and altered our understanding of Saturn. The extended, close-range observations provided high-resolution data far different from the picture assembled during centuries of Earth-based studies. Saturn's atmosphere is almost entirely hydrogen and helium. Voyager 1 found that about 7 percent of the volume of Saturn's upper atmosphere is helium (compared with 11 percent of Jupiter's atmosphere), while almost all the rest is hydrogen. Since Saturn's internal helium abundance was expected to be the same as Jupiter's and the Sun's, the lower abundance of helium in the upper atmosphere may imply that the heavier helium may be slowly sinking through Saturn's hydrogen; that might explain the excess heat that Saturn radiates over energy it receives from the Sun. Saturn is the only planet less dense than water. In the unlikely event that a lake could be found large enough, Saturn would float in it." + }, + "related": ["saturn"] +} diff --git a/experiences/asteroids/web/events/sc_voyager_2/all_events.json b/experiences/asteroids/web/events/sc_voyager_2/all_events.json new file mode 100644 index 0000000..4bdae1d --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_2/all_events.json @@ -0,0 +1,61 @@ +{ + "launch": { + "id": "launch", + "title": "Voyager 2 Launch", + "start": "1977-08-20T14:29:00", + "end": "1977-08-20T20:00:00", + "target": "earth", + "rate": 60, + "distance": 0.03 + }, + "jupiter": { + "id": "jupiter", + "title": "Voyager 2 at Jupiter", + "start": "1979-07-09T01:00:00", + "end": "1979-07-10T07:00:00", + "target": "jupiter", + "rate": 1200, + "horizontalOffset": -3, + "distance": 0.06 + }, + "saturn": { + "id": "saturn", + "title": "Voyager 2 at Saturn", + "start": "1981-08-25T00:00:00", + "end": "1981-08-28T00:00:00", + "target": "saturn", + "rate": 2400, + "distance": 0.06, + "horizontalOffset": -8 + }, + "uranus": { + "id": "uranus", + "title": "Voyager 2 at Uranus", + "start": "1986-01-23T12:00:00", + "end": "1986-01-26T15:00:00", + "target": "uranus", + "rate": 3600, + "horizontalOffset": -16, + "distance": 0.06 + }, + "neptune": { + "id": "neptune", + "title": "Voyager 2 at Neptune", + "start": "1989-08-24T10:00:00", + "end": "1989-08-25T14:00:00", + "target": "neptune", + "rate": 3600, + "horizontalOffset": -6, + "verticalOffset": 6, + "distance": 0.06 + }, + "heliosphere": { + "id": "heliosphere", + "title": "Voyager 2 leaves the Heliosphere", + "start": "2018-11-05T23:00:00", + "target": "sun", + "horizontalOffset": 0, + "verticalOffset": 20, + "distance": 10000000000 + } +} diff --git a/experiences/asteroids/web/events/sc_voyager_2/heliosphere.json b/experiences/asteroids/web/events/sc_voyager_2/heliosphere.json new file mode 100644 index 0000000..53420be --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_2/heliosphere.json @@ -0,0 +1,8 @@ +{ + "description": { + "blurb": "Scientists have three key indicators for determining whether the Voyager spacecraft have reached interstellar space.", + "more": "The three key indicators for determining whether the Voyager spacecraft have reached interstellar space are: 1) Outside Particles - An increase and leveling off of high-energy particles coming in from far outside our solar system.2) Inside Particles - A drop to near-zero of low-energy particles that originate from inside the solar bubble. 3) A shift in the direction of the magnetic field or measurements of the plasma environment." + }, + "related": ["sc_voyager_2"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_voyager_2/jupiter.json b/experiences/asteroids/web/events/sc_voyager_2/jupiter.json new file mode 100644 index 0000000..acf1ac6 --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_2/jupiter.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "Voyager 2 picked up the baton in late April and its encounter continued into August. The Voyager spacecraft took more than 33,000 pictures of Jupiter and its five major satellites." + }, + "related": ["jupiter"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_voyager_2/launch.json b/experiences/asteroids/web/events/sc_voyager_2/launch.json new file mode 100644 index 0000000..30b2a11 --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_2/launch.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "Voyager 2 launched on August 20, 1977, from Cape Canaveral, Florida aboard a Titan-Centaur rocket." + }, + "related": ["earth"], + "layers": true +} diff --git a/experiences/asteroids/web/events/sc_voyager_2/neptune.json b/experiences/asteroids/web/events/sc_voyager_2/neptune.json new file mode 100644 index 0000000..fdc9940 --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_2/neptune.json @@ -0,0 +1,6 @@ +{ + "description": { + "blurb": "In the summer of 1989, NASA's Voyager 2 became the first spacecraft to observe the planet Neptune, its final planetary target. Passing about 4,950 kilometers (3,000 miles) above Neptune's north pole, Voyager 2 made its closest approach to any planet 12 years after leaving Earth in 1977. Five hours later, Voyager 2 passed about 40,000 kilometers (25,000 miles) from Neptune's largest moon, Triton, the last solid body the spacecraft will have an opportunity to study." + }, + "related": ["neptune"] +} diff --git a/experiences/asteroids/web/events/sc_voyager_2/saturn.json b/experiences/asteroids/web/events/sc_voyager_2/saturn.json new file mode 100644 index 0000000..6c47eb4 --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_2/saturn.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "The Voyager 2 Saturn encounter occurred in August 1981, nine months after Voyager 1's Saturn encounter.", + "more": "Subdued contrasts and color differences on Saturn could be a result of more horizontal mixing or less production of localized colors than in Jupiter's atmosphere. While Voyager 1 saw few markings, Voyager 2's more sensitive cameras saw many: Long-lived ovals, tilted features in east-west shear zones, and others similar to, but generally smaller than, on Jupiter. Winds blow at high speeds in Saturn. Near the equator, the Voyagers measured winds about 500 meters a second (1,100 miles an hour). The wind blows mostly in an easterly direction. Strongest winds are found near the equator, and velocity falls off uniformly at higher latitudes. At latitudes greater than 35 degrees, winds alternate east and west as latitude increases. Marked dominance of eastward jet streams indicates that winds are not confined to the cloud layer, but must extend inward at least 2,000 kilometers (1,200 miles). Furthermore, measurements by Voyager 2 showing a striking north-south symmetry that leads some scientists to suggest the winds may extend from north to south through the interior of the planet." + }, + "related": ["saturn"] +} diff --git a/experiences/asteroids/web/events/sc_voyager_2/uranus.json b/experiences/asteroids/web/events/sc_voyager_2/uranus.json new file mode 100644 index 0000000..ebdd454 --- /dev/null +++ b/experiences/asteroids/web/events/sc_voyager_2/uranus.json @@ -0,0 +1,7 @@ +{ + "description": { + "blurb": "At its closet, the spacecraft came within 81,800 kilometers (50,600 miles) of Uranus's cloudtops on Jan. 24, 1986.", + "more": "Voyager 2's images of the five largest moons around Uranus revealed complex surfaces indicative of varying geologic pasts. The cameras also detected 10 previously unseen moons. Several instruments studied the ring system, uncovering the fine detail of the previously known rings and two newly detected rings. Voyager data showed that the planet's rate of rotation is 17 hours, 14 minutes. The spacecraft also found a Uranian magnetic field that is both large and unusual. In addition, the temperature of the equatorial region, which receives less sunlight over a Uranian year, is nevertheless about the same as that at the poles." + }, + "related": ["uranus"] +} diff --git a/experiences/asteroids/web/favicon-16x16.png b/experiences/asteroids/web/favicon-16x16.png new file mode 100644 index 0000000..96f068a Binary files /dev/null and b/experiences/asteroids/web/favicon-16x16.png differ diff --git a/experiences/asteroids/web/footron-messaging.development.js b/experiences/asteroids/web/footron-messaging.development.js new file mode 100644 index 0000000..ce15746 --- /dev/null +++ b/experiences/asteroids/web/footron-messaging.development.js @@ -0,0 +1,867 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.FootronMessaging = {})); +}(this, (function (exports) { 'use strict'; + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends.apply(this, arguments); + } + + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + + _setPrototypeOf(subClass, superClass); + } + + function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + + return _setPrototypeOf(o, p); + } + + function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) return false; + if (Reflect.construct.sham) return false; + if (typeof Proxy === "function") return true; + + try { + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); + return true; + } catch (e) { + return false; + } + } + + function _construct(Parent, args, Class) { + if (_isNativeReflectConstruct()) { + _construct = Reflect.construct; + } else { + _construct = function _construct(Parent, args, Class) { + var a = [null]; + a.push.apply(a, args); + var Constructor = Function.bind.apply(Parent, a); + var instance = new Constructor(); + if (Class) _setPrototypeOf(instance, Class.prototype); + return instance; + }; + } + + return _construct.apply(null, arguments); + } + + function _isNativeFunction(fn) { + return Function.toString.call(fn).indexOf("[native code]") !== -1; + } + + function _wrapNativeSuper(Class) { + var _cache = typeof Map === "function" ? new Map() : undefined; + + _wrapNativeSuper = function _wrapNativeSuper(Class) { + if (Class === null || !_isNativeFunction(Class)) return Class; + + if (typeof Class !== "function") { + throw new TypeError("Super expression must either be null or a function"); + } + + if (typeof _cache !== "undefined") { + if (_cache.has(Class)) return _cache.get(Class); + + _cache.set(Class, Wrapper); + } + + function Wrapper() { + return _construct(Class, arguments, _getPrototypeOf(this).constructor); + } + + Wrapper.prototype = Object.create(Class.prototype, { + constructor: { + value: Wrapper, + enumerable: false, + writable: true, + configurable: true + } + }); + return _setPrototypeOf(Wrapper, Class); + }; + + return _wrapNativeSuper(Class); + } + + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return self; + } + + var PROTOCOL_VERSION = 1; // TODO Make Protocol project for JS library similar to the python messaging library + + var MessageType; + + (function (MessageType) { + MessageType["HeartbeatApp"] = "ahb"; + MessageType["HeartbeatClient"] = "chb"; + MessageType["Connect"] = "con"; + MessageType["Access"] = "acc"; + MessageType["ApplicationClient"] = "cap"; + MessageType["ApplicationApp"] = "app"; + MessageType["Error"] = "err"; + MessageType["DisplaySettings"] = "dse"; + MessageType["Lifecycle"] = "lcy"; + })(MessageType || (MessageType = {})); + + var LockStateError = /*#__PURE__*/function (_Error) { + _inheritsLoose(LockStateError, _Error); + + function LockStateError(msg) { + var _this; + + _this = _Error.call(this, msg) || this; + Object.setPrototypeOf(_assertThisInitialized(_this), LockStateError.prototype); + return _this; + } + + return LockStateError; + }( /*#__PURE__*/_wrapNativeSuper(Error)); + + function _empty$1() {} + + function _awaitIgnored$1(value, direct) { + if (!direct) { + return value && value.then ? value.then(_empty$1) : Promise.resolve(); + } + } + + function _invokeIgnored(body) { + var result = body(); + + if (result && result.then) { + return result.then(_empty$1); + } + } + + function _await$1(value, then, direct) { + if (direct) { + return then ? then(value) : value; + } + + if (!value || !value.then) { + value = Promise.resolve(value); + } + + return then ? value.then(then) : value; + } + + var Connection = /*#__PURE__*/function () { + /* + Public Connection interface + */ + function Connection(connectionImpl) { + this.impl = connectionImpl; + } + + var _proto = Connection.prototype; + + _proto.getId = function getId() { + return this.impl.id; + }; + + _proto.isPaused = function isPaused() { + return this.impl.paused; + }; + + _proto.accept = function accept() { + try { + var _this2 = this; + + return _this2.impl.accept(); + } catch (e) { + return Promise.reject(e); + } + }; + + _proto.sendMessage = function sendMessage(body, requestId) { + try { + var _this4 = this; + + return _this4.impl.sendMessage(body, requestId); + } catch (e) { + return Promise.reject(e); + } + }; + + _proto.addMessageListener = function addMessageListener(callback) { + this.impl.addMessageListener(callback); + }; + + _proto.removeMessageListener = function removeMessageListener(callback) { + this.impl.removeMessageListener(callback); + }; + + _proto.addCloseListener = function addCloseListener(callback) { + this.impl.addCloseListener(callback); + }; + + _proto.removeCloseListener = function removeCloseListener(callback) { + this.impl.removeCloseListener(callback); + }; + + return Connection; + }(); + var ConnectionImpl = /*#__PURE__*/function () { + function ConnectionImpl(id, accepted, messagingClient, sendProtocolMessage, paused) { + if (paused === void 0) { + paused = false; + } + + this.id = id; + this.sendProtocolMessage = sendProtocolMessage; + this.accepted = accepted; + this.messagingClient = messagingClient; + this.paused = paused; + this.messageListeners = new Set(); + this.closeListeners = new Set(); + } // + // Access methods + // + + + var _proto2 = ConnectionImpl.prototype; + + _proto2.accept = function accept() { + try { + var _this6 = this; + + return _await$1(_this6.updateAccess(true), function () { + return _invokeIgnored(function () { + if (!_this6.messagingClient.hasInitialState) { + return _awaitIgnored$1(_this6.sendEmptyInitialMessage()); + } + }); + }); + } catch (e) { + return Promise.reject(e); + } + }; + + _proto2.deny = function deny(reason) { + try { + var _this8 = this; + + return _awaitIgnored$1(_this8.updateAccess(false, reason)); + } catch (e) { + return Promise.reject(e); + } + }; + + _proto2.updateAccess = function updateAccess(accepted, reason) { + try { + var _this10 = this; + + if (!_this10.messagingClient.lock) { + throw new LockStateError("locked"); + } + + return _await$1(_this10.sendProtocolMessage({ + type: MessageType.Access, + accepted: accepted, + reason: reason + }), function () { + _this10.accepted = true; + }); + } catch (e) { + return Promise.reject(e); + } + } // + // Message methods + // + ; + + _proto2.sendMessage = function sendMessage(body, requestId) { + try { + var _this12 = this; + + if (!_this12.accepted) { + throw new Error("client not accepted"); + } + + if (_this12.paused) { + return; + } + + return _awaitIgnored$1(_this12.sendProtocolMessage({ + type: MessageType.ApplicationApp, + body: body, + req: requestId, + client: _this12.id + })); + } catch (e) { + return Promise.reject(e); + } + }; + + _proto2.sendEmptyInitialMessage = function sendEmptyInitialMessage() { + try { + var _this14 = this; + + return _awaitIgnored$1(_this14.sendMessage({ + __start: "" + })); + } catch (e) { + return Promise.reject(e); + } + } // + // Message listener handling + // + ; + + _proto2.addMessageListener = function addMessageListener(callback) { + this.messageListeners.add(callback); + }; + + _proto2.removeMessageListener = function removeMessageListener(callback) { + this.messageListeners["delete"](callback); + }; + + _proto2.clearMessageListener = function clearMessageListener() { + this.messageListeners.clear(); + }; + + _proto2.notifyMessageListeners = function notifyMessageListeners(message) { + this.messageListeners.forEach(function (callback) { + return callback(message); + }); + } // + // Connection close listener handling + // + ; + + _proto2.addCloseListener = function addCloseListener(callback) { + this.closeListeners.add(callback); + }; + + _proto2.removeCloseListener = function removeCloseListener(callback) { + this.closeListeners["delete"](callback); + }; + + _proto2.clearCloseListeners = function clearCloseListeners() { + this.closeListeners.clear(); + }; + + _proto2.notifyCloseListeners = function notifyCloseListeners() { + this.closeListeners.forEach(function (callback) { + return callback(); + }); + }; + + return ConnectionImpl; + }(); + + var Request = function Request(body, id) { + this.body = body; + this.id = id; + }; + + function _await(value, then, direct) { + if (direct) { + return then ? then(value) : value; + } + + if (!value || !value.then) { + value = Promise.resolve(value); + } + + return then ? value.then(then) : value; + } + + function _invoke(body, then) { + var result = body(); + + if (result && result.then) { + return result.then(then); + } + + return then(result); + } + + function _empty() {} + + function _awaitIgnored(value, direct) { + if (!direct) { + return value && value.then ? value.then(_empty) : Promise.resolve(); + } + } + + var MessagingClient = /*#__PURE__*/function () { + function MessagingClient(url, hasInitialState) { + if (hasInitialState === void 0) { + hasInitialState = false; + } + + this.url = url; + this.connections = new Map(); + this.connectionListeners = new Set(); + this.messageListeners = new Set(); + this._lock = false; + this.hasInitialState = hasInitialState; + this._status = "idle"; + this.bindMethods(); + } + + var _proto = MessagingClient.prototype; + + _proto.bindMethods = function bindMethods() { + this.sendMessage = this.sendMessage.bind(this); + this.addMessageListener = this.addMessageListener.bind(this); + this.removeMessageListener = this.removeMessageListener.bind(this); + this.sendProtocolMessage = this.sendProtocolMessage.bind(this); + }; + + _proto.setLock = function setLock(lock) { + try { + var _this2 = this; + + return _await(_this2.sendProtocolMessage({ + type: MessageType.DisplaySettings, + settings: { + lock: lock + } + }), function () { + _this2._lock = lock; + }); + } catch (e) { + return Promise.reject(e); + } + }; + + // + // Client lifecycle methods (not to be confused with protocol lifecycle + // messages) + // + _proto.mount = function mount() { + this._status = "loading"; + this.openSocket(); + }; + + _proto.unmount = function unmount() { + this.close(); + }; + + _proto.close = function close() { + if (this._status == "closed") { + // @vinhowe: This return statement just makes close() idempotent because + // I can't think of a reason why we'd care whether this method is called + // multiple times. It could be bad practice not to throw an error here. + // If we decided that we cared that this method is only called once, we + // could throw an error here instead. + return; + } + + this.closeSocket(); + this.clearMessageListeners(); + this.clearConnectionListeners(); + } // + // Socket-level logic + // + ; + + _proto.openSocket = function openSocket() { + var _this3 = this; + + // TODO: Handle retries here + this.socket = new WebSocket(this.url); + this.socket.addEventListener("message", function (_ref) { + var data = _ref.data; + return _this3.onMessage(data); + }); + this.socket.addEventListener("open", function () { + return _this3._status = "open"; + }); + this.socket.addEventListener("close", this.onSocketClose); + }; + + _proto.closeSocket = function closeSocket() { + if (this.socket === undefined) { + return; + } // We're closing the socket manually here, so we don't want onSocketClose to + // try reopening it + + + this.socket.removeEventListener("close", this.onSocketClose); + this.socket.close(); + }; + + _proto.onSocketClose = function onSocketClose() { + // Status is idle, loading, or open, so we'll retry opening the socket + // after a delay to avoid spamming the server + setTimeout(this.openSocket, 1000); + }; + + _proto.socketReady = function socketReady() { + try { + var _exit2 = false; + + var _this5 = this; + + if (_this5.socket === undefined) { + return false; + } + + if (_this5.socket.readyState == WebSocket.OPEN) { + return true; + } + + return _invoke(function () { + if (_this5.socket.readyState == WebSocket.CONNECTING) { + // Await until either socket connects or closes + // @vinhowe: Technically we could just return a boolean promise, but + // there's no non-error state where it would potentially return anything + // other than true, so that didn't make sense to me. + return _await(new Promise(function (resolve, reject) { + if (_this5.socket === undefined) { + reject(new Error("Socket was set to undefined during CONNECTING state; " + "this is probably a bug")); + return; + } + + var openCallback = function openCallback() { + removeListeners(); + resolve(); + }; + + var closeCallback = function closeCallback() { + removeListeners(); + reject(new Error("Socket closed during CONNECTING state; it may have timed out")); + }; + + var removeListeners = function removeListeners() { + var _this5$socket, _this5$socket2; + + (_this5$socket = _this5.socket) == null ? void 0 : _this5$socket.removeEventListener("open", openCallback); + (_this5$socket2 = _this5.socket) == null ? void 0 : _this5$socket2.removeEventListener("close", closeCallback); + }; + + _this5.socket.addEventListener("open", openCallback); + + _this5.socket.addEventListener("close", closeCallback); + }), function () { + _exit2 = true; + return true; + }); + } + }, function (_result) { + return _exit2 ? _result : false; + }); + } catch (e) { + return Promise.reject(e); + } + }; + + MessagingClient.parseMessage = function parseMessage(data) { + var message; + + try { + message = JSON.parse(data); + } catch (error) { + console.error("An error occurred while attempting to parse a Controls message"); + throw error; + } + + if (!("type" in message) || typeof message["type"] !== "string") { + throw Error("Message received from router didn't specify valid type"); + } + + return message; + }; + + _proto.onMessage = function onMessage(data) { + try { + var _exit5 = false; + + var _this7 = this; + + var message = MessagingClient.parseMessage(data); + return _invoke(function () { + if (message.type == MessageType.HeartbeatClient) { + if (!message.up) { + message.clients.forEach(function (id) { + return _this7.removeConnection(id); + }); + _exit5 = true; + return; + } // TODO: This test might be expensive and unnecessary, consider simplifying + // or removing it + + + return _await(_this7.compareHeartbeatUpConnections(message.clients), function () { + _exit5 = true; + }); + } + }, function (_result2) { + var _exit4 = false; + if (_exit5) return _result2; + + if (!("client" in message) || typeof message.client !== "string") { + throw Error("Incoming message of type '" + message.type + "' doesn't contain valid 'client' field required by all remaining message handlers"); + } + + return _invoke(function () { + if (message.type == MessageType.Connect) { + var connection = _this7.connections.get(message.client); + + if (!connection) { + connection = _this7.addConnection(message.client); + } + + return _invoke(function () { + if (!_this7.hasInitialState && connection.accepted) { + return _awaitIgnored(connection.sendEmptyInitialMessage()); + } + }, function () { + _exit4 = true; + }); + } + }, function (_result3) { + if (_exit4) return _result3; + + if (!_this7.connections.has(message.client)) { + throw Error("Unauthorized client '" + message.client + "' attempted to send an authenticated message"); + } + + if (message.type == MessageType.ApplicationClient) { + var _this7$connections$ge; + + var listenerMessage = message.req == null ? message.body : new Request(message.body, message.req); + + _this7.notifyMessageListeners(listenerMessage); + + (_this7$connections$ge = _this7.connections.get(message.client)) == null ? void 0 : _this7$connections$ge.notifyMessageListeners(listenerMessage); + return; + } + + if (message.type == MessageType.Lifecycle) { + var connection = _this7.connections.get(message.client); + + if (!connection) { + return; + } + + connection.paused = message.paused; + return; + } + + throw Error("Couldn't handle message type '" + message.type + "'"); + }); + }); + } catch (e) { + return Promise.reject(e); + } + } // Based on implementation at + // https://github.com/BYU-PCCL/footron-messaging-python/blob/9206e273e5c620e984b67c377fcc319996492e27/foomsg/client.py#L171-L193 + ; + + _proto.compareHeartbeatUpConnections = function compareHeartbeatUpConnections(connections) { + var _this8 = this; + + var localConnections = new Set(this.connections.keys()); + var heartbeatConnections = new Set(connections); + Array.from(heartbeatConnections.keys()).forEach(function (client) { + if (localConnections.has(client)) { + heartbeatConnections["delete"](client); + localConnections["delete"](client); + return; + } + + _this8.addConnection(client); + }); + Array.from(localConnections.keys()).forEach(function (client) { + if (heartbeatConnections.has(client)) { + heartbeatConnections["delete"](client); + localConnections["delete"](client); + return; + } + + _this8.removeConnection(client); + }); + }; + + _proto.sendMessage = function sendMessage(body, requestId) { + this.connections.forEach(function (connection) { + return connection.sendMessage(body, requestId); + }); + } // + // Client connection handling + // (these methods just handle updating internal state and notifying listeners + // _after_ connections are added/removed) + // + ; + + _proto.addConnection = function addConnection(id) { + var connection = new ConnectionImpl(id, !this._lock, this, this.sendProtocolMessage // Is this correct? + ); + this.connections.set(id, connection); + this.notifyConnectionListeners(connection); + return connection; + }; + + _proto.removeConnection = function removeConnection(id) { + var _this$connections, _this$connections$get; + + if (!this.connections.has(id)) { + return; + } + + (_this$connections = this.connections) == null ? void 0 : (_this$connections$get = _this$connections.get(id)) == null ? void 0 : _this$connections$get.notifyCloseListeners(); + this.connections["delete"](id); + } // + // Message handling + // + ; + + _proto.sendProtocolMessage = function sendProtocolMessage(message) { + try { + var _exit7 = false; + + var _this10 = this; + + return _await(_this10.socketReady(), function (_this9$socketReady) { + var _this10$socket; + + if (!_this9$socketReady) { + // TODO: Do we want to queue up messages and wait for the socket to be + // available again? Or does our little CONNECTING await in socketReady + // basically provide that behavior for all of the states we care about? + throw Error("Couldn't send protocol message because socket isn't available"); + } + + (_this10$socket = _this10.socket) == null ? void 0 : _this10$socket.send(JSON.stringify(_extends({}, message, { + version: PROTOCOL_VERSION + }))); + }); + } catch (e) { + return Promise.reject(e); + } + } // + // Message listener handling + // + ; + + _proto.addMessageListener = function addMessageListener(callback) { + this.messageListeners.add(callback); + }; + + _proto.removeMessageListener = function removeMessageListener(callback) { + this.messageListeners["delete"](callback); + }; + + _proto.clearMessageListeners = function clearMessageListeners() { + this.messageListeners.clear(); + }; + + _proto.notifyMessageListeners = function notifyMessageListeners(body) { + this.messageListeners.forEach(function (callback) { + return callback(body); + }); + } // + // Connection listener handling + // + ; + + _proto.addConnectionListener = function addConnectionListener(callback) { + this.connectionListeners.add(callback); + }; + + _proto.removeConnectionListener = function removeConnectionListener(callback) { + this.connectionListeners["delete"](callback); + }; + + _proto.clearConnectionListeners = function clearConnectionListeners() { + this.connectionListeners.clear(); + }; + + _proto.notifyConnectionListeners = function notifyConnectionListeners(connection) { + this.connectionListeners.forEach(function (callback) { + callback(new Connection(connection)); + }); + }; + + _createClass(MessagingClient, [{ + key: "lock", + get: function get() { + return this._lock; + } + }, { + key: "status", + get: function get() { + return this._status; + } + }]); + + return MessagingClient; + }(); + + var Messaging = /*#__PURE__*/function (_MessagingClient) { + _inheritsLoose(Messaging, _MessagingClient); + + function Messaging(url) { + if (url == null) { + var _URLSearchParams$get; + + url = (_URLSearchParams$get = new URLSearchParams(location.search).get("ftMsgUrl")) != null ? _URLSearchParams$get : "ws://localhost:8089/out"; + } + + return _MessagingClient.call(this, url) || this; + } + + return Messaging; + }(MessagingClient); + + exports.Connection = Connection; + exports.Messaging = Messaging; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); +//# sourceMappingURL=footron-messaging.development.js.map diff --git a/experiences/asteroids/web/footron.js b/experiences/asteroids/web/footron.js new file mode 100644 index 0000000..d246924 --- /dev/null +++ b/experiences/asteroids/web/footron.js @@ -0,0 +1,404 @@ +// TIME METHODS +/** + * Sets time to current date and time and the speed of time to 1s/s + */ +async function live() { + await setTimeRate(1); + await app.getManager("time").setToNow(); +} + +/** + * Sets time to current date and time and the speed of time to 5d/s + */ +function defaultTimeSettings() { + setTimeRate(432000); + app.getManager("time").setToNow(); +} + +/** + * Sets the speed of time in the experience + * + * @param {*} rate - number sim-seconds per second positive or negative + */ +async function setTimeRate(rate) { + await app.getManager("time").setTimeRate(rate); +} + +let cameraOrbitParameters = { + yaw: 0, + pitch: 0, + roll: 0, + zoom: 0, +}; + +let cameraFreeFlyParameters = { + xAngleDv: 0, + yAngleDv: 0, + zAngleDv: 0, + velocity: 0, + context: { id: "sun" }, +}; + +function setMotionParameters(message) { + isFreefly = app.getManager("camera")._isFreeFly; + if (isFreefly) { + if ( + "pitch" in message || + "zoom" in message || + "yaw" in message || + "roll" in message + ) + app.getManager("camera").toggleFreeFly(); + } else { + if ( + "xAngleDv" in message || + "velocity" in message || + "yAngleDv" in message || + "zAngleDv" in message + ) + app.getManager("camera").toggleFreeFly(); + } + if ("pitch" in message) cameraOrbitParameters.pitch = message.pitch; + if ("yaw" in message) cameraOrbitParameters.yaw = message.yaw; + if ("roll" in message) cameraOrbitParameters.roll = message.roll; + if ("zoom" in message) cameraOrbitParameters.zoom = message.zoom; + if ("xAngleDv" in message) + cameraFreeFlyParameters.xAngleDv = message.xAngleDv; + if ("yAngleDv" in message) + cameraFreeFlyParameters.yAngleDv = message.yAngleDv; + if ("zAngleDv" in message) cameraOrbitParameters.roll = message.zAngleDv; + if ("velocity" in message) + cameraFreeFlyParameters.velocity = message.velocity; +} + +// FLY METHODS + +let currentTarget = null; + +/** + * Moves the camera smoothly to destination specified + * + * @param {*} destination - The requested destination. Must have a parameters type and target + */ +async function flyTo(destination) { + if (Object.values(entities).includes(destination) == null) + throw "entities doesn't contain " + destination; + let destinationInfo = allInfo[destination]; + + if (destinationInfo == null) throw `${destination} not in allInfo`; + + // duration helps to make sure entities are loaded + const flyParameters = { duration: 3 }; + + // change date if destination doesn't exist currently. + if (destinationInfo.dates) { + timeManager = app.getManager("time"); + currentTime = timeManager.parseTime(timeManager.getTime()); + start = timeManager.parseTime(destinationInfo.dates.start); + if (!start.isValid()) start = timeManager.getLimits().min; + end = timeManager.parseTime(destinationInfo.dates.end); + if (!end.isValid()) end = timeManager.getLimits().max; + if (currentTime.isBefore(start) || currentTime.isAfter(end)) { + newTime = null; + if (destinationInfo.dates.highlight) + newTime = destinationInfo.dates.highlight; + else if (timeManager.getNow().isBefore(end)) + newTime = timeManager.getNow(); + else { + newTime = timeManager.getMidTime( + timeManager.parseTime(start), + timeManager.parseTime(end) + ); + } + timeManager.setTime(newTime); + } + } + + // go to shared parent if it exists + if (allInfo[destination].parent) { + await app.cameraScripts.goToSystem(allInfo[destination].parent, { + duration: 3, + }); + } else { + await app.cameraScripts.goToSystem("inner_solar_system", { duration: 3 }); + } + + if (celestialObjects.includes(destination)) + await app.cameraScripts.goToCelestialObject(destination, flyParameters); + else if (spacecraft.includes(destination)) + await app.cameraScripts.goToSpacecraft(destination, flyParameters); + else if (systems.includes(destination)) { + destination = systemToTarget[destination]; + await app.cameraScripts.goToSystem(destination, flyParameters); + } else { + try { + await app.cameraScripts.goToCelestialObject(destination, flyParameters); + } catch (error) { + destinationInfo.description = { + blurb: "Error flying to entity. Please try again", + }; + console.error( + "destination " + destination + " is not in any confirmed lists." + ); + } + } + client.sendMessage({ title: destination, content: destinationInfo }); +} + +/** + * zooms the camera in + */ +function zoomIn() { + app.getManager("camera").zoomIn(true); +} + +/** + * zooms the camera out + */ +function zoomOut() { + app.getManager("camera").zoomOut(true); +} + +/** + * zooms the camera in or out based on the zoom ratio given. 0.5 zooms in halfway + * + * @param {number} zoomRatio + */ +function zoom(zoomRatio) { + // 5% seems a little fast. + app.getManager("camera").zoom(zoomRatio); +} + +// SETTINGS METHODS + +/** + * changes the lighting mode + * + * @param {string} lightOption - accepts either "flood", "natural", or "shadow" + */ +function setLighting(lightOption) { + if ( + lightOption !== "flood" && + lightOption !== "natural" && + lightOption !== "shadow" + ) + throw lightOption + " is not a valid light setting"; + app.getComponent("settings").toggleLightOptions(lightOption); +} + +function resetFilters() { + showPHOs(false); + showComets(false); + showAsteroids(false); +} + +/** + * Changes units... only on the asteroid watch view. + * Eyes doesn't have the unit switch implemented elsewhere + */ +function toggleUnits() { + app.getComponent("settings").toggleUnit(); + app.getManager("watch").toggleUnit(); +} + +function filters() { + app.getManager("router").navigate({ + modal: "filters", + }); +} + +async function showAsteroids(show) { + let result = null; + await new Promise((resolve) => { + app.getManager("filters").setFilter("asteroids", show, (t) => { + result = t; + resolve(); + }); + }); + return result; +} + +async function showComets(show) { + let result = null; + await new Promise((resolve) => { + app.getManager("filters").setFilter("comets", show, (t) => { + result = t; + resolve(); + }); + }); + return result; +} + +async function showPHOs(show) { + let result = null; + await new Promise((resolve) => { + app.getManager("filters").setFilter("phos", show, (t) => { + result = t; + resolve(); + }); + }); + return result; +} + +/** + * Toggles layers in the ui like star field or labels + * + * @param {*} layer - the layer to turn on or off + */ +function toggleLayer(layer) { + if (layer == "planets") { + app.getManager("layer").toggleLayer("planets"); + app.getManager("layer").toggleLayer("dwarfPlanets"); + } else { + app.getManager("layer").toggleLayer(layer); + } + getCurrentSettings(); // TODO: remove +} + +// ASTEROID WATCH METHODS +function cycleWatchView() { + app.getManager("watch").setSlideIndex(0); +} + +/** + * Removes the compenent from the screen + * + * @param {*} component + */ +function hideComponent(component) { + app.getComponent(component).hide(); +} + +/** + * adds the compenent to the screen + * + * @param {*} component + */ +function showComponent(component) { + app.getComponent(component).show(); +} + +function minimizeWatch() { + app.getManager("watch").updateURL(""); +} + +function nextAsteroidWatch() { + index = app.getManager("watch")._slideIndex; + app.getManager("watch").setSlideUrlByIndex((index + 1) % 5); +} + +function prevAsteroidWatch() { + index = app.getManager("watch")._slideIndex; + app.getManager("watch").setSlideUrlByIndex((index + 4) % 5); +} + +// GENERAL METHODS +function goHome() { + app.getManager("router").navigate( + { + __remove: "all", + }, + "/home" + ); +} + +function learn() { + app.getManager("router").navigate({ + modal: "learn", + }); +} + +async function watch() { + live(); + if (!app.getComponent("watchPanel").isEnabled()) + app.getManager("watch").onWatchClick(); +} + +// STORY METHODS +// It is going to be so much easier to have a local slide info table here +// and just update with this. +let currentSlideshow = null; +let currentSlideIndex = null; + +function startStoryAsteroids() { + currentSlideshow = asteroidsSlides; + currentSlideIndex = 0; + let t = { + path: "asteroids_101", + }; + app.getComponent("learnModal").goToStory(t); + getSlideInfo(); +} + +function startStoryCloseApproaches() { + currentSlideshow = closeApproachesSlides; + currentSlideIndex = 0; + let t = { + path: "asteroids_close_approach", + }; + app.getComponent("learnModal").goToStory(t); + getSlideInfo(); +} + +function startStoryMissions() { + currentSlideshow = missionSlides; + currentSlideIndex = 0; + let t = { + path: "asteroids_missions", + }; + app.getComponent("learnModal").goToStory(t); + getSlideInfo(); +} + +function getStorySlideIndex() { + index = app.getComponent("story")._state.currentSlideIndex; + return index; +} + +function nextSlide() { + if (currentSlideIndex + 1 < currentSlideshow.length) { + currentSlideIndex++; + app.getComponent("story")._onSlideChange(currentSlideIndex); + getSlideInfo(); + } else + client.sendMessage({ + type: "error", + info: "Error: Trying to load slide past end", + }); +} + +function prevSlide() { + if (currentSlideIndex > 0) { + currentSlideIndex--; + app.getComponent("story")._onSlideChange(currentSlideIndex); + getSlideInfo(); + } else + client.sendMessage({ + type: "error", + info: "Error: Trying to load slide before beginning", + }); +} + +function firstSlide() { + app.getComponent("story").goToFirstSlide(); + currentSlideIndex = 0; + getSlideInfo(); +} + +function closeStory() { + app.getComponent("story").close(); + currentSlideshow = null; + currentSlideIndex = null; +} + +function getSlideInfo() { + info = currentSlideshow[currentSlideIndex]; + info.nextSlideButton = currentSlideIndex + 1 < currentSlideshow.length; + info.prevSlideButton = currentSlideIndex > 0; + client.sendMessage({ type: "slideInfo", slideInfo: info }); +} + +function replayAnimation() { + const t = app.getManager("router"); + t.reload(); +} diff --git a/experiences/asteroids/web/index.html b/experiences/asteroids/web/index.html new file mode 100644 index 0000000..42cd097 --- /dev/null +++ b/experiences/asteroids/web/index.html @@ -0,0 +1,154 @@ + + + + + Eyes on Asteroids - NASA/JPL + + + + + + +
      +
      +
      + + + +
      +
      +
      +
      + +
      +
      Loading
      +
      +
      +
      +
      +
      + +
      + + + + + + + + + + + + + + +
      + diff --git a/experiences/asteroids/web/messageHandler.js b/experiences/asteroids/web/messageHandler.js new file mode 100644 index 0000000..0726f17 --- /dev/null +++ b/experiences/asteroids/web/messageHandler.js @@ -0,0 +1,170 @@ +let defaultTime = setTimeout(() => { + setTimeRate(432000); + console.log("TIME"); +}, 3000); + +let automationTimer = setTimeout(automation, 30000); + +let automationChoices = [ + () => flyTo("sun"), + () => flyTo("mercury"), + () => flyTo("mars"), + () => flyTo("moon"), + () => flyTo("earth"), + () => flyTo("jupiter"), + () => flyTo("saturn"), + () => flyTo("uranus"), + () => flyTo("neptune"), + () => flyTo("1_ceres"), + () => flyTo("4_vesta"), + () => flyTo("134340_pluto"), + () => flyTo("sc_jwst"), + () => flyTo("sc_parker_solar_probe"), +]; + +async function automation() { + let choice = Math.floor(Math.random() * automationChoices.length); + automationChoices[choice](); + live(); + resetTimer(); +} + +function resetTimer() { + clearTimeout(automationTimer); // Clear any existing timer + automationTimer = setTimeout(automation, 20000); // Set a new timer for 30 seconds +} + +async function messageHandler(message) { + if (message == null) throw "message is null"; + clearTimeout(automationTimer); + switch (message.type) { + case "settings": + handleSettingsMessage(message); + break; + case "fly": + handleFlyMessage(message); + break; + case "time": + handleTimeMessage(message); + break; + case "learn": + handleLearnMessage(message); + break; + case "context": + handleContextMessage(message); + break; + case "watch": + handleWatchMessage(message); + break; + case "zoom": + handleZoomMessage(message); + break; + case "move": + handleMoveMessage(message); + break; + default: + throw "Can't understand message: " + message; + } +} + +console.log("MESSAGE HANDLER"); +const client = new FootronMessaging.Messaging(); +client.mount(); +client.addMessageListener(messageHandler); + +const layersList = [ + "asteroids", + "constellations", + "icons", + "labels", + "landers", + "lightOption", + "planets", + "spacecraft", + "starfield", + "trails", + "ui", +]; +async function handleSettingsMessage(message) { + let count = null; + if (message.setting == null) throw "message.setting is null"; + switch (message.setting) { + case "asteroidsFilter": + if (message.value == null) throw "message.value is null"; + count = await showAsteroids(message.value); + // client.sendMessage(count); + break; + case "phosFilter": + if (message.value == null) throw "message.value is null"; + count = await showPHOs(message.value); + // client.sendMessage(count); + break; + case "cometsFilter": + if (message.value == null) throw "message.value is null"; + count = await showComets(message.value); + // client.sendMessage(count); + showComets(message.value); + break; + case "lighting": + if (message.value == null) throw "message.value is null"; + else if (message.value == "flood") setLighting("flood"); + else if (message.value == "shadow") setLighting("shadow"); + else if (message.value == "natural") setLighting("natural"); + else throw "unknown value: " + message.value; + break; + default: + if (layersList.includes(message.setting)) toggleLayer(message.setting); + else throw "Unknown setting: " + message.setting; + } +} + +function handleFlyMessage(message) { + console.log(message); + if (message.value == null) throw "message.value is null"; + flyTo(message.value); +} + +function handleTimeMessage(message) { + if (message.value == null) throw "message.value is null"; + if (message.value == "live") live(); + else setTimeRate(message.value); +} + +function handleLearnMessage(message) { + if (message.value == null) throw "message.value is null"; + if (message.value == "asteroids-101") startStoryAsteroids(); + else if (message.value == "close-approaches") startStoryCloseApproaches(); + else if (message.value == "missions") startStoryMissions(); + else if (message.value == "next") nextSlide(); + else if (message.value == "previous") prevSlide(); + else if (message.value == "first") firstSlide(); + else if (message.value == "replay") replayAnimation(); + else throw "unknown value: " + message.value; +} + +function handleContextMessage(message) { + if (message.value == null) throw "message.value is null"; + if (message.value == "home") goHome(); + else if (message.value == "watch") watch(); + else if (message.value == "fly") goHome(); + else if (message.value == "learn") goHome(); + else throw "unknown value: " + message.value; +} + +function handleWatchMessage(message) { + if (message.value == null) throw "message.value is null"; + if (message.value == "next") nextAsteroidWatch(); + else if (message.value == "previous") prevAsteroidWatch(); + else throw "unknown value: " + message.value; +} + +function handleZoomMessage(message) { + if (message.value == null) throw "message.value is null"; + if (message.value == "in") zoomIn(); + else if (message.value == "out") zoomOut(); + else throw "unknown value: " + message.value; +} + +function handleMoveMessage(message) { + setMotionParameters(message); +} diff --git a/experiences/asteroids/web/min-app.js b/experiences/asteroids/web/min-app.js new file mode 100644 index 0000000..2281d32 --- /dev/null +++ b/experiences/asteroids/web/min-app.js @@ -0,0 +1,9892 @@ +(function(){var __webpack_modules__=({"./src/app.html": + /*!**********************!*\ + !*** ./src/app.html ***! + \**********************/ + (function(module){var code="
      \ + \ + \ + \ +
      \ + \ + \ + \ + \ + \ + \ +
      \ +
      \ +
      \ + \ + \ + \ +
      \ + \ +
      \ +
      \ + \ + \ +
      \ + \ + \ + \ + ";module.exports=code}),"./src/components/asteroid_modals/asteroid_modals.html": + /*!*************************************************************!*\ + !*** ./src/components/asteroid_modals/asteroid_modals.html ***! + \*************************************************************/ + (function(module){var code="
      \ +
      \ +
      \ +
      \ +

      {{title}}

      \ +
      \ + \ +
      \ +
      \ + \ + \ + \ +
      \ +
      \ +
      \ + \ + \ +
      \ +
      \ +
      ";module.exports=code}),"./src/components/asteroid_modals/modals/filters_modal/filters_modal.html": + /*!********************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/filters_modal/filters_modal.html ***! + \********************************************************************************/ + (function(module){var code="
      \ +

      \ + Apply a variety of filters to visualize the different groups of astronomical\ + objects\ +

      \ +
      \ +
      \ +
      Composition
      \ +
      \ +
      \ +
      \ +
      \ +
      Asteroids
      \ + \ + \ + \ + \ + \ + \ +
      \ +
      \ +
      Made up of rock, metals and dust
      \ +
      \ +
      \ +
      \ + \ + \ +
      \ +
      \ +
      \ + \ +
      \ +
      \ +
      \ +
      Comets
      \ +
      \ + \ + \ + \ + \ + \ +
      \ +
      \ +
      Made up of rock, dust and frozen ices
      \ +
      \ +
      \ +
      \ + \ + \ +
      \ +
      \ +
      \ +
      \ +
      \ +
      \ +
      Potential Threats
      \ +
      \ +
      \ +
      \ +
      \ +
      PHOs
      \ +
      \ + \ + \ + \ + \ + \ +
      \ +
      \ +
      Potentially hazardous objects
      \ +
      \ +
      \ +
      \ + \ + \ +
      \ +
      \ +
      \ +
      \ +
      \ +
      \ + \ +
      \ +
      \ + \ +
      \ + \ + ";module.exports=code}),"./src/components/asteroid_modals/modals/learn_modal/learn_modal.html": + /*!****************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/learn_modal/learn_modal.html ***! + \****************************************************************************/ + (function(module){var code="
      \ +

      \ + Take a deeper dive into Asteroids with our interactive scrollable stories\ +

      \ +
      \ + \ + ";module.exports=code}),"./src/components/countdown/countdown.html": + /*!*************************************************!*\ + !*** ./src/components/countdown/countdown.html ***! + \*************************************************/ + (function(module){var code="
      \ + COUNTDOWN\ +
      \ +
      {{tText}}
      \ +
      \ +

      {{numDays}}

      \ + DAYS\ +
      \ +

      :

      \ +
      \ +

      {{numHours}}

      \ + HOURS\ +
      \ +

      :

      \ +
      \ +

      {{numMinutes}}

      \ + MINUTES\ +
      \ +

      :

      \ +
      \ +

      {{numSeconds}}

      \ + SECONDS\ +
      \ +
      \ +
      \ + ";module.exports=code}),"./src/components/definition_overlay/definition_overlay.html": + /*!*******************************************************************!*\ + !*** ./src/components/definition_overlay/definition_overlay.html ***! + \*******************************************************************/ + (function(module){var code="
      \ +
      \ +
      \ +
      \ +

      {{title}}

      \ +
      \ +
      \ +
      {{content}}
      \ +
      \ +
      RELATED TERMS
      \ +
      \ +
      \ +
      \ +
      \ + ";module.exports=code}),"./src/components/navigation/navigation.html": + /*!***************************************************!*\ + !*** ./src/components/navigation/navigation.html ***! + \***************************************************/ + (function(module){var code="\ + ";module.exports=code}),"./src/components/splash_screen/splash_screen.html": + /*!*********************************************************!*\ + !*** ./src/components/splash_screen/splash_screen.html ***! + \*********************************************************/ + (function(module){var code="
      \ +
      \ +
      \ +
      \ +
      \ +
      \ +
      \ +
      Eyes
      \ +
      on
      \ +
      Asteroids
      \ +
      \ +
      \ +
      \ +
      \ +
      \ +
      \ + \ + \ + \ + \ +
      \ +
      \ +
      \ +
      \ +
      \ + ";module.exports=code}),"./src/components/time_slider/time_slider.html": + /*!*****************************************************!*\ + !*** ./src/components/time_slider/time_slider.html ***! + \*****************************************************/ + (function(module){var code="
      \ + \ +
      \ +
      \ +
      ;\ + ";module.exports=code}),"./src/components/watch_panel/watch_card.html": + /*!****************************************************!*\ + !*** ./src/components/watch_panel/watch_card.html ***! + \****************************************************/ + (function(module){var code="
      \ +
      \ +

      {{title}}

      \ +
      \ + DATE\ +
      \ +
      {{date}}
      \ + {{time}}\ +
      \ + \ +
      \ +
      \ + DISTANCE\ +
      \ +
      {{distance}}
      \ +
      {{distanceUnit}}
      \ +
      \ + \ +
      \ +
      \ +
      \ +
      \ +
      \ +
      \ + {{diameter}}\ + {{diameterUnit}}\ + {{diameterEstimatedText}}\ +
      \ + \ +
      \ +
      \ + ";module.exports=code}),"../eyes/src/components/breadcrumb/breadcrumb.html": + /*!*********************************************************!*\ + !*** ../eyes/src/components/breadcrumb/breadcrumb.html ***! + \*********************************************************/ + (function(module){var code="\ + ";module.exports=code}),"../eyes/src/components/carousel/carousel.html": + /*!*****************************************************!*\ + !*** ../eyes/src/components/carousel/carousel.html ***! + \*****************************************************/ + (function(module){var code="
      \ +
      \ + \ +
      \ +
      \ +
      \ +
      \ +
      \ + ";module.exports=code}),"../eyes/src/components/carousel/slide_template.html": + /*!***********************************************************!*\ + !*** ../eyes/src/components/carousel/slide_template.html ***! + \***********************************************************/ + (function(module){var code="\ + ";module.exports=code}),"../eyes/src/components/carousel_panel/carousel_panel.html": + /*!*****************************************************************!*\ + !*** ../eyes/src/components/carousel_panel/carousel_panel.html ***! + \*****************************************************************/ + (function(module){var code="
      \ + \ + \ +
      \ +
      \ +
      \ +
      \ +
      {{preTitle}}
      \ +

      {{title}}

      \ +
      \ + \ + \ +
      \ + \ +
      \ +
      \ +
      \ +

      {{title}}

      \ +
      \ +
      {{caption}}
      \ +
      \ + \ + \ +
      \ + \ +
      \ +
      \ + \ + \ +
      \ + \ +
      \ +
      \ + \ +
      \ + \ +
      \ +
      \ + \ +
      \ + \ + \ + \ +
      \ + ";module.exports=code}),"../eyes/src/components/checkbox/checkbox.html": + /*!*****************************************************!*\ + !*** ../eyes/src/components/checkbox/checkbox.html ***! + \*****************************************************/ + (function(module){var code="
    • \ + \ + {{text}}\ +
    • \ + ";module.exports=code}),"../eyes/src/components/clock/clock.html": + /*!***********************************************!*\ + !*** ../eyes/src/components/clock/clock.html ***! + \***********************************************/ + (function(module){var code="\ + ";module.exports=code}),"../eyes/src/components/clock_shortcut/clock_shortcut.html": + /*!*****************************************************************!*\ + !*** ../eyes/src/components/clock_shortcut/clock_shortcut.html ***! + \*****************************************************************/ + (function(module){var code="\ + ";module.exports=code}),"../eyes/src/components/kiosk_base/kiosk_base.html": + /*!*********************************************************!*\ + !*** ../eyes/src/components/kiosk_base/kiosk_base.html ***! + \*********************************************************/ + (function(module){var code="
      \ +
      \ + Starting experience...\ +
      \ +
      \ +
      \ +
      \ + This session has ended\ +
      \ +
      \ + START OVER\ +
      \ +
      \ + CONTINUE\ +
      \ +
      \ +
      \ +
      \ +
      \ + TOUCH TO START\ +
      \ +
      \ +
      \ +
      Time left:
      \ + \ +
      \ +
      \ + ";module.exports=code}),"../eyes/src/components/layer_panel/layer_panel.html": + /*!***********************************************************!*\ + !*** ../eyes/src/components/layer_panel/layer_panel.html ***! + \***********************************************************/ + (function(module){var code="
      \ +
      \ +
      Layers
      \ + \ +
      \ +
      \ +
      \ +
      \ + ";module.exports=code}),"../eyes/src/components/load_icon/load_icon.html": + /*!*******************************************************!*\ + !*** ../eyes/src/components/load_icon/load_icon.html ***! + \*******************************************************/ + (function(module){var code="
      \ +
      \ +
      \ +
      \ +
      \ +
      \ +
      \ +
      Loading
      \ +
      \ + ";module.exports=code}),"../eyes/src/components/overlay/overlay.html": + /*!***************************************************!*\ + !*** ../eyes/src/components/overlay/overlay.html ***! + \***************************************************/ + (function(module){var code="
      \ + \ +
      \ +
      \ + \ +
      \ +
      \ + ";module.exports=code}),"../eyes/src/components/search/search.html": + /*!*************************************************!*\ + !*** ../eyes/src/components/search/search.html ***! + \*************************************************/ + (function(module){var code="
      \ + \ +
      \ +
      \ +
      \ + \ + \ + \ +
      \ +
      \ +
      \ + {{searchInfo}}\ +
      \ +
        \ +
        \ +
        \ +
        \ +
        \ + ";module.exports=code}),"../eyes/src/components/settings/settings.html": + /*!*****************************************************!*\ + !*** ../eyes/src/components/settings/settings.html ***! + \*****************************************************/ + (function(module){var code="
        \ +
        \ +
        \ + \ + \ + \ + \ + \ + \ + \ +
        \ + \ + \ + \ +
        \ + \ +
        \ +
        \ + \ +
        \ + ";module.exports=code}),"../eyes/src/components/share_modal/share_modal.html": + /*!***********************************************************!*\ + !*** ../eyes/src/components/share_modal/share_modal.html ***! + \***********************************************************/ + (function(module){var code="
        \ +
        \ +
        \ +
        \ +

        Share

        \ + \ +
          \ +
        • \ +
        • \ +
        \ + \ +
        \ +
        \ + \ +
        \ +
        \ + \ + \ + \ + \ +
        \ +
        \ + \ +
        \ +
        \ + Interactive Preview\ +
        \ +
        \ + \ +
        \ + \ + \ + \ +
        \ + \ + \ +
        \ +
        \ +
        Embed Options
        \ +
        \ +
        \ +
        \ + Advanced Options\ +
        \ +
        \ +
        \ + \ +
        \ +
        \ +
        \ + \ +
        \ +

        Copied to clipboard!

        \ + \ +
        \ +
        \ + ";module.exports=code}),"../eyes/src/components/story/blocks/buttons_block/buttons_block.html": + /*!****************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/buttons_block/buttons_block.html ***! + \****************************************************************************/ + (function(module){var code="
        \ +
        {$blockTitle}
        \ +
        \ + ";module.exports=code}),"../eyes/src/components/story/blocks/checkbox_block/checkbox_block.html": + /*!******************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/checkbox_block/checkbox_block.html ***! + \******************************************************************************/ + (function(module){var code="
        \ +
        {$checkboxBlockTitle}
        \ +
        \ + ";module.exports=code}),"../eyes/src/components/story/blocks/description_block/description_block.html": + /*!************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/description_block/description_block.html ***! + \************************************************************************************/ + (function(module){var code="
        \ +
        \ +

        {$title}

        \ +

        {$subtitle}

        \ +
        \ +
        \ +
        {$description}
        \ + \ + {$more}\ + \ + \ + \ + {{moreMessage}}\ + \ + \ + \ +
        \ +
        \ +
        \ + ";module.exports=code}),"../eyes/src/components/story/blocks/hint_block/hint_block.html": + /*!**********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/hint_block/hint_block.html ***! + \**********************************************************************/ + (function(module){var code="
        \ + \ + {{text}}\ + \ +
        \ + ";module.exports=code}),"../eyes/src/components/story/blocks/image_block/image_block.html": + /*!************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/image_block/image_block.html ***! + \************************************************************************/ + (function(module){var code="
        \ + \"{$alt}\"\ + {$title}\ +
        \ + ";module.exports=code}),"../eyes/src/components/story/blocks/replay_button_block/replay_button_block.html": + /*!****************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/replay_button_block/replay_button_block.html ***! + \****************************************************************************************/ + (function(module){var code="
        \ + \ +
        \ + ";module.exports=code}),"../eyes/src/components/story/blocks/title_block/title_block.html": + /*!************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/title_block/title_block.html ***! + \************************************************************************/ + (function(module){var code="
        \ +

        {$title}

        \ +

        {$subtitle}

        \ +
        \ + ";module.exports=code}),"../eyes/src/components/story/blocks/toggle_block/toggle_block.html": + /*!**************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/toggle_block/toggle_block.html ***! + \**************************************************************************/ + (function(module){var code="
        \ + \ +
        \ + ";module.exports=code}),"../eyes/src/components/time_controller/time_controller.html": + /*!*******************************************************************!*\ + !*** ../eyes/src/components/time_controller/time_controller.html ***! + \*******************************************************************/ + (function(module){var code="
        \ +
        \ + \ + \ + \ +
        \ + \ + \ +
        \ +
        \ + ";module.exports=code}),"../eyes/src/components/toast/toast.html": + /*!***********************************************!*\ + !*** ../eyes/src/components/toast/toast.html ***! + \***********************************************/ + (function(module){var code="
        \ + \ +
        {{toastContent}}
        \ + \ +
        \ + ";module.exports=code}),"../eyes/src/components/tutorial_overlay/tutorial_overlay.html": + /*!*********************************************************************!*\ + !*** ../eyes/src/components/tutorial_overlay/tutorial_overlay.html ***! + \*********************************************************************/ + (function(module){var code="
        \ + \ +
        \ +
        \ + \ +
        \ +
        \ + \ +
        \ + \ +
        \ + \ +
        \ + \ +
        \ + \ + \ + \ +
        \ + ";module.exports=code}),"./src/assets/css/asteroid.css": + /*!*************************************!*\ + !*** ./src/assets/css/asteroid.css ***! + \*************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/assets/css/clock.css": + /*!**********************************!*\ + !*** ./src/assets/css/clock.css ***! + \**********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/assets/css/color.css": + /*!**********************************!*\ + !*** ./src/assets/css/color.css ***! + \**********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/assets/css/font.css": + /*!*********************************!*\ + !*** ./src/assets/css/font.css ***! + \*********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/assets/css/grid.css": + /*!*********************************!*\ + !*** ./src/assets/css/grid.css ***! + \*********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/assets/css/icon.css": + /*!*********************************!*\ + !*** ./src/assets/css/icon.css ***! + \*********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/assets/css/label.css": + /*!**********************************!*\ + !*** ./src/assets/css/label.css ***! + \**********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/assets/css/search.css": + /*!***********************************!*\ + !*** ./src/assets/css/search.css ***! + \***********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/assets/css/settings.css": + /*!*************************************!*\ + !*** ./src/assets/css/settings.css ***! + \*************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/assets/css/viewport.css": + /*!*************************************!*\ + !*** ./src/assets/css/viewport.css ***! + \*************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/asteroid_modals/asteroid_modals.css": + /*!************************************************************!*\ + !*** ./src/components/asteroid_modals/asteroid_modals.css ***! + \************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/asteroid_modals/modals/filters_modal/filters_modal.css": + /*!*******************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/filters_modal/filters_modal.css ***! + \*******************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/asteroid_modals/modals/learn_modal/learn_modal.css": + /*!***************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/learn_modal/learn_modal.css ***! + \***************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/asteroid_panel/asteroid_panel.css": + /*!**********************************************************!*\ + !*** ./src/components/asteroid_panel/asteroid_panel.css ***! + \**********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/breadcrumb/breadcrumb.css": + /*!**************************************************!*\ + !*** ./src/components/breadcrumb/breadcrumb.css ***! + \**************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/countdown/countdown.css": + /*!************************************************!*\ + !*** ./src/components/countdown/countdown.css ***! + \************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/definition_overlay/definition_overlay.css": + /*!******************************************************************!*\ + !*** ./src/components/definition_overlay/definition_overlay.css ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/following_panel/following_panel.css": + /*!************************************************************!*\ + !*** ./src/components/following_panel/following_panel.css ***! + \************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/home_button/home_button.css": + /*!****************************************************!*\ + !*** ./src/components/home_button/home_button.css ***! + \****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/mission_panel/mission_panel.css": + /*!********************************************************!*\ + !*** ./src/components/mission_panel/mission_panel.css ***! + \********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/navigation/navigation.css": + /*!**************************************************!*\ + !*** ./src/components/navigation/navigation.css ***! + \**************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/splash_screen/splash_screen.css": + /*!********************************************************!*\ + !*** ./src/components/splash_screen/splash_screen.css ***! + \********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/time_slider/time_slider.css": + /*!****************************************************!*\ + !*** ./src/components/time_slider/time_slider.css ***! + \****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/watch_panel/watch_card.css": + /*!***************************************************!*\ + !*** ./src/components/watch_panel/watch_card.css ***! + \***************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/watch_panel/watch_panel.css": + /*!****************************************************!*\ + !*** ./src/components/watch_panel/watch_panel.css ***! + \****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/animation.css": + /*!********************************************!*\ + !*** ../eyes/src/assets/css/animation.css ***! + \********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/camera_follow.css": + /*!************************************************!*\ + !*** ../eyes/src/assets/css/camera_follow.css ***! + \************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/color.css": + /*!****************************************!*\ + !*** ../eyes/src/assets/css/color.css ***! + \****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/components.css": + /*!*********************************************!*\ + !*** ../eyes/src/assets/css/components.css ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/font.css": + /*!***************************************!*\ + !*** ../eyes/src/assets/css/font.css ***! + \***************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/grid.css": + /*!***************************************!*\ + !*** ../eyes/src/assets/css/grid.css ***! + \***************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/grid_layout.css": + /*!**********************************************!*\ + !*** ../eyes/src/assets/css/grid_layout.css ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/icon.css": + /*!***************************************!*\ + !*** ../eyes/src/assets/css/icon.css ***! + \***************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/label.css": + /*!****************************************!*\ + !*** ../eyes/src/assets/css/label.css ***! + \****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/layout.css": + /*!*****************************************!*\ + !*** ../eyes/src/assets/css/layout.css ***! + \*****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/scrollbar.css": + /*!********************************************!*\ + !*** ../eyes/src/assets/css/scrollbar.css ***! + \********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/sprite.css": + /*!*****************************************!*\ + !*** ../eyes/src/assets/css/sprite.css ***! + \*****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/assets/css/style.css": + /*!****************************************!*\ + !*** ../eyes/src/assets/css/style.css ***! + \****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/breadcrumb/breadcrumb.css": + /*!********************************************************!*\ + !*** ../eyes/src/components/breadcrumb/breadcrumb.css ***! + \********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/carousel/carousel.css": + /*!****************************************************!*\ + !*** ../eyes/src/components/carousel/carousel.css ***! + \****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/carousel_panel/carousel_panel.css": + /*!****************************************************************!*\ + !*** ../eyes/src/components/carousel_panel/carousel_panel.css ***! + \****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/checkbox/checkbox.css": + /*!****************************************************!*\ + !*** ../eyes/src/components/checkbox/checkbox.css ***! + \****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/clock/clock.css": + /*!**********************************************!*\ + !*** ../eyes/src/components/clock/clock.css ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/clock_shortcut/clock_shortcut.css": + /*!****************************************************************!*\ + !*** ../eyes/src/components/clock_shortcut/clock_shortcut.css ***! + \****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/kiosk_base/kiosk_base.css": + /*!********************************************************!*\ + !*** ../eyes/src/components/kiosk_base/kiosk_base.css ***! + \********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/layer_panel/layer_panel.css": + /*!**********************************************************!*\ + !*** ../eyes/src/components/layer_panel/layer_panel.css ***! + \**********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/load_icon/load_icon.css": + /*!******************************************************!*\ + !*** ../eyes/src/components/load_icon/load_icon.css ***! + \******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/overlay/overlay.css": + /*!**************************************************!*\ + !*** ../eyes/src/components/overlay/overlay.css ***! + \**************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/search/search.css": + /*!************************************************!*\ + !*** ../eyes/src/components/search/search.css ***! + \************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/settings/settings.css": + /*!****************************************************!*\ + !*** ../eyes/src/components/settings/settings.css ***! + \****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/share_modal/share_modal.css": + /*!**********************************************************!*\ + !*** ../eyes/src/components/share_modal/share_modal.css ***! + \**********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/story/blocks/buttons_block/buttons_block.css": + /*!***************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/buttons_block/buttons_block.css ***! + \***************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/story/blocks/checkbox_block/checkbox_block.css": + /*!*****************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/checkbox_block/checkbox_block.css ***! + \*****************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/story/blocks/description_block/description_block.css": + /*!***********************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/description_block/description_block.css ***! + \***********************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/story/blocks/hint_block/hint_block.css": + /*!*********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/hint_block/hint_block.css ***! + \*********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/story/blocks/image_block/image_block.css": + /*!***********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/image_block/image_block.css ***! + \***********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/story/blocks/replay_button_block/replay_button_block.css": + /*!***************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/replay_button_block/replay_button_block.css ***! + \***************************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/story/blocks/story_base_content_block/story_base_content_block.css": + /*!*************************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/story_base_content_block/story_base_content_block.css ***! + \*************************************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/story/blocks/toggle_block/toggle_block.css": + /*!*************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/toggle_block/toggle_block.css ***! + \*************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/story/story.css": + /*!**********************************************!*\ + !*** ../eyes/src/components/story/story.css ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/time_controller/time_controller.css": + /*!******************************************************************!*\ + !*** ../eyes/src/components/time_controller/time_controller.css ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/toast/toast.css": + /*!**********************************************!*\ + !*** ../eyes/src/components/toast/toast.css ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/components/tutorial_overlay/tutorial_overlay.css": + /*!********************************************************************!*\ + !*** ../eyes/src/components/tutorial_overlay/tutorial_overlay.css ***! + \********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/app.js": + /*!********************!*\ + !*** ./src/app.js ***! + \********************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"AsteroidsApp":function(){return AsteroidsApp}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");var pioneer__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! ./internal */"./src/internal.js");var _configs_components_info__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(/*! ./configs/components_info */"./src/configs/components_info.js");var _data_heroes_json__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(/*! ./data/heroes.json */"./src/data/heroes.json");var _data_tutorials_json__WEBPACK_IMPORTED_MODULE_7__=__webpack_require__(/*! ./data/tutorials.json */"./src/data/tutorials.json");var _configs_time_info_json__WEBPACK_IMPORTED_MODULE_8__=__webpack_require__(/*! ./configs/time_info.json */"./src/configs/time_info.json");var _configs_scene_info_json__WEBPACK_IMPORTED_MODULE_9__=__webpack_require__(/*! ./configs/scene_info.json */"./src/configs/scene_info.json");var _configs_view_info_json__WEBPACK_IMPORTED_MODULE_10__=__webpack_require__(/*! ./configs/view_info.json */"./src/configs/view_info.json");var _configs_story_info_json__WEBPACK_IMPORTED_MODULE_11__=__webpack_require__(/*! ./configs/story_info.json */"./src/configs/story_info.json");var _views__WEBPACK_IMPORTED_MODULE_12__=__webpack_require__(/*! ./views */"./src/views/index.js");var _data_stories__WEBPACK_IMPORTED_MODULE_13__=__webpack_require__(/*! ./data/stories */"./src/data/stories/index.js");var _app_html__WEBPACK_IMPORTED_MODULE_14__=__webpack_require__(/*! ./app.html */"./src/app.html");var _app_html__WEBPACK_IMPORTED_MODULE_14___default=__webpack_require__.n(_app_html__WEBPACK_IMPORTED_MODULE_14__);class AsteroidsApp extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseApp{constructor(){super(_internal__WEBPACK_IMPORTED_MODULE_4__.Types);this._timeInfo=_configs_time_info_json__WEBPACK_IMPORTED_MODULE_8__;this._sceneInfo=_configs_scene_info_json__WEBPACK_IMPORTED_MODULE_9__;this._viewClasses={..._views__WEBPACK_IMPORTED_MODULE_12__["default"]};this._viewInfo=_configs_view_info_json__WEBPACK_IMPORTED_MODULE_10__;this._componentInfo=_configs_components_info__WEBPACK_IMPORTED_MODULE_5__["default"];this._heroes=_data_heroes_json__WEBPACK_IMPORTED_MODULE_6__;this._neos=new Map();this._particleMatchFunctions={};this._colors={neos:[0.823,0.882,0.909],spacecraft:[0.969,0.957,0.875]};this._resetValues={};this.tutorials=_data_tutorials_json__WEBPACK_IMPORTED_MODULE_7__;this.bindFunctions(['addParticleMatchFunction','removeParticleMatchFunction','createAsteroidParticles'])} + get heroes(){return this._heroes} + get neos(){return this._neos} + setUpRoutes(){this.getManager('router').addRoutes([{route:this.getManager('router').homeRoute,view:'home'},{route:'/story/:id',view:'story'},{route:'/missions/:spacecraft',view:'mission'},{route:'/planets/:planet',view:'following'},{route:'/stars/:star',view:'following'},{route:'/moons/:moon',view:'following'},{route:'/watch',view:'watch'},{route:'/watch/:neoName',view:'watch'},{route:'/:spaceObject',view:'asteroid'}])} + async setUpScene(){this._neos=await _internal__WEBPACK_IMPORTED_MODULE_4__.NEOUtils.loadNEOs(this.pioneer);const labelManager=this.getManager('label');labelManager._iconMap.Asteroid='asteroid';labelManager._iconMap['Dwarf Planet']='asteroid';labelManager._iconMap.Comet='comet';labelManager._iconMap.Spacecraft='spacecraft';labelManager._iconMap.Default='';await super.setUpScene();const scene=(this.scene);for(const name of Object.keys(this._heroes)){if(scene.getEntity(name)===null&&this._neos.has(name)){const entity=_internal__WEBPACK_IMPORTED_MODULE_4__.NEOUtils.createEntity(this._neos.get(name),scene);this.setUpLabels(entity,{category:_data_heroes_json__WEBPACK_IMPORTED_MODULE_6__[name].category})}} + labelManager._weightMap.Moon='5';labelManager._weightMap.Planet='10';labelManager._weightMap.Spacecraft='15';labelManager._weightMap.Comet='20';labelManager._weightMap.Asteroid='20';labelManager._weightMap['Dwarf Planet']='20';labelManager._weightMap.Star='30';labelManager._weightMap.Watch='40';labelManager._weightMap.Focus='50';labelManager.setWeights(this.getManager('content').getEntityList());if(this._neos.size){this.createAsteroidParticles()}else{console.error('NEOs data could not be loaded.')} + const trailManager=this.getManager('trail');const defaultOpacity=trailManager._opacity.primary;const width={default:[4,4],hover:[5,5]};const planets=pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityNamesInGroup('planets');planets.forEach(id=>{this._resetValues[id]={}});const sun=this.scene.get('sun');if(!sun.get('orbiterLineOfSight')){const lineOfSight=sun.addComponent('orbiterLineOfSight');lineOfSight.setEnabled(!1)} + const sceneManager=this.getManager('scene');await pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.SceneHelpers.waitTillEntitiesInPlace(scene,['earth']);sceneManager.createRing('sunRing',eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm*1.3,'sun',{orbitPlaneEntityName:'earth',color:new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(1,1,1),labelText:'1.3 AU distance from Sun',isEnable:!1});sceneManager.createTorus('sunTorus',1.496e8*0.95,1.496e8*1.05,'sun',{orbitPlaneEntityName:'earth',color:new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(1,1,1,0.2),labelText:'PHO boundary zone',isEnable:!1});labelManager.addException('sunRingLabel');labelManager.addException('sunTorusLabel')} + setUpLabels(entity,{category=undefined}={}){const contentManager=this.getManager('content');const labelManager=this.getManager('label');const colorLabels=['mercury','venus','earth','mars','jupiter','saturn','uranus','neptune'];const handleMouseEnter=(_,entityName)=>labelManager.triggerCallbacks('hoverchange',[entityName,!0,colorLabels.includes(entityName)]);const handleMouseLeave=(e,entityName)=>{if(e.target?.classList?.contains('selected')&&e.target?.classList?.contains('asteroid-watch-label')){return} + labelManager.triggerCallbacks('hoverchange',[entityName,!1,colorLabels.includes(entityName)])};labelManager.addEntity(entity);labelManager.setLabelProps({getLabelClass:entityName=>`no-select ${colorLabels.includes(entityName) ? 'color' : ''} ${contentManager.getClassName(entityName, category) ?? ''}`,handleMouseEnter,handleMouseLeave,...category&&{getIconClass:_=>category.toLowerCase()}},[entity.getName()])} + setUpManagers(){super.setUpManagers();this.addManager('watch',_internal__WEBPACK_IMPORTED_MODULE_4__.WatchManager);this.addManager('filters',_internal__WEBPACK_IMPORTED_MODULE_4__.FiltersManager,this._scene);this.addManager('neos',_internal__WEBPACK_IMPORTED_MODULE_4__.NEOsManager,this._scene);this.addManager('link',_internal__WEBPACK_IMPORTED_MODULE_4__.LinkManager);const titleManagerOptions={...this._sceneInfo.title,parseFn:({url,params,query}={})=>{const{spaceObject,spacecraft,planet,star,moon}=params;const entityName=spaceObject||spacecraft||planet||star||moon;if(query?.includes('=learn')){return'Learn'} + if(query?.includes('=filters')){return'Filters'} + if(url?.includes('/story')&¶ms.id){const story=_configs_story_info_json__WEBPACK_IMPORTED_MODULE_11__.find(({path})=>path===params.id);if(story?.title){return story.title}} + if(url?.includes('/watch')){return'Asteroid Watch'} + if(entityName){const entity=this.scene.get(entityName);const{innerText:label}=entity?.getComponentByType('div')?.getDiv()||{};if(label){return label}} + return'Home'}};const titleManagerClass=_internal__WEBPACK_IMPORTED_MODULE_4__.Types.get('TitleManager');const titleManager=this.addManager('title',titleManagerClass,titleManagerOptions)} + _buildSearchDatabase(){const entityInfo=eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.deepCopy(this.getManager('content').getEntityList());const entityList=this.scene._entities._itemsByName;const exceptions=['observable_universe','milky_way'];const database={};entityList.forEach(key=>{const info=entityInfo[key];if(!exceptions.includes(key)&&info){info.url=`/${info.id}`;database[key]=info}});this._neos.forEach((value,key)=>{if(key in database){database[key].neo=value}else{database[key]={id:key,iauName:value.name,url:`/${key}`,neo:value}}});return database} + async setUpComponents(){await super.setUpComponents();const entityInfo=this.getManager('content').getEntityList();const contentManager=this.getManager('content');contentManager.setStoryList(_data_stories__WEBPACK_IMPORTED_MODULE_13__.STORY_LIST);contentManager.setStories(_data_stories__WEBPACK_IMPORTED_MODULE_13__.STORIES);const searchDatabase=this._buildSearchDatabase();this.getManager('search').setDatabase(searchDatabase);const featuredItems=Object.keys(this.heroes).map(heroName=>{const heroEntity=entityInfo[heroName];if(!heroEntity){const heroData=_data_heroes_json__WEBPACK_IMPORTED_MODULE_6__[heroName];if(heroData.iauName&&heroData.id){return{text:heroData.iauName,sortText:heroData.displayName||heroData.iauName,url:`/${heroData.id}`}}else{console.error(`No entity found for hero: ${heroName}`);return!1}} + return{text:heroEntity.iauName,sortText:heroEntity.displayName||heroEntity.iauName,url:`/${heroEntity.id}`}});featuredItems.sort((a,b)=>a.sortText>b.sortText?1:-1);this.getComponent('search').setupFeaturedSuggestion(featuredItems);const trailManager=this.getManager('trail');const neoIds=['73p_schwassmann_wachmann_3'];const spacecraftIds=[];this.scene._entities._items.forEach(entity=>{const id=entity.getName();const{category}=entityInfo[id]||{};if(category==='Asteroid'||category==='Dwarf Planet'||category==='Comet')neoIds.push(id);else if(category==='Spacecraft')spacecraftIds.push(id);});trailManager.setColor(neoIds,new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(...this._colors.neos,0.35));trailManager.setColor(spacecraftIds,new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(...this._colors.spacecraft,0.5));const layerManager=this.getManager('layer');const layerPanel=this.getComponent('layerPanel');if(!layerManager.getLayer('asteroids').visible){layerPanel.toggleLayer('asteroids')} + if(!layerManager.getLayer('comets').visible){layerPanel.toggleLayer('comets')} + if(!layerManager.getLayer('dwarfPlanets').visible){layerPanel.toggleLayer('dwarfPlanets')} + layerManager.getLayer('starfield').toggleCallback[0](!1)} + setTutorialVariables(allTutorials){const allTutorialsStr=JSON.stringify(allTutorials);const replacedJsonString=allTutorialsStr.replace(/\{\{(.+?)\}\}/g,(match,functionName)=>{if(this[functionName]&&typeof this[functionName]==='function'){return this[functionName]()} + return match});return JSON.parse(replacedJsonString)} + addParticleMatchFunction(matchFunction,functionId,andRun,callback){this._particleMatchFunctions[functionId]=matchFunction;if(andRun)this.createAsteroidParticles(callback);} + removeParticleMatchFunction(functionId,andRun,callback){delete this._particleMatchFunctions[functionId];if(andRun)this.createAsteroidParticles(callback);} + createAsteroidParticles(callback){const sun=this.scene.getEntity('sun');if(sun.getComponentByType('orbitalParticles')!==null){sun.removeComponent(sun.getComponentByType('orbitalParticles'))} + const minColor=new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(0,0.25,0.35);const maxColor=new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(0,0.45,0.65);const white=new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color(1,1,1);minColor.lerp(minColor,white,0.10);maxColor.lerp(maxColor,white,0.15);const orbitalParticles=(sun.addComponent('orbitalParticles'));orbitalParticles.setLoadFunction(async()=>{const colors=([]);const scales=([]);const orbitalElements=([]);let shouldSkip;for(const neo of this._neos.values()){shouldSkip=!1;for(const f in this._particleMatchFunctions){if(!this._particleMatchFunctions[f](neo)){shouldSkip=!0;break}} + if(shouldSkip)continue;if(pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityOptions(neo.pioneerName)!==undefined){continue} + const color=new pioneer__WEBPACK_IMPORTED_MODULE_3__.Color();if(neo.comet){color.set(...this._colors.neos)}else{const u=Math.random();color.lerp(minColor,maxColor,u)} + colors.push(color);const scale=(neo.comet?1.3:1)*(neo.pho?1.5:1)*3e-3*Math.max(1.0,Math.log10(1.0+neo.diameter));scales.push(scale);orbitalElements.push(neo.orbitalElements)} + if(typeof callback==='function')callback(orbitalElements);return{colors,scales,orbitalElements}});orbitalParticles.setResourcesLoadedCallback(()=>{const material=(this._pioneer.get('main','sun','orbitalParticles')).getThreeJsMaterials()[0];material.uniforms.masterOpacity=new pioneer__WEBPACK_IMPORTED_MODULE_3__.THREE.Uniform(0.5);material.vertexShader=material.vertexShader.replace('vec4 viewPosition = modelViewMatrix * vec4(offset, 1.0) + vec4(position, 0.0) * scale;',` + vec4 viewOffset = modelViewMatrix * vec4(offset, 1.0); + vec4 viewPosition = viewOffset + vec4(position, 0.0) * scale; + `);material.vertexShader=material.vertexShader.replace('gl_Position = projectionMatrix * viewPosition;',` + float aspect_ratio_h = min(1.0, projectionMatrix[0][0] / projectionMatrix[2][1]); + float aspect_ratio_v = min(1.0, projectionMatrix[2][1] / projectionMatrix[0][0]); + gl_Position = projectionMatrix * viewOffset + vec4(position.x * viewOffset.y * scale * aspect_ratio_h, position.z * viewOffset.y * scale * aspect_ratio_v, 0, 0); + `);material.vertexShader=material.vertexShader.replace('fColor = color;','fColor = color * clamp((length(viewPosition) - 21937.0) / 40000.0, 0.0, 1.0);');material.fragmentShader=material.fragmentShader.replace('varying vec2 fPosition;',`uniform float masterOpacity; + varying vec2 fPosition; + `);material.fragmentShader=material.fragmentShader.replace('gl_FragColor = fColor * (1.0 - length(fPosition));','gl_FragColor = fColor * (1.0 - step(1.0, length(fPosition))) * vec4(1.0, 1.0, 1.0, masterOpacity);');material.needsUpdate=!0;material.blending=pioneer__WEBPACK_IMPORTED_MODULE_3__.THREE.NormalBlending})} + getNeoTotal(maximumSignificantDigits=2){return this.neos?.size.toLocaleString(undefined,{maximumSignificantDigits,roundingMode:'floor'})}} + AsteroidsApp.html=(_app_html__WEBPACK_IMPORTED_MODULE_14___default());AsteroidsApp.setAppClass()}),"./src/assets/index.js": + /*!*****************************!*\ + !*** ./src/assets/index.js ***! + \*****************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"./src/components/asteroid_menu_bottom/asteroid_menu_bottom.js": + /*!*********************************************************************!*\ + !*** ./src/components/asteroid_menu_bottom/asteroid_menu_bottom.js ***! + \*********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"AsteroidMenuBottom":function(){return AsteroidMenuBottom}});var _navigation_navigation__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../navigation/navigation */"./src/components/navigation/navigation.js");class AsteroidMenuBottom extends _navigation_navigation__WEBPACK_IMPORTED_MODULE_0__.Navigation{init(){super.init();this.bindFunctions(['isFilteringChange']);this._callbackRegistry.push({emitter:this._app.getManager('filters'),event:'isFilteringChange',callback:this.isFilteringChange});const param={position:'bottom',entry:[{title:'Learn',svg:'./assets/default/svg/learn.svg',onClick:()=>{this._app.getManager('router').navigate({modal:'learn'})}},{title:'Asteroid Watch',svg:'./assets/svg/asteroid.svg',onClick:()=>{this._app.getManager('watch').onWatchClick()}},{title:'Filters',svg:'./assets/svg/filter_inactive.svg',onClick:()=>{this._app.getManager('router').navigate({modal:'filters'})}}]};super.setup(param)} + isFilteringChange(isFiltering){super.toggleBadge('Filters',isFiltering)}}}),"./src/components/asteroid_menu_top/asteroid_menu_top.js": + /*!***************************************************************!*\ + !*** ./src/components/asteroid_menu_top/asteroid_menu_top.js ***! + \***************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"AsteroidMenuTop":function(){return AsteroidMenuTop}});var _navigation_navigation__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../navigation/navigation */"./src/components/navigation/navigation.js");class AsteroidMenuTop extends _navigation_navigation__WEBPACK_IMPORTED_MODULE_0__.Navigation{init(){super.init();this.bindFunctions(['isFilteringChange']);this._callbackRegistry.push({emitter:this._app.getManager('filters'),event:'isFilteringChange',callback:this.isFilteringChange});const currentRoute=this._app.getManager('router')._currentRoute;const query=currentRoute?.query||'';const param={position:'top',entry:[{title:'Learn',svg:'./assets/default/svg/learn.svg',active:query.includes('modal=learn'),onClick:()=>{const router=this._app.getManager('router');router.navigate({modal:'learn'},router.currentRoute.url)}},{title:'Asteroid Watch',svg:'./assets/svg/asteroid.svg',onClick:()=>{this._app.getManager('watch').onWatchClick()},active:currentRoute.url?.includes('watch')},{title:'Filters',svg:'./assets/svg/filter_inactive.svg',active:query.includes('modal=filters'),onClick:()=>{this._app.getManager('router').navigate({modal:'filters'})}}]};super.setup(param)} + async onQueryChange({modal}={}){super.toggleActive('Learn',modal==='learn');super.toggleActive('Filters',modal==='filters')} + isFilteringChange(isFiltering){super.toggleBadge('Filters',isFiltering)}}}),"./src/components/asteroid_modals/asteroid_modals.js": + /*!***********************************************************!*\ + !*** ./src/components/asteroid_modals/asteroid_modals.js ***! + \***********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"AsteroidModals":function(){return AsteroidModals}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _modals__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./modals */"./src/components/asteroid_modals/modals/index.js");var _asteroid_modals_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./asteroid_modals.html */"./src/components/asteroid_modals/asteroid_modals.html");var _asteroid_modals_html__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_asteroid_modals_html__WEBPACK_IMPORTED_MODULE_2__);class AsteroidModals extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options){super(app,null,{title:'',isVisible:!1,...options});this._components=['filtersModal','learnModal'];this._eventNames.push('overlay');this._initCallbacks();this._modals={};this._activeModal=null;this.bindFunctions(['close'])} + async init(){super.init();this._modals.filters=await this._app.addComponentWithPlaceholder({type:_modals__WEBPACK_IMPORTED_MODULE_1__.FiltersModal,name:'filtersModal'},this._element);this._modals.learn=await this._app.addComponentWithPlaceholder({type:_modals__WEBPACK_IMPORTED_MODULE_1__.LearnModal,name:'learnModal'},this._element);this._iconEl=document.createElement('img');this._children.header?.prepend(this._iconEl)} + onQueryChange({cancelToken,modal}={}){if(cancelToken&&cancelToken.isCanceled){return} + const activeModal=this._modals[modal]??null;if(this._activeModal===activeModal){return} + this._activeModal=activeModal;this._disableAllModals();if(this._activeModal){const{_title:title,_svg:svg}=this._activeModal;this.setState({title});this._iconEl.src=svg??'';this._iconEl.alt=title??'';this.setEnabled(!0);this.show();this._activeModal.setEnabled(!0);this._activeModal.show()}} + close(){const router=this._app.getManager('router');router.navigate({__remove:['modal']},router.currentRoute.url,{keepTime:!0})} + get components(){return this._components} + _disableAllModals(){Object.values(this._modals).forEach(modal=>{modal.hide();modal.setEnabled(!1)});this.hide();this.setEnabled(!1)}} + AsteroidModals.html=(_asteroid_modals_html__WEBPACK_IMPORTED_MODULE_2___default())}),"./src/components/asteroid_modals/modals/filters_modal/filters_modal.js": + /*!******************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/filters_modal/filters_modal.js ***! + \******************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _filters_modal_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./filters_modal.html */"./src/components/asteroid_modals/modals/filters_modal/filters_modal.html");var _filters_modal_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_filters_modal_html__WEBPACK_IMPORTED_MODULE_1__);class FiltersModal extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options){super(app,null,{...options});this.state={asteroids:!1,comets:!1,phos:!1};this._app=app;this._title='Filters';this._svg='./assets/svg/filter_inactive.svg';this._lastSize=null;this.bindFunctions(['_filterCallback'])} + init(){super.init();this.filtersManager=this._app.getManager('filters')} + onShow(){const filters=this.filtersManager.getFilters();document.getElementById('filters-asteroids-checkbox').checked=filters.asteroids;document.getElementById('filters-comets-checkbox').checked=filters.comets;document.getElementById('filters-phos-toggle').checked=filters.phos;this._lastSize=this._lastSize!=null?this._lastSize:this._app.neos.size;document.getElementsByClassName('filters-modal-count')[0].innerHTML=`${this._lastSize != null ? `${this._lastSize.toLocaleString()}` : 'All'} objects`} + show(){this.onShow();super.show()} + handleAsteroidCheck(e){const checked=e.target.checked;this.filtersManager.setFilter('asteroids',checked,this._filterCallback)} + handleCometCheck(e){const checked=e.target.checked;this.filtersManager.setFilter('comets',checked,this._filterCallback)} + handlePHOToggle(e){const checked=e.target.checked;this.filtersManager.setFilter('phos',checked,this._filterCallback)} + _filterCallback(size){this._lastSize=size;document.getElementsByClassName('filters-modal-count')[0].innerHTML=`${this._lastSize?.toLocaleString()} objects`} + handleResetFilters(){const filters=this.filtersManager.getFilters();if(filters.asteroids)document.getElementById('filters-asteroids-checkbox').click();if(filters.comets)document.getElementById('filters-comets-checkbox').click();if(filters.phos)document.getElementById('filters-phos-toggle').click();this._lastSize=this._app.neos.size} + handleHelp(e){this._app.getComponent('definitionOverlay').navigateToDefinition(e.target?.dataset?.def)}} + FiltersModal.html=(_filters_modal_html__WEBPACK_IMPORTED_MODULE_1___default());__webpack_exports__["default"]=(FiltersModal)}),"./src/components/asteroid_modals/modals/filters_modal/index.js": + /*!**********************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/filters_modal/index.js ***! + \**********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _filters_modal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./filters_modal */"./src/components/asteroid_modals/modals/filters_modal/filters_modal.js");__webpack_exports__["default"]=(_filters_modal__WEBPACK_IMPORTED_MODULE_0__["default"])}),"./src/components/asteroid_modals/modals/index.js": + /*!********************************************************!*\ + !*** ./src/components/asteroid_modals/modals/index.js ***! + \********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"FiltersModal":function(){return _filters_modal__WEBPACK_IMPORTED_MODULE_0__["default"]},"LearnModal":function(){return _learn_modal__WEBPACK_IMPORTED_MODULE_1__["default"]}});var _filters_modal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./filters_modal */"./src/components/asteroid_modals/modals/filters_modal/index.js");var _learn_modal__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./learn_modal */"./src/components/asteroid_modals/modals/learn_modal/index.js")}),"./src/components/asteroid_modals/modals/learn_modal/index.js": + /*!********************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/learn_modal/index.js ***! + \********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _learn_modal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./learn_modal */"./src/components/asteroid_modals/modals/learn_modal/learn_modal.js");__webpack_exports__["default"]=(_learn_modal__WEBPACK_IMPORTED_MODULE_0__["default"])}),"./src/components/asteroid_modals/modals/learn_modal/learn_modal.js": + /*!**************************************************************************!*\ + !*** ./src/components/asteroid_modals/modals/learn_modal/learn_modal.js ***! + \**************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _learn_modal_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./learn_modal.html */"./src/components/asteroid_modals/modals/learn_modal/learn_modal.html");var _learn_modal_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_learn_modal_html__WEBPACK_IMPORTED_MODULE_1__);var _configs_story_info_json__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ../../../../configs/story_info.json */"./src/configs/story_info.json");class LearnModal extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options){super(app,null,{...options});this._title='Learn';this._svg='./assets/default/svg/learn.svg'} + goToStory(story){const router=this._app.getManager('router');document.getElementsByClassName('asteroid-modal-close')[0]?.click();setTimeout(()=>{router.navigate({__remove:['modal']},`/story/${story.path}`)},200)} + onShow(){const stories=_configs_story_info_json__WEBPACK_IMPORTED_MODULE_3__||[];const modalBody=this._children.asteroidLearnModalBody;if(modalBody){modalBody.textContent='';stories.forEach(story=>{const markup=['
        ',`

        ${story.title}

        `,story.questions.map((q)=>{return `
        ${q}
        `}).join('\n')].join('\n');const card=document.createElement('div');card.className='learn-modal-story-card';card.innerHTML=markup;card.addEventListener('click',()=>{this.goToStory(story)});modalBody.append(card)})}} + show(){this.onShow();super.show()}} + LearnModal.html=(_learn_modal_html__WEBPACK_IMPORTED_MODULE_1___default());__webpack_exports__["default"]=(LearnModal)}),"./src/components/asteroid_panel/asteroid_panel.js": + /*!*********************************************************!*\ + !*** ./src/components/asteroid_panel/asteroid_panel.js ***! + \*********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"AsteroidPanel":function(){return AsteroidPanel}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class AsteroidPanel extends eyes__WEBPACK_IMPORTED_MODULE_0__.CarouselPanel{constructor(app,options){super(app,{panelTypeClass:'asteroid-panel',carouselClass:'asteroid-carousel',prevButtonClass:'asteroid-carousel-prev',nextButtonClass:'asteroid-carousel-next',title:'Asteroid Panel',caption:'',headerIconClass:'asteroid',...options});this._isPopulated=!1;this._expandOnShow=!0} + populate(neoData,heroData){const icon=neoData.comet?'comet':'asteroid';this.setState({title:neoData.name,headerIconClass:icon});const allTabsContent=[];const essentialStats=this.getEssentialStats(neoData,heroData);essentialStats.length&&allTabsContent.push({title:'Essential stats',content:essentialStats});const orbitalPath=this.getOrbitalPath(neoData);orbitalPath.length&&allTabsContent.push({title:'Orbital path',content:orbitalPath});const closeApproach=this.getCloseApproach(neoData,heroData);closeApproach.length&&allTabsContent.push({title:'Close approach',content:closeApproach});this.createTabs(allTabsContent);this._isPopulated=!0} + getEssentialStats(neoData,heroData){const{pioneerName,diameter,diameterEstimated,nextClosestApproachTime}=neoData;const neoEntity=this._app._scene.get(pioneerName);const earthEntity=this._app._scene.get('earth');const essentialStats=[];if(heroData?.stats?.discovery){essentialStats.push({title:'Discovery',content:heroData.stats.discovery})} + if(diameter){essentialStats.push({title:'Size',content:`

        Average ${diameterEstimated ? 'estimated' : ''} diameter

        `,value:`${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(diameter * 1000, 2)} m`})} + const posDifference=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3();neoEntity.getPositionRelativeToEntity(posDifference,pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero,earthEntity);const distanceKm=posDifference.magnitude();const distanceAU=distanceKm/eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm;if(!posDifference.isNaN()){essentialStats.push({title:'Distance',content:'

        Current distance from Earth

        ',value:`${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(distanceAU, 2)} AU`})} + const asteroidVelocity=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3();neoEntity.getVelocityAtTime(asteroidVelocity,nextClosestApproachTime);const magnitude=asteroidVelocity.magnitude();if(magnitude){essentialStats.push({title:'Velocity',content:'

        Current velocity relative to the Sun

        ',value:`${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(magnitude, 2)} km/s`})} + if(heroData?.stats?.rotation){essentialStats.push({title:'Period of Rotation',content:'

        Time to complete one full rotation

        ',value:`${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(heroData.stats.rotation, 2)} hours`})} + return essentialStats} + getOrbitalPath(neoData){const{orbitalElements}=neoData;const orbitalPath=[];if(orbitalElements){const period=orbitalElements.getPeriod();const days=Math.round(period/86400);const years=days/365;const time=years>=1?`${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(years, 2)} ${years === 1 ? 'year' : 'years'}`:`${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(days, 1)} ${days === 1 ? 'day' : 'days'}`;orbitalPath.push({title:'Orbital Period',content:'

        Time to complete one solar orbit

        ',value:time});const{eccentricity}=orbitalElements;if(eccentricity){orbitalPath.push({title:'Eccentricity',content:'

        Deviation from circular orbit

        ',value:eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(eccentricity,3)})} + const eclipJ2000ToJ2000Rotation=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.9791532214288992,0.2031230389823101,0,0);const orbitalElementsRelEcliptic=new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements();orbitalElementsRelEcliptic.copy(orbitalElements);orbitalElementsRelEcliptic.orbitOrientation.multInverseL(eclipJ2000ToJ2000Rotation,orbitalElementsRelEcliptic.orbitOrientation);const periapsisKm=orbitalElementsRelEcliptic.getPeriapsis();if(periapsisKm){orbitalPath.push({title:'Perihelion',content:'

        Closest distance to the Sun

        ',value:`${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(periapsisKm / eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm, 2)} AU`})} + const apoapsisKm=orbitalElementsRelEcliptic.getApoapsis();if(apoapsisKm){orbitalPath.push({title:'Aphelion',content:'

        Farthest distance from the Sun

        ',value:`${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(apoapsisKm / eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm, 2)} AU`})} + const inclination=orbitalElementsRelEcliptic.getInclination();if(inclination){orbitalPath.push({title:'Inclination',content:'

        Angle relative to the x-y ecliptic plane

        ',value:`${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(pioneer__WEBPACK_IMPORTED_MODULE_1__.MathUtils.radToDeg(inclination), 3)} deg`})}} + return orbitalPath} + getCloseApproach(neoData,heroData){const{nextClosestApproachDistance,nextClosestApproachTime}=neoData;const closeApproach=[];if(heroData?.approach?.fact){closeApproach.push({content:heroData.approach.fact})} + if(nextClosestApproachTime){const unixSeconds=pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.etToUnix(nextClosestApproachTime);const date=new Date(unixSeconds*1000);if(date){closeApproach.push({title:'Date',content:'

        Closest approach to Earth < 0.05 AU

        ',value:eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatDate(date)})}} + if(nextClosestApproachDistance){closeApproach.push({title:'Distance',content:'

        Nearest distance to Earth

        ',value:`${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatNumber(nextClosestApproachDistance, 0)} km`})} + return closeApproach} + show(initSwiper=!0){this._isPopulated&&super.show(initSwiper)} + _destroy(){this._isPopulated=!1;super._destroy()}}}),"./src/components/breadcrumb/breadcrumb.js": + /*!*************************************************!*\ + !*** ./src/components/breadcrumb/breadcrumb.js ***! + \*************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Breadcrumb":function(){return Breadcrumb}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class Breadcrumb extends eyes__WEBPACK_IMPORTED_MODULE_0__.Breadcrumb{async init(){super.init();this.setState({moduleText:this._crumbTexts.asteroids})} + _goToHome(){this._app.getManager('router').navigate({__remove:'all'},'/home')}}}),"./src/components/countdown/countdown.js": + /*!***********************************************!*\ + !*** ./src/components/countdown/countdown.js ***! + \***********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Countdown":function(){return Countdown}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var _countdown_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./countdown.html */"./src/components/countdown/countdown.html");var _countdown_html__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_countdown_html__WEBPACK_IMPORTED_MODULE_2__);class Countdown extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={}){super(app,null,{isVisible:!0,tText:'T -',numDays:'00',numHours:'00',numMinutes:'00',numSeconds:'00',...options});this._timeTarget=null;this._remainingSeconds=null;this.bindFunctions(['update'])} + init(){super.init();this._callbackRegistry.push({emitter:this._app.getManager('time'),event:'update',callback:this.update})} + _parseRemaining(remaining){const minuteSeconds=60;const hourSeconds=minuteSeconds*60;const daySeconds=hourSeconds*24;let numSeconds=parseInt(Math.abs(remaining),10);const numDays=Math.floor(numSeconds/daySeconds);numSeconds-=numDays*daySeconds;const numHours=Math.floor(numSeconds/hourSeconds);numSeconds-=numHours*hourSeconds;const numMinutes=Math.floor(numSeconds/minuteSeconds);numSeconds-=numMinutes*minuteSeconds;return{tText:remaining>0?'T﹣':'T﹢',numDays:String(numDays).padStart(2,'0'),numHours:String(numHours).padStart(2,'0'),numMinutes:String(numMinutes).padStart(2,'0'),numSeconds:String(numSeconds).padStart(2,'0')}} + update(currentMoment){if(!this._state.isVisible){return} + const currentEtTime=this._app?._pioneer?.getTime()||pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.unixToEt(currentMoment.valueOf()*0.001);const remainingSeconds=Math.round(this._timeTarget-currentEtTime);if(remainingSeconds!==this._remainingSeconds){const{tText,numDays,numHours,numMinutes,numSeconds}=this._parseRemaining(remainingSeconds);this.setState({tText,numDays,numHours,numMinutes,numSeconds});this._remainingSeconds=remainingSeconds}} + setTimeTarget(time){this._timeTarget=time} + getTimeTarget(){return this._timeTarget} + hide(){console.log('hide');super.hide()}} + Countdown.html=(_countdown_html__WEBPACK_IMPORTED_MODULE_2___default())}),"./src/components/definition_overlay/definition_overlay.js": + /*!*****************************************************************!*\ + !*** ./src/components/definition_overlay/definition_overlay.js ***! + \*****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"DefinitionOverlay":function(){return DefinitionOverlay}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _definition_overlay_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./definition_overlay.html */"./src/components/definition_overlay/definition_overlay.html");var _definition_overlay_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_definition_overlay_html__WEBPACK_IMPORTED_MODULE_1__);var _data_definitions_json__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ../../data/definitions.json */"./src/data/definitions.json");class DefinitionOverlay extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={}){super(app,null,{isVisible:!1});this._definitions=_data_definitions_json__WEBPACK_IMPORTED_MODULE_2__;this._router=null;this._queryUnsubscribe=null;this._scrollbar=null;this._class.fontSize.small='';this._activeDef=null;this._prevDef=null;Object.assign(this._state,{title:null,content:null,fontSizeClass:''});this.bindFunctions(['navigateToDefinition','_updateDefinition','_handleOutsideClick','_handleContainerClick'])} + init(){super.init();this._router=this._app.getManager('router')} + async onQueryChange({cancelToken,definition}={}){if(cancelToken&&cancelToken.isCanceled){return} + this._prevDef=this._activeDef;this._activeDef=definition;this._updateDefinition(this._activeDef,this._prevDef)} + _updateDefinition(currDefinition,prevDefinition){const currDefObj=this._definitions[currDefinition]??!1;const prevDefObj=this._definitions[prevDefinition]??!1;if(currDefObj){const{title,html:content,related}=currDefObj;this.setState({title,content});this._scrollbar??=eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addScrollbar(this._children.contentEl,{sizeAutoCapable:!0});this._scrollbar.scroll(0,300);const relatedElements=related.map(defId=>{const title=this._definitions[defId]?.title;const relatedItem=document.createElement('div');relatedItem.className='definition-related-item small clickable';relatedItem.setAttribute('data-def',defId);relatedItem.innerText=title;return relatedItem});this._children.relatedEl.replaceChildren(...relatedElements);if(!prevDefObj){this.show()}}else if(prevDefObj){this.hide()}} + navigateToDefinition(definitionId){if(definitionId){this._router.navigate({definition:definitionId},this._router.currentRoute.url)}else if(definitionId===!1){this._router.navigate({__remove:['definition']},this._router.currentRoute.url)}} + navigateToStory(storyId,storySlide='1'){const query={slide:`slide_${storySlide}`};const path=`/story/${storyId}`;const options={__remove:['modal','definition']};this.app.getManager('router').navigate(query,path,options)} + _handleOutsideClick(e){e.stopPropagation();this.navigateToDefinition(!1)} + _handleContainerClick(e){e.stopPropagation();const{storyid:storyId,storyslide:storySlide,def:definitionId}=e?.target?.dataset||{};if(storyId){this.navigateToStory(storyId,storySlide)}else if(definitionId){this.navigateToDefinition(definitionId)}} + __destroy(){if(typeof this._queryUnsubscribe==='function'){this._queryUnsubscribe()} + this._queryUnsubscribe=null;this._router=null;this._definitions=null;super.__destroy()}} + DefinitionOverlay.html=(_definition_overlay_html__WEBPACK_IMPORTED_MODULE_1___default())}),"./src/components/following_panel/following_panel.js": + /*!***********************************************************!*\ + !*** ./src/components/following_panel/following_panel.js ***! + \***********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"FollowingPanel":function(){return FollowingPanel}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class FollowingPanel extends eyes__WEBPACK_IMPORTED_MODULE_0__.CarouselPanel{constructor(app,options){super(app,{panelTypeClass:'following-panel',title:'',preTitle:'following',...options})}}}),"./src/components/home_button/home_button.js": + /*!***************************************************!*\ + !*** ./src/components/home_button/home_button.js ***! + \***************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"HomeButton":function(){return HomeButton}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class HomeButton extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{init(){this._element=document.createElement('h5');this._element.innerText='See all asteroids';this._element.className='home-button clickable {{isVisibleClass}}';this._element.addEventListener('click',()=>{const routeManager=this._app.getManager('router');routeManager.navigate({__remove:'all'},'/home')});super.init()}}}),"./src/components/mission_panel/mission_panel.js": + /*!*******************************************************!*\ + !*** ./src/components/mission_panel/mission_panel.js ***! + \*******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"MissionPanel":function(){return MissionPanel}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class MissionPanel extends eyes__WEBPACK_IMPORTED_MODULE_0__.CarouselPanel{constructor(app,options){super(app,{panelTypeClass:'mission-panel',carouselClass:'mission-carousel',prevButtonClass:'mission-carousel-prev',nextButtonClass:'mission-carousel-next',title:'Mission Panel',caption:'',headerIconClass:'spacecraft',...options});this._isPopulated=!1;this._expandOnShow=!0} + populate(title,blurb,cameraTarget,events={}){const{hideExternalLinks}=this._app.getManager('router').configs;const panelTitle=hideExternalLinks===!0?this._app.getManager('content').hideExternalLinksInText(title):title;this.setState({title:panelTitle});const allTabsContent=[];const panelBlurb=hideExternalLinks===!0?this._app.getManager('content').hideExternalLinksInText(blurb):blurb;panelBlurb&&allTabsContent.push({title:'Overview',content:[{content:`

        ${panelBlurb}

        `}]});const filteredEvents=events?Object.values(events).filter(({visual})=>visual):[];if(filteredEvents.length){const timeManager=(this.app.getManager('time'));const routeManager=(this.app.getManager('router'));const content=filteredEvents.map(({title,start,rate,target,id,distance,verticleOffset,horizontalOffset})=>{const dateInt=start?.valueOf();const date=dateInt&&new Date(dateInt);return{title,...date&&{content:`

        ${eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.formatDate(date)}

        `,value:'Watch'},onClick:async()=>{if(start&&routeManager?.currentRoute){if(id==='launch'){start=start.clone().add(1,'s')} + timeManager.setTime(start);timeManager.setTimeRate(rate||1);const query={time:timeManager.getTimeUrl(),rate:timeManager.getTimeRate()};this.app.getComponent('filtersModal').handleResetFilters();await routeManager.navigate(query,routeManager.currentRoute.url);if(target){await this.app.getManager('scene').isListReady([cameraTarget,target]);await this.app.scene.getEntity(cameraTarget).getLoadedPromise();await this.app.scene.getEntity(target).getLoadedPromise();await this.app.cameraScripts.alignObjects(cameraTarget,target,{duration:1,distance:distance??0.1,verticleOffset:verticleOffset??0,horizontalOffset:horizontalOffset??0})}}}}});allTabsContent.push({title:'Events',content})} + this.createTabs(allTabsContent);this._isPopulated=!0} + show(initSwiper=!0){this._isPopulated&&super.show(initSwiper)} + _destroy(){this._isPopulated=!1;super._destroy()}}}),"./src/components/navigation/navigation.js": + /*!*************************************************!*\ + !*** ./src/components/navigation/navigation.js ***! + \*************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Navigation":function(){return Navigation}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _navigation_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./navigation.html */"./src/components/navigation/navigation.html");var _navigation_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_navigation_html__WEBPACK_IMPORTED_MODULE_1__);class Navigation extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app){super(app,null,{position:'top'});this._entries={};this.bindFunctions(['toggleBadge'])} + setup(param){const{position='top',entry=[]}=param;this.setState({position});this._children.list.innerHTML='';for(let i=0;i

        ${entry[i].title}

        `;if(entry[i].svg){const img=document.createElement('img');img.src=entry[i].svg;img.alt=entry[i].title;div.appendChild(img)} + div.appendChild(button);if(entry[i].onClick){div.addEventListener('click',e=>{e.preventDefault();entry[i].onClick(entry[i],e)},!1);div.addEventListener('touchend',e=>{e.preventDefault();entry[i].onClick(entry[i],e)},!1)} + this._entries[entry[i].title]={entry:entry[i],element:div};this._children.list.append(div)}} + toggleActive(entryName,on){if(this._entries[entryName]){const elm=this._entries[entryName].element;const wasOn=elm.classList.contains('active');if(wasOn!==on){elm.classList.toggle('active')}}} + toggleBadge(entryName,on){if(this._entries[entryName]){const elm=this._entries[entryName].element;const wasOn=elm.classList.contains('badged');if(wasOn!==on){elm.classList.toggle('badged')}}}} + Navigation.html=(_navigation_html__WEBPACK_IMPORTED_MODULE_1___default())}),"./src/components/search/search.js": + /*!*****************************************!*\ + !*** ./src/components/search/search.js ***! + \*****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Search":function(){return Search}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class Search extends eyes__WEBPACK_IMPORTED_MODULE_0__.Search{_getLink(link){return this._app.getManager('link')?.getParsedLink?.(link)||link}}}),"./src/components/settings/asteroids_settings.js": + /*!*******************************************************!*\ + !*** ./src/components/settings/asteroids_settings.js ***! + \*******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"AsteroidsSettings":function(){return AsteroidsSettings}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class AsteroidsSettings extends eyes__WEBPACK_IMPORTED_MODULE_0__.Settings{toggleInfoPanel(){const tutorialIndex=0;const goHome=!0;this._app.getComponent('tutorialOverlay')?.navigateToTutorial(tutorialIndex,goHome)}}}),"./src/components/splash_screen/splash_screen.js": + /*!*******************************************************!*\ + !*** ./src/components/splash_screen/splash_screen.js ***! + \*******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SplashScreen":function(){return SplashScreen}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _splash_screen_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./splash_screen.html */"./src/components/splash_screen/splash_screen.html");var _splash_screen_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_splash_screen_html__WEBPACK_IMPORTED_MODULE_1__);class SplashScreen extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={}){super(app,null,{...options});this._dragging=!1;this._mousedownY=null;this._mousewheelDeltaY=0;this._animationPercent=0;this._timeout=null;this._lockEnd=!1} + _displaySplash(){this._element.style.pointerEvents='all';this._element.addEventListener('mousedown',this._onDown.bind(this));this._element.addEventListener('touchstart',this._onDown.bind(this));this._element.addEventListener('mousemove',this._onMove.bind(this));this._element.addEventListener('touchmove',this._onMove.bind(this));this._element.addEventListener('mouseup',this._onUp.bind(this));this._element.addEventListener('touchend',this._onUp.bind(this));this._element.addEventListener('wheel',this._onWheel.bind(this));this._timeout=setTimeout(()=>{this._setAnimationPercent(1,!0)},5500);let starsBoxShadow1='';for(let i=0;i<8;i++){starsBoxShadow1+=`${parseInt(Math.random() * window.innerWidth)}px ${parseInt(Math.random() * window.innerHeight)}px hsl(0deg, 0%, ${parseInt(Math.random() * 80) + 20}%), `} + this._children.splashScreenStars1.style.boxShadow=starsBoxShadow1.slice(0,-2);let starsBoxShadow2='';for(let i=0;i<24;i++){starsBoxShadow2+=`${parseInt(Math.random() * window.innerWidth)}px ${parseInt(Math.random() * window.innerHeight)}px hsl(0deg, 0%, ${parseInt(Math.random() * 80) + 20}%), `} + this._children.splashScreenStars2.style.boxShadow=starsBoxShadow2.slice(0,-2);const pioneerElm=document.getElementById('pioneer');if(pioneerElm){pioneerElm.style.transform='scale(1.2)';pioneerElm.style.filter='brightness(0) grayscale(0)';pioneerElm.style.opacity='0'} + this.app.endLoadingScreen()} + _onWheel(e){this._setAnimationPercent(1,!0)} + _onDown(e){if(e.touches?.length>0)e=e.touches[0];this._mousedownY=e.clientY} + _onMove(e){if(e.touches?.length>0)e=e.touches[0];const dragDistance=this._mousedownY-e.clientY;if(this._mousedownY!=null&&dragDistance>6){this._dragging=!0} + if(this._dragging){this._setAnimationPercent(1,!0)}} + _onUp(){this._setAnimationPercent(1,!0);this._dragging=!1;this._mousedownY=null} + _setAnimationPercent(percent,useTransitions){const previousPercent=this._animationPercent;this._animationPercent=percent;const baseTransition='all 0.8s cubic-bezier(0.645, 0.045, 0.355, 1)';const longTransition='all 1.1s cubic-bezier(0.645, 0.045, 0.355, 1)';this._children.splashScreen.style.transition=useTransitions?baseTransition:'unset';this._children.splashScreen.style.opacity=`${1 - (Math.pow(percent, 2))}`;this._children.splashScreenAsteroid.style.transition=useTransitions?baseTransition:'unset';this._children.splashScreenAsteroid.style.width=`${68 - (percent * 30)}vh`;this._children.splashScreenAsteroid.style.height=`${68 - (percent * 30)}vh`;this._children.splashScreenEnterBackground.style.transition=useTransitions?baseTransition:'unset';this._children.splashScreenEnterBackground.style.top=`calc(${86 - (percent * 44)}% - 54px)`;this._children.splashScreenEnterBackground.style.width=`${100 + (percent * 1200)}vw`;this._children.splashScreenEnterBackground.style.height=`${100 + (percent * 1200)}vw`;this._children.splashScreenText.style.transition=useTransitions?baseTransition:'unset';this._children.splashScreenText.style.top=`${55 - (percent * 40)}%`;this._children.splashScreenTextEyes.style.transition=useTransitions?baseTransition:'unset';this._children.splashScreenTextEyes.style.lineHeight=`${60 - (percent * 50)}px`;this._children.splashScreenTextOn.style.transition=useTransitions?baseTransition:'unset';this._children.splashScreenTextOn.style.lineHeight=`${40 - (percent * 50)}px`;this._children.splashScreenTextAsteroids.style.transition=useTransitions?baseTransition:'unset';this._children.splashScreenTextAsteroids.style.lineHeight=`${80 - (percent * 50)}px`;this._children.splashScreenEnter.style.transition=useTransitions?baseTransition:'unset';this._children.splashScreenEnter.style.top=`${81 - (percent * 30)}%`;this._children.splashScreenStars1.style.transition=useTransitions?baseTransition:'unset';this._children.splashScreenStars1.style.marginTop=`${(percent * 1)}%`;this._children.splashScreenStars2.style.transition=useTransitions?baseTransition:'unset';this._children.splashScreenStars2.style.marginTop=`${(percent * 0.5)}%`;const pioneerElm=document.getElementById('pioneer');if(pioneerElm){pioneerElm.style.transition=useTransitions?longTransition:'unset';pioneerElm.style.transform=`scale(${1.2 - (percent * 0.2)})`;pioneerElm.style.opacity=`${percent}`;pioneerElm.style.filter=`brightness(${percent}) grayscale(${1 - percent})`} + if(this._animationPercent>=1){this._element.style.pointerEvents='none'}else{this._element.style.pointerEvents='all'} + if(!this._dragging&&this._animationPercent>=1&&!this._lockEnd){this._lockEnd=!0;setTimeout(()=>{clearTimeout(this._timeout);if(pioneerElm){pioneerElm.style.transform='unset';pioneerElm.style.transition='unset';pioneerElm.style.opacity='unset';pioneerElm.style.filter='unset'} + this.destroy()},1100*(1-previousPercent))}} + __enable(){super.__enable();const{currentRoute,previousRoute,homeRoute}=this.app.getManager('router');if(previousRoute.url===undefined&&(currentRoute.url===undefined||currentRoute.url===homeRoute)){this._displaySplash()}else{this.destroy()}}} + SplashScreen.html=(_splash_screen_html__WEBPACK_IMPORTED_MODULE_1___default())}),"./src/components/time_slider/time_slider.js": + /*!***************************************************!*\ + !*** ./src/components/time_slider/time_slider.js ***! + \***************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TimeSlider":function(){return TimeSlider}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _time_slider_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./time_slider.html */"./src/components/time_slider/time_slider.html");var _time_slider_html__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_time_slider_html__WEBPACK_IMPORTED_MODULE_2__);const{debounce}=eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils;class TimeSlider extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={}){options.config={snapPoints:[1,10,60,300,600,3600,86400,604800,5256000,31540000],enableDynamicRate:!1,defaultCamDistance:700000000,fastestRate:{min:86400,max:157700000},...options.config};super(app,null,{startX:null,transX:0,lineMeasures:{left:null,width:null,isMeasured:!1},fastestRate:null,rateArray:null,realtimeVisibleClass:'hidden',...options});this._currentRate=null;this._camDistance=null;this._limit=null;this._extraClasses=['offset-right','v-squeezy','h-squeezy','portrait','landscape'];this._camDistanceResolve=null;this.bindFunctions(['_onMouseTouchDown','_onMouseTouchMove','_onMouseTouchUp','_getFastestRate','_snapToRate','_getRateArray','_onRealtimeClick','_update']);this._resizeDebounced=debounce(this._onResize,300)} + init(){super.init();const timeManager=this.app.getManager('time');this._callbackRegistry.push({emitter:timeManager,event:'update',callback:this._update},{emitter:timeManager,event:'forcedpause',callback:(_,limit)=>this._setLimit(limit)});this._addHandlers()} + async onQueryChange({rate}){const negative=rate<0;const absRate=Math.abs(rate??1);if(rate===0){this.setCurrentRate(0);this._setTransX(0);return} + const{width}=this._measureLine();await this._waitForCamDistance();const{rateArray}=this._state;let snappedAbsRate=this._snapToRate(absRate);if(snappedAbsRate{this._camDistanceResolve=resolve})} + _addHandlers(){const{iconEl}=this._children;iconEl.addEventListener('mousedown',this._onMouseTouchDown);iconEl.addEventListener('touchstart',this._onMouseTouchDown)} + _onMouseTouchDown(e){e?.preventDefault();this._measureLine();const{iconEl}=this._children;const{isTouch,canHover}=this.app;const xSource=e.touches?.length?e.touches[0]:e;const{clientX:startX}=xSource;iconEl.style.setProperty('transition','none');document.body.style.setProperty('cursor','grabbing');if(isTouch){document.addEventListener('touchmove',this._onMouseTouchMove);document.addEventListener('touchend',this._onMouseTouchUp)} + if(canHover){document.addEventListener('mousemove',this._onMouseTouchMove);document.addEventListener('mouseup',this._onMouseTouchUp)} + this.setState({startX})} + _onMouseTouchMove(e){const{lineMeasures:{left,width}}=this._state;const xSource=e.touches?.length?e.touches[0]:e;let{clientX:newTransX}=xSource;const min=left;const max=left+width;const halfWidth=width*0.5;newTransX=Math.max(newTransX,min);newTransX=Math.min(newTransX,max);newTransX-=(left+halfWidth);const normValue=newTransX/halfWidth;let rate=this._calculateRate(normValue);if(isNaN(normValue)||isNaN(rate)){return} + const negative=normValue<0;const belowMin=this._limit==='min'&&negative;const aboveMax=this._limit==='max'&&!negative;if(belowMin||aboveMax){newTransX=0;rate=0} + this._setTransX(newTransX);if(eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobilePortrait()){const{snapPoints}=this._config;const rateIsExtreme=Math.abs(rate)>snapPoints[snapPoints.length-3];const rateIsFarLeft=rateIsExtreme&&(rate<(snapPoints[snapPoints.length-3]*-1));const rateIsFarRight=rateIsExtreme&&(rate>(snapPoints[snapPoints.length-3]));const customMargin=rateIsFarLeft?'100%':rateIsFarRight?'-10%':'50%';document.documentElement.style.setProperty('--customIconLabelMargin',customMargin)} + this.setCurrentRate(rate)} + _onMouseTouchUp(e){e?.preventDefault();const{isTouch,canHover}=this.app;const{iconEl}=this._children;if(isTouch){document.removeEventListener('touchmove',this._onMouseTouchMove);document.removeEventListener('touchend',this._onMouseTouchUp)} + if(canHover){document.removeEventListener('mousemove',this._onMouseTouchMove);document.removeEventListener('mouseup',this._onMouseTouchUp)} + iconEl.style.setProperty('transition','transform 0.5s cubic-bezier(.3,1.24,.34,.98)');document.body.style.setProperty('cursor','default');this.updateQuery()} + _onRealtimeClick(e){this.updateQuery(1)} + _setTransX(transX){const{trans:currTransX}=this._state;if(transX===currTransX){return} + this._element.style.setProperty('--x-icon-trans',`${transX}px`);this.setState({transX})} + _getRateArray(fastestRate){const{snapPoints}=this._config;const nearestIndex=snapPoints.findIndex(point=>fastestRate<=point);const largerThanAllPoints=nearestIndex===-1;let maxSliceStart=8;if(!largerThanAllPoints){maxSliceStart-=(snapPoints.length-nearestIndex)*2} + if(largerThanAllPoints){return[1,...snapPoints.slice(maxSliceStart),fastestRate]} + const sliceRefIndex=snapPoints.length-maxSliceStart;const sliceStart=nearestIndex-sliceRefIndex;return[1,...snapPoints.slice(sliceStart,nearestIndex),fastestRate]} + _calculateRate(normValue){const{fastestRate,rateArray}=this._state;const negative=normValue<0;const absValue=Math.abs(normValue);const maxIndex=rateArray.length-1;let interpolatedRate=absValue*fastestRate;if(rateArray){const interpIndex=absValue*maxIndex;const interpFraction=interpIndex%1;const rateIndex=Math.floor(interpIndex);interpolatedRate=rateArray[rateIndex];if(rateIndex=rateArray[i]){rateIndex=i}else{break}} + if(rateIndex===maxIndex||rateIndex===-1){return 1}else{const lowerRate=rateArray[rateIndex];const upperRate=rateArray[rateIndex+1];const rateFraction=(absRate-lowerRate)/(upperRate-lowerRate);const normValue=(rateIndex+rateFraction)/maxIndex;return normValue}} + _snapToRate(value){const{snapPoints}=this._config;const nearestIndex=snapPoints.findIndex(point=>value-1?snapPoints[nearestIndex-1]:snapPoints[snapPoints.length-1];const snappedMultiple=Math.round(value/prevPoint);return snappedMultiple*prevPoint} + setCurrentRate(rate){rate!==0&&this._setLimit(null);this.app.pioneer.setTimeRate(rate);this._currentRate=rate;const formattedRate=this.formatRate(rate);this._element.style.setProperty('--x-rate',`'${formattedRate}'`);const realtimeVisibleClass=(rate===1||rate===0)?'hidden':'';this.setState({realtimeVisibleClass})} + updateQuery(rate=this.app.pioneer.getTimeRate()){const router=this.app.getManager('router');const time=this.app.getManager('time').getTimeUrl();router.navigate({time,rate},router.currentRoute.url)} + _getFastestRate(){const{enableDynamicRate,fastestRate,defaultCamDistance}=this._config;const{defaultMaxDistance}=this._app.getManager('camera');let camDistance=this._camDistance;if(!camDistance||isNaN(camDistance)){console.warn('Time Slider:: Missing camera distance.');camDistance=defaultCamDistance} + const rateCoefficient=defaultMaxDistance&&!isNaN(defaultMaxDistance)?Math.round(camDistance)/defaultMaxDistance:1;return enableDynamicRate?fastestRate.min+(fastestRate.max-fastestRate.min)*rateCoefficient:fastestRate.max} + formatRate(rate){if(rate===1){return''} + if(rate===0){return'Paused'} + const negative=rate<0;const absRate=Math.abs(rate);const yrs=absRate/31540000;const months=absRate/2628000;const weeks=absRate/604800;const days=absRate/86400;const hrs=absRate/3600;const mins=absRate/60;const oneDP=(val)=>{const toOneDP=Number(`${Math.round(`${val}e1`)}e-1`);return negative?toOneDP*-1:toOneDP};if(yrs>=1){return `${oneDP(yrs)} yrs/s`} + if(months>=2){return `${Math.round(negative ? months * -1 : months)} mths/s`} + if(weeks>=1){return `${Math.round(negative ? weeks * -1 : weeks)} wks/s`} + if(days>=1){return `${oneDP(days)} days/s`} + if(hrs>=1){return `${oneDP(hrs)} hrs/s`} + if(mins>=1){return `${oneDP(mins)} mins/s`} + return `${rate} secs/s`} + _getClasses(options){const classes=[];if(options.removeAll){return classes} + const limitedHeightThreshold=641;const limitedWidthThreshold=961;const offsetRightThreshold=641;const portrait=eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobilePortrait();const landscape=eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isLandscape();const limitedHeight=window.innerHeight{const addClass=(classes.includes(extraClass)&&!options.removeAll);this._parent.classList.toggle(extraClass,addClass)})} + get extraClasses(){return this._parent.classList} + _measureLine(){const{left,width}=this._children?.lineEl?.getBoundingClientRect()||{};if(left===undefined||width===undefined){return null} + this.setState({lineMeasures:{left,width,isMeasured:!0}});return{left,width}} + _onResize(){const{width}=this._measureLine();const rate=this._currentRate??1;const negative=rate<0;const absRate=Math.abs(rate);const normVal=this._calculateNormValue(absRate);const absTransX=normVal*width*0.5;const transX=negative?absTransX*-1:absTransX;this._setTransX(transX)} + resize(){this._resizeDebounced()} + _update(){const{cameraEntity}=this.app.getManager('camera');const camDistance=cameraEntity.getPosition().magnitude();if(this._camDistance?.toFixed(4)!==camDistance?.toFixed(4)){this._camDistance=camDistance;if(this._camDistance&&!isNaN(this._camDistance)){const fastestRate=this._snapToRate(this._getFastestRate());const rateArray=this._getRateArray(fastestRate);this.setState({fastestRate,rateArray})}} + if(this._camDistanceResolve&&this._camDistance&&!isNaN(this._camDistance)){this._camDistanceResolve(this._camDistance);this._camDistanceResolve=null}} + show(){this._parent?.classList.toggle('hidden',!1)} + hide(){this._parent?.classList.toggle('hidden',!0)} + setSliderVisibility(visible){this._parent?.classList.toggle('no-slider',!visible)}} + TimeSlider.html=(_time_slider_html__WEBPACK_IMPORTED_MODULE_2___default())}),"./src/components/watch_panel/watch_card.js": + /*!**************************************************!*\ + !*** ./src/components/watch_panel/watch_card.js ***! + \**************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"WatchCard":function(){return WatchCard}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var _watch_card_html__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ./watch_card.html */"./src/components/watch_panel/watch_card.html");var _watch_card_html__WEBPACK_IMPORTED_MODULE_3___default=__webpack_require__.n(_watch_card_html__WEBPACK_IMPORTED_MODULE_3__);class WatchCard extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={}){super(app,null,{title:'Asteroid Name',date:'April 13, 2029',time:'10:52am',diameterUnit:'km',diameter:'0.5',diameterEstimatedText:'',diameterRaw:0.5,distanceUnit:'km',distance:'512,321',distanceRaw:512321,unitType:'metric',...options});this.bindFunctions(['toggleUnit'])} + init(){super.init();this._callbackRegistry.push({emitter:this._app.getManager('watch'),event:'toggleUnit',callback:this.toggleUnit})} + handleToggleUnit(e){this._app.getManager('watch')?.toggleUnit()} + toggleUnit(newUnitType){const metric=newUnitType==='metric';const kmMiRatio=1.609344;const ftInMiles=5280;const mInKm=1000;const{diameterRaw,distanceRaw}=this._state;const currentDiameter=diameterRaw||0;let newDiameter=currentDiameter;let newDiameterUnit=metric?'km':'mi';const currentDistance=distanceRaw||0;let newDistance=currentDistance;let newDistanceUnit=metric?'km':'mi';if(metric){if(newDiameter<1){newDiameterUnit='m';newDiameter*=mInKm} + if(newDistance<1){newDistanceUnit='m';newDistance*=mInKm}}else{newDiameter=currentDiameter/kmMiRatio;newDistance=currentDistance/kmMiRatio;if(newDiameter<1){newDiameterUnit='ft';newDiameter*=ftInMiles} + if(newDistance<1){newDistanceUnit='ft';newDistance*=ftInMiles}} + this.setState({diameterUnit:newDiameterUnit,diameter:this._parseDiameter(newDiameter),distanceUnit:newDistanceUnit,distance:`${Math.round(newDistance).toLocaleString(undefined)}`,unitType:newUnitType})} + _parseDiameter(diameter){return parseFloat(diameter).toFixed(1).replace(/\.0+$/,'')} + setTarget(neoData){const{name,nextClosestApproachTime,nextClosestApproachDistance,diameter,diameterEstimated}=neoData;const unixSeconds=pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.etToUnix(nextClosestApproachTime);const date=new Date(unixSeconds*1000);this.setState({title:name,date:date.toLocaleDateString(undefined,{year:'numeric',month:'short',day:'numeric'}),time:date.toLocaleTimeString(undefined),diameter:this._parseDiameter(diameter),diameterRaw:diameter,diameterEstimatedText:diameterEstimated?'〚estimated〛':'',distance:`${Math.round(nextClosestApproachDistance).toLocaleString(undefined)}`,distanceRaw:nextClosestApproachDistance});this.toggleUnit(this._state.unitType)}} + WatchCard.html=(_watch_card_html__WEBPACK_IMPORTED_MODULE_3___default())}),"./src/components/watch_panel/watch_panel.js": + /*!***************************************************!*\ + !*** ./src/components/watch_panel/watch_panel.js ***! + \***************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"WatchPanel":function(){return WatchPanel}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _countdown_countdown__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ../countdown/countdown */"./src/components/countdown/countdown.js");var _watch_card__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./watch_card */"./src/components/watch_panel/watch_card.js");class WatchPanel extends eyes__WEBPACK_IMPORTED_MODULE_0__.CarouselPanel{constructor(app,options){super(app,{panelTypeClass:'watch-panel',carouselClass:'watch-carousel',paginationClass:'watch-carousel-fraction',prevButtonClass:'watch-carousel-prev',nextButtonClass:'watch-carousel-next',title:'Asteroid Watch',caption:'The next five closest approaches to Earth',headerIconClass:'asteroid',...options});this.shouldBeExpanded=null;this._onSlideChange=({realIndex})=>{const watchManager=this._app.getManager('watch');const neoName=watchManager.getNeoNameByIndex(realIndex);watchManager.updateURL(neoName)}} + populate(nextFive){nextFive.forEach(asteroid=>{const watchCard=new _watch_card__WEBPACK_IMPORTED_MODULE_2__.WatchCard(this._app);watchCard.init();watchCard.setTarget(asteroid);this._components.push(watchCard);const countdown=new _countdown_countdown__WEBPACK_IMPORTED_MODULE_1__.Countdown(this._app);countdown.init();countdown.setTimeTarget(asteroid.nextClosestApproachTime);this._components.push(countdown);this.addSlide([watchCard.element,countdown.element])})} + setExpandState(){super.setExpandState(this.shouldBeExpanded)} + show(){this.setExpandState();super.show(!1)} + expand(){const watchManager=this._app.getManager('watch');const currentSwiperSlide=this._swiper?.realIndex;watchManager.setSlideUrlByIndex(currentSwiperSlide)} + collapse(){const watchManager=this._app.getManager('watch');watchManager.updateURL('')}}}),"./src/configs/components_info.js": + /*!****************************************!*\ + !*** ./src/configs/components_info.js ***! + \****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_exports__["default"]=([{type:'Search',name:'search',options:{config:{placeholderText:'Search asteroids and comets...',allowFeatured:!0,allowDetail:!1,allowInfo:!0,stopOnExactMatch:!1,maxSuggestions:3}}},{type:'TutorialOverlay',name:'tutorialOverlay'},{type:'AsteroidMenuTop',name:'asteroid_menu_top'},{type:'AsteroidMenuBottom',name:'asteroid_menu_bottom'},{type:'AsteroidModals',name:'asteroid_modals'},{type:'Breadcrumb',name:'breadcrumb',options:{params:{title:'Unminified and Edited'}}},{type:'Clock',name:'clock',postCreationFunction:(_,component)=>{const timeNodes=component._element?.querySelectorAll('.time, .meridiem');timeNodes.forEach(node=>node.classList.add('x-small'))}},{type:'ClockShortcut',name:'clockShortcut'},{type:'TimeSlider',name:'timeSlider',options:{config:{enableDynamicRate:!0,fastestRate:{min:3629000,max:157700000}}}},{type:'AsteroidsSettings',name:'settings'},{type:'HomeButton',name:'homeButton'},{type:'AsteroidPanel',name:'asteroidPanel'},{type:'MissionPanel',name:'missionPanel'},{type:'FollowingPanel',name:'followingPanel'},{type:'WatchPanel',name:'watchPanel'},{type:'LayerPanel',name:'layerPanel',options:{layers:[['planets'],['spacecraft'],['trails','labels','icons','starfield'],['ui']],checkboxType:'eyes'}},{type:'DefinitionOverlay',name:'definitionOverlay'},{type:'SplashScreen',name:'splashScreen'},{type:'Story',name:'story'}])}),"./src/data/stories/asteroids_101.js": + /*!*******************************************!*\ + !*** ./src/data/stories/asteroids_101.js ***! + \*******************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");let globalNonce=0;__webpack_exports__["default"]=({type:'nonsequential',entities:['4_vesta','67p_churyumov_gerasimenko'],slides:[{id:'slide_1',type:'overlay',classList:['opaque','black'],content:[{type:'title',title:'Asteroids and Comets 101'}]},{id:'slide_2',type:'overlay',classList:['opaque','black'],content:[{type:'image',src:'assets/images/outterAsteroidBelt.png',title:'Main Asteroid Belt. Credit: NASA/JPL',alt:'This image illustrates the millions of asteroids between the Sun and Jupiter — know as the asteroid belt.',clickable:!0},{type:'description',description:'This image illustrates the millions of asteroids between the Sun and Jupiter — know as the asteroid belt.

        The current number of known asteroids in the entire solar system is:
        0

        ',onEnter:async(app,block)=>{const element=block.element.querySelector('.tween-count');const count=1362000 + eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.tween({i:0},{i:count},{onUpdate:object=>{if(element){const value=Math.round(object.i);element.innerHTML=Number(value).toLocaleString()}},duration:3000})}}]},{id:'slide_3',type:'panel',content:[{type:'title',classList:['semi'],title:"Vesta"}],camera:[async app=>{const localNonce=++globalNonce;await app.getManager('scene').isReady('4_vesta');if(localNonce!==globalNonce)return;await app.cameraScripts.goToSystem('inner_solar_system',{duration:1});if(localNonce!==globalNonce)return;await app.cameraScripts.goToCelestialObject('4_vesta',{duration:4})}]},{id:'slide_4',type:'panel',content:[{type:'title',title:"67P Churyumov-Gerasimenko"}],camera:[async app=>{const localNonce=++globalNonce;await app.getManager('scene').isReady('67p_churyumov_gerasimenko');if(localNonce!==globalNonce)return;await app.cameraScripts.goToSystem('inner_solar_system',{duration:1});if(localNonce!==globalNonce)return;await app.cameraScripts.goToCelestialObject('67p_churyumov_gerasimenko',{duration:4})}]},{id:'slide_5',type:'panel',content:[{type:'title',title:""}],camera:[async app=>{++globalNonce;await app.cameraScripts.goToSystem('inner_solar_system',{duration:2})}],rate:604800}]})}),"./src/data/stories/asteroids_close_approach.js": + /*!******************************************************!*\ + !*** ./src/data/stories/asteroids_close_approach.js ***! + \******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");__webpack_exports__["default"]=({type:'nonsequential',entities:['moon','99942_apophis'],slides:[{id:'slide_1',type:'overlay',classList:['opaque','black'],content:[{type:'title',title:'What is a Close Approach?'}],camera:[async app=>{await app.cameraScripts.goToSystem('outer_solar_system')}]},{id:'slide_2',type:'panel',content:[{type:'description',description:''}],camera:[async app=>{await app.cameraScripts.goToSystem('inner_solar_system')}],rate:259200},{id:'slide_3',type:'panel',content:[{type:'description',title:'Apophis',description:''}],time:'2029-04-13T14:40:12-07:00',camera:[async app=>{await app.getManager('scene').isListReady(['99942_apophis','earth']);app.getManager('time').pause();await app.cameraScripts.alignObjects('99942_apophis','earth',{duration:2,verticalOffset:15,horizontalOffset:-15});app.getManager('time').play()}],onEnter:app=>{app.scene.get('sun').getComponentByType('orbitalParticles').setEnabled(!1)},onLeave:app=>{app.scene.get('sun').getComponentByType('orbitalParticles').setEnabled(!0)},rate:60},{id:'slide_4',type:'panel',content:[{type:'description',title:"Apophis's closest approach to Earth",classList:['large','semi'],description:'
        Distance: {{distance}} km
        ',onEnter:(app,block)=>{block.addState('distance','0');block.update=()=>{const distance=app.getManager('scene').getDistance('earth','99942_apophis',{precision:3}).toLocaleString();block.setState({distance})};app.pioneer.addCallback(block.update,!0)},onLeave:(app,block)=>{app.pioneer.removeCallback(block.update)}}],time:'2029-04-12T12:00:00-07:00',camera:[async app=>{await app.getManager('scene').isListReady(['earth','moon','99942_apophis']);app.getManager('time').pause();await app.cameraScripts.goToSystem('earth',{duration:2,planeId:'moon',otherEntityNames:['moon'],distance:385000*2.5,angle:35,includeChildren:!1,isRelativeToPreviousCamera:!1});app.getManager('time').play()}],onEnter:async(app,slide)=>{await app.getManager('scene').isListReady(['sun','earth','moon','99942_apophis']);const sun=app.scene.get('sun');sun.getComponentByType('orbitalParticles').setEnabled(!1);const lineOfSight=sun.get('orbiterLineOfSight');lineOfSight.setEnabled(!0);lineOfSight.setTargets('earth','99942_apophis');app.scene.get('earth').get('orbitLine').setEnabled(!1);if(slide.getState('previousIndex')!==slide.getState('currentIndex')){slide.reset={};const apophis=app.scene.get('99942_apophis');apophis.getControllerByType('dynamo',0)?.setEnabled(!1);const dynamoController=apophis.addController('dynamo','earth_centric');dynamoController.setBaseUrl('$DYNAMIC_ASSETS_URL/dynamo/ssd/99942_apophis/earth/orb/');apophis.removeParentingTableEntry(Number.NEGATIVE_INFINITY);apophis.addParentingTableEntry(Number.NEGATIVE_INFINITY,'earth')} + app.getManager('time').setMax('2029-04-14T12:00:00-07:00')},onLeave:async(app,slide)=>{const apophis=app.scene.get('99942_apophis');apophis.removeParentingTableEntry(Number.NEGATIVE_INFINITY);apophis.addParentingTableEntry(Number.NEGATIVE_INFINITY,'sun');apophis.removeController(apophis.getController('earth_centric'));apophis.getControllerByType('dynamo',0)?.setEnabled(!0);const sun=app.scene.get('sun');sun.getComponentByType('orbitalParticles').setEnabled(!0);const lineOfSight=sun.get('orbiterLineOfSight');lineOfSight.setEnabled(!1);app.scene.get('earth').get('orbitLine').setEnabled(!0);app.getManager('time').resetMax();await app.scene.getLoadedPromise();await app.pioneer.waitUntilNextFrame()},rate:1800},{id:'slide_5',type:'panel',content:[{type:'description',title:'Near Earth Objects (NEOs)',description:'',onEnter:(app,block)=>{block.auLinkClick=()=>{app.getComponent('definitionOverlay').navigateToDefinition('au')};block._children.auLink?.addEventListener('click',block.auLinkClick);block._children.auLink?.addEventListener('click',block.auLinkClick)},onLeave:(app,block)=>{block._children.auLink?.removeEventListener('click',block.auLinkClick)}}],time:'2029-03-01T10:45:12-07:00',rate:300000,camera:[async app=>{await app.getManager('scene').isListReady(['sun','earth','99942_apophis']);app.getManager('time').pause();await app.cameraScripts.showLocation('sun','earth','earth','planeNormal',{distance:eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm*1.3*1.5,duration:2,startFromTarget:!1,rotateByScreenRatio:!1});app.getManager('time').play()}],onEnter:app=>{const planets=pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.getEntityNamesInGroup('planets');planets.forEach(planet=>{if(planet!=='earth'){app.scene.get(planet).setEnabled(!1)}});app.getManager('layer').toggleLayer('trails');app.scene.get('earth').get('orbitLine').setEnabled(!0);app.getManager('label').addException('earth');app.getManager('label').addException('99942_apophis');const ringEntity=app.scene.get('sunRing');const labelEntity=app.scene.get('sunRingLabel');ringEntity.setEnabled(!0);labelEntity.setEnabled(!0)},onLeave:app=>{const planets=pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.getEntityNamesInGroup('planets');planets.forEach(planet=>{if(planet!=='earth'){app.scene.get(planet).setEnabled(!0)}});app.getManager('layer').toggleLayer('trails',undefined,!0);app.getManager('label').removeException('earth');app.getManager('label').removeException('99942_apophis');const ringEntity=app.scene.get('sunRing');ringEntity.setEnabled(!1);const labelEntity=app.scene.get('sunRingLabel');labelEntity.setEnabled(!1)}},{id:'slide_6',type:'panel',content:[{type:'description',title:'Potentially Hazardous Objects (PHOs)',description:'',onEnter:(app,block)=>{block.addState('phoCount','0');app.getManager('filters').setFilter({asteroids:!0,comets:!0,phos:!0},null,(size)=>{block.setState({phoCount:Number(size).toLocaleString()})})},onLeave:(app,block)=>{const filtersManager=app.getManager('filters');filtersManager.setFilter(filtersManager.getPreviousFilters())}}],time:'2029-03-27T14:45:12-07:00',rate:10000,camera:[async app=>{await app.getManager('scene').isListReady(['earth','99942_apophis']);app.getManager('time').pause();await app.cameraScripts.showLocation('sun','earth','earth','planeNormal',{distance:eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm*1.3*1.5,duration:2,startFromTarget:!1,rotateByScreenRatio:!1});await app.cameraScripts.goToSystemSideway('earth',{duration:2,distance:eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.conversionTable.auToKm*0.05*20,angleInDegree:30,includeChildren:!1});app.getManager('time').play()}],onEnter:async app=>{const torus=app.scene.get('sunTorus');torus.setEnabled(!0);const torusLabel=app.scene.get('sunTorusLabel');torusLabel.setEnabled(!0)},onLeave:app=>{const torus=app.scene.get('sunTorus');torus.setEnabled(!1);const torusLabel=app.scene.get('sunTorusLabel');torusLabel.setEnabled(!1)}},{id:'slide_7',type:'panel',content:[{type:'description',description:'Explore the next 5 closest approaches here. These are continuously updated, as NASA is constantly on the lookout.'}],camera:[async app=>{await app.cameraScripts.goToSystem('inner_solar_system')}],rate:259200}],onEnter:app=>{},onLeave:app=>{const sceneManager=app.getManager('scene');app.getManager('layer').toggleLayer('trails',undefined,!0);app.scene.get('earth').get('orbitLine').setEnabled(!0)}})}),"./src/data/stories/asteroids_missions.js": + /*!************************************************!*\ + !*** ./src/data/stories/asteroids_missions.js ***! + \************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);const forceLoad=[];let globalNonce=0;let isLabelClicked=!1;const resetLabelClick=()=>{isLabelClicked=!1};const addLabelClick=(app,entityName,callback)=>{const labelEl=app.scene.getEntity(entityName)?.get('div')?.getDiv();if(labelEl){labelEl.classList.remove('unclickable');labelEl.addEventListener('click',async()=>{isLabelClicked=!0;await callback(entityName,app)})}};const removeLabelClick=(app,entityName,callback)=>{const labelEl=app.scene.getEntity(entityName)?.get('div')?.getDiv();if(labelEl){labelEl.classList.add('unclickable');labelEl.removeEventListener('click',callback)}};const goToSpacecraft=async(entityName,app)=>{await app.cameraScripts.goToSpacecraft(entityName)};const goToCelestialObject=async(entityName,app)=>{await app.cameraScripts.goToCelestialObject(entityName)};__webpack_exports__["default"]=({type:'nonsequential',slides:[{id:'slide_1',type:'overlay',classList:['opaque','black'],content:[{type:'title',title:'Asteroid and Comet Missions'}],camera:[async app=>{++globalNonce;await app.cameraScripts.goToSystem('inner_solar_system')}]},{id:'slide_2',type:'panel',time:'2015-02-14T08:14:00Z',content:[{type:'description',title:'The Rosetta mission',description:'Orbiting comet 67P Churyumov-Gerasimenko'}],camera:[async app=>{const localNonce=++globalNonce;const time=app.getManager('time');await app.getManager('scene').isListReady(['67p_churyumov_gerasimenko','sc_rosetta']);if(localNonce!==globalNonce)return;time.pause();await app.cameraScripts.goToSpacecraft('sc_rosetta',{cinematic:!0,duration:3});time.play()}],onEnter:(app,slide)=>{const camera=app.getManager('camera');addLabelClick(app,'sc_rosetta',goToSpacecraft);addLabelClick(app,'67p_churyumov_gerasimenko',goToCelestialObject);slide.selectionCallback=camera.getSelectionCallback();camera.setSelectionCallback(async entity=>{const entityName=entity?.getName();if(entityName==='67p_churyumov_gerasimenko'){await app.cameraScripts.goToCelestialObject(entityName)}else if(entityName==='sc_rosetta'){await app.cameraScripts.goToSpacecraft(entityName)}})},onLeave:(app,slide)=>{removeLabelClick(app,'sc_rosetta',goToSpacecraft);removeLabelClick(app,'67p_churyumov_gerasimenko',goToCelestialObject);app.getManager('camera').setSelectionCallback(slide.selectionCallback)}},{id:'slide_3',type:'panel',time:'2001-02-12T18:00:00Z',rate:0,content:[{type:'description',title:'The NEAR Shoemaker mission',description:'orbiting the asteroid Eros'}],camera:[async app=>{const localNonce=++globalNonce;const time=app.getManager('time');await app.getManager('scene').isListReady(['433_eros','sc_near_shoemaker']);if(localNonce!==globalNonce)return;time.pause();await app.cameraScripts.alignObjects('sc_near_shoemaker','433_eros',{duration:3,verticalOffset:15,horizontalOffset:-15,distance:0.05});time.play()}],onEnter:(app,slide)=>{const camera=app.getManager('camera');addLabelClick(app,'sc_near_shoemaker',goToSpacecraft);addLabelClick(app,'433_eros',goToCelestialObject);slide.selectionCallback=camera.getSelectionCallback();camera.setSelectionCallback(async entity=>{const entityName=entity?.getName();if(entityName==='433_eros'){await app.cameraScripts.goToCelestialObject(entityName)}else if(entityName==='sc_near_shoemaker'){await app.cameraScripts.goToSpacecraft(entityName)}})},onLeave:(app,slide)=>{removeLabelClick(app,'sc_near_shoemaker',goToSpacecraft);removeLabelClick(app,'433_eros',goToCelestialObject);app.getManager('camera').setSelectionCallback(slide.selectionCallback)}},{id:'slide_4',type:'panel',time:'2005-07-04T05:44:20Z',content:[{type:'description',title:'The Deep Impact mission',description:'The Deep Impact Impactor on collision course with comet Tempel 1 (9P/Tempel)'}],camera:[async app=>{const localNonce=++globalNonce;const time=app.getManager('time');await app.getManager('scene').isListReady(['9p_tempel_1','sc_deep_impact','sc_deep_impact_impactor']);if(localNonce!==globalNonce)return;time.pause();await app.cameraScripts.alignObjects('sc_deep_impact_impactor','9p_tempel_1',{duration:3,distance:0.005,verticalOffset:15,horizontalOffset:15});time.play()}],onEnter:(app,slide)=>{const maxTime='2005-07-04T05:44:33Z';slide.update=()=>{const time=app.getManager('time');if(time.getTime().valueOf()>=time.parseTime(maxTime).valueOf()){time.pause()}};app.pioneer.addCallback(slide.update,!0);app.getManager('time').setMax(maxTime);const camera=app.getManager('camera');addLabelClick(app,'sc_deep_impact_impactor',goToSpacecraft);addLabelClick(app,'sc_deep_impact',goToSpacecraft);addLabelClick(app,'9p_tempel_1',goToCelestialObject);slide.selectionCallback=camera.getSelectionCallback();camera.setSelectionCallback(async entity=>{const entityName=entity?.getName();if(entityName==='9p_tempel_1'){await app.cameraScripts.goToCelestialObject(entityName)}else if(entityName==='sc_deep_impact_impactor'){await app.cameraScripts.goToSpacecraft(entityName)}})},onLeave:(app,slide)=>{app.pioneer.removeCallback(slide.update);app.getManager('time').resetMax();removeLabelClick(app,'sc_deep_impact_impactor',goToSpacecraft);removeLabelClick(app,'9p_tempel_1',goToCelestialObject);app.getManager('camera').setSelectionCallback(slide.selectionCallback)}},{id:'slide_5',type:'panel',time:'2012-07-21T12:01:00Z',rate:35,content:[{type:'description',title:'The Dawn mission',description:"in orbit around Vesta"}],camera:[async app=>{const localNonce=++globalNonce;const time=app.getManager('time');await app.getManager('scene').isListReady(['4_vesta','sc_dawn']);if(localNonce!==globalNonce)return;time.pause();await app.cameraScripts.goToSpacecraft('sc_dawn',{cinematic:!0,duration:3});time.play()}],onEnter:(app,slide)=>{const camera=app.getManager('camera');addLabelClick(app,'sc_dawn',goToSpacecraft);addLabelClick(app,'4_vesta',goToCelestialObject);slide.selectionCallback=camera.getSelectionCallback();camera.setSelectionCallback(async entity=>{const entityName=entity?.getName();if(entityName==='4_vesta'){await app.cameraScripts.goToCelestialObject(entityName)}else if(entityName==='sc_dawn'){await app.cameraScripts.goToSpacecraft(entityName)}})},onLeave:(app,slide)=>{removeLabelClick(app,'sc_dawn',goToSpacecraft);removeLabelClick(app,'4_vesta',goToCelestialObject);app.getManager('camera').setSelectionCallback(slide.selectionCallback)}},{id:'slide_6',type:'panel',time:'2016-03-18T13:30:00Z',rate:40,content:[{type:'description',title:'The Dawn mission',description:'in orbit around Ceres'}],camera:[async app=>{const localNonce=++globalNonce;const time=app.getManager('time');await app.getManager('scene').isListReady(['1_ceres','sc_dawn']);if(localNonce!==globalNonce)return;time.pause();await app.cameraScripts.goToCelestialObject('1_ceres',{cinematic:!1,duration:3,distance:2});time.play()}],onEnter:(app,slide)=>{const camera=app.getManager('camera');addLabelClick(app,'sc_dawn',goToSpacecraft);addLabelClick(app,'1_ceres',goToCelestialObject);slide.selectionCallback=camera.getSelectionCallback();camera.setSelectionCallback(async entity=>{const entityName=entity?.getName();if(entityName==='1_ceres'){await app.cameraScripts.goToCelestialObject(entityName)}else if(entityName==='sc_dawn'){await app.cameraScripts.goToSpacecraft(entityName)}})},onLeave:(app,slide)=>{removeLabelClick(app,'sc_dawn',goToSpacecraft);removeLabelClick(app,'1_ceres',goToCelestialObject);app.getManager('camera').setSelectionCallback(slide.selectionCallback)}},{id:'slide_7',type:'panel',time:'2003-12-24T00:00:00Z',rate:90,content:[{type:'description',title:'The Stardust mission',description:'flying by the comet Wild 2'}],camera:[async app=>{const localNonce=++globalNonce;const time=app.getManager('time');await app.getManager('scene').isReady('sc_stardust');if(localNonce!==globalNonce)return;time.pause();await app.cameraScripts.goToSpacecraft('sc_stardust',{distance:-0.01,cinematic:!1,duration:3});time.play()}],onEnter:(app,slide)=>{addLabelClick(app,'sc_stardust',goToSpacecraft);addLabelClick(app,'81p_wild_2',goToCelestialObject)},onLeave:(app,slide)=>{removeLabelClick(app,'sc_stardust',goToSpacecraft);removeLabelClick(app,'81p_wild_2',goToCelestialObject)}},{id:'slide_8',type:'panel',time:'2020-10-20T21:50:24Z',content:[{type:'description',title:'The OSIRIS-REx mission',description:'sampling the surface of the asteroid Bennu'}],camera:[async app=>{const localNonce=++globalNonce;const time=app.getManager('time');await app.getManager('scene').isListReady(['101955_bennu','sc_osiris_rex']);if(localNonce!==globalNonce)return;time.pause();await app.cameraScripts.alignObjects('sc_osiris_rex','101955_bennu',{duration:4,distance:0.1,verticalOffset:30,horizontalOffset:-80});time.play()}],onEnter:(app,slide)=>{app.getComponent('settings').toggleLightOptions('flood');const camera=app.getManager('camera');addLabelClick(app,'sc_osiris_rex',goToSpacecraft);addLabelClick(app,'101955_bennu',goToCelestialObject);slide.selectionCallback=camera.getSelectionCallback();camera.setSelectionCallback(async entity=>{if(isLabelClicked){return} + const entityName=entity?.getName();if(entityName==='101955_bennu'){await app.cameraScripts.goToCelestialObject(entityName)}else if(entityName==='sc_osiris_rex'){await app.cameraScripts.goToSpacecraft(entityName)}})},onLeave:(app,slide)=>{app.getComponent('settings').toggleLightOptions('shadow');removeLabelClick(app,'sc_osiris_rex',goToSpacecraft);removeLabelClick(app,'101955_bennu',goToCelestialObject);app.getManager('camera').setSelectionCallback(slide.selectionCallback)}},{id:'slide_9',type:'panel',time:'2029-08-17T01:02:00Z',content:[{type:'description',title:'The Psyche mission',description:'en route to metal asteroid 16 Psyche.'}],camera:[async app=>{const localNonce=++globalNonce;const time=app.getManager('time');await app.getManager('scene').isListReady(['16_psyche','sc_psyche']);if(localNonce!==globalNonce)return;time.pause();await app.cameraScripts.goToSpacecraft('sc_psyche',{cinematic:!0,duration:3,distance:0.05});time.play()}],onEnter:(app,slide)=>{app.getComponent('settings').toggleLightOptions('flood');const camera=app.getManager('camera');addLabelClick(app,'sc_psyche',goToSpacecraft);addLabelClick(app,'16_psyche',goToCelestialObject);slide.selectionCallback=camera.getSelectionCallback();camera.setSelectionCallback(async entity=>{const entityName=entity?.getName();if(entityName==='16_psyche'){await app.cameraScripts.goToCelestialObject(entityName)}else if(entityName==='sc_psyche'){await app.cameraScripts.goToSpacecraft(entityName)}})},onLeave:(app,slide)=>{app.getComponent('settings').toggleLightOptions('shadow');removeLabelClick(app,'sc_psyche',goToSpacecraft);removeLabelClick(app,'16_psyche',goToCelestialObject);app.getManager('camera').setSelectionCallback(slide.selectionCallback)}},{id:'slide_10',type:'panel',time:'2022-09-26T23:14:11Z',content:[{type:'description',title:'The DART mission',description:'impacting the asteroid moon Dimorphos'}],camera:[async app=>{const localNonce=++globalNonce;const time=app.getManager('time');await app.getManager('scene').isListReady(['65803_didymos','dimorphos','sc_dart']);if(localNonce!==globalNonce)return;time.pause();await app.cameraScripts.goToSpacecraft('sc_dart',{cinematic:!1,duration:3,verticalOffset:15});time.play()}],onEnter:(app,slide)=>{app.getManager('time').setMax('2022-09-26T23:14:18.054Z');const camera=app.getManager('camera');addLabelClick(app,'sc_dart',goToSpacecraft);addLabelClick(app,'dimorphos',goToCelestialObject);addLabelClick(app,'65803_didymos',goToCelestialObject);slide.selectionCallback=camera.getSelectionCallback();camera.setSelectionCallback(async entity=>{const entityName=entity?.getName();if(['dimorphos','65803_didymos'].includes(entityName)){await app.cameraScripts.goToCelestialObject(entityName)}else if(entityName==='sc_dart'){await app.cameraScripts.goToSpacecraft(entityName)}})},onLeave:(app,slide)=>{app.getManager('time').resetMax();removeLabelClick(app,'sc_dart',goToSpacecraft);removeLabelClick(app,'dimorphos',goToCelestialObject);removeLabelClick(app,'65803_didymos',goToCelestialObject);app.getManager('camera').setSelectionCallback(slide.selectionCallback)}},{id:'slide_11',type:'panel',content:[{type:'description',description:''}],camera:[async app=>{const localNonce=++globalNonce;const time=app.getManager('time');await app.getManager('scene').isReady('earth');if(localNonce!==globalNonce)return;time.pause();await app.cameraScripts.goToCelestialObject('earth',{cinematic:!0,duration:3});time.play()}]}],onEnter:app=>{app.scene.get('sun','orbitalParticles').setEnabled(!1);app.getManager('layer').toggleLayer('starfield',{category:'Star Field'},!0);window.addEventListener('mousedown',resetLabelClick);window.addEventListener('touchstart',resetLabelClick)},onLeave:app=>{app.scene.get('sun','orbitalParticles').setEnabled(!0);app.getManager('layer').toggleLayer('starfield',{category:'Star Field'},!1);window.removeEventListener('mousedown',resetLabelClick);window.removeEventListener('touchstart',resetLabelClick)}})}),"./src/data/stories/index.js": + /*!***********************************!*\ + !*** ./src/data/stories/index.js ***! + \***********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"STORY_LIST":function(){return _story_list_json__WEBPACK_IMPORTED_MODULE_3__},"STORIES":function(){return STORIES}});var _asteroids_101__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./asteroids_101 */"./src/data/stories/asteroids_101.js");var _asteroids_close_approach__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./asteroids_close_approach */"./src/data/stories/asteroids_close_approach.js");var _asteroids_missions__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./asteroids_missions */"./src/data/stories/asteroids_missions.js");var _story_list_json__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ./story_list.json */"./src/data/stories/story_list.json");const STORIES={asteroids_101:_asteroids_101__WEBPACK_IMPORTED_MODULE_0__["default"],asteroids_close_approach:_asteroids_close_approach__WEBPACK_IMPORTED_MODULE_1__["default"],asteroids_missions:_asteroids_missions__WEBPACK_IMPORTED_MODULE_2__["default"]}}),"./src/internal.js": + /*!*************************!*\ + !*** ./src/internal.js ***! + \*************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"FiltersManager":function(){return _managers_filters_manager__WEBPACK_IMPORTED_MODULE_0__.FiltersManager},"NEOsManager":function(){return _managers_neos_manager__WEBPACK_IMPORTED_MODULE_1__.NEOsManager},"WatchManager":function(){return _managers_watch_manager__WEBPACK_IMPORTED_MODULE_2__.WatchManager},"LinkManager":function(){return _managers_link_manager__WEBPACK_IMPORTED_MODULE_3__.LinkManager},"SelectionManager":function(){return _managers_selection_manager__WEBPACK_IMPORTED_MODULE_4__.SelectionManager},"LabelManager":function(){return _managers_label_manager__WEBPACK_IMPORTED_MODULE_5__.LabelManager},"TrailManager":function(){return _managers_trail_manager__WEBPACK_IMPORTED_MODULE_6__.TrailManager},"AsteroidMenuTop":function(){return _components_asteroid_menu_top_asteroid_menu_top__WEBPACK_IMPORTED_MODULE_7__.AsteroidMenuTop},"AsteroidMenuBottom":function(){return _components_asteroid_menu_bottom_asteroid_menu_bottom__WEBPACK_IMPORTED_MODULE_8__.AsteroidMenuBottom},"AsteroidModals":function(){return _components_asteroid_modals_asteroid_modals__WEBPACK_IMPORTED_MODULE_9__.AsteroidModals},"HomeButton":function(){return _components_home_button_home_button__WEBPACK_IMPORTED_MODULE_10__.HomeButton},"WatchPanel":function(){return _components_watch_panel_watch_panel__WEBPACK_IMPORTED_MODULE_11__.WatchPanel},"AsteroidPanel":function(){return _components_asteroid_panel_asteroid_panel__WEBPACK_IMPORTED_MODULE_12__.AsteroidPanel},"MissionPanel":function(){return _components_mission_panel_mission_panel__WEBPACK_IMPORTED_MODULE_13__.MissionPanel},"FollowingPanel":function(){return _components_following_panel_following_panel__WEBPACK_IMPORTED_MODULE_14__.FollowingPanel},"Countdown":function(){return _components_countdown_countdown__WEBPACK_IMPORTED_MODULE_15__.Countdown},"SplashScreen":function(){return _components_splash_screen_splash_screen__WEBPACK_IMPORTED_MODULE_16__.SplashScreen},"AsteroidsApp":function(){return _app__WEBPACK_IMPORTED_MODULE_17__.AsteroidsApp},"NEO":function(){return _neos__WEBPACK_IMPORTED_MODULE_18__.NEO},"NEOUtils":function(){return _neos__WEBPACK_IMPORTED_MODULE_18__.NEOUtils},"DefinitionOverlay":function(){return _components_definition_overlay_definition_overlay__WEBPACK_IMPORTED_MODULE_19__.DefinitionOverlay},"TimeSlider":function(){return _components_time_slider_time_slider__WEBPACK_IMPORTED_MODULE_20__.TimeSlider},"Breadcrumb":function(){return _components_breadcrumb_breadcrumb__WEBPACK_IMPORTED_MODULE_21__.Breadcrumb},"AsteroidsSettings":function(){return _components_settings_asteroids_settings__WEBPACK_IMPORTED_MODULE_22__.AsteroidsSettings},"Search":function(){return _components_search_search__WEBPACK_IMPORTED_MODULE_23__.Search},"Types":function(){return _types__WEBPACK_IMPORTED_MODULE_24__.Types}});var _managers_filters_manager__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./managers/filters_manager */"./src/managers/filters_manager.js");var _managers_neos_manager__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./managers/neos_manager */"./src/managers/neos_manager.js");var _managers_watch_manager__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./managers/watch_manager */"./src/managers/watch_manager.js");var _managers_link_manager__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ./managers/link_manager */"./src/managers/link_manager.js");var _managers_selection_manager__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! ./managers/selection_manager */"./src/managers/selection_manager.js");var _managers_label_manager__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(/*! ./managers/label_manager */"./src/managers/label_manager.js");var _managers_trail_manager__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(/*! ./managers/trail_manager */"./src/managers/trail_manager.js");var _components_asteroid_menu_top_asteroid_menu_top__WEBPACK_IMPORTED_MODULE_7__=__webpack_require__(/*! ./components/asteroid_menu_top/asteroid_menu_top */"./src/components/asteroid_menu_top/asteroid_menu_top.js");var _components_asteroid_menu_bottom_asteroid_menu_bottom__WEBPACK_IMPORTED_MODULE_8__=__webpack_require__(/*! ./components/asteroid_menu_bottom/asteroid_menu_bottom */"./src/components/asteroid_menu_bottom/asteroid_menu_bottom.js");var _components_asteroid_modals_asteroid_modals__WEBPACK_IMPORTED_MODULE_9__=__webpack_require__(/*! ./components/asteroid_modals/asteroid_modals */"./src/components/asteroid_modals/asteroid_modals.js");var _components_home_button_home_button__WEBPACK_IMPORTED_MODULE_10__=__webpack_require__(/*! ./components/home_button/home_button */"./src/components/home_button/home_button.js");var _components_watch_panel_watch_panel__WEBPACK_IMPORTED_MODULE_11__=__webpack_require__(/*! ./components/watch_panel/watch_panel */"./src/components/watch_panel/watch_panel.js");var _components_asteroid_panel_asteroid_panel__WEBPACK_IMPORTED_MODULE_12__=__webpack_require__(/*! ./components/asteroid_panel/asteroid_panel */"./src/components/asteroid_panel/asteroid_panel.js");var _components_mission_panel_mission_panel__WEBPACK_IMPORTED_MODULE_13__=__webpack_require__(/*! ./components/mission_panel/mission_panel */"./src/components/mission_panel/mission_panel.js");var _components_following_panel_following_panel__WEBPACK_IMPORTED_MODULE_14__=__webpack_require__(/*! ./components/following_panel/following_panel */"./src/components/following_panel/following_panel.js");var _components_countdown_countdown__WEBPACK_IMPORTED_MODULE_15__=__webpack_require__(/*! ./components/countdown/countdown */"./src/components/countdown/countdown.js");var _components_splash_screen_splash_screen__WEBPACK_IMPORTED_MODULE_16__=__webpack_require__(/*! ./components/splash_screen/splash_screen */"./src/components/splash_screen/splash_screen.js");var _app__WEBPACK_IMPORTED_MODULE_17__=__webpack_require__(/*! ./app */"./src/app.js");var _neos__WEBPACK_IMPORTED_MODULE_18__=__webpack_require__(/*! ./neos */"./src/neos.js");var _components_definition_overlay_definition_overlay__WEBPACK_IMPORTED_MODULE_19__=__webpack_require__(/*! ./components/definition_overlay/definition_overlay */"./src/components/definition_overlay/definition_overlay.js");var _components_time_slider_time_slider__WEBPACK_IMPORTED_MODULE_20__=__webpack_require__(/*! ./components/time_slider/time_slider */"./src/components/time_slider/time_slider.js");var _components_breadcrumb_breadcrumb__WEBPACK_IMPORTED_MODULE_21__=__webpack_require__(/*! ./components/breadcrumb/breadcrumb */"./src/components/breadcrumb/breadcrumb.js");var _components_settings_asteroids_settings__WEBPACK_IMPORTED_MODULE_22__=__webpack_require__(/*! ./components/settings/asteroids_settings */"./src/components/settings/asteroids_settings.js");var _components_search_search__WEBPACK_IMPORTED_MODULE_23__=__webpack_require__(/*! ./components/search/search */"./src/components/search/search.js");var _types__WEBPACK_IMPORTED_MODULE_24__=__webpack_require__(/*! ./types */"./src/types.js")}),"./src/managers/filters_manager.js": + /*!*****************************************!*\ + !*** ./src/managers/filters_manager.js ***! + \*****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"FiltersManager":function(){return FiltersManager}});var eyes__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class FiltersManager extends eyes__WEBPACK_IMPORTED_MODULE_1__.BaseManager{constructor(app,scene){super(app,scene);this.state={isFiltering:!1,filters:{asteroids:!1,comets:!1,phos:!1},lastSize:null};this.previousFilters={asteroids:!1,comets:!1,phos:!1};this._app=app;this._eventNames.push('isFilteringChange');this._eventNames.push('lastSizeChange');this._initCallbacks();this.bindFunctions(['getFilters','getLastSize','_matchFunction'])} + _setFiltering(isFiltering){if(this.state.isFiltering!==isFiltering){this.state.isFiltering=isFiltering;this.triggerCallbacks('isFilteringChange',[this.state.isFiltering])}} + _setLastSize(lastSize){if(this.state.lastSize!==lastSize){this.state.lastSize=lastSize;this.triggerCallbacks('lastSizeChange',[this.state.lastSize])}} + get isFiltering(){return this.state.isFiltering} + getFilters(){return this.state.filters} + getPreviousFilters(){return this.previousFilters} + getLastSize(){return this.state.lastSize} + setFilter(filter,on,callback){this.previousFilters=this.state.filters;if(typeof filter==='string'){if(this.state.filters[filter]!=null&&this.state.filters[filter]!==on){this.state.filters[filter]=on;this._filter(callback)}}else{for(const key in filter){if(this.state.filters[key]!==filter[key]){this.state.filters={...this.state.filters,...filter};this._filter(callback);break}}}} + setFilterToReveal(reveal,resetAll,callback){let refilterNeeded=!1;if(reveal.pho!==!0&&this.state.filters.phos===!0){this.state.filters.phos=!1;refilterNeeded=!0} + if(!(this.state.filters.asteroids===!1&&this.state.filters.comets===!1)){if(reveal.asteroid===!0&&this.state.filters.asteroids===!1){this.state.filters.asteroids=!0;refilterNeeded=!0};if(reveal.comet===!0&&this.state.filters.comets===!1){this.state.filters.comets=!0;refilterNeeded=!0}} + if(refilterNeeded){if(resetAll===!0){this.state.filters={asteroids:!1,comets:!1,phos:!1}};this._filter(callback)};return refilterNeeded} + _toggleLayer(key,on){const layerManager=this._app.getManager('layer');const categories={ui:'User Interface',planets:'Planet',asteroids:'Asteroid',comets:'Comet',dwarfPlanets:'Dwarf Planet',spacecraft:'Spacecraft',trails:'Trail',labels:'Label'};if(on==null||(on===!0&&layerManager._layers[key]?.visible===!1)||(on===!1&&layerManager._layers[key]?.visible===!0)){layerManager.toggleLayer(key,{category:categories[key]})}} + _matchFunction(neo){if(this.app.getManager('selection')?._id===neo.pioneerName){return!0} + if(this.state.filters.asteroids&&!this.state.filters.comets&&neo.comet===!0){return!1};if(this.state.filters.comets&&!this.state.filters.asteroids&&neo.comet===!1){return!1};if(this.state.filters.phos&&neo.pho===!1){return!1};return!0} + _filter(callback){const filtersAreActive=(this.state.filters.asteroids||this.state.filters.comets||this.state.filters.phos);this._app.addParticleMatchFunction(this._matchFunction,'filters_manager',!0,(orbitalElements)=>{this._setLastSize((filtersAreActive?orbitalElements.length:this.app.neos.size)||0);this._setFiltering(filtersAreActive);if(typeof callback==='function')callback(this.state.lastSize);});if(!this.state.filters.asteroids&&!this.state.filters.comets){this._toggleLayer('asteroids',!0);this._toggleLayer('comets',!0)}else{this._toggleLayer('asteroids',this.state.filters.asteroids);this._toggleLayer('comets',this.state.filters.comets)} + const{neos}=this._app;const{_itemsByName:sceneEntities}=this.app.scene?._entities||{};const sceneEntityNames=sceneEntities?Array.from(sceneEntities.keys()):[];const foundNeos=[];for(const neoName of neos.keys()){if(sceneEntityNames.includes(neoName)){foundNeos.push(neoName);sceneEntities.get(neoName).setEnabled(this._matchFunction(neos.get(neoName)))}} + const allEntities=this._app.getManager('content')?.getEntityList();for(const sceneEntityName of sceneEntityNames){if(!foundNeos.includes(sceneEntityName)&&allEntities[sceneEntityName]&&['Asteroid','Comet','Dwarf Planet'].includes(allEntities[sceneEntityName].category)){sceneEntities.get(sceneEntityName)?.setEnabled(this._matchFunction({comet:allEntities[sceneEntityName].category==='Comet',pho:!1}))}}}}}),"./src/managers/label_manager.js": + /*!***************************************!*\ + !*** ./src/managers/label_manager.js ***! + \***************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"LabelManager":function(){return LabelManager}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class LabelManager extends eyes__WEBPACK_IMPORTED_MODULE_0__.LabelManager{_getLink(entityName){const link=super._getLink(entityName);return this._app.getManager('link')?.getParsedLink?.(link)||link}}}),"./src/managers/link_manager.js": + /*!**************************************!*\ + !*** ./src/managers/link_manager.js ***! + \**************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"LinkManager":function(){return LinkManager}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class LinkManager extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseManager{getParsedLink(link){const entityName=link.startsWith('/')?link.slice(1):link;const info=this._app?.getManager('content')?.getEntityInfo(entityName);if(info){if(info.id==='sun'){return `/stars/${entityName}`} + if(info.id==='moon'){return `/moons/${entityName}`} + if(info.category==='Spacecraft'){return `/missions/${entityName}`} + if(info.category==='Planet'){return `/planets/${entityName}`}} + return `/${entityName}`}}}),"./src/managers/neos_manager.js": + /*!**************************************!*\ + !*** ./src/managers/neos_manager.js ***! + \**************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"NEOsManager":function(){return NEOsManager}});var eyes__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ../internal */"./src/internal.js");class NEOsManager extends eyes__WEBPACK_IMPORTED_MODULE_1__.BaseManager{createTempNEO(data,scene=this._app.scene,addLabel=!0){const entity=_internal__WEBPACK_IMPORTED_MODULE_2__.NEOUtils.createEntity(data,scene);this._app.getManager('label').addEntity(entity);this._app.getManager('scene').addTempEntity(entity);if(addLabel){const contentManager=this._app.getManager('content');const labelManager=this._app.getManager('label');const{dwarfPlanet,asteroid,comet}=data;const iconClass=asteroid||dwarfPlanet?'asteroid':(comet?'comet':'');labelManager.setLabelProps({getLabelClass:entityName=>`no-select asteroid ${contentManager.getClassName(entityName) ?? ''}`,getIconClass:()=>iconClass},[entity.getName()])} + return entity}}}),"./src/managers/selection_manager.js": + /*!*******************************************!*\ + !*** ./src/managers/selection_manager.js ***! + \*******************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SelectionManager":function(){return SelectionManager}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class SelectionManager extends eyes__WEBPACK_IMPORTED_MODULE_0__.SelectionManager{_getLink(entityName){const link=super._getLink(entityName);return this._app.getManager('link')?.getParsedLink?.(link)||link}}}),"./src/managers/trail_manager.js": + /*!***************************************!*\ + !*** ./src/managers/trail_manager.js ***! + \***************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TrailManager":function(){return TrailManager}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");class TrailManager extends eyes__WEBPACK_IMPORTED_MODULE_0__.TrailManager{toggleTrails(active){super.toggleTrails(active,{scene:this._scene});this.toggleOrbits(active)}}}),"./src/managers/watch_manager.js": + /*!***************************************!*\ + !*** ./src/managers/watch_manager.js ***! + \***************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"WatchManager":function(){return WatchManager}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class WatchManager extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseManager{constructor(app){super(app);this._hasRedirected=null;this._currentTime=pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now();this._nextFiveData=null;this._nextFiveEntities=null;this._nextFiveNames=null;this._labelWeights=null;this._focusEntityNames=null;this._backgroundPlanets=['mercury','venus','mars','jupiter','saturn','uranus','neptune'];this._defaultPlanetTrailWidth=4;this._slideIndex=null;this._dynamoCoverage=null;this._unitType='metric';this._eventNames.push('toggleUnit');this._initCallbacks();this.bindFunctions(['setData','_calculateNextNEOs','_createEntities','_calculateTimeLimits','getNeoNameByIndex','updateURL','toggleUnit'])} + setData(){if(this._nextFiveData){return};const allNEOs=this._app.neos;if(!allNEOs){throw Error('Cannot get NEO data.')} + this._nextFiveData=this._calculateNextNEOs(allNEOs);this._setLabelWeights()} + _setLabelWeights(focusName){this._labelWeights=Object.fromEntries(this._nextFiveData.map(({pioneerName})=>[pioneerName,{category:pioneerName===focusName?'Focus':'Watch'}]));this._app.getManager('label')?.setWeights(this._labelWeights,!1)} + determineSlideIndex(neoName){return neoName?this._nextFiveData.findIndex(neo=>neo.pioneerName===neoName):null} + setSlideIndex(index){this._slideIndex=index} + setAsteroidSelection(){const labelManager=this._app.getManager('label');const asteroidName=this._nextFiveData[this._slideIndex]?.pioneerName??!1;this._setLabelWeights(asteroidName);labelManager.removeClassFromLabels('selected',this._nextFiveNames);const selected=this._nextFiveNames.find(name=>name===asteroidName);selected&&labelManager.addClassToLabels('selected',[selected]);for(const name of this._nextFiveNames){labelManager.triggerCallbacks('hoverchange',[name,name===asteroidName])}} + _calculateNextNEOs(allNEOs,amount=5){const maxDistance=7479893.535;const nextFive=[];const nearestDiffs=[];for(const[_,value]of allNEOs.entries()){const inTheFuture=value.nextClosestApproachTime>this._currentTime;const withinDistance=value.nextClosestApproachDistance(a.nextClosestApproachTime>=b.nextClosestApproachTime)?1:-1)} + _createEntities(){if(this._nextFiveEntities){return Promise.resolve()} + const sceneManager=this._app.getManager('scene');const neosManager=this._app.getManager('neos');const labelManager=this._app.getManager('label');const contentManager=this._app.getManager('content');const trailManager=this._app.getManager('trail');this._nextFiveEntities=this._nextFiveData.map(neo=>neosManager.createTempNEO(neo,sceneManager.main,!1));this._nextFiveNames=this._nextFiveData.map(neo=>neo.pioneerName);this._focusEntityNames=['earth','moon',...this._nextFiveNames];const handleMouseLeave=(e,entityName)=>{if(e.target?.classList?.contains('selected')&&e.target?.classList?.contains('asteroid-watch-label')){return} + labelManager.triggerCallbacks('hoverchange',[entityName,!1])};labelManager.setLabelProps({getLabelClass:entityName=>`no-select asteroid-watch-label ${contentManager.getClassName(entityName) ?? ''}`,getIconClass:()=>'asteroid-watch-icon',getTextClass:()=>'asteroid-watch-text',handleClick:(_,entityName)=>{this.updateURL(entityName)},handleTouch:(_,entityName)=>{if(!this.app.isDragging()&&!this.app.isTouchMax()){this.updateURL(entityName)}},handleMouseLeave},this._nextFiveNames);const trailColorArray=this._app._colors?.neos;trailColorArray&&trailManager.setColor(this._nextFiveNames,new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(...trailColorArray,0.35));return Promise.all(this._nextFiveEntities.map(neoEntity=>neoEntity.getLoadedPromise()))} + _calculateTimeLimits(){const padding=86400*99;const timeManager=this.app.getManager('time');const now=timeManager.getNow();const todayEtTime=timeManager.momentToET(now);const{nextClosestApproachTime:lastApproachTime}=this._nextFiveData[this._nextFiveData.length-1];const largestRemainingTime=lastApproachTime-todayEtTime;const maxPadding=padding-largestRemainingTime;const minET=lastApproachTime-maxPadding;const maxET=lastApproachTime+maxPadding;return new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(minET,maxET)} + restrictEarthCoverage(){const earthController=this._app.scene.getEntity('earth')?.getControllerByType('dynamo');if(!earthController){console.warn('Could not find Earth dynamo.');return} + this._dynamoCoverage=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval();this._dynamoCoverage.copy(earthController.getCoverage());earthController.setCoverage(this._calculateTimeLimits())} + restoreEarthCoverage(){const earthController=this._app.scene.getEntity('earth')?.getControllerByType('dynamo');if(!earthController){console.warn('Could not find Earth dynamo.');return} + earthController.setCoverage(this._dynamoCoverage)} + dimBackgroundLabels(value){const labelManager=this._app.getManager('label');const dimClass='watch-dim';const backgroundLabels=Object.keys(labelManager._labels).filter(labelName=>!this._focusEntityNames?.includes(labelName));if(value){labelManager.addClassToLabels(dimClass,backgroundLabels)}else{labelManager.removeClassFromLabels(dimClass,backgroundLabels)}} + setBgTrailWidthDefault(value=this._defaultPlanetTrailWidth){for(const planetId of this._backgroundPlanets){const entity=this.app.scene.get(planetId);if(entity?.trailHover?.width?.default){entity.trailHover.width.default=[value,value]}} + if(value===this._defaultPlanetTrailWidth){const trailManager=this._app.getManager('trail');trailManager.setMultipleWidths(this._backgroundPlanets,value,value)}} + getNeoNameByIndex(index){return this._nextFiveData?.[index]?.pioneerName} + updateURL(neoName,removeQuery=!1){const routeManager=this._app.getManager('router');const options={...removeQuery&&{__remove:'all',keepTime:!1}};routeManager.navigate({},`/watch/${neoName}`,options)} + onWatchClick(){const transitioning=this._app.getManager('camera')?._isTransitioning;if(transitioning){return} + const inWatchView=this._app.getManager('router').currentView==='watch';if(this._nextFiveData&&!inWatchView){const index=this.slideIndex===null?0:this.slideIndex;const removeQuery=!0;this.setSlideUrlByIndex(index,removeQuery)}else{this._app.getManager('router').navigate({},'watch',{__remove:'all',keepTime:!1})}} + setSlideUrlByIndex(index,removeQuery=!1){const neoName=this.getNeoNameByIndex(index);this.updateURL(neoName,removeQuery);return neoName} + removeReferences(){this._app.getManager('label')?.removeWeights(this._labelWeights);this._labelWeights=null;this.setSlideIndex(null);this._nextFiveEntities=null} + setHasRedirected(value){this._hasRedirected=value} + get hasRedirected(){return this._hasRedirected} + get defaultPlanetTrailWidth(){return this._defaultPlanetTrailWidth} + get backgroundPlanets(){return this._backgroundPlanets} + get slideIndex(){return this._slideIndex} + get nextFiveData(){return this._nextFiveData} + get nextFiveEntities(){return this._nextFiveEntities} + toggleUnit(unitType){unitType=unitType||this._unitType==='metric'?'imperial':'metric';if(['metric','imperial'].includes(unitType)){if(this._unitType!==unitType){this._unitType=unitType;this.triggerCallbacks('toggleUnit',[unitType])}}} + get unitType(){return this._unitType}}}),"./src/neos.js": + /*!*********************!*\ + !*** ./src/neos.js ***! + \*********************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"NEO":function(){return NEO},"NEOUtils":function(){return NEOUtils}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");class NEO{constructor(){this.name='';this.pioneerName='';this.orbitClass='';this.asteroid=!1;this.comet=!1;this.dwarfPlanet=!1;this.neo=!1;this.pho=!1;this.hasSPK=!1;this.absoluteMagnitude=0;this.diameter=0;this.diameterEstimated=!1;this.moid=0;this.spinRate=0;this.spinRateEstimated=!1;this.spinAxis=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();this.spinAxisEstimated=!1;this.nextClosestApproachTime=0;this.nextClosestApproachDistance=0;this.orbitalElements=new pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements()}} + class NEOUtils{static async loadNEOs(pioneer){const neos=new Map();const loadPromises=[];const urls=[];for(let n=0;n<10;n++){urls.push(`neos.${n}.v1.dat`)} + urls.push('dwarf_planets.v1.dat');urls.push('custom.v1.dat');for(const url of urls){loadPromises.push(pioneer.getDownloader().download(`$DYNAMIC_ASSETS_URL/ssd/${url}`,!0).then(async(download)=>{if(download.status==='cancelled'){return Promise.resolve()}else if(download.status==='failed'){return Promise.reject(new Error('Failed to load asteroid file "'+download.url+'": '+download.errorMessage))} + if(!(download.content instanceof ArrayBuffer)){return Promise.reject(new Error('Failed to load asteroid file "'+download.url+'": Not a binary file.'))} + const reader=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content);const version=reader.readUInt16();if(version!==1){throw new Error('Invalid version.')} + const numNEOs=reader.readUInt32();for(let i=0;i>6)===0;neo.comet=((flags&0xc0)>>6)===1;neo.dwarfPlanet=((flags&0xc0)>>6)===2;neo.neo=((flags&0x20)>>5)===1;neo.pho=((flags&0x10)>>4)===1;neo.hasSPK=((flags&0x08)>>3)===1;neo.diameterEstimated=((flags&0x01)>>0)===1;neo.absoluteMagnitude=reader.readFloat32();neo.diameter=reader.readFloat32();if(Number.isNaN(neo.diameter)){neo.diameter=0.652999997138977} + if(neo.neo){neo.moid=reader.readFloat32();neo.nextClosestApproachTime=reader.readFloat32();neo.nextClosestApproachDistance=reader.readFloat32()} + neo.orbitalElements.epoch=reader.readFloat32();neo.orbitalElements.eccentricity=reader.readFloat32();neo.orbitalElements.semiMajorAxis=reader.readFloat32();neo.orbitalElements.meanAngularMotion=reader.readFloat32();neo.orbitalElements.meanAnomalyAtEpoch=reader.readFloat32();neo.orbitalElements.orbitOrientation.set(reader.readFloat32(),reader.readFloat32(),reader.readFloat32(),reader.readFloat32());const hasSpinRate=(flags&0x04)>>2;const hasSpinAxis=(flags&0x02)>>1;if(hasSpinRate){neo.spinRate=reader.readFloat32();neo.spinRateEstimated=!1}else{neo.spinRate=0.0075092;neo.spinRateEstimated=!0} + if(hasSpinAxis){neo.spinAxis.set(reader.readFloat32(),reader.readFloat32(),reader.readFloat32());neo.spinAxisEstimated=!1}else{neo.spinAxis.set(0,0,1);neo.spinAxisEstimated=!0} + neo.pioneerName=neo.name.replace(/[- /]/g,'_');neo.pioneerName=neo.pioneerName.replace(/[^a-zA-Z0-9_]/g,'');neo.pioneerName=neo.pioneerName.toLowerCase();neos.set(neo.pioneerName,neo)}}))} + await Promise.all(loadPromises);neos.set('dimorphos',{...neos.get('65803_didymos'),name:'Dimorphos',pioneerName:'dimorphos',diameter:0.170});return neos} + static getNextClosestApproaches(neos,n){const nextClosestApproachNEOs=([]);const now=pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.now();for(const entry of neos){const neo=entry[1];if(neo.nextClosestApproachDistance<7479893.535&&(nextClosestApproachNEOs.length===0||neo.nextClosestApproachTime=now){const indexToInsert=pioneer__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(neo.nextClosestApproachTime,nextClosestApproachNEOs,(neo,time)=>neo.nextClosestApproachTimen){nextClosestApproachNEOs.pop()}}} + return nextClosestApproachNEOs.map(neo=>neo.pioneerName)} + static createEntity(neo,scene){let entity=(null);if(pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.getEntityOptions(neo.pioneerName)!==undefined){entity=pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.create(neo.pioneerName,scene)}else{const options={radius:neo.diameter/2,label:neo.name,parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:31536000/2},model:{url:'$STATIC_ASSETS_URL/models/generic/'+asteroidUrls[Math.floor(Math.random()*3)],scale:[neo.diameter/2,neo.diameter/2,neo.diameter/2]},controllers:[{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity},{type:'spin',axis:neo.spinAxis,periodInHours:Math.PI/neo.spinRate/3600,relativeToTime:0},{type:'custom',func:(entity)=>{const controller=(entity.addController('orbitalElements'));controller.addOrbitalElements(-3155716758.816,neo.orbitalElements);if(neo.nextClosestApproachDistance!==0||isNaN(neo.nextClosestApproachTime)){controller.addOrbitalElements(3155716758.816,neo.orbitalElements)}else{controller.addOrbitalElements(neo.nextClosestApproachTime,neo.orbitalElements)} + return controller}}]};if(neo.hasSPK){options.controllers.push({type:'dynamo',url:`ssd/${neo.pioneerName}/earth/orb/`})} + entity=pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.createFromOptions(neo.pioneerName,options,scene);if(neo.hasSPK){const dynamoController=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.DynamoController);dynamoController.getLoadedPromise().then(()=>{entity.addParentingTableEntry(dynamoController.getCoverage().min,'earth');entity.addParentingTableEntry(dynamoController.getCoverage().max,neo.nextClosestApproachDistance!==0?'sun':'');if(neo.nextClosestApproachDistance===0){const oeController=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitalElementsController);oeController.removeOrbitalElements(1);oeController.addOrbitalElements(dynamoController.getCoverage().max,neo.orbitalElements)}})}} + return entity}} + const asteroidUrls=['asteroid_1/generic_asteroid_1.gltf','asteroid_2/generic_asteroid_2.gltf','asteroid_3/generic_asteroid_3.gltf']}),"./src/types.js": + /*!**********************!*\ + !*** ./src/types.js ***! + \**********************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Types":function(){return eyes__WEBPACK_IMPORTED_MODULE_0__.Types}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./internal */"./src/internal.js");eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('SelectionManager',_internal__WEBPACK_IMPORTED_MODULE_1__.SelectionManager);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('LabelManager',_internal__WEBPACK_IMPORTED_MODULE_1__.LabelManager);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('TrailManager',_internal__WEBPACK_IMPORTED_MODULE_1__.TrailManager);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidsSettings',_internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidsSettings);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidMenuTop',_internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidMenuTop);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidMenuBottom',_internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidMenuBottom);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidModals',_internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidModals);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidMenuTop',_internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidMenuTop);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidMenuBottom',_internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidMenuBottom);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('AsteroidPanel',_internal__WEBPACK_IMPORTED_MODULE_1__.AsteroidPanel);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('Breadcrumb',_internal__WEBPACK_IMPORTED_MODULE_1__.Breadcrumb);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('DefinitionOverlay',_internal__WEBPACK_IMPORTED_MODULE_1__.DefinitionOverlay);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('FollowingPanel',_internal__WEBPACK_IMPORTED_MODULE_1__.FollowingPanel);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('HomeButton',_internal__WEBPACK_IMPORTED_MODULE_1__.HomeButton);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('MissionPanel',_internal__WEBPACK_IMPORTED_MODULE_1__.MissionPanel);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('SplashScreen',_internal__WEBPACK_IMPORTED_MODULE_1__.SplashScreen);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('TimeSlider',_internal__WEBPACK_IMPORTED_MODULE_1__.TimeSlider);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('WatchPanel',_internal__WEBPACK_IMPORTED_MODULE_1__.WatchPanel);eyes__WEBPACK_IMPORTED_MODULE_0__.Types.set('Search',_internal__WEBPACK_IMPORTED_MODULE_1__.Search)}),"./src/views/asteroid_view.js": + /*!************************************!*\ + !*** ./src/views/asteroid_view.js ***! + \************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"AsteroidView":function(){return AsteroidView}});var _base_view__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./base_view */"./src/views/base_view.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");class AsteroidView extends _base_view__WEBPACK_IMPORTED_MODULE_0__["default"]{constructor(...args){super(...args);this._rules.spaceObject={value:name=>Boolean(this._app.neos.get(name)?.pioneerName)};this._asteroidPanel=null;this._target=null;this._neoData=null;this._heroData=null;this._entityInfo=null;this.filtersManager=null} + async onEnter(params){this.addUIexcludedComponents(['asteroid_modals','definitionOverlay','clock','clockShortcut','asteroid_menu_bottom']);this.filtersManager=this._app.getManager('filters');this._asteroidPanel??=this._app.getComponent('asteroidPanel');await super.onEnter(params);this._mainViewportEl.style.top='';this._mainViewportEl.style.left=''} + onLeave(params){this._app.removeParticleMatchFunction('asteroid_view',!0);if(params&¶ms.cancelToken&¶ms.cancelToken.isCanceled){return} + this._asteroidPanel.hide();this._mainViewportEl.style.top='0px';this._mainViewportEl.style.left='0px';super.onLeave(params)} + _reset(params){super._reset(params);this._target=null;this._neoData=null;this._heroData=null;this._entityInfo=null} + registerCallbacks(){super.registerCallbacks();this._asteroidPanel.registerCallback('expandtoggle',this._onExpandToggle)} + removeCallbacks(){super.removeCallbacks();this._asteroidPanel.removeCallback('expandtoggle',this._onExpandToggle)} + async _updateResources({spaceObject}){const contentManager=this._app.getManager('content');this._target=spaceObject;this._neoData=this._allNEOs.get(this._target);this._heroData=this._allHeroes[this._neoData.pioneerName];this._entityInfo=contentManager.getEntityInfo(this._target);let targetEntity=this._app.scene.getEntity(this._target);if(!targetEntity){targetEntity=this._app.getManager('neos').createTempNEO(this._neoData)}else if(!targetEntity._enabled){const entry=this._app.getManager('search').getEntry(this._target);if(entry.neo){this.filtersManager.setFilterToReveal(entry.neo,!0)}} + const currentTime=this.app.pioneer.getTime();let startTime=currentTime;if(currentTime=targetEntity.getPositionCoverage().max-3600){startTime=targetEntity.getPositionCoverage().max-3600} + const startDateTime=new pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.DateTime();startDateTime.fromET(startTime);this.app.pioneer.setTime(currentTime);const{nextClosestApproachTime}=this._neoData;if(nextClosestApproachTime!=0&&nextClosestApproachTimeneo.pioneerName!==this._target,'asteroid_view',!0);this._app.getManager('layer').setTarget(this._target);this._app.getManager('selection').selectEntity(this._target);contentManager.resetContext();this._entityInfo&&await contentManager.loadDescriptions([this._target])} + async _updateComponents(params){this._asteroidPanel.populate(this._neoData,this._heroData);super._updateComponents(params)} + async _updateComponentsVisibility(params){await super._updateComponentsVisibility(params);this._updateTimeSliderPosition();const visibleUI=this._app.getManager('layer').getLayer('ui').visible;visibleUI&&this._asteroidPanel.show();this._app.getComponent('asteroid_menu_bottom')?.hide()} + async _updateCamera(params){await this._app.cameraScripts.goToCelestialObject(this._target)} + resize(){super.resize();const isExpanded=this._asteroidPanel?._state.isExpanded;this._onExpandToggle(isExpanded)}}}),"./src/views/base_view.js": + /*!********************************!*\ + !*** ./src/views/base_view.js ***! + \********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"default":function(){return ExtendedBaseView}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");var pioneer__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class ExtendedBaseView extends eyes__WEBPACK_IMPORTED_MODULE_0__.BaseView{constructor(app,element,components=[]){super(app,element,components);this._UIexcludedComponents=null;this.resetUIexcludedComponents();this._floatMid=null;this._floatMidBottom=null;this._pioneerParentEl=null;this._mainViewportEl=null;this._allNEOs=null;this._allHeroes=null;this._lastTime=null;this._rules.redirect=name=>{const router=this._app.getManager('router');const parsedLink=this._app.getManager('link')?.getParsedLink?.(name);const parsedLinkIsValid=parsedLink!==`/${name}`;if(parsedLinkIsValid){router.navigate(parsedLink)}else if(name==='asteroids'){router.navigate(router.homeRoute)}else{console.warn(`No object with name, ${name}.`);router.navigate(router._previousRoute?.url||'');this._app.getComponent('search').simulate(name)}};this.bindFunctions(['_onExpandToggle'])} + async onEnter(params,unsubscribed=[]){this._mainViewportEl=this._app.pioneer?.getViewport('main-viewport')?.getDiv();this._pioneerParentEl=document.getElementById('pioneer');this._allNEOs??=this._app.neos;this._allHeroes??=this._app.heroes;await super.onEnter(params,unsubscribed);const visibleUI=this._app.getManager('layer').getLayer('ui').visible;this.toggleViewUI(visibleUI,!1)} + _showControls(){this._app.getComponent('clock').show();this._app.getComponent('clockShortcut').show();this._app.getComponent('settings').show();this._floatMidBottom=this._floatMidBottom||document.getElementById('float-mid-bottom');this._floatMid=this._floatMid||document.getElementById('float-mid');this._floatMidBottom.classList.remove('hidden');this._floatMidBottom.classList.add('active');if(eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode()){this._floatMid.classList.add('low')}else{this._floatMid.classList.remove('hidden');this._floatMid.classList.remove('low')}} + _hideControls(){if(eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode()){this._app.getComponent('clock').hide();this._app.getComponent('clockShortcut').hide();this._app.getComponent('settings').hide();this._floatMidBottom=this._floatMidBottom||document.getElementById('float-mid-bottom');this._floatMid=this._floatMid||document.getElementById('float-mid');this._floatMidBottom.classList.add('hidden');this._floatMidBottom.classList.remove('active');this._floatMid.classList.remove('low')}} + async onQueryChange(params){super.onQueryChange(params);this._callQueryChanges(params)} + _updateComponents(params){this._app.getComponent('breadcrumb')?.onRouteChange({...params});this._app.getComponent('settings').setConfig({orientation:{smallLandscape:{ori:'vertical'}}});this._callQueryChanges(params)} + async _updateTime(params){this._lastTime=this.app.pioneer.getTime();await super._updateTime(params)} + async _checkReady(params){const{cameraEntity}=this.app.getManager('camera');const initialEntity=cameraEntity.getParent();const targetEntity=this.app.scene.get(this._target);if(initialEntity&&targetEntity){const time=this.app.pioneer.getTime();const lca=initialEntity.getLowestCommonAncestorAtTime(targetEntity,time);if(lca===null){const tempEntityName=`${initialEntity.getName()}_temp`;const initialPosCopy=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3();initialPosCopy.copy(initialEntity.getPosition());const tempEntity=pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.createFromOptions(tempEntityName,{radius:initialEntity.getExtentsRadius(),parents:[[Number.NEGATIVE_INFINITY,'sun']]},this.app.scene);tempEntity.setPosition(initialPosCopy);const tempParentName=initialEntity.getParentAtTime(this._lastTime)??'sun';const tempParent=this.app.scene.get(tempParentName);tempEntity.setParent(tempParent);cameraEntity.setParent(tempEntity);this.app.getManager('scene').addTempEntity(tempEntity)}} + await super._checkReady(params);this.app.endLoadingScreen()} + _callQueryChanges(params){const router=this.app.getManager('router');const prevQueries=router.parseQuery(router.previousRoute.query);const{modal,definition,tutorial,rate}={...params,...prevQueries};if(modal){this.app.getComponent('asteroid_menu_top')?.onQueryChange(params);this.app.getComponent('asteroid_modals')?.onQueryChange(params)} + definition&&this.app.getComponent('definitionOverlay')?.onQueryChange(params);tutorial&&this.app.getComponent('tutorialOverlay')?.onQueryChange(params);rate!==undefined&&this.app.getComponent('timeSlider')?.onQueryChange(params)} + onLeave(params){this.resetUIexcludedComponents();super.onLeave(params)} + _shouldResetStatus(){return!0} + addUIexcludedComponents(componentNames){this._UIexcludedComponents.push(...componentNames)} + resetUIexcludedComponents(){this._UIexcludedComponents=['breadcrumb','settings','loadIcon','layerPanel']} + toggleViewUI(showUI=this._app.getManager('layer').getLayer('ui').visible,initSwiper=!0){this._app.getComponent('layerPanel').hide();this._components.forEach(componentName=>{if(this._UIexcludedComponents.includes(componentName)){return} + if(this.app.getManager('router')._alwaysHiddenComponents?.includes(componentName)){return} + const component=this._app.getComponent(componentName);const isStory=componentName==='story';if(showUI){component.setEnabled(!0);component.show(initSwiper);isStory&&component.resize()}else{component.hide()}});const extendedControlsDiv=document.getElementById('extended-controls');if(extendedControlsDiv)extendedControlsDiv.style.display=showUI?'grid':'none'} + get shouldOffsetRight(){return!eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobilePortrait()} + get shouldOffsetUp(){return eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobilePortrait()} + _onExpandToggle(expanded,updateTimeSlider=!0){updateTimeSlider&&this._updateTimeSliderPosition({expanded});const loadIconEl=this._app.getComponent('loadIcon')?.element;const offsetRight=this.shouldOffsetRight&&expanded;this._pioneerParentEl?.classList.toggle('offset-right',offsetRight);this._mainViewportEl?.classList.toggle('offset-right',offsetRight);loadIconEl?.classList.toggle('offset-right',offsetRight);const offsetUp=this.shouldOffsetUp&&expanded;this._pioneerParentEl?.classList.toggle('offset-up',offsetUp);this._mainViewportEl?.classList.toggle('offset-up',offsetUp);loadIconEl?.classList.toggle('offset-up',offsetUp);const settings=this._app.getComponent('settings');if(offsetUp){settings?.hide()}else{settings?.show()}} + _updateTimeSliderPosition(options={}){this._app.getComponent('timeSlider')?.toggleExtraClasses(options)}}}),"./src/views/following_view.js": + /*!*************************************!*\ + !*** ./src/views/following_view.js ***! + \*************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"FollowingView":function(){return FollowingView}});var _base_view__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./base_view */"./src/views/base_view.js");class FollowingView extends _base_view__WEBPACK_IMPORTED_MODULE_0__["default"]{constructor(...args){super(...args);this._rules={...this._rules,planet:{value:name=>this._app.getManager('content')?.getEntityInfo(name)?.category==='Planet'},moon:{value:name=>this._app.getManager('content')?.getEntityInfo(name)?.id==='moon'},sun:{value:name=>this._app.getManager('content')?.getEntityInfo(name)?.id==='sun'}};this._followingPanel=null;this._entityInfo=null} + async onEnter(params){this.addUIexcludedComponents(['asteroid_modals','definitionOverlay','clock','clockShortcut','asteroid_menu_bottom']);this._followingPanel??=this._app.getComponent('followingPanel');await super.onEnter(params)} + onLeave(params){this._followingPanel.hide();super.onLeave(params)} + _reset(params){super._reset(params);const{planet,star,moon}=params;this._target=planet||star||moon} + async _updateResources(params){this._app.getManager('layer').setTarget(this._target);this._app.getManager('selection').selectEntity(this._target)} + async _updateComponents(params){const info=this._app.getManager('content')?.getEntityInfo(this._target);this._followingPanel.setState({title:info.iauName||info.displayName});super._updateComponents(params)} + async _updateComponentsVisibility(params){await super._updateComponentsVisibility(params);this._updateTimeSliderPosition();const visibleUI=this._app.getManager('layer').getLayer('ui').visible;visibleUI&&this._followingPanel.show();this._app.getComponent('asteroid_menu_bottom')?.hide()} + async _updateCamera(){await this._app.cameraScripts.goToCelestialObject(this._target)} + resize(){super.resize();this._onExpandToggle(!1)}}}),"./src/views/home_view.js": + /*!********************************!*\ + !*** ./src/views/home_view.js ***! + \********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"HomeView":function(){return HomeView}});var _base_view__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./base_view */"./src/views/base_view.js");class HomeView extends _base_view__WEBPACK_IMPORTED_MODULE_0__["default"]{async onEnter(params){this.addUIexcludedComponents(['splashScreen','asteroid_modals','definitionOverlay','clock','clockShortcut','tutorialOverlay']);this._updateTimeSliderPosition();this._app.getComponent('asteroid_menu_bottom')?.show();const unsubscribed=[];if(this._app.getComponent('splashScreen')?.element===null){unsubscribed.push('splashScreen')};await super.onEnter(params,unsubscribed)} + _updateResources(params){this._app.getManager('time').resetLimits();this._app.getManager('layer').setTarget('');this._target='sun'} + async _updateCamera(params){await this.app.cameraScripts.goToSystem('inner_solar_system')} + resize(){super.resize();this._updateTimeSliderPosition()}}}),"./src/views/index.js": + /*!****************************!*\ + !*** ./src/views/index.js ***! + \****************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _asteroid_view__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./asteroid_view */"./src/views/asteroid_view.js");var _mission_view__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./mission_view */"./src/views/mission_view.js");var _following_view__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./following_view */"./src/views/following_view.js");var _watch_view__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ./watch_view */"./src/views/watch_view.js");var _home_view__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! ./home_view */"./src/views/home_view.js");var _story_view__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(/*! ./story_view */"./src/views/story_view.js");__webpack_exports__["default"]=({AsteroidView:_asteroid_view__WEBPACK_IMPORTED_MODULE_0__.AsteroidView,MissionView:_mission_view__WEBPACK_IMPORTED_MODULE_1__.MissionView,FollowingView:_following_view__WEBPACK_IMPORTED_MODULE_2__.FollowingView,WatchView:_watch_view__WEBPACK_IMPORTED_MODULE_3__.WatchView,HomeView:_home_view__WEBPACK_IMPORTED_MODULE_4__.HomeView,StoryView:_story_view__WEBPACK_IMPORTED_MODULE_5__.StoryView})}),"./src/views/mission_view.js": + /*!***********************************!*\ + !*** ./src/views/mission_view.js ***! + \***********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"MissionView":function(){return MissionView}});var _base_view__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./base_view */"./src/views/base_view.js");class MissionView extends _base_view__WEBPACK_IMPORTED_MODULE_0__["default"]{constructor(...args){super(...args);this._rules.spacecraft={value:name=>this._app.getManager('content')?.getEntityInfo(name)?.category==='Spacecraft'};this._missionPanel=null;this._entityInfo=null;this.filtersManager=null} + async onEnter(params){this.addUIexcludedComponents(['asteroid_modals','definitionOverlay','clock','clockShortcut','asteroid_menu_bottom']);this.filtersManager=this._app.getManager('filters');this._missionPanel??=this._app.getComponent('missionPanel');await super.onEnter(params);this._mainViewportEl.style.top='';this._mainViewportEl.style.left=''} + onLeave(params){if(params&¶ms.cancelToken&¶ms.cancelToken.isCanceled){return} + this._missionPanel.hide();this._mainViewportEl.style.top='0px';this._mainViewportEl.style.left='0px';super.onLeave(params)} + registerCallbacks(){super.registerCallbacks();this._missionPanel.registerCallback('expandtoggle',this._onExpandToggle)} + removeCallbacks(){super.removeCallbacks();this._missionPanel.removeCallback('expandtoggle',this._onExpandToggle)} + _reset(params){super._reset(params);this._target=null;this._entityInfo=null} + async _updateResources({spacecraft}){const contentManager=this._app.getManager('content');this._target=spacecraft;this._entityInfo=contentManager.getEntityInfo(this._target);await this._app.getManager('content').loadDescriptions([this._target]);await this._app.getManager('content').loadEvents(this._target,{all:'all_events'});this._app.getManager('layer').setTarget(this._target);this._app.getManager('selection').selectEntity(this._target);if(this._entityInfo===null){this._handleError(`MissionView._updateResources: Cannot find entity named ${this._target}.`);return} + if(this._entityInfo?.related){this.filtersManager.setFilterToReveal(Object.keys(this._entityInfo.related).filter((r)=>this._entityInfo.related[r].length>0).reduce((acc,cur)=>{acc[cur]=!0;return acc},{}),!0)}} + async _updateComponents(params){const contentManager=this._app.getManager('content');const blurb=contentManager.context[this._target]?.description?.blurb;const events=contentManager.context?.events;const{iauName,displayName}=this._entityInfo;const title=iauName||displayName;this._missionPanel.populate(title,blurb,this._target,events);super._updateComponents(params)} + async _updateComponentsVisibility(params){await super._updateComponentsVisibility(params);this._updateTimeSliderPosition();const visibleUI=this._app.getManager('layer').getLayer('ui').visible;visibleUI&&this._missionPanel.show();this._app.getComponent('asteroid_menu_bottom')?.hide()} + async _updateCamera(params){const hasLanded=this._app.getManager('content').hasLanded(this._entityInfo);if(hasLanded){await this._app.cameraScripts.alignSpacecraftPlanet(this._target)}else{await this._app.cameraScripts.goToSpacecraft(this._target)}} + resize(){super.resize();const isExpanded=this._missionPanel?._state.isExpanded;this._onExpandToggle(isExpanded)}}}),"./src/views/story_view.js": + /*!*********************************!*\ + !*** ./src/views/story_view.js ***! + \*********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"StoryView":function(){return StoryView}});var eyes__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! eyes */"../eyes/src/index.js");var _base_view__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./base_view */"./src/views/base_view.js");class StoryView extends _base_view__WEBPACK_IMPORTED_MODULE_1__["default"]{constructor(...args){super(...args);this._story=null;this._rules.id={value:val=>val in this._app.getManager('content').getStoryList().stories};this._onLeaveCallbacks=[]} + async onQueryChange(params){this._app.getComponent('definitionOverlay')?.onQueryChange(params);await super.onQueryChange(params);await this._updateTime(params);await this._app.getComponent('story').onQueryChange(params);await this._updateCamera(params)} + async onEnter(params,unsubscribed=[]){this.addUIexcludedComponents(['asteroid_modals','overlay','definitionOverlay','clock','clockShortcut','asteroid_menu_bottom']);const storyComponent=this._app.getComponent('story');storyComponent.hide();await super.onEnter(params,unsubscribed);const visibleUI=this._app.getManager('layer').getLayer('ui').visible;visibleUI&&storyComponent.show();const layerManager=this._app.getManager('layer');const layerPanel=this._app.getComponent('layerPanel');if(!layerManager.getLayer('spacecraft').visible){layerPanel.toggleLayer('spacecraft')} + if(!layerManager.getLayer('planets').visible){layerPanel.toggleLayer('planets')} + layerPanel.setCategoryEnabled('spacecraft',!1);this._app.getManager('filters')?.setFilter({phos:!1,asteroids:!1,comets:!1});const clock=this._app.getComponent('clock');clock.setState({allowEdit:!1});clock.toggle('time',!1);clock.toggle('meridiem',!1);this._app.getManager('label').setClickable(!1);this._app.getManager('selection').setClickable(!1);this._app.getComponent('timeSlider')?.setSliderVisibility(!1)} + async onLeave(params){super.onLeave(params);await this._story?.onLeave?.(this._app);await this._app.getComponent('story').onLeave();const clock=this._app.getComponent('clock');clock.setState({allowEdit:!0});clock.toggle('time',!0);clock.toggle('meridiem',!0);this._app.getManager('label').setClickable(!0);this._app.getManager('selection').setClickable(!0);this._app.getComponent('timeSlider')?.setSliderVisibility(!0);this._app.getComponent('layerPanel')?.setCategoryEnabled('spacecraft',!0);for(let i=0;islide.id===params.slide):this._story.slides[0];const{min,max}=slideInfo?.timeLimits||{};min&&timeManager.setMin(min);max&&timeManager.setMin(max);if(!params.time&&slideInfo.time){timeManager.setTime(slideInfo.time);await this._app.pioneer.waitUntilNextFrame()}} + _shouldHideControls(){return eyes__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode()&&this._app.getComponent('story').getState('isVisible')} + async _updateComponents(params){super._updateComponents(params);const settings=this._app.getComponent('settings');const{allowInfoPanel}=settings.getConfig();this._onLeaveCallbacks.push(()=>{settings.setConfig({allowInfoPanel})});settings.setConfig({allowInfoPanel:!1});const storyComponent=this._app.getComponent('story');await storyComponent.onRouteChange(this._story.slides,params);storyComponent.show()} + async _updateCamera(params){const slideInfo=params.slide?this._story.slides.find(slide=>slide.id===params.slide):this._story.slides[0];if(slideInfo&&slideInfo.camera){const story=this._app.getComponent('story');if(story.getState('previousIndex')!==story.getState('currentIndex')){const preset=slideInfo.camera[0];await preset(this._app)}}else{await this._app.cameraScripts.goToSystem('outer_solar_system')}}}}),"./src/views/watch_view.js": + /*!*********************************!*\ + !*** ./src/views/watch_view.js ***! + \*********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"WatchView":function(){return WatchView}});var _base_view__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./base_view */"./src/views/base_view.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class WatchView extends _base_view__WEBPACK_IMPORTED_MODULE_0__["default"]{constructor(...args){super(...args);this._rules.neoName={value:name=>Boolean(this._app.neos.get(name)?.pioneerName)};this._watchManager=null;this._watchPanel=null;this.filtersManager=null} + async onRouteChange(params){const missingNeoName=params.neoName===undefined;const cameFromOutside=this._app.getManager('router').previousView!=='watch'&&missingNeoName;let slideIndex=this._watchManager.determineSlideIndex(params.neoName);const alreadyPassed=slideIndex===-1;const notInDatabase=params.neoName&&!this._app.scene.get(params.neoName);if(cameFromOutside||alreadyPassed||notInDatabase){if(notInDatabase){console.warn(`Asteroid, ${params.neoName} is not in the database. Re-directing to Next Closest Approach.`)}else if(alreadyPassed){console.warn(`Asteroid, ${params.neoName} has safely passed earth. Re-directing to Next Closest Approach.`)} + slideIndex=0;this._watchManager.setHasRedirected(!0);this._watchManager.setSlideUrlByIndex(slideIndex);return} + const{neoName}=params;this._watchPanel.shouldBeExpanded=Boolean(neoName);this._watchManager.setSlideIndex(slideIndex);const swiper=this._watchPanel._swiper;if(neoName&&swiper){const{realIndex}=swiper;if(slideIndex!==null&&slideIndex!==realIndex){swiper.slideTo(slideIndex,undefined,!1)}} + await this._entitiesLoadedPromise;this._watchManager.setAsteroidSelection();await super.onRouteChange(params)} + async onEnter(params){this.filtersManager=this._app.getManager('filters');this._app.getComponent('asteroid_menu_top')?.toggleActive('Asteroid Watch',!0);this._watchManager=this._app.getManager('watch');this._watchManager.setData();const{nextFiveData}=this._watchManager;this._entitiesLoadedPromise=this._watchManager._createEntities();if(!this._watchPanel){this._watchPanel=this._app.getComponent('watchPanel')} + if(!this._watchPanel._swiper){this._watchPanel.populate(nextFiveData);this._watchPanel.initSwiper()} + this._watchManager.restrictEarthCoverage();this._watchManager.dimBackgroundLabels(!0);this._watchManager.setBgTrailWidthDefault(0);this._app.getManager('selection').setClickable(!1);const labelManager=this._app.getManager('label');labelManager.setLabelClickable('earth',!1);this.filtersManager.setFilter({asteroids:!1,comets:!1,phos:!1});this.app.getComponent('filtersModal').handleResetFilters();this.addUIexcludedComponents(['asteroid_modals','definitionOverlay','clock','clockShortcut','asteroid_menu_bottom','tutorialOverlay']);await super.onEnter(params);this._mainViewportEl.style.top='';this._mainViewportEl.style.left=''} + async onLeave(params){this._watchPanel.hide();await super.onLeave(params);this._watchManager.restoreEarthCoverage();this._watchManager.dimBackgroundLabels(!1);this._watchManager.setBgTrailWidthDefault();const particleShader=this._getParticleShader();if(particleShader){particleShader.uniforms.masterOpacity.value=0.5} + this._app.getComponent('asteroid_menu_top')?.toggleActive('Asteroid Watch',!1);this._watchManager.removeReferences();this._mainViewportEl.style.top='0px';this._mainViewportEl.style.left='0px';this._app.getManager('selection').setClickable(!0);const labelManager=this._app.getManager('label');labelManager.setLabelClickable('earth',!0)} + _reset(){this._target='earth'} + registerCallbacks(){super.registerCallbacks();this._watchPanel.registerCallback('expandtoggle',this._onExpandToggle)} + removeCallbacks(){super.removeCallbacks();this._watchPanel.removeCallback('expandtoggle',this._onExpandToggle)} + async goToWatchAsteroids(targetId,{asteroidData=[],duration=2,distanceCoeff=4,maxCamDistance=50000000,onTransition=undefined,forceAnimation=!1}){const scene=(this.app.getManager('scene')).main;const cameraManager=(this.app.getManager('camera'));const cameraEntity=cameraManager.cameraEntity;const targetEntity=scene.getEntity(targetId);const cinematic=!0;const halfDuration=duration*0.5;const currCamPosition=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3();cameraEntity?.getPositionRelativeToEntity(currCamPosition,pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero,targetEntity);const currCamDistance=currCamPosition.magnitude();const asteroidPos=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3();const currDistances=asteroidData.map(({pioneerName})=>{const entity=scene.getEntity(pioneerName);targetEntity.getPositionRelativeToEntity(asteroidPos,pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero,entity);return asteroidPos.magnitude()});const furthestDistance=Math.max(...currDistances);const distance=Math.min(furthestDistance*distanceCoeff,maxCamDistance);const tooFarAway=isNaN(currCamDistance)||currCamDistance>maxCamDistance;const tooNear=currCamDistance{const particleOpacity=targetParticleOpacity+(1-t)*(defaultParticleOpacity-targetParticleOpacity);const trailWidth=defaultPlanetTrailWidth*(1-t);watchView._setParticleOpacity(particleOpacity);trailManager.setMultipleWidths(backgroundPlanets,trailWidth,trailWidth)};const cameFromOutside=hasRedirected||this._app.getManager('router').previousView!=='watch';await this.goToWatchAsteroids(this._target,{asteroidData:nextFiveData,...cameFromOutside&&{onTransition,forceAnimation:!0}});if(cancelToken.isCanceled){this._setParticleOpacity(defaultParticleOpacity);this._watchManager.setBgTrailWidthDefault()}else{this._setParticleOpacity(targetParticleOpacity);trailManager.setMultipleWidths(backgroundPlanets,0,0)}} + _getParticleShader(){return this._app._pioneer.get('main','sun','orbitalParticles')?.getThreeJsMaterials()?.[0]} + _setParticleOpacity(opacity){const particleShader=this._getParticleShader();if(particleShader){particleShader.uniforms.masterOpacity.value=opacity}} + after(params){this._app.getManager('layer').resetTarget();if(this._watchManager.hasRedirected){this._watchManager.setHasRedirected(!1)}} + async _updateComponentsVisibility(params){await super._updateComponentsVisibility(params);const visibleUI=this._app.getManager('layer').getLayer('ui').visible;visibleUI&&this._watchPanel.show();this._app.getComponent('asteroid_menu_bottom')?.hide()} + resize(){super.resize();const isExpanded=this._watchPanel?._state.isExpanded;this._onExpandToggle(isExpanded)}}}),"../eyes/node_modules/moment/locale sync recursive ^\\.\\/.*$": + /*!*********************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ sync ^\.\/.*$ ***! + \*********************************************************/ + (function(module,__unused_webpack_exports,__webpack_require__){var map={"./af":"../eyes/node_modules/moment/locale/af.js","./af.js":"../eyes/node_modules/moment/locale/af.js","./ar":"../eyes/node_modules/moment/locale/ar.js","./ar-dz":"../eyes/node_modules/moment/locale/ar-dz.js","./ar-dz.js":"../eyes/node_modules/moment/locale/ar-dz.js","./ar-kw":"../eyes/node_modules/moment/locale/ar-kw.js","./ar-kw.js":"../eyes/node_modules/moment/locale/ar-kw.js","./ar-ly":"../eyes/node_modules/moment/locale/ar-ly.js","./ar-ly.js":"../eyes/node_modules/moment/locale/ar-ly.js","./ar-ma":"../eyes/node_modules/moment/locale/ar-ma.js","./ar-ma.js":"../eyes/node_modules/moment/locale/ar-ma.js","./ar-sa":"../eyes/node_modules/moment/locale/ar-sa.js","./ar-sa.js":"../eyes/node_modules/moment/locale/ar-sa.js","./ar-tn":"../eyes/node_modules/moment/locale/ar-tn.js","./ar-tn.js":"../eyes/node_modules/moment/locale/ar-tn.js","./ar.js":"../eyes/node_modules/moment/locale/ar.js","./az":"../eyes/node_modules/moment/locale/az.js","./az.js":"../eyes/node_modules/moment/locale/az.js","./be":"../eyes/node_modules/moment/locale/be.js","./be.js":"../eyes/node_modules/moment/locale/be.js","./bg":"../eyes/node_modules/moment/locale/bg.js","./bg.js":"../eyes/node_modules/moment/locale/bg.js","./bm":"../eyes/node_modules/moment/locale/bm.js","./bm.js":"../eyes/node_modules/moment/locale/bm.js","./bn":"../eyes/node_modules/moment/locale/bn.js","./bn-bd":"../eyes/node_modules/moment/locale/bn-bd.js","./bn-bd.js":"../eyes/node_modules/moment/locale/bn-bd.js","./bn.js":"../eyes/node_modules/moment/locale/bn.js","./bo":"../eyes/node_modules/moment/locale/bo.js","./bo.js":"../eyes/node_modules/moment/locale/bo.js","./br":"../eyes/node_modules/moment/locale/br.js","./br.js":"../eyes/node_modules/moment/locale/br.js","./bs":"../eyes/node_modules/moment/locale/bs.js","./bs.js":"../eyes/node_modules/moment/locale/bs.js","./ca":"../eyes/node_modules/moment/locale/ca.js","./ca.js":"../eyes/node_modules/moment/locale/ca.js","./cs":"../eyes/node_modules/moment/locale/cs.js","./cs.js":"../eyes/node_modules/moment/locale/cs.js","./cv":"../eyes/node_modules/moment/locale/cv.js","./cv.js":"../eyes/node_modules/moment/locale/cv.js","./cy":"../eyes/node_modules/moment/locale/cy.js","./cy.js":"../eyes/node_modules/moment/locale/cy.js","./da":"../eyes/node_modules/moment/locale/da.js","./da.js":"../eyes/node_modules/moment/locale/da.js","./de":"../eyes/node_modules/moment/locale/de.js","./de-at":"../eyes/node_modules/moment/locale/de-at.js","./de-at.js":"../eyes/node_modules/moment/locale/de-at.js","./de-ch":"../eyes/node_modules/moment/locale/de-ch.js","./de-ch.js":"../eyes/node_modules/moment/locale/de-ch.js","./de.js":"../eyes/node_modules/moment/locale/de.js","./dv":"../eyes/node_modules/moment/locale/dv.js","./dv.js":"../eyes/node_modules/moment/locale/dv.js","./el":"../eyes/node_modules/moment/locale/el.js","./el.js":"../eyes/node_modules/moment/locale/el.js","./en-au":"../eyes/node_modules/moment/locale/en-au.js","./en-au.js":"../eyes/node_modules/moment/locale/en-au.js","./en-ca":"../eyes/node_modules/moment/locale/en-ca.js","./en-ca.js":"../eyes/node_modules/moment/locale/en-ca.js","./en-gb":"../eyes/node_modules/moment/locale/en-gb.js","./en-gb.js":"../eyes/node_modules/moment/locale/en-gb.js","./en-ie":"../eyes/node_modules/moment/locale/en-ie.js","./en-ie.js":"../eyes/node_modules/moment/locale/en-ie.js","./en-il":"../eyes/node_modules/moment/locale/en-il.js","./en-il.js":"../eyes/node_modules/moment/locale/en-il.js","./en-in":"../eyes/node_modules/moment/locale/en-in.js","./en-in.js":"../eyes/node_modules/moment/locale/en-in.js","./en-nz":"../eyes/node_modules/moment/locale/en-nz.js","./en-nz.js":"../eyes/node_modules/moment/locale/en-nz.js","./en-sg":"../eyes/node_modules/moment/locale/en-sg.js","./en-sg.js":"../eyes/node_modules/moment/locale/en-sg.js","./eo":"../eyes/node_modules/moment/locale/eo.js","./eo.js":"../eyes/node_modules/moment/locale/eo.js","./es":"../eyes/node_modules/moment/locale/es.js","./es-do":"../eyes/node_modules/moment/locale/es-do.js","./es-do.js":"../eyes/node_modules/moment/locale/es-do.js","./es-mx":"../eyes/node_modules/moment/locale/es-mx.js","./es-mx.js":"../eyes/node_modules/moment/locale/es-mx.js","./es-us":"../eyes/node_modules/moment/locale/es-us.js","./es-us.js":"../eyes/node_modules/moment/locale/es-us.js","./es.js":"../eyes/node_modules/moment/locale/es.js","./et":"../eyes/node_modules/moment/locale/et.js","./et.js":"../eyes/node_modules/moment/locale/et.js","./eu":"../eyes/node_modules/moment/locale/eu.js","./eu.js":"../eyes/node_modules/moment/locale/eu.js","./fa":"../eyes/node_modules/moment/locale/fa.js","./fa.js":"../eyes/node_modules/moment/locale/fa.js","./fi":"../eyes/node_modules/moment/locale/fi.js","./fi.js":"../eyes/node_modules/moment/locale/fi.js","./fil":"../eyes/node_modules/moment/locale/fil.js","./fil.js":"../eyes/node_modules/moment/locale/fil.js","./fo":"../eyes/node_modules/moment/locale/fo.js","./fo.js":"../eyes/node_modules/moment/locale/fo.js","./fr":"../eyes/node_modules/moment/locale/fr.js","./fr-ca":"../eyes/node_modules/moment/locale/fr-ca.js","./fr-ca.js":"../eyes/node_modules/moment/locale/fr-ca.js","./fr-ch":"../eyes/node_modules/moment/locale/fr-ch.js","./fr-ch.js":"../eyes/node_modules/moment/locale/fr-ch.js","./fr.js":"../eyes/node_modules/moment/locale/fr.js","./fy":"../eyes/node_modules/moment/locale/fy.js","./fy.js":"../eyes/node_modules/moment/locale/fy.js","./ga":"../eyes/node_modules/moment/locale/ga.js","./ga.js":"../eyes/node_modules/moment/locale/ga.js","./gd":"../eyes/node_modules/moment/locale/gd.js","./gd.js":"../eyes/node_modules/moment/locale/gd.js","./gl":"../eyes/node_modules/moment/locale/gl.js","./gl.js":"../eyes/node_modules/moment/locale/gl.js","./gom-deva":"../eyes/node_modules/moment/locale/gom-deva.js","./gom-deva.js":"../eyes/node_modules/moment/locale/gom-deva.js","./gom-latn":"../eyes/node_modules/moment/locale/gom-latn.js","./gom-latn.js":"../eyes/node_modules/moment/locale/gom-latn.js","./gu":"../eyes/node_modules/moment/locale/gu.js","./gu.js":"../eyes/node_modules/moment/locale/gu.js","./he":"../eyes/node_modules/moment/locale/he.js","./he.js":"../eyes/node_modules/moment/locale/he.js","./hi":"../eyes/node_modules/moment/locale/hi.js","./hi.js":"../eyes/node_modules/moment/locale/hi.js","./hr":"../eyes/node_modules/moment/locale/hr.js","./hr.js":"../eyes/node_modules/moment/locale/hr.js","./hu":"../eyes/node_modules/moment/locale/hu.js","./hu.js":"../eyes/node_modules/moment/locale/hu.js","./hy-am":"../eyes/node_modules/moment/locale/hy-am.js","./hy-am.js":"../eyes/node_modules/moment/locale/hy-am.js","./id":"../eyes/node_modules/moment/locale/id.js","./id.js":"../eyes/node_modules/moment/locale/id.js","./is":"../eyes/node_modules/moment/locale/is.js","./is.js":"../eyes/node_modules/moment/locale/is.js","./it":"../eyes/node_modules/moment/locale/it.js","./it-ch":"../eyes/node_modules/moment/locale/it-ch.js","./it-ch.js":"../eyes/node_modules/moment/locale/it-ch.js","./it.js":"../eyes/node_modules/moment/locale/it.js","./ja":"../eyes/node_modules/moment/locale/ja.js","./ja.js":"../eyes/node_modules/moment/locale/ja.js","./jv":"../eyes/node_modules/moment/locale/jv.js","./jv.js":"../eyes/node_modules/moment/locale/jv.js","./ka":"../eyes/node_modules/moment/locale/ka.js","./ka.js":"../eyes/node_modules/moment/locale/ka.js","./kk":"../eyes/node_modules/moment/locale/kk.js","./kk.js":"../eyes/node_modules/moment/locale/kk.js","./km":"../eyes/node_modules/moment/locale/km.js","./km.js":"../eyes/node_modules/moment/locale/km.js","./kn":"../eyes/node_modules/moment/locale/kn.js","./kn.js":"../eyes/node_modules/moment/locale/kn.js","./ko":"../eyes/node_modules/moment/locale/ko.js","./ko.js":"../eyes/node_modules/moment/locale/ko.js","./ku":"../eyes/node_modules/moment/locale/ku.js","./ku.js":"../eyes/node_modules/moment/locale/ku.js","./ky":"../eyes/node_modules/moment/locale/ky.js","./ky.js":"../eyes/node_modules/moment/locale/ky.js","./lb":"../eyes/node_modules/moment/locale/lb.js","./lb.js":"../eyes/node_modules/moment/locale/lb.js","./lo":"../eyes/node_modules/moment/locale/lo.js","./lo.js":"../eyes/node_modules/moment/locale/lo.js","./lt":"../eyes/node_modules/moment/locale/lt.js","./lt.js":"../eyes/node_modules/moment/locale/lt.js","./lv":"../eyes/node_modules/moment/locale/lv.js","./lv.js":"../eyes/node_modules/moment/locale/lv.js","./me":"../eyes/node_modules/moment/locale/me.js","./me.js":"../eyes/node_modules/moment/locale/me.js","./mi":"../eyes/node_modules/moment/locale/mi.js","./mi.js":"../eyes/node_modules/moment/locale/mi.js","./mk":"../eyes/node_modules/moment/locale/mk.js","./mk.js":"../eyes/node_modules/moment/locale/mk.js","./ml":"../eyes/node_modules/moment/locale/ml.js","./ml.js":"../eyes/node_modules/moment/locale/ml.js","./mn":"../eyes/node_modules/moment/locale/mn.js","./mn.js":"../eyes/node_modules/moment/locale/mn.js","./mr":"../eyes/node_modules/moment/locale/mr.js","./mr.js":"../eyes/node_modules/moment/locale/mr.js","./ms":"../eyes/node_modules/moment/locale/ms.js","./ms-my":"../eyes/node_modules/moment/locale/ms-my.js","./ms-my.js":"../eyes/node_modules/moment/locale/ms-my.js","./ms.js":"../eyes/node_modules/moment/locale/ms.js","./mt":"../eyes/node_modules/moment/locale/mt.js","./mt.js":"../eyes/node_modules/moment/locale/mt.js","./my":"../eyes/node_modules/moment/locale/my.js","./my.js":"../eyes/node_modules/moment/locale/my.js","./nb":"../eyes/node_modules/moment/locale/nb.js","./nb.js":"../eyes/node_modules/moment/locale/nb.js","./ne":"../eyes/node_modules/moment/locale/ne.js","./ne.js":"../eyes/node_modules/moment/locale/ne.js","./nl":"../eyes/node_modules/moment/locale/nl.js","./nl-be":"../eyes/node_modules/moment/locale/nl-be.js","./nl-be.js":"../eyes/node_modules/moment/locale/nl-be.js","./nl.js":"../eyes/node_modules/moment/locale/nl.js","./nn":"../eyes/node_modules/moment/locale/nn.js","./nn.js":"../eyes/node_modules/moment/locale/nn.js","./oc-lnc":"../eyes/node_modules/moment/locale/oc-lnc.js","./oc-lnc.js":"../eyes/node_modules/moment/locale/oc-lnc.js","./pa-in":"../eyes/node_modules/moment/locale/pa-in.js","./pa-in.js":"../eyes/node_modules/moment/locale/pa-in.js","./pl":"../eyes/node_modules/moment/locale/pl.js","./pl.js":"../eyes/node_modules/moment/locale/pl.js","./pt":"../eyes/node_modules/moment/locale/pt.js","./pt-br":"../eyes/node_modules/moment/locale/pt-br.js","./pt-br.js":"../eyes/node_modules/moment/locale/pt-br.js","./pt.js":"../eyes/node_modules/moment/locale/pt.js","./ro":"../eyes/node_modules/moment/locale/ro.js","./ro.js":"../eyes/node_modules/moment/locale/ro.js","./ru":"../eyes/node_modules/moment/locale/ru.js","./ru.js":"../eyes/node_modules/moment/locale/ru.js","./sd":"../eyes/node_modules/moment/locale/sd.js","./sd.js":"../eyes/node_modules/moment/locale/sd.js","./se":"../eyes/node_modules/moment/locale/se.js","./se.js":"../eyes/node_modules/moment/locale/se.js","./si":"../eyes/node_modules/moment/locale/si.js","./si.js":"../eyes/node_modules/moment/locale/si.js","./sk":"../eyes/node_modules/moment/locale/sk.js","./sk.js":"../eyes/node_modules/moment/locale/sk.js","./sl":"../eyes/node_modules/moment/locale/sl.js","./sl.js":"../eyes/node_modules/moment/locale/sl.js","./sq":"../eyes/node_modules/moment/locale/sq.js","./sq.js":"../eyes/node_modules/moment/locale/sq.js","./sr":"../eyes/node_modules/moment/locale/sr.js","./sr-cyrl":"../eyes/node_modules/moment/locale/sr-cyrl.js","./sr-cyrl.js":"../eyes/node_modules/moment/locale/sr-cyrl.js","./sr.js":"../eyes/node_modules/moment/locale/sr.js","./ss":"../eyes/node_modules/moment/locale/ss.js","./ss.js":"../eyes/node_modules/moment/locale/ss.js","./sv":"../eyes/node_modules/moment/locale/sv.js","./sv.js":"../eyes/node_modules/moment/locale/sv.js","./sw":"../eyes/node_modules/moment/locale/sw.js","./sw.js":"../eyes/node_modules/moment/locale/sw.js","./ta":"../eyes/node_modules/moment/locale/ta.js","./ta.js":"../eyes/node_modules/moment/locale/ta.js","./te":"../eyes/node_modules/moment/locale/te.js","./te.js":"../eyes/node_modules/moment/locale/te.js","./tet":"../eyes/node_modules/moment/locale/tet.js","./tet.js":"../eyes/node_modules/moment/locale/tet.js","./tg":"../eyes/node_modules/moment/locale/tg.js","./tg.js":"../eyes/node_modules/moment/locale/tg.js","./th":"../eyes/node_modules/moment/locale/th.js","./th.js":"../eyes/node_modules/moment/locale/th.js","./tk":"../eyes/node_modules/moment/locale/tk.js","./tk.js":"../eyes/node_modules/moment/locale/tk.js","./tl-ph":"../eyes/node_modules/moment/locale/tl-ph.js","./tl-ph.js":"../eyes/node_modules/moment/locale/tl-ph.js","./tlh":"../eyes/node_modules/moment/locale/tlh.js","./tlh.js":"../eyes/node_modules/moment/locale/tlh.js","./tr":"../eyes/node_modules/moment/locale/tr.js","./tr.js":"../eyes/node_modules/moment/locale/tr.js","./tzl":"../eyes/node_modules/moment/locale/tzl.js","./tzl.js":"../eyes/node_modules/moment/locale/tzl.js","./tzm":"../eyes/node_modules/moment/locale/tzm.js","./tzm-latn":"../eyes/node_modules/moment/locale/tzm-latn.js","./tzm-latn.js":"../eyes/node_modules/moment/locale/tzm-latn.js","./tzm.js":"../eyes/node_modules/moment/locale/tzm.js","./ug-cn":"../eyes/node_modules/moment/locale/ug-cn.js","./ug-cn.js":"../eyes/node_modules/moment/locale/ug-cn.js","./uk":"../eyes/node_modules/moment/locale/uk.js","./uk.js":"../eyes/node_modules/moment/locale/uk.js","./ur":"../eyes/node_modules/moment/locale/ur.js","./ur.js":"../eyes/node_modules/moment/locale/ur.js","./uz":"../eyes/node_modules/moment/locale/uz.js","./uz-latn":"../eyes/node_modules/moment/locale/uz-latn.js","./uz-latn.js":"../eyes/node_modules/moment/locale/uz-latn.js","./uz.js":"../eyes/node_modules/moment/locale/uz.js","./vi":"../eyes/node_modules/moment/locale/vi.js","./vi.js":"../eyes/node_modules/moment/locale/vi.js","./x-pseudo":"../eyes/node_modules/moment/locale/x-pseudo.js","./x-pseudo.js":"../eyes/node_modules/moment/locale/x-pseudo.js","./yo":"../eyes/node_modules/moment/locale/yo.js","./yo.js":"../eyes/node_modules/moment/locale/yo.js","./zh-cn":"../eyes/node_modules/moment/locale/zh-cn.js","./zh-cn.js":"../eyes/node_modules/moment/locale/zh-cn.js","./zh-hk":"../eyes/node_modules/moment/locale/zh-hk.js","./zh-hk.js":"../eyes/node_modules/moment/locale/zh-hk.js","./zh-mo":"../eyes/node_modules/moment/locale/zh-mo.js","./zh-mo.js":"../eyes/node_modules/moment/locale/zh-mo.js","./zh-tw":"../eyes/node_modules/moment/locale/zh-tw.js","./zh-tw.js":"../eyes/node_modules/moment/locale/zh-tw.js"};function webpackContext(req){var id=webpackContextResolve(req);return __webpack_require__(id)} + function webpackContextResolve(req){if(!__webpack_require__.o(map,req)){var e=new Error("Cannot find module '"+req+"'");e.code='MODULE_NOT_FOUND';throw e} + return map[req]} + webpackContext.keys=function webpackContextKeys(){return Object.keys(map)};webpackContext.resolve=webpackContextResolve;module.exports=webpackContext;webpackContext.id="../eyes/node_modules/moment/locale sync recursive ^\\.\\/.*$"}),"../eyes/src/app.js": + /*!**************************!*\ + !*** ../eyes/src/app.js ***! + \**************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"BaseApp":function(){return BaseApp}});var moment_timezone__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! moment-timezone */"../eyes/node_modules/moment-timezone/index.js");var moment_timezone__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(moment_timezone__WEBPACK_IMPORTED_MODULE_0__);var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");var _data_entity_info_json__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! ./data/entity_info.json */"../eyes/src/data/entity_info.json");var _data_entity_spheroid_layers_js__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(/*! ./data/entity_spheroid_layers.js */"../eyes/src/data/entity_spheroid_layers.js");var _data_entity_spheroid_features_js__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(/*! ./data/entity_spheroid_features.js */"../eyes/src/data/entity_spheroid_features.js");var _internal__WEBPACK_IMPORTED_MODULE_7__=__webpack_require__(/*! ./internal */"../eyes/src/internal.js");class BaseApp{static setAppClass(){BaseApp._appClass=this} + constructor(componentTypes){window.app=this;this._pioneer=null;this._scene=null;this._router=null;this._element=null;this._dynamicElement=null;this._timeInfo={};this._sceneInfo=undefined;this._cameraScripts=new _internal__WEBPACK_IMPORTED_MODULE_7__.CameraScripts(this);this._componentInfo=[];this._componentTypes=componentTypes;this._managers={};this._components={};this._views={};this._viewInfo=[];this._viewClasses={};this._updates=[];this.isTouch=null;this.canHover=null;this._isSearching=null;this._touchStartPos={x:0,y:0};this._dragging=!1;this._entityInfo=_data_entity_info_json__WEBPACK_IMPORTED_MODULE_4__;this.bindFunctions(['resize','onTouchStart','onTouchMove','onTouchEnd','update']);this._touchCount=0;this._scrollable=!1;this._touchMax=!1;window.addEventListener('touchstart',this.onTouchStart,!1);window.addEventListener('touchmove',this.onTouchMove,{passive:!1});window.addEventListener('touchend',this.onTouchEnd);const vh=window.innerHeight;document.documentElement.style.setProperty('--vh',`${vh}px`);window.addEventListener('resize',this.resize,!1);this.resize()} + async init(){this._element=document.getElementById('ui');this._dynamicElement=document.getElementById('dynamic-ui');this._staticElement=document.getElementById('static-ui');const rootDiv=(document.getElementById('pioneer'));rootDiv.style.position='absolute';this._pioneer=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Engine(rootDiv);if(typeof window.config.staticAssetsUrl==='string'){this._pioneer.getDownloader().setReplacement('STATIC_ASSETS_URL',window.config.staticAssetsUrl)} + if(typeof window.config.dynamicAssetsUrl==='string'){this._pioneer.getDownloader().setReplacement('DYNAMIC_ASSETS_URL',window.config.dynamicAssetsUrl)} + if(typeof window.config.animdataUrl==='string'){this._pioneer.getDownloader().setReplacement('ANIMDATA_URL',window.config.animdataUrl)} + this._pioneer.getConfig().setValue('fontFamily','Raleway');this._pioneer.getConfig().setValue('fontSize',16);this._pioneer.getConfig().setValue('pbr',!0);this._pioneer.registerComponentType('distanceLine',_internal__WEBPACK_IMPORTED_MODULE_7__.DistanceLineComponent);this._pioneer.registerComponentType('orbiterLineOfSight',_internal__WEBPACK_IMPORTED_MODULE_7__.OrbiterLineOfSightComponent);this._pioneer.registerComponentType('wmts',pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.WMTSComponent);this._pioneer.registerComponentType('discGrid',pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.DiscGridComponent);this._pioneer.registerComponentType('torus',pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.TorusComponent);this._pioneer.registerComponentType('constellations',pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.ConstellationsComponent);this._pioneer.registerControllerType('positionSum',pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.PositionSumController);this._pioneer.registerControllerType('zoomFit',pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.ZoomFitController);this._pioneer.registerComponentType('orbitLine',pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.OrbitLineComponent);this._pioneer.setTime(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now());this._pioneer.setTimeRate(1.0);await this.createManagers();await this.createComponents();this.setUpRoutes();this.setUpUpdates();(this.getManager('router')).start();const{spout}=this.getManager('router').configs;if(spout===!0){const{spoutGlobe,spoutRenderWidth,spoutGlobeDistance,spoutTarget,spoutFontSize,spoutLonAngleOffset,spoutAlignToNorthPole}=this.getManager('router').configs;const target=spoutTarget||await this.getManager('spout').getSpoutCameraTargetEntity(this.getManager('router').currentRoute.params);this.getManager('spout').enableSpout(spoutGlobe,spoutRenderWidth,spoutGlobeDistance,target,spoutFontSize,spoutLonAngleOffset,spoutAlignToNorthPole)}} + get pioneer(){return this._pioneer} + get scene(){return this._scene} + set scene(scene){this._scene=scene} + get cameraScripts(){return this._cameraScripts} + get dynamicElement(){return this._dynamicElement} + get staticElement(){return this._staticElement} + get sceneInfo(){return this._sceneInfo} + get element(){return this._element} + set element(element){this._element=element} + get isSearching(){return this._isSearching} + set isSearching(isSearching){this._isSearching=isSearching} + addManager(name,TypeConstructor,...args){if(this._managers[name]===undefined){this._managers[name]=new TypeConstructor(this,...args)} + return(this._managers[name])} + removeManager(name){if(this._managers[name]!==undefined){this._managers[name].destroy();delete this._managers[name]}} + getManager(name){if(this._managers[name]!==undefined){return this._managers[name]} + return null} + async createManagers(){const timeManagerClass=_internal__WEBPACK_IMPORTED_MODULE_7__.Types.get('TimeManager');const timeMgr=this.addManager('time',timeManagerClass);const min=moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().tz('1949-12-31','Etc/UTC');const max=moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().tz('2049-12-31','Etc/UTC');timeMgr.setDefaultLimits({min,max});timeMgr.setLimits({min,max});const contentMgr=this.addManager('content',_internal__WEBPACK_IMPORTED_MODULE_7__.ContentManager);contentMgr.setEntityList(_data_entity_info_json__WEBPACK_IMPORTED_MODULE_4__);contentMgr.setSpheroidLayers(_data_entity_spheroid_layers_js__WEBPACK_IMPORTED_MODULE_5__["default"]);contentMgr.setSpheroidFeatures(_data_entity_spheroid_features_js__WEBPACK_IMPORTED_MODULE_6__["default"]);contentMgr.setFolders({description:'descriptions/',event:'events/',stories:'stories/'});const sceneManager=this.addManager('scene',_internal__WEBPACK_IMPORTED_MODULE_7__.SceneManager);this._scene=sceneManager.main;const layerManager=this.addManager('layer',_internal__WEBPACK_IMPORTED_MODULE_7__.LayerManager);const SATELLITE_GROUPS=['CYGNSS','TROPICS','STARLING','PREFIRE'];layerManager.addLayer('ui',{name:'User Interface'});layerManager.addLayer('trails',{name:'Trails'});layerManager.addLayer('orbits',{name:'Orbits'});layerManager.addLayer('labels',{name:'Labels'});layerManager.addLayer('icons',{name:'Icons'});layerManager.addLayer('planets',{name:'Planets',categories:'Planet'});layerManager.addLayer('asteroids',{name:'Asteroids',categories:'Asteroid',defaultVisibility:!1});layerManager.addLayer('comets',{name:'Comets',categories:'Comet',defaultVisibility:!1});layerManager.addLayer('dwarfPlanets',{name:'Dwarf Planets',categories:'Dwarf Planet',defaultVisibility:!1});layerManager.addLayer('spacecraft',{name:'Spacecraft',categories:'Spacecraft',sublayers:['orbiters','landers','satelliteGroup']});layerManager.addLayer('majorMoons',{name:'Major Moons',categories:'Major Moon',group:'moons'});layerManager.addLayer('minorMoons',{name:'Minor Moons',categories:'Minor Moon',defaultVisibility:!1,group:'moons'});layerManager.addLayer('orbiters',{name:'Orbiters',categories:'Orbiter',group:'spacecraft'});layerManager.addLayer('satelliteGroup',{name:'Satellite Group',categories:SATELLITE_GROUPS,group:'spacecraft',defaultVisibility:!0});layerManager.addLayer('landers',{name:'Landers',categories:['Lander','Rover','Landing site'],group:'spacecraft'});layerManager.addLayer('starfield',{name:'Star Field',defaultVisibility:!1});layerManager.addLayer('heliosphere',{name:'Heliosphere',defaultVisibility:!1});layerManager.addLayer('constellations',{name:'Constellations',categories:'Constellations',defaultVisibility:!1});const cameraManager=this.addManager('camera',_internal__WEBPACK_IMPORTED_MODULE_7__.CameraManager,this._scene);this._cameraScripts.setCameraManager(cameraManager);cameraManager.createViewportAndCamera(this._scene);this.addManager('search',_internal__WEBPACK_IMPORTED_MODULE_7__.SearchManager,{keys:[{name:'iauName',weight:0.99},{name:'displayName',weight:0.98},{name:'altName',weight:0.98},{name:'keywords',weight:0.3},{name:'category',weight:0.3}]});this.addManager('comparison',_internal__WEBPACK_IMPORTED_MODULE_7__.ComparisonManager);const labelManagerClass=_internal__WEBPACK_IMPORTED_MODULE_7__.Types.get('LabelManager');const labelManager=this.addManager('label',labelManagerClass,this._scene);labelManager.setWeights(contentMgr.getEntityList());labelManager.setAlgorithm(labelManagerClass.Quadtree);const selectionManagerClass=_internal__WEBPACK_IMPORTED_MODULE_7__.Types.get('SelectionManager');const selectionManager=this.addManager('selection',selectionManagerClass,this._scene);selectionManager.init3Dcallback(cameraManager);labelManager.registerCallback('labelclicked',selectionManager.setSuppress);const routeManager=this.addManager('router',_internal__WEBPACK_IMPORTED_MODULE_7__.RouteManager);routeManager.setValidQueries(['time','rate']);routeManager.init();routeManager.addConfigs({embed:undefined,kiosk:undefined,logo:undefined,detailPanel:undefined,content:undefined,featured:undefined,menu:undefined,locked:undefined,surfaceMapTiling:undefined,hd:undefined,lighting:undefined,hideExternalLinks:undefined,hideFullScreenToggle:undefined,maxSessionTime:undefined,maxInactivityTime:undefined,forceRestart:undefined,noKeyboard:undefined,search:undefined,collapseSettingsOptions:undefined,shareButton:undefined,spout:undefined,spoutGlobe:undefined,spoutRenderWidth:undefined,spoutGlobeDistance:undefined,spoutTarget:undefined,spoutFontSize:undefined,spoutLonAngleOffset:undefined,spoutAlignToNorthPole:undefined,interactPrompt:undefined});const trailManagerClass=_internal__WEBPACK_IMPORTED_MODULE_7__.Types.get('TrailManager');const trailManager=this.addManager('trail',trailManagerClass,this._scene);labelManager.registerCallback('hoverchange',trailManager.onHoverChange);this.addManager('spout',_internal__WEBPACK_IMPORTED_MODULE_7__.SpoutManager);layerManager.addCallback('trails',trailManager.toggleTrails);layerManager.addCallback('orbits',trailManager.toggleOrbits);layerManager.addCallback('labels',labelManager.toggleLabels);layerManager.addCallback('icons',labelManager.toggleIcons);layerManager.addCallback('starfield',sceneManager.toggleStarfield);layerManager.addCallback('heliosphere',sceneManager.toggleHeliosphere);layerManager.addCallback('constellations',sceneManager.toggleConstellations);this.addViews();this.setUpViewportAndCamera();await this.setUpScene();this.setUpManagers();await this.setUpComponents();this.addShortcuts();this._pioneer.addCallback(this.update,!0)} + setUpManagers(){const scene=this.scene;const trailManager=this.getManager('trail');const timeManager=this.getManager('time');let{limits}=this._timeInfo;if(!limits){limits={min:moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.constants.minDate),max:moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.constants.maxDate)}}else{limits.min=!('min' in limits)||limits.min==='-Infinity'?moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.constants.minDate):this.getManager('time').parseTime(limits.min);limits.max=!('max' in limits)||limits.max==='Infinity'?moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.constants.maxDate):this.getManager('time').parseTime(limits.max)} + timeManager.setDefaultLimits(limits);timeManager.setLimits(limits);this.getManager('label').setScene(scene);this.getManager('selection').setScene(scene);trailManager.setScene(scene);trailManager.ids=Array.from(this.getManager('scene').getEntitiesNames());trailManager.setColor(trailManager.ids)} + async addComponent(name,TypeConstructor,...args){if(this._components[name]!==undefined){throw new Error(`Component ${name} was already added.`)} + const component=new TypeConstructor(this,...args);this._components[name]=component;await component.init();return component} + async addComponentWithPlaceholder(componentClass,element=document,placeholder=null){if(!componentClass.args){componentClass.args=[]} + if(!componentClass.options){componentClass.options={}} + if(!placeholder){const placeholders=Array.from(element.getElementsByTagName(componentClass.type.name));placeholder=(placeholders.find(item=>item instanceof HTMLElement&&item.id===componentClass.name));if(!placeholder&&placeholders[0]instanceof HTMLElement){placeholder=placeholders[0]} + if(!placeholder){return Promise.reject(new Error(`addComponentWithPlaceholder: There is no placeholder element for ${componentClass.type}`))}} + Object.assign(componentClass.options,_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.convertObjType({...placeholder.dataset}));const component=await this.addComponent(componentClass.name,componentClass.type,...componentClass.args,componentClass.options);component.setParent(placeholder.parentElement,placeholder);return component} + removeComponent(name){if(this._components[name]!==undefined){this._components[name].destroy();delete this._components[name];return!0} + return!1} + removeComponents(){for(let i=0;i{if(event.code===searchShortcut){if(!this.isSearching){desktopSearch.open();desktopSearch._children.input.focus()}}})}} + async setUpComponents(){this.dynamicElement.innerHTML=this.constructor.html;for(let i=0;i{if(entity.getName()==='sc_mars_science_laboratory'){entity.get('div').setFadeWhenCloseToEntity('mars')}else if(entity.getName()==='sc_mars_2020'){entity.get('div').setFadeWhenCloseToEntity('mars')}});sceneManager.addEntityWillBeUnloadedCallback(labelManager.removeLabel);sceneManager.update();this.scene=this.getManager('scene').main;this.scene.get('sun','model')?.setEnabled(!1)} + setUpViewportAndCamera(){const scene=this.getManager('scene').main;const camera=this.getManager('camera');camera.createViewportAndCamera(scene);this.cameraScripts.scene=scene;this.cameraScripts.cameraEntity=camera.cameraEntity} + setUpUpdates(){this.addUpdate(this.getManager('scene').update);this.addUpdate(this.getManager('label').update);this.addUpdate(this.getManager('camera').update)} + addUpdate(callback){if(typeof callback==='function'){this._updates.push(callback)}} + removeUpdate(callback){const index=this._updates.indexOf(callback);if(index<0){return} + this._updates.splice(index,1)} + update(){for(let i=0;i{loadingScreen.remove()},duration)}} + setUpRoutes(){} + isDragging(){return this._dragging} + isTouchMax(){return this._touchMax} + resize(){const vh=window.innerHeight;document.documentElement.style.setProperty('--vh',`${vh}px`);document.body.style.height=vh+'px';const isTouch=_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.isTouch();const canHover=_internal__WEBPACK_IMPORTED_MODULE_7__.AppUtils.canHover();if(this.isTouch!==isTouch){document.body.classList.toggle('touch',isTouch);this.isTouch=isTouch} + if(this.canHover!==canHover){document.body.classList.toggle('hover',canHover);this.canHover=canHover} + setTimeout(()=>{if(vh!==window.innerHeight){const newVH=window.innerHeight;document.documentElement.style.setProperty('--vh',`${newVH}px`);document.body.style.height=newVH+'px'}},1000)} + onTouchStart(event){this._touchCount++;this._touchMax=this._touchCount>1;const touchEvent=event.changedTouches[0];this._touchStartPos.x=touchEvent.pageX;this._touchStartPos.y=touchEvent.pageY;this._dragging=!1;this._scrollable=!1;let element=(event.target);while(element.parentElement!==null){if(element.classList.contains('scrollable')){this._scrollable=!0;break} + element=element.parentElement}} + onTouchMove(event){const touchEvent=event.changedTouches[0];const pressedPositionDistance=Math.max(Math.abs(touchEvent.pageX-this._touchStartPos.x),Math.abs(touchEvent.pageY-this._touchStartPos.y));if(pressedPositionDistance>5){this._dragging=!0} + if(!this._scrollable){event.preventDefault()}} + onTouchEnd(event){this._touchCount--;if(event.touches.length===0){this._touchMax=!1} + this._dragging=!1;this._scrollable=!1} + getPioneerVersion(){return this.pioneer.getVersion()} + getEyesVersion(){return _internal__WEBPACK_IMPORTED_MODULE_7__.EyesVersion}} + window.addEventListener('load',async()=>{try{const app=new BaseApp._appClass();app.init()}catch(error){document.body.innerHTML='';throw error}});BaseApp._appClass=BaseApp;window.Pioneer=pioneer__WEBPACK_IMPORTED_MODULE_1__;window.PioneerScripts=pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__}),"../eyes/src/assets/index.js": + /*!***********************************!*\ + !*** ../eyes/src/assets/index.js ***! + \***********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__)}),"../eyes/src/base_view.js": + /*!********************************!*\ + !*** ../eyes/src/base_view.js ***! + \********************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"BaseView":function(){return BaseView}});var moment_timezone__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! moment-timezone */"../eyes/node_modules/moment-timezone/index.js");var moment_timezone__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(moment_timezone__WEBPACK_IMPORTED_MODULE_0__);var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./internal */"../eyes/src/internal.js");class BaseView extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseComponent{constructor(app,element,components=[]){super(app,element);this._components=[...components];this._validQueries=[];this._rules={};this._target=null;this._enabled=!1;this.bindFunctions(['resize','updateVisibility','toggleViewUI'])} + get app(){return(super.app)} + _showControls(){} + _hideControls(){} + _shouldHideControls(){return!1} + updateVisibility(){const showUI=this._app.getManager('layer').getLayer('ui').visible;if(!showUI){return} + if(this._shouldHideControls()){this._hideControls()}else{this._showControls()}} + resize(){this.updateVisibility()} + toggleViewUI(){} + _shouldResetStatus(){return this._app.getManager('layer').getLayer('ui').visible} + _resetStatus(unsubscribed=[]){if(this._shouldResetStatus()){const allComponents=Object.keys(this._app.getComponents());for(let i=allComponents.length-1;i>=0;i--){const component=allComponents[i];if(unsubscribed.includes(component)){continue} + this._app.getComponent(component).setEnabled(this._components.includes(component))}}} + registerCallbacks(){this._app.getManager('layer').addCallback('ui',this.toggleViewUI)} + removeCallbacks(){this._app.getManager('layer').removeCallback('ui',this.toggleViewUI)} + async onEnter(params,unsubscribed=[]){if(params.cancelToken.isCanceled){return} + this._resetStatus(unsubscribed);window.addEventListener('resize',this.resize);this.registerCallbacks();const className=this._app.getManager('router').currentView+'-view';document.body.classList.add(className);if(this._app.getManager('router').configs.locked){document.body.classList.add('locked');this._app.getManager('label').setClickable(!1);this._app.getManager('selection').setClickable(!1)}} + async onRouteChange(params){await this.before(params);if(params.cancelToken.isCanceled){return} + this._reset(params);await this._updateResources(params);if(params.cancelToken.isCanceled){return} + params.setTimeLimits=!0;await this.processQuery(params);await this._updateComponentsVisibility(params);if(params.cancelToken.isCanceled){return} + await this._checkReady(params);try{await this._updateCamera(params);this._updateLoading(params)}finally{await this.after(params)} + const{spout}=this.app.getManager('router').configs;if(spout===!0){const{spoutGlobe,spoutRenderWidth,spoutGlobeDistance,spoutTarget,spoutFontSize,spoutLonAngleOffset,spoutAlignToNorthPole}=this.app.getManager('router').configs;const spoutTargetEntity=spoutTarget||await this.app.getManager('spout').getSpoutCameraTargetEntity(params);this.app.getManager('spout').enableSpout(spoutGlobe,spoutRenderWidth,spoutGlobeDistance,spoutTargetEntity,spoutFontSize,spoutLonAngleOffset,spoutAlignToNorthPole)}} + async onQueryChange(params){if(params.cancelToken.isCanceled){return} + await this.processQuery(params)} + validateQuery(input){const queries={...input};const keys=Object.keys(queries);const newQueries={};const isInvalid={};const routeManager=this._app.getManager('router');for(let i=keys.length-1;i>=0;i--){const key=keys[i];if(!(key in this._rules)){delete queries[key];continue} + const rule=this._rules[key];const valid=typeof rule.value==='function'?rule.value(queries[key]):rule.value===queries[key];if(!valid){isInvalid[key]=queries[key];if(typeof this._rules.redirect==='function'){this._rules.redirect(queries[key]);return!1} + if('route' in rule){routeManager.navigate(rule.route);return!1}else if('default' in rule){newQueries[key]=rule.default}}} + if(!_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isEmptyObject(newQueries)){routeManager.navigate({...queries,...newQueries});return!1} + if(!_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isEmptyObject(isInvalid)){this._handleError(`validateQuery: Invalid input - ${JSON.stringify(isInvalid)}`);return!1} + return!0} + async processQuery(query){await this._updateTime(query);this._updateTimeRate(query);const router=this._app.getManager('router');const prevQuery=router.parseQuery(router.previousRoute?.query);for(const queryKey of Object.keys(router._queryCallbacks)){const currQueryVal=query[queryKey];const prevQueryVal=prevQuery[queryKey];if(currQueryVal||prevQueryVal){router._queryCallbacks[queryKey].forEach(callbackFn=>callbackFn(currQueryVal,prevQueryVal))}} + const layerManager=this._app.getManager('layer');const layerPanel=this._app.getComponent('layerPanel');const layerQueries={layerUI:'ui',layerTrails:'trails',layerOrbits:'orbits',layerLabels:'labels',layerIcons:'icons',layerPlanets:'planets',layerAsteroids:'asteroids',layerComets:'comets',layerDwarfPlanets:'dwarfPlanets',layerConstellations:'constellations',layerSpacecraft:'spacecraft'};for(const key in layerQueries){if(key in query){const layer=layerQueries[key];if(query[key]==='disable'){layerPanel?.setCategoryEnabled(layer,!1)}else{if(layerPanel?.isCategoryEnabled(layer)){if(query[key]==='show'){if(!layerManager.getLayer(layer).visible){layerPanel.toggleLayer(layer)}}else if(query[key]==='hide'){if(layerManager.getLayer(layer).visible){layerPanel.toggleLayer(layer)}}}}}} + this.app.getManager('title')?.updateTitle(router.currentRoute)} + _handleError(message=''){const err=new Error(message);console.error(err);const router=this._app.getManager('router');if(router!==null){let url=this._app.getManager('router').previousRoute.url;if(!url){url=this._app.getManager('router').homeRoute} + this._app.getManager('router').navigate(url)}} + onLeave(params){window.removeEventListener('resize',this.resize);this.removeCallbacks();const className=this._app.getManager('router').previousView+'-view';document.body.classList.remove(className);this._app.getManager('selection').unselect();this._app.getManager('scene').clearForceLoad();this._validQueries.length&&this._app.getManager('router').navigate({__remove:this._validQueries})} + _reset(params){this._app.getManager('scene').clearForceLoad()} + async _updateResources(params){} + _updateTimeRate(query){const timeManager=this._app.getManager('time');if('rate' in query){timeManager.setTimeRate(parseInt(query.rate))}else{timeManager.resetTimeRate()}} + async _updateTime(params){const timeManager=this._app.getManager('time');const routeManager=this._app.getManager('router');const isStory=routeManager.currentRoute.url.includes('story');let numSlides=0;if(isStory&&this._storyId){const story=this._app.getManager('content').getStory(this._storyId);numSlides=story.slides.length} + if((!this._target&&(numSlides>1))||(isStory&&!this._target&&!this._storyId)){timeManager.resetMin();timeManager.resetMax()} + if(this._target){await this._updateTimeForTarget(params)}else if(params.time){const time=this._app.getManager('time').parseTime(params.time);if(time.isValid()){this._app.getManager('time').setTime(params.time)}else{this._app.getManager('router').navigate({__remove:['time']})}}else{this._app.getManager('time').setToNow()}} + async _updateTimeForTarget(params,waitForEntity=!0){const timeManager=this._app.getManager('time');let min=timeManager.timeLimits.min.clone();let max=timeManager.timeLimits.max.clone();if(params.setTimeLimits){const defaultLimits=timeManager.getDefaultLimits();min=defaultLimits.min.clone();max=defaultLimits.max.clone();waitForEntity&&await this._app.getManager('scene').get('main').getEntity(this._target).getLoadedPromise();const coverage=this._app.getManager('scene').getCoverage(this._target);if(coverage.min!==null){min=moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().max(min,coverage.min)} + if(coverage.max!==null){max=moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().min(max,coverage.max)} + if(this._entityDesc?.dates?.start){const startTime=timeManager.parseTime(this._entityDesc.dates.start);min=moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().max(startTime,min)} + if(this._entityDesc?.dates?.end){const endTime=timeManager.parseTime(this._entityDesc.dates.end);max=moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().min(endTime,max)} + if(min.isAfter(max)){console.error('Start date provided is after end date.');const router=this._app.getManager('router');this._app.getComponent('clock')?.setLimitMessage(1,'time limit error');setTimeout(()=>router.navigate('/'),1000);return} + timeManager.setMax(max);timeManager.setMin(min)} + if(!params.time&&this._eventInfo?.start){const eventStart=timeManager.parseTime(this._eventInfo.start);timeManager.setTime(moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().max(eventStart,min))}else if(!params.time){const now=this._app.getManager('time').getNow();if(now.isAfter(max)||now.isBefore(min)){timeManager.setTime(min)}else{timeManager.setToNow()}}else{const time=timeManager.parseTime(params.time);if(time.isAfter(max)){timeManager.setTime(max);timeManager.setTimeRate(0);this._app.getComponent('clock')?.setLimitMessage(1)}else if(time.isBefore(min)){timeManager.setTime(min);this._app.getComponent('clock')?.setLimitMessage(-1)}else{timeManager.setTime(time)}}} + async _updateComponentsVisibility(params){await this._updateComponents(params);if(params.cancelToken.isCanceled){return} + this.updateVisibility()} + async _updateComponents(params){} + async _updateCamera(params){} + _updateLoading(params){if(this._target!==null){const promises=[];const loadComponents=['model','wmts','spheroidLOD'];const sceneManager=this._app.getManager('scene');const contentManager=this._app.getManager('content');const entityInfoCategory=contentManager.getEntityInfo(this._target)?.category;if(entityInfoCategory){if(entityInfoCategory==='Instrument'){sceneManager.addLoading(sceneManager._scene.getEntity(this._target).getParent().getName(),'view')}} + sceneManager.addLoading(this._target,'view');for(let i=0;i{if(entityInfoCategory){if(entityInfoCategory==='Instrument'){sceneManager.removeLoading(sceneManager._scene.getEntity(this._target).getParent().getName(),'view')}} + sceneManager.removeLoading(this._target,'view')})}} + async _checkReady(params){if(this._target===null){return} + const checklist=[];let parent=this._target;while(parent!=='sun'){checklist.push(parent);const parentEntity=this._app.getManager('scene').get('main').get(parent)?.getParent();if(!parentEntity){break} + parent=parentEntity.getName()} + await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(this._app.getManager('scene').get('main'),checklist);await this._app.pioneer.waitUntilNextFrame()} + async before(params){} + after(params){this._app.getManager('layer').resetTarget();this._app.getManager('scene').clearTempEntities()}}}),"../eyes/src/components/base_component.js": + /*!************************************************!*\ + !*** ../eyes/src/components/base_component.js ***! + \************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"BaseComponent":function(){return BaseComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class BaseComponent{constructor(app,element,options={parent:null,config:{},params:{},isVisible:!0}){this._element=element;this._app=app;this._config=options.config||{};delete options.config;if(!('hiddenMode' in this._config)){this._config.hiddenMode='hidden'} + this._params=options.params||{};delete options.params;if(!('isVisible' in options)){options.isVisible=!1} + this._class={isVisible:{true:'active',false:this._config.hiddenMode==='hidden'?'hidden':'invisible'},fontSize:{small:'small',default:'',large:''}};this._state={...options,isVisibleClass:this._class.isVisible[options.isVisible?'true':'false'],fontSizeClass:this._class.fontSize.default};this._oldState={};this._children={};this._components=[];this._vars={};this._parent=this._element?this._element.parentElement:(options.parent||null);this._enabled=!1;this._eventNames=['statuschange','visiblechange'];this._callbacks={};this._initCallbacks();this._callbackRegistry=[];this.bindFunctions(['resize','isEnabled','setEnabled','show','hide','toggle','loadHTML','getState','setState'])} + get components(){return this._components} + get app(){return this._app} + resize(){this._updateFontSize()} + _updateFontSize(){let fontSizeClass=this._class.fontSize.default;if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobile()){fontSizeClass=this._class.fontSize.small}else if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isTablet()){fontSizeClass=this._class.fontSize.default}else if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isPanorama()){fontSizeClass=this._class.fontSize.default}else if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.is2K()||_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.is4K()){fontSizeClass=this._class.fontSize.large} + this.setState({fontSizeClass})} + get element(){return this._element} + getParent(){return this._parent} + setParent(parent,replaceElement=null){this._parent=parent;if(replaceElement){this._parent.removeChild(replaceElement)} + if(this._enabled){this._parent.appendChild(this._element)}} + async init(params={}){Object.assign(this._params,params);const componentType=(this.constructor);if(componentType.html!==undefined){this._element=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.htmlWithParamsToElement(componentType.html,this._params);this._element.classList.add('{{fontSizeClass}}');this._setVariables(this._element);this._setEventHandlersFromAttributes(this._element)}else{this._element.classList.add('{{fontSizeClass}}');this._setVariables(this._element)} + this._updateFontSize()} + getConfig(){return this._config} + setConfig(config){Object.assign(this._config,config)} + bindFunctions(fns=[]){const thisAsObject=(this);for(let i=0;i{const component=(typeof item==='string')?this._app.getComponent(item):item;component.setEnabled(enabled)})} + destroy(){this.__destroy()} + show(){this.setState({isVisible:!0,isVisibleClass:this._class.isVisible.true},()=>this.triggerCallbacks('visiblechange',[!0]))} + hide(){this.setState({isVisible:!1,isVisibleClass:this._class.isVisible.false},()=>this.triggerCallbacks('visiblechange',[!1]))} + toggle(){if(this._state.isVisible){this.hide()}else{this.show()}} + async loadHTML(filename,element=null){const response=await fetch(filename);if(!response.ok){console.error(response.status+': '+response.statusText)}else{const html=await response.text();this._parseHTML(html,element)}} + getState(key){if(!(key in this._state)){return null} + return this._state[key]} + addState(key,value,element){this._state[key]=value;if(element){this._setVariables(element)}} + setState(state,callback){if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isEmptyObject(state)){return} + let hasChanged=!1;for(const key in state){if(state[key]!==this._state[key]){hasChanged=!0;break}} + if(!hasChanged){return} + this._oldState={...this._state};this._state={...this._state,...state};this._render(state);if(callback!==undefined){callback()}} + _parseHTML(html,element=null){if(!html){return} + const outElement=element||this._element;this._roots=[..._internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.htmlToElements(html)];const docFrag=document.createDocumentFragment();for(let i=0;ipart!=='')} + _setVariables(element,setForChildren=!0){let outElement;if(element instanceof Element){for(let i=element.attributes.length-1;i>=0;i--){const attribute=element.attributes[i];if(attribute.name==='key'){this._children[attribute.value]=element;break}}} + const elementVars=[];if(element.nodeType===Node.TEXT_NODE){if(this._containVar(element.nodeValue)){elementVars.push({field:'nodeValue',elementVar:element.nodeValue})}}else if(element instanceof Element){let className=element.className;while(this._containVar(className)){const endIndex=className.indexOf('}}')+2;elementVars.push({field:'classList',elementVar:className.substring(className.indexOf('{{'),endIndex)});className=className.substring(endIndex)}} + for(let i=0;i=0;i--){this._setVariables(element.childNodes[i])}}} + _setEventHandlersFromAttributes(element){const attributeNamesToRemove=[];for(let i=element.attributes.length-1;i>=0;i--){const attribute=element.attributes[i];if(attribute.name.startsWith('on')){const event=attribute.name.substring(2).toLowerCase();const handler=(this)[attribute.value];if(handler===undefined||!(handler instanceof Function)){throw new Error('Could not find valid '+event+' handler '+attribute.value+' for element with id '+element.id)} + const boundHandler=handler.bind(this);attributeNamesToRemove.push(attribute.name);element.addEventListener(event,boundHandler)}} + for(let i=attributeNamesToRemove.length-1;i>=0;i--){element.removeAttribute(attributeNamesToRemove[i])} + for(let i=element.children.length-1;i>=0;i--){this._setEventHandlersFromAttributes(element.children[i])}} + _render(state){const keys=Object.keys(state);for(let i=keys.length-1;i>=0;i--){const key=keys[i];if(key in this._vars&&state[key]!==this._oldState[key]){const _var=this._vars[key];for(let j=0;j<_var.length;j++){const{field,element}=_var[j];if(field==='classList'){let classList=this._splitNonEmpty(this._oldState[key]);const elementAsObj=(element);elementAsObj[field].remove(...classList);classList=this._splitNonEmpty(state[key]);elementAsObj[field].add(...classList)}else{if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isHTML(state[key])){const newElement=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.htmlToElement(state[key]);element.parentNode.replaceChild(newElement,element);this._vars[key][j].element=newElement}else if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.hasHTML(state[key])){if(element.nodeType===Node.TEXT_NODE){const newElement=document.createElement('span');newElement.innerHTML=state[key];const parent=element.parentElement||element.parentNode;parent.replaceChild(newElement,element);this._vars[key][j].element=newElement;this._vars[key][j].field='innerHTML'}else{element.innerHTML=state[key]}}else{const elementAsObj=(element);elementAsObj[field]=state[key]}}}}}} + __enable(){window.addEventListener('resize',this.resize);this.registerCallbacks();if(this._parent){this._parent.appendChild(this._element);this.triggerCallbacks('statuschange',[!0,this])}} + __disable(){if(this._parent&&this._parent.contains(this._element)){this.triggerCallbacks('statuschange',[!1,this]);this._element=this._parent.removeChild(this._element)} + window.removeEventListener('resize',this.resize);this.removeCallbacks()} + __destroy(){this.__disable();this._element=null;this._parent=null} + _initCallbacks(){for(let i=0;i-1){this._callbacks[eventName].splice(index,1)}} + triggerCallbacks(eventName,params=[]){for(let i=this._callbacks[eventName].length-1;i>=0;i--){const callback=this._callbacks[eventName][i];callback(...params)}} + registerCallbacks(){for(let i=0;i{const component=hasPlaceholder?await app.addComponentWithPlaceholder({type:TypeConstructor,name,args,options}):await app.addComponent(name,TypeConstructor,...args,options);if(TypeConstructor.postCreationFunction){TypeConstructor.postCreationFunction(app,component)} + return component};BaseComponent.html=undefined;BaseComponent.postCreationFunction=undefined}),"../eyes/src/components/breadcrumb/breadcrumb.js": + /*!*******************************************************!*\ + !*** ../eyes/src/components/breadcrumb/breadcrumb.js ***! + \*******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Breadcrumb":function(){return Breadcrumb}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _breadcrumb_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./breadcrumb.html */"../eyes/src/components/breadcrumb/breadcrumb.html");var _breadcrumb_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_breadcrumb_html__WEBPACK_IMPORTED_MODULE_1__);class Breadcrumb extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={params:{}}){options.params={title:'',...options.params};super(app,null,options);this._class.isHomeActiveClass={true:'active',false:''};this._crumbTexts={compare:'Compare Size',events:'Mission Events'};this.setCrumbClickHandler(route=>{this._app.getManager('router').navigate(route,'',{__remove:'all',keepTime:!0})});Object.assign(this._state,{isHomeActive:!1,isHomeActiveClass:this._class.isHomeActiveClass.false});this.bindFunctions(['_goToHome'])} + updateBreadcrumb(routeParts){this._element.innerHTML='';const docFrag=document.createDocumentFragment();if(this._app.getManager('router').configs.logo===!1){this._children.staticLogo.classList.add('hidden')} + if(this._app.getManager('router').configs.locked){this._children.static.classList.remove('clickable')} + docFrag.appendChild(this._children.static);const isHomeActive=!routeParts||routeParts.length===0||(routeParts.length===1&&routeParts[0]==='home');if(isHomeActive){routeParts=null} + this.setState({isHomeActive,isHomeActiveClass:this._class.isHomeActiveClass[isHomeActive]});if(routeParts&&routeParts.length>0){for(let i=0;i{this._onCrumbClick(route)})} + const separator=document.createElement('span');separator.className='separator icon icon-greater';container.appendChild(separator);const textSpan=document.createElement('a');textSpan.innerHTML=this._getCrumbText(text)||text;textSpan.className='text link';container.appendChild(textSpan);return container}} + Breadcrumb.html=(_breadcrumb_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/carousel/carousel.js": + /*!***************************************************!*\ + !*** ../eyes/src/components/carousel/carousel.js ***! + \***************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var tippy_js__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! tippy.js */"../eyes/node_modules/tippy.js/dist/tippy.esm.js");var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _carousel_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./carousel.html */"../eyes/src/components/carousel/carousel.html");var _carousel_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_carousel_html__WEBPACK_IMPORTED_MODULE_1__);var _slide_template_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./slide_template.html */"../eyes/src/components/carousel/slide_template.html");var _slide_template_html__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_slide_template_html__WEBPACK_IMPORTED_MODULE_2__);class Carousel extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,element,options={}){const hintAction=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isPrimaryTouch()?'Swipe/Tap':'Scroll/Click';options.config={infinite:!1,initialSlideIndex:0,vertical:!0,timeout:1000,navigationButtons:{prev:{text:'Prev',icon:'icon-greater up'},next:{text:'Next',icon:'icon-greater down'},replay:{text:'Back To Start',icon:'icon-replay'}},hintText:{default:``,first:`Click arrows on phone to continue`,last:`Click arrows on phone for previous`},...options.config};super(app,element,{slideType:'',previousIndex:-1,currentIndex:options.config.initialSlideIndex||0,isScrolling:!1,isScrollingClass:'',isTimeout:!1,collapseClass:'expand',isCollapsed:!1,collapseButtonClass:'icon-collapse',isCloseButtonVisible:!1,closeButtonText:'Exit',isControlsVisible:!1,...options});Object.assign(this._state,{isCloseButtonVisibleClass:this._class.isVisible[this._state.isCloseButtonVisible],isControlsVisibleClass:this._class.isVisible[this._state.isControlsVisible]});this._children={track:null,slides:[]};this._progressTooltip=null;this._onEnter={};this._onLeave={};this._slideTypes=['panel','overlay'];this._currentInfo=null;this._onSlideChange=this.goToSlide;this._toggleControls=null;this._eventNames.push('slidechange','expandtoggle');this._initCallbacks();this.bindFunctions(['_setSlideTrackDimensions','_updateCarousel','_onScroll','_toggleCollapse','_onControlsToggle','goToPrevSlide','goToNextSlide','close'])} + get currentInfo(){return this._currentInfo} + _onControlsToggle(){this._toggleControls()} + setOnControlsToggle(cb){this._toggleControls=cb} + init(){super.init();this._children.carousel.classList.add(this._config.vertical?'vertical':'horizontal');this._createSlideTrack();this._updateCarousel();this._children.carousel.classList.add('initialized');window.addEventListener('keydown',event=>{if(event.key==='Tab'&&this._state.isScrolling){event.preventDefault()}});this._children.carousel.addEventListener('transitionstart',event=>{if(event.target===this._children.track&&event.propertyName==='transform'){this.setState({isScrolling:!0,isScrollingClass:'scrolling'});this._children.carousel.style.pointerEvents='all'}},!0);this._children.carousel.addEventListener('transitionend',event=>{if(event.target===this._children.track&&event.propertyName==='transform'){this.setState({isScrolling:!1,isScrollingClass:'scrolling-done'});this._children.carousel.style.pointerEvents='none'}},!0);this._children.progress.addEventListener('wheel',this._onScroll,{passive:!1});this._children.progress.addEventListener('touchstart',event=>{const touchEvent=event.changedTouches[0];this._touchStartY=touchEvent.pageY});this._children.progress.addEventListener('touchmove',event=>{const touchEvent=event.changedTouches[0];event.deltaY=touchEvent.pageY-this._touchStartY;this._onScroll(event,'touch')},{passive:!1});this._children.progress.addEventListener('touchend',event=>{const touchEvent=event.changedTouches[0];event.deltaY=touchEvent.pageY-this._touchStartY;this._onScroll(event,'touch')},{passive:!1})} + resize(){super.resize();setTimeout(this._setSlideTrackDimensions,100);this._updateTooltipsProps()} + _updateTooltipsProps(){const{slideType}=this._state;this._progressTooltip.setProps({offset:slideType==='overlay'?[0,-30]:[0,10]})} + _createSlideTrack(){this._children.slides.forEach(slide=>{this._children.track.appendChild(slide)});this._setSlideTrackDimensions()} + _setSlideTrackDimensions(){const{track,slides}=this._children;const{vertical}=this._config;slides.forEach(slide=>{slide.style.transition='none'});track.style.transition='none';if(vertical){const height=[...slides].reduce((acc,slide)=>(acc+slide.getBoundingClientRect().height),0);track.style.height=height+'px'}else{const width=[...slides].reduce((acc,slide)=>(acc+slide.getBoundingClientRect().width),0);track.style.width=width+'px'} + track.style.transition='';slides.forEach(slide=>{slide.style.transition=''});this._updateTrackPosition()} + _updateTrackPosition(){const{currentIndex}=this._state;let trackOffset=0;for(let i=0;i=element.scrollHeight;if(event.deltaY<0){if(type==='mouse'){if(event.deltaY<-4&&scrolledToTop){this.goToPrevSlide()}}else{if(event.deltaY<-5&&scrolledToBottom){this.goToNextSlide()}}}else if(event.deltaY>0){if(type==='mouse'){if(event.deltaY>4&&scrolledToBottom){this.goToNextSlide()}}else{if(event.deltaY>5&&scrolledToTop){this.goToPrevSlide()}}}} + this.setState({isTimeout:!0},()=>setTimeout(()=>this.setState({isTimeout:!1}),this._config.timeout));if(['wheel','touchmove'].includes(event.type)){event.stopPropagation()}} + addSlide(slideInfo,{isLast=!1,isFirst=!1}={}){const html=slideInfo.html||(_slide_template_html__WEBPACK_IMPORTED_MODULE_2___default());const{type,content}=slideInfo;if(!this._slideTypes.includes(type)){console.warn(`addSlide: Unknown slide type "${type}". Supported types: ${this._slideTypes}`)} + const slide=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.htmlWithParamsToElement(html,{prevButtonText:this._config.navigationButtons.prev.text,prevButtonIcon:this._config.navigationButtons.prev.icon,nextButtonText:this._config.navigationButtons.next.text,nextButtonIcon:this._config.navigationButtons.next.icon,replayButtonText:this._config.navigationButtons.replay.text,replayButtonIcon:this._config.navigationButtons.replay.icon,hintText:()=>{if(isLast){return this._config.hintText.last}else if(isFirst){return this._config.hintText.first}else{return this._config.hintText.default}},type});slide.querySelector('.content').appendChild(content);if(isLast){slide.classList.add('last')} + if(isFirst){slide.classList.add('first')} + if(slideInfo.classList){slide.classList.add(...slideInfo.classList)} + if(slideInfo.id){slide.dataset.id=slideInfo.id} + slide.dataset.type=slideInfo.type||'';this._children.track.appendChild(slide);this._children.slides.push(slide);const slideContainer=slide.firstChild;slideContainer.addEventListener('wheel',this._onScroll,{passive:!1});slideContainer.addEventListener('touchstart',event=>{const touchEvent=event.changedTouches[0];this._touchStartY=touchEvent.pageY});slideContainer.addEventListener('touchmove',event=>{const touchEvent=event.changedTouches[0];event.deltaY=touchEvent.pageY-this._touchStartY;this._onScroll(event,'touch')},{passive:!1});slideContainer.addEventListener('touchend',event=>{const touchEvent=event.changedTouches[0];event.deltaY=touchEvent.pageY-this._touchStartY;this._onScroll(event,'touch')},{passive:!1});this._setVariables(slide);this._setEventHandlersFromAttributes(slide);this._setSlideTrackDimensions();this._updateCarousel();_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addScrollbar(slideContainer);this._progressTooltip=(0,tippy_js__WEBPACK_IMPORTED_MODULE_3__["default"])(this._children.progress.parentElement,{theme:'default',onShow(instance){clearTimeout(instance.timeout);instance.timeout=setTimeout(()=>{instance.hide()},2000)}})} + addSlides(slidesInfo){for(let i=0;i{this._updateCarousel();this._children.progress.style.top=`calc(${currentIndex * 100 / (this._children.slides.length - 1)}% - ${this._children.progress.offsetHeight / 2}px)`;const element=this._children.slides[currentIndex].querySelector('.os-viewport');if(element){element.scrollTop=0} + this.triggerCallbacks('slidechange',[this._currentInfo]);this._progressTooltip.setContent(`${currentIndex + 1} of ${this._children.slides.length}`);this._updateTooltipsProps();if(this._state.isVisible){}});await this.onEnter(currentIndex);if(spout===!0){await this.app.getManager('spout').setUpSpoutLabels(spoutFontSize)}} + goToPrevSlide(){const{currentIndex}=this._state;const lastSlideIndex=this._children.slides.length-1;const slideToGo=currentIndex-1;if(slideToGo<0){if(this._config.infinite){this._onSlideChange(lastSlideIndex)}}else{this._onSlideChange(slideToGo)}} + goToNextSlide(){const{currentIndex}=this._state;const lastSlideIndex=this._children.slides.length-1;const slideToGo=currentIndex+1;if(slideToGo>lastSlideIndex){if(this._config.infinite){this._onSlideChange(0)}}else{this._onSlideChange(slideToGo)}} + goToFirstSlide(){this._onSlideChange(0)} + isVisible(){return this._state.isVisible} + collapse(){this.setState({isCollapsed:!0,collapseClass:'collapse',collapseButtonClass:'icon-expand'});this.triggerCallbacks('expandtoggle',[!1])} + expand(){this.setState({isCollapsed:!1,collapseClass:'expand',collapseButtonClass:'icon-collapse'});this.triggerCallbacks('expandtoggle',[!0])} + close(){} + show(){super.show();this._updateCarousel();if((this._progressTooltip!==null)&&(this._children.slides.length>1)){}} + clear(){this._children.track.innerHTML='';this._children.slides=[];this._onEnter={};this._onLeave={};this._currentInfo=null;this._state.previousIndex=1;this._state.currentIndex=this._config.initialSlideIndex||0} + _toggleCollapse(){if(this._state.isCollapsed){this.expand()}else{this.collapse()}}} + Carousel.html=(_carousel_html__WEBPACK_IMPORTED_MODULE_1___default());__webpack_exports__["default"]=(Carousel)}),"../eyes/src/components/carousel/index.js": + /*!************************************************!*\ + !*** ../eyes/src/components/carousel/index.js ***! + \************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _carousel_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./carousel.js */"../eyes/src/components/carousel/carousel.js");__webpack_exports__["default"]=(_carousel_js__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/carousel_panel/carousel_panel.js": + /*!***************************************************************!*\ + !*** ../eyes/src/components/carousel_panel/carousel_panel.js ***! + \***************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var swiper__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! swiper */"../eyes/node_modules/swiper/swiper.esm.js");var _internal__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _carousel_panel_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./carousel_panel.html */"../eyes/src/components/carousel_panel/carousel_panel.html");var _carousel_panel_html__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_carousel_panel_html__WEBPACK_IMPORTED_MODULE_2__);swiper__WEBPACK_IMPORTED_MODULE_0__["default"].use([swiper__WEBPACK_IMPORTED_MODULE_0__.Navigation,swiper__WEBPACK_IMPORTED_MODULE_0__.Pagination,swiper__WEBPACK_IMPORTED_MODULE_0__.Keyboard,swiper__WEBPACK_IMPORTED_MODULE_0__.Mousewheel]);class CarouselPanel extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseComponent{constructor(app,options={}){const{paginationClass,prevButtonClass,nextButtonClass}=options;options.config={direction:'horizontal',speed:600,grabCursor:!0,touchStartPreventDefault:!1,slidesPerView:1,spaceBetween:100,keyboard:{enabled:!0},mousewheel:{forceToAxis:!0,thresholdDelta:100},navigation:{prevEl:`.${prevButtonClass}`,nextEl:`.${nextButtonClass}`},...paginationClass&&{pagination:{el:`.${paginationClass}`,type:'custom',renderCustom:(swiper,current,total)=>`${current} of ${total}`}},...options.config};super(app,null,{isVisible:!1,preTitle:'viewing',title:'Panel Title',caption:'This is the panel subtitle',carouselClass:'',paginationClass:'',prevButtonClass:'',nextButtonClass:'',isExpandedClass:'collapsed',tabsVisibleClass:'hidden',tabNumClass:'',...options});this._swiper=null;this._tabIndices=null;this._activeTabIndex=null;this._tabElements=null;this._bulletClass='swiper-pagination-bullet';this._activeBulletClass='swiper-pagination-bullet-active';this._swiperSlideClass='swiper-slide';this._onSlideChange=null;this._expandOnShow=!1;this._orientation=null;this._resizeTimeout=null;this._isInitialized=null;this._eventNames.push('expandtoggle');this._initCallbacks();this.bindFunctions(['_onTabClick'])} + _addEvents(){this._swiper.on('slideChange',params=>{const{realIndex,previousIndex}=params;let bulletIndex=realIndex;typeof this._onSlideChange==='function'&&this._onSlideChange(params);const prevSlideEl=this._children.swiperSlides.childNodes[previousIndex];if(prevSlideEl?._scrollInstance){prevSlideEl._isMousedown=!1;prevSlideEl._scrollInstance.scroll(0)} + if(this._tabElements){const newTabIndex=this._tabIndices.findIndex(({start,end})=>realIndex>=start&&realIndex<=end);const{start}=this._tabIndices[newTabIndex];bulletIndex-=start;if(newTabIndex>-1&&newTabIndex!==this._activeTabIndex){this._tabElements.forEach((tabEl,i)=>{tabEl.classList.toggle('active',i===newTabIndex)});this._activeTabIndex=newTabIndex;this._createBullets(bulletIndex);return}} + this._setActiveBullet(bulletIndex)});this._children.swiperSlides.addEventListener('click',event=>{const definition=event?.target?.dataset?.def;if(definition){this._app.getComponent('definitionOverlay').navigateToDefinition(definition)}})} + _hasOrientationChanged(){const newOrientation=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.isPortrait()?'portrait':'landscape';const orientationChanged=this._orientation!==newOrientation;this._orientation=newOrientation;return orientationChanged} + _addScrollbars(){const orientationChanged=this._hasOrientationChanged();this._children?.swiperSlides?.childNodes?.forEach(slideEl=>{const{clientHeight,scrollHeight,cHeight,sHeight}=slideEl;const heightUnchanged=(cHeight&&cHeight===clientHeight)&&(sHeight&&sHeight===scrollHeight);if(heightUnchanged&&!orientationChanged){return} + slideEl._scrollInstance?.destroy();const{clientHeight:newClientHeight,scrollHeight:newScrollHeight}=slideEl;slideEl.sHeight=newClientHeight;slideEl.cHeight=newScrollHeight;if(newScrollHeight>newClientHeight){slideEl.classList.add('scrollable');slideEl._scrollInstance??=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.addScrollbar(slideEl);slideEl._isMousedown=!1;slideEl._clientY=0;const onMouseMove=({clientY})=>{if(slideEl._isMousedown){const yDiff=slideEl._clientY-clientY;slideEl._scrollInstance.scroll({y:`+=${yDiff}`});slideEl._clientY=clientY}};slideEl.onmousedown=({clientY})=>{slideEl._isMousedown=!0;slideEl._clientY=clientY;window.addEventListener('mousemove',onMouseMove);window.addEventListener('mouseup',function onMouseUp(){slideEl._isMousedown=!1;window.removeEventListener('mousemove',onMouseMove);window.removeEventListener('mouseup',onMouseUp)})}}})} + createTabs(allTabsContent){this._tabIndices=[];this._activeTabIndex=0;let indexPointer=0;if(this._swiper){this._destroy()} + this._tabElements=allTabsContent.map(({title,content},i)=>{const tabButtonEl=document.createElement('button');tabButtonEl.innerHTML=title;tabButtonEl.className=`clickable ${i === this._activeTabIndex ? 'active' : ''}`;tabButtonEl.addEventListener('click',this._onTabClick);this._tabIndices.push({start:indexPointer,end:indexPointer+content.length-1});indexPointer+=content.length;for(const tabData of content){const slideElements=this._createSlideElements(tabData);this.addSlide(slideElements,tabData.onClick)} + return tabButtonEl});this._children.tabsContainer.replaceChildren(...this._tabElements);this.setState({tabsVisibleClass:'',tabNumClass:`tabs-${this._tabElements.length}`})} + _createSlideElements(tabData){const{title,content,value}=tabData;const slideElements=[];if(title){const titleEl=document.createElement('h4');titleEl.className='title semi';titleEl.innerHTML=title;slideElements.push(titleEl)} + if(content){const contentEl=document.createElement('div');contentEl.className='description';contentEl.innerHTML=content;slideElements.push(contentEl)} + if(value){const valueEl=document.createElement('div');valueEl.className='value semi';valueEl.innerHTML=value;slideElements.push(valueEl)} + return slideElements} + _createBullets(activeBullet=0){const{bullets}=this._children;const{slides}=this._swiper;let slidesArray=[...slides];let startOffset=0;if(this._tabElements){const{start,end}=this._tabIndices[this._activeTabIndex];startOffset=start;slidesArray=slidesArray.slice(start,end+1)} + const allBullets=[...slidesArray].map((slide,i)=>{const bullet=document.createElement('span');bullet.classList.add(this._bulletClass);bullet.setAttribute('data-slide-index',i+startOffset);bullet.addEventListener('click',e=>{const{slideIndex}=e.target.dataset;this._swiper.slideTo(slideIndex)});return bullet});const onHideFinish=transition=>{if(transition&&transition.propertyName!=='width'){return} + bullets.replaceChildren(...allBullets);bullets.classList.remove('hidden');this._setActiveBullet(activeBullet)};if(bullets.classList.contains('hidden')){onHideFinish()}else{bullets.classList.add('hidden');bullets.ontransitionend=onHideFinish;bullets.ontransitioncancel=onHideFinish}} + _setActiveBullet(activeIndex){const{bullets}=this._children;bullets.childNodes.forEach((bullet,i)=>{bullet.classList.remove(this._activeBulletClass);if(i===activeIndex){bullet.classList.add(this._activeBulletClass)}})} + addSlide(elements=[],onClick){const slideEl=document.createElement('div');slideEl.className=`${onClick ? 'clickable' : ''} ${this._swiperSlideClass}`;onClick&&slideEl.addEventListener('click',onClick);slideEl.replaceChildren(...elements);this._children.swiperSlides.append(slideEl)} + initSwiper(){const{carouselClass}=this._state;const selector=`.${carouselClass} .swiper-wrapper > div`;return _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.elementReady(selector).then(()=>{if(this._swiper){this._swiper.update();this._addScrollbars();this._createBullets();this._swiper.slideTo(0)}else{this._swiper=new swiper__WEBPACK_IMPORTED_MODULE_0__["default"](`.${carouselClass}`,this._config);this._postSwiperInitFunction(this._swiper)}})} + _postSwiperInitFunction(){this._addEvents();this._addScrollbars();this._createBullets();this._swiper.update();this._swiper.slideTo(0)} + _destroy(){this._children.swiperSlides.innerHTML='';clearTimeout(this._resizeTimeout)} + _onTabClick(e){const activeTabIndex=this._tabElements.findIndex(tab=>tab===e.target);const{start}=this._tabIndices[activeTabIndex];this._swiper.slideTo(start)} + expand(){this.setState({isExpanded:!0,isExpandedClass:'expanded'});this.triggerCallbacks('expandtoggle',[!0])} + collapse(){this.setState({isExpanded:!1,isExpandedClass:'collapsed'});this.triggerCallbacks('expandtoggle',[!1])} + setExpandState(expanded){this.setState({isExpanded:expanded,isExpandedClass:expanded?'expanded':'collapsed'});this.triggerCallbacks('expandtoggle',[expanded])} + show(initSwiper=!0){const visibleUI=this._app.getManager('layer').getLayer('ui').visible;const hasSwiperContent=this._children.swiperSlides?.childNodes?.length;const showFunc=()=>{if(this._expandOnShow){this.setState({isVisible:!0,isVisibleClass:this._class.isVisible.true,isExpanded:!0,isExpandedClass:'expanded'});this.triggerCallbacks('expandtoggle',[!0]);this.triggerCallbacks('visiblechange',[!0])}else{super.show()}};if(initSwiper&&visibleUI&&hasSwiperContent){this.initSwiper().then(()=>showFunc())}else{showFunc()}} + hide(){this.setState({isVisible:!1,isVisibleClass:this._class.isVisible.false,isExpanded:!1,isExpandedClass:'collapsed'});this.triggerCallbacks('expandtoggle',[!1,!1]);this.triggerCallbacks('visiblechange',[!1]);if(this._expandOnShow){this._isInitialized=!1}} + resize(){clearTimeout(this._resizeTimeout);this._resizeTimeout=setTimeout(()=>{this._addScrollbars()},200)}} + CarouselPanel.html=(_carousel_panel_html__WEBPACK_IMPORTED_MODULE_2___default());__webpack_exports__["default"]=(CarouselPanel)}),"../eyes/src/components/carousel_panel/index.js": + /*!******************************************************!*\ + !*** ../eyes/src/components/carousel_panel/index.js ***! + \******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _carousel_panel__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./carousel_panel */"../eyes/src/components/carousel_panel/carousel_panel.js");__webpack_exports__["default"]=(_carousel_panel__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/checkbox/checkbox.js": + /*!***************************************************!*\ + !*** ../eyes/src/components/checkbox/checkbox.js ***! + \***************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Checkbox":function(){return Checkbox}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _checkbox_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./checkbox.html */"../eyes/src/components/checkbox/checkbox.html");var _checkbox_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_checkbox_html__WEBPACK_IMPORTED_MODULE_1__);class Checkbox extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={}){super(app,null,{config:{key:'',colorClass:'',function:null},isChecked:!1,text:'',checkboxClass:'',textClass:'',...options});Object.assign(this._class,{checkbox:{true:'checked',false:''},color:{true:this._config.colorClass,false:''},checkmark:{true:'icon-checkmark',false:'checkbox-hover'}});Object.assign(this._state,{isCheckedClass:this._class.checkbox[this._state.isChecked],colorClass:this._class.color[this._state.isChecked],iconCheckmarkClass:this._class.checkmark[this._state.isChecked]});this.bindFunctions(['toggle'])} + init(){super.init();if(this._config.key){this._element.setAttribute('key',this._config.key)} + this._element.addEventListener('click',this.toggle)} + async toggle(e,suppress=!1){const isChecked=!this._state.isChecked;const isCheckedClass=this._class.checkbox[isChecked];const colorClass=this._class.color[isChecked];const iconCheckmarkClass=this._class.checkmark[isChecked];this.setState({isChecked,isCheckedClass,colorClass,iconCheckmarkClass},async()=>{if(!suppress&&this._config.function instanceof Function){await this._config.function(e)}})}} + Checkbox.html=(_checkbox_html__WEBPACK_IMPORTED_MODULE_1___default());__webpack_exports__["default"]=(Checkbox)}),"../eyes/src/components/checkbox/index.js": + /*!************************************************!*\ + !*** ../eyes/src/components/checkbox/index.js ***! + \************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _checkbox_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./checkbox.js */"../eyes/src/components/checkbox/checkbox.js");__webpack_exports__["default"]=(_checkbox_js__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/clock/clock.js": + /*!*********************************************!*\ + !*** ../eyes/src/components/clock/clock.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Clock":function(){return Clock}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _clock_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./clock.html */"../eyes/src/components/clock/clock.html");var _clock_html__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_clock_html__WEBPACK_IMPORTED_MODULE_2__);class Clock extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={}){super(app,null,{isVisible:!1,isDateVisible:!0,isTimeVisible:!0,isMeridiemVisible:!0,allowEdit:!0,date:'Date',time:'Time',meridiem:'',alert:'',isKioskSessionTimer:!1,...options});Object.assign(this._state,{isDateVisibleClass:this._class.isVisible[this._state.isDateVisible],isTimeVisibleClass:this._class.isVisible[this._state.isTimeVisible],isMeridiemVisibleClass:this._class.isVisible[this._state.isMeridiemVisible]});this.bindFunctions(['update','onDateTimeClick'])} + init(){super.init();const{allowEdit,isKioskSessionTimer}=this._state;this._app.getManager('time').setDateFormats({utc:{date:'MMM DD, YYYY',time:'HH[:]mm[:]ss'},local:{date:'MMM DD, YYYY',time:'hh[:]mm[:]ss',meridiem:'a',parse:['MMM D, YYYY h:m:s a','MMM D, YYYY h:m a','MMM D, YYYY h a','MMM D, YYYY']}});this._app.getManager('time').setDisplayUTC(!1);const{displayContainer,timeInput,timeForm}=this._children;if(allowEdit){displayContainer.classList.add('editable');timeInput.addEventListener('keyup',event=>{event.stopPropagation()});timeInput.addEventListener('keydown',event=>{event.stopPropagation()});timeForm.classList.add('editable');timeForm.addEventListener('submit',event=>{timeInput.blur();this._parseTime(timeInput.value);event.preventDefault()});timeInput.addEventListener('blur',_=>{timeForm.classList.add('hidden');displayContainer.classList.remove('hidden')})} + this._setVariables(this._element);this._children.date.classList.add('semi');this._children.time.classList.add('semi');this._children.meridiem.classList.add('semi');this._children.timeInput.classList.add('semi');this._children.timeForm.classList.add('semi');if(!isKioskSessionTimer){this._callbackRegistry.push({emitter:this._app.getManager('time'),event:'update',callback:this.update})}} + onDateTimeClick(){const{displayContainer,timeInput,timeForm,date,time,meridiem}=this._children;const routeManager=this._app.getManager('router');const isStory=routeManager.currentRoute.url.includes('story');if(!this._state.allowEdit||isStory){return} + const meridiemText=this._state.meridiem?` ${meridiem.innerHTML}`:'';timeInput.value=`${date.innerHTML} ${time.innerHTML}${meridiemText}`;displayContainer.classList.add('hidden');timeForm.classList.remove('hidden');timeInput.focus()} + isERT(){return this._isERT} + toggle(field,isVisible){switch(field){case 'date':this.setState({isDateVisible:isVisible,isDateVisibleClass:this._class.isVisible[isVisible]});break;case 'time':this.setState({isTimeVisible:isVisible,isTimeVisibleClass:this._class.isVisible[isVisible]});break;case 'meridiem':this.setState({isMeridiemVisible:isVisible,isMeridiemVisibleClass:this._class.isVisible[isVisible]});break;default:break}} + _parseTime(timeString){const router=this._app.getManager('router');const time=this._app.getManager('time').parseTime(timeString,'parse');if(time.isValid()){this._app.getManager('time').setDisplayUTC(time.isUTC());const timeUrl=this._app.getManager('time').getTimeUrl(time);router.navigate({time:timeUrl},router.currentRoute.url)}else{console.error('Invalid input: '+timeString);router.navigate({__remove:['time']},router.currentRoute.url)}} + update(time,kioskCountdown=!1){if(!this._state.isVisible){return} + if(kioskCountdown){this.setState({time})}else{this.setState({date:time.format(this._app.getManager('time').getDateFormat('date')),time:time.format(this._app.getManager('time').getDateFormat('time')),meridiem:this._app.getManager('time').isUTC()?'':time.format(this._app.getManager('time').getDateFormat('meridiem')),alert:this._app.getManager('time').forcedPause?'alert':''})}} + backToLive(){const router=this._app.getManager('router');const timeManager=this._app.getManager('time');if(!timeManager.isNow()){const time=timeManager.getTimeUrl(timeManager.getNow());const oldTime=router.query.time;router.navigate({__remove:['time','rate']},router.currentRoute.url);if(oldTime!==time){timeManager.setTimeRate(1);timeManager.setToNow()}}} + setLimitMessage(limit,message){const messageTimeMs=3000;let limitMessage;if(!message){const{currentView}=this._app.getManager('router');const{_isSpacecraft}=this._app.getView(currentView);let messageSuffix=`time ${limit === 1 ? 'maximum' : 'minimum'}`;if(currentView==='event'){messageSuffix=`event ${limit === 1 ? 'end' : 'start'}`}else if(_isSpacecraft){messageSuffix=`mission ${limit === 1 ? 'end' : 'start'}`} + limitMessage=limit===1?`"cannot exceed ${messageSuffix}"`:`"cannot preceed ${messageSuffix}"`}else{limitMessage=`"${message}"`} + this._children.displayContainer?.style.setProperty('--limit-message',limitMessage);this._displayLimitMessage(!0);this.limitMessageTimeout=setTimeout(()=>{this._displayLimitMessage(!1)},messageTimeMs)} + _displayLimitMessage(visible){this._children.displayContainer?.classList.toggle('limit',visible)} + __disable(){this._displayLimitMessage(!1);clearTimeout(this.limitMessageTimeout);super.__disable()}} + Clock.html=(_clock_html__WEBPACK_IMPORTED_MODULE_2___default());__webpack_exports__["default"]=(Clock)}),"../eyes/src/components/clock/index.js": + /*!*********************************************!*\ + !*** ../eyes/src/components/clock/index.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _clock_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./clock.js */"../eyes/src/components/clock/clock.js");__webpack_exports__["default"]=(_clock_js__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/clock_shortcut/clock_shortcut.js": + /*!***************************************************************!*\ + !*** ../eyes/src/components/clock_shortcut/clock_shortcut.js ***! + \***************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var tippy_js__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! tippy.js */"../eyes/node_modules/tippy.js/dist/tippy.esm.js");var _internal__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _clock_shortcut_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./clock_shortcut.html */"../eyes/src/components/clock_shortcut/clock_shortcut.html");var _clock_shortcut_html__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_clock_shortcut_html__WEBPACK_IMPORTED_MODULE_2__);class ClockShortcut extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseComponent{constructor(app){super(app,null,{hasHover:!1,liveContainerClass:'hidden',liveClass:'live',liveText:'live',liveIcon:'icon-live',replayClass:'container',replayIcon:'icon-replay'});this._state.replayClass='hidden';this._class.fontSize.small='x-small';this._liveCallback=null;this.bindFunctions(['_replay','backToLive','update'])} + init(){super.init();const{canHover,isTouch}=this._app;if(canHover&&!isTouch){this._children.liveContainer.addEventListener('mouseenter',()=>{this.setState({hasHover:!0,liveIcon:'icon-live'})});this._children.liveContainer.addEventListener('mouseleave',()=>{this.setState({hasHover:!1,liveIcon:'icon-back-to-live'})})} + tippy_js__WEBPACK_IMPORTED_MODULE_3__["default"].setDefaultProps({theme:'default',touch:['hold',2000],delay:[600,null],plugins:[tippy_js__WEBPACK_IMPORTED_MODULE_3__.followCursor]});(0,tippy_js__WEBPACK_IMPORTED_MODULE_3__["default"])(this._children.liveContainer,{content:'Reset time to live.',placement:'top'});this._children.live.classList.add('semi','color');this._children.replay.classList.add('semi','color');this._element.removeChild(this._children.replayContainer);this._callbackRegistry.push({emitter:this._app.getManager('time'),event:'update',callback:this.update})} + setCallback(callback){if(typeof callback==='function'){this._liveCallback=callback}else{this._liveCallback=null}} + backToLive(){if(typeof this._liveCallback==='function'){this._liveCallback()}else{const router=this._app.getManager('router');const timeManager=this._app.getManager('time');if(!timeManager.isNow()){const time=timeManager.getTimeUrl(timeManager.getNow());const oldTime=router.query.time;router.navigate({__remove:['time','rate']},router.currentRoute.url);if(oldTime!==time){timeManager.setTimeRate(1);timeManager.setToNow()}}}} + _replay(){const navigated=this._app.getManager('router').navigate({__remove:['time','rate']});if(!navigated){this._app.getManager('time').setTimeRate(1);this._app.getManager('time').setToStart()}} + update(time){if(!this._state.isVisible){return} + const isNow=this._app.getManager('time').isNow();const now=this._app.getManager('time').getNow();const inBounds=this._app.getManager('time').isWithinLimits(now);const newState={liveContainerClass:(inBounds===0)?(isNow?'active':'clickable'):'hidden',liveClass:isNow?'live':'',replayClass:_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.isMobileMode()?'icon icon-box':'container'};if(!this._state.hasHover){newState.liveIcon=isNow?'icon-live':'icon-back-to-live'} + this.setState(newState)}} + ClockShortcut.html=(_clock_shortcut_html__WEBPACK_IMPORTED_MODULE_2___default());__webpack_exports__["default"]=(ClockShortcut)}),"../eyes/src/components/clock_shortcut/index.js": + /*!******************************************************!*\ + !*** ../eyes/src/components/clock_shortcut/index.js ***! + \******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _clock_shortcut_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./clock_shortcut.js */"../eyes/src/components/clock_shortcut/clock_shortcut.js");__webpack_exports__["default"]=(_clock_shortcut_js__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/kiosk_base/kiosk_base.js": + /*!*******************************************************!*\ + !*** ../eyes/src/components/kiosk_base/kiosk_base.js ***! + \*******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"KioskBase":function(){return KioskBase}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var _kiosk_base_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./kiosk_base.html */"../eyes/src/components/kiosk_base/kiosk_base.html");var _kiosk_base_html__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_kiosk_base_html__WEBPACK_IMPORTED_MODULE_2__);class KioskBase extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{static screenLastClicked=Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now());constructor(app,options={}){super(app,null,{isVisible:!1,loadingTextVisibleClass:'hidden',sessionEndVisibleClass:'hidden',autoplayVisibleClass:'hidden',sessionTimerVisibleClass:'hidden',continueButtonVisibleClass:'',forceRestartClass:'',...options});this._router=this.app.getManager('router');this.inactivityInterval=null;this.sessionInterval=null;this.timeOfDaySessionStarted=Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now());this.componentDefaultVisibility={menu:!1,shareModal:!1,infoPanel:!1,layerPanel:!1,featuredStoriesPanel:!0,timecontrolsCollapsible:!0}} + init(){super.init();const scene=this.app.pioneer.get('main');scene.getLoadedPromise().then(()=>{this.resetLastClicked();this.validateQueries();const{maxSessionTime,maxInactivityTime,forceRestart}=this._router.configs;if(this._isValidTime(maxSessionTime)){this.maxSessionTime=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.minToSec(maxSessionTime);this.setUpSessionTimerComponent();this.startSessionTimer();if(forceRestart===!0){this.setState({continueButtonVisibleClass:'hidden',forceRestartClass:'force-restart'})}} + if(this._isValidTime(maxInactivityTime)&&!this.inactivityInterval){this.maxInactivityTime=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.minToSec(maxInactivityTime);this.startInactivityTimer()} + return!0}).catch(error=>{console.warn(error)})} + validateQueries(){const{maxSessionTime:maxSessionTimeFromURL,maxInactivityTime:maxInactivityTimeFromURL}=this._router.configs;const queryValues={};for(const[key,value]of Object.entries(this._router.configs)){if(value){queryValues[key]=value}} + for(const query in queryValues){if(query.toLowerCase().includes('time')&&!this._isValidTime(queryValues[query])){delete queryValues[query]}} + const{maxSessionTime,maxInactivityTime}=queryValues;const bothTimersInURL=this._isValidTime(maxSessionTime)&&this._isValidTime(maxInactivityTime);if(bothTimersInURL){if(Math.abs(maxSessionTimeFromURL-maxInactivityTimeFromURL)<=0.05&&maxSessionTimeFromURL>0&&maxInactivityTimeFromURL>0){queryValues.maxInactivityTime=maxSessionTimeFromURL+0.1}else if(maxSessionTimeFromURL>=maxInactivityTimeFromURL){if(maxInactivityTimeFromURL===0){delete queryValues.maxSessionTime}else{queryValues.maxInactivityTime=maxSessionTimeFromURL+1}}} + this._router.setConfig('maxSessionTime',queryValues.maxSessionTime);this._router.setConfig('maxInactivityTime',queryValues.maxInactivityTime)} + _isValidTime(time){return time!==''&&!isNaN(Number(time))&&Number(time)>-1} + setEnabled(enabled){super.setEnabled(enabled);const{kiosk,maxSessionTime,maxInactivityTime}=this._router.configs;if(enabled&&(kiosk||this._isValidTime(maxSessionTime)||this._isValidTime(maxInactivityTime))){this.show()}} + resetLastClicked(){KioskBase.screenLastClicked=Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now())} + async sessionStartOverButtonClick(){this.setState({loadingTextVisibleClass:''});await this.resetApp();this.app.getManager('camera').waitForTransitionComplete().then(()=>{this.setState({loadingTextVisibleClass:'hidden'});return null}).catch(error=>{console.warn('error: ',error)})} + async onWindowInteract(){const{maxSessionTime,maxInactivityTime,forceRestart}=this._router.configs;const{kioskAutoplay,kioskSessionEnd}=this._children;const inAutoplay=!this.isHidden(kioskAutoplay);const sessionOver=!this.isHidden(kioskSessionEnd);this.setState({autoplayVisibleClass:'hidden'});this.setState({sessionEndVisibleClass:'hidden'});if((inAutoplay||sessionOver)&&!forceRestart){this.setState({loadingTextVisibleClass:''})} + clearInterval(this.inactivityInterval);this.inactivityInterval=null;if(inAutoplay){await this.app.cameraScripts.goToSystem('inner_solar_system')} + this.app.getManager('camera').waitForTransitionComplete().then(()=>{this.setState({loadingTextVisibleClass:'hidden'});return null}).catch(error=>{console.warn('error: ',error)});this.setState({sessionEndVisibleClass:'hidden'});this.resetLastClicked();if(this._isValidTime(maxSessionTime)&&(inAutoplay||sessionOver)){this.resetSessionTimer()} + if(this._isValidTime(maxInactivityTime)){this.startInactivityTimer()}} + setUpSessionTimerComponent(){const sessionClockComponent=this.app.getComponent('kioskSessionClock');const{kioskSessionTimer}=this._children;sessionClockComponent.setState({isKioskSessionTimer:!0});sessionClockComponent.show();sessionClockComponent.setEnabled(!0);sessionClockComponent.setParent(kioskSessionTimer);this.updateSessionTimerComponent()} + startSessionTimer(){this.timeOfDaySessionStarted=Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now());this.sessionInterval=setInterval(()=>{this.handleSessionTimer()},1000)} + handleSessionTimer(){const{kioskAutoplay}=this._children;const inAutoplay=!this.isHidden(kioskAutoplay);const now=Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now());this.timeElapsed=now-this.timeOfDaySessionStarted;this.setState({sessionTimerVisibleClass:''});if(this.timeElapsed{this.handleMaxInactivityTime()},1000)} + handleMaxInactivityTime(){this.currentTimeWithoutActivity=Math.ceil(pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.now())-KioskBase.screenLastClicked} + async startAutoplay(){this.setState({sessionTimerVisibleClass:'hidden'});this.setState({sessionEndVisibleClass:'hidden'});this.setState({autoplayVisibleClass:''});await this.resetApp();clearInterval(this.inactivityInterval);this.inactivityInterval=null} + resetLayers(layersToReset){if(layersToReset){for(const layer of Object.keys(layersToReset)){const{defaultVisibility}=this.app.getManager('layer').getLayer(layer);this.app.getManager('layer').toggleLayer(layer,{},defaultVisibility)}}} + resetComponents(componentsToReset){if(componentsToReset){for(const[componentName,showComponent]of Object.entries(componentsToReset)){const component=this.app.getComponent(componentName);showComponent?component?.show():component?.hide();this.app.getComponent(componentName)?.setExpanded?.(showComponent)}}} + async resetApp(){const uiLayers=this.app.getComponent('layerPanel').getCategoriesDisplay();const{currentView}=this._router;const isAtSystem=this.app.getManager('camera').getContext().context===_internal__WEBPACK_IMPORTED_MODULE_0__.CameraScripts.CONTEXT.SYSTEM;const isAtInnerSolarSystem=isAtSystem&&this.app.getManager('camera').getContext().id==='sun';const isTransitioning=this.app.getManager('camera').getIsTransitioning();this.resetLayers(uiLayers);this.resetComponents(this.componentDefaultVisibility);if(!isAtInnerSolarSystem){this._router.navigate('/home')}else if(!isTransitioning){await this.app.cameraScripts.goToSystem('inner_solar_system');if(currentView==='story'){this.app.getComponent('story')?.close()}} + this.app.getManager('camera').waitForTransitionComplete().then(()=>{const clock=this.app.getComponent('clock');clock.backToLive();this.app.getManager('layer').toggleLayer('planets',{},!0)}).catch(error=>{console.warn('error: ',error)})} + isHidden(component){return component?.classList.contains('hidden')}} + KioskBase.html=(_kiosk_base_html__WEBPACK_IMPORTED_MODULE_2___default())}),"../eyes/src/components/layer_panel/layer_panel.js": + /*!*********************************************************!*\ + !*** ../eyes/src/components/layer_panel/layer_panel.js ***! + \*********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"LayerPanel":function(){return LayerPanel}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _layer_panel_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./layer_panel.html */"../eyes/src/components/layer_panel/layer_panel.html");var _layer_panel_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_layer_panel_html__WEBPACK_IMPORTED_MODULE_1__);class LayerPanel extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={}){options.config={layers:options.layers||[],checkboxType:options.checkboxType||'default',...options.config};super(app,null,{isVisible:!1,ui:app.getManager('layer').getLayer('ui').defaultVisibility,planets:app.getManager('layer').getLayer('planets').defaultVisibility,asteroids:app.getManager('layer').getLayer('asteroids').defaultVisibility,comets:app.getManager('layer').getLayer('comets').defaultVisibility,dwarfPlanets:app.getManager('layer').getLayer('dwarfPlanets').defaultVisibility,spacecraft:app.getManager('layer').getLayer('spacecraft').defaultVisibility,trails:app.getManager('layer').getLayer('trails').defaultVisibility,orbits:app.getManager('layer').getLayer('orbits').defaultVisibility,labels:app.getManager('layer').getLayer('labels').defaultVisibility,icons:app.getManager('layer').getLayer('icons').defaultVisibility,starfield:app.getManager('layer').getLayer('starfield').defaultVisibility,constellations:app.getManager('layer').getLayer('constellations').defaultVisibility,...options});this._eyesCheck=options.checkboxType==='eyes';Object.assign(this._class,{checkbox:{true:this._eyesCheck?'active':'active icon-checkmark',false:this._eyesCheck?'':'checkbox-hover'},boxColor:{true:'settings-alt',false:''},isVisible:{true:'',false:''}});Object.assign(this._state,{uiClass:this._class.checkbox[this._state.ui],uiColorClass:this._class.boxColor[this._state.ui],planetsClass:this._class.checkbox[this._state.planets],planetsColorClass:this._class.boxColor[this._state.planets],asteroidsClass:this._class.checkbox[this._state.asteroids],asteroidsColorClass:this._class.boxColor[this._state.asteroids],cometsClass:this._class.checkbox[this._state.comets],cometsColorClass:this._class.boxColor[this._state.comets],dwarfPlanetsClass:this._class.checkbox[this._state.dwarfPlanets],dwarfPlanetsColorClass:this._class.boxColor[this._state.dwarfPlanets],constellationsClass:this._class.checkbox[this._state.constellations],constellationsColorClass:this._class.boxColor[this._state.constellations],spacecraftClass:this._class.checkbox[this._state.spacecraft],spacecraftColorClass:this._class.boxColor[this._state.spacecraft],trailsClass:this._class.checkbox[this._state.trails],trailsColorClass:this._class.boxColor[this._state.trails],orbitsClass:this._class.checkbox[this._state.orbits],orbitsColorClass:this._class.boxColor[this._state.orbits],labelsClass:this._class.checkbox[this._state.labels],labelsColorClass:this._class.boxColor[this._state.labels],iconsClass:this._class.checkbox[this._state.icons],iconsColorClass:this._class.boxColor[this._state.icons],starfieldClass:this._class.checkbox[this._state.starfield],starfieldColorClass:this._class.boxColor[this._state.starfield]});this._categories={ui:'User Interface',planets:'Planet',asteroids:'Asteroid',comets:'Comet',dwarfPlanets:'Dwarf Planet',spacecraft:'Spacecraft',trails:'Trail',labels:'Label',icons:'Icons',starfield:'Star Field',constellations:'Constellations'};this._categoriesDisplay={ui:'User Interface',planets:'Planets',asteroids:'Asteroids',comets:'Comets',dwarfPlanets:'Dwarf Planets',constellations:'Constellations',spacecraft:'Spacecraft',trails:'Trails',orbits:'Orbits',labels:'Labels',icons:'Icons',starfield:'Star Field'};this.bindFunctions(['toggleLayer','handleLayerToggle']);this._fadeInRight=null;this._fadeOutRight=null;this._fadeInBottom=null;this._fadeOutBottom=null;this._lastMode=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode();this._initCallbacks()} + getCategoriesDisplay(){return this._categoriesDisplay} + resize(){super.resize();this._updatePosition()} + init(){super.init();this._callbackRegistry.push({emitter:this._app.getManager('layer'),event:'toggleLayer',callback:this.handleLayerToggle});const layerPanelBody=this._children.layerPanelBody;if(layerPanelBody){layerPanelBody.textContent='';const container=document.createElement('div');container.className='container';this._config.layers.forEach(layerGroup=>{const blockDiv=document.createElement('div');blockDiv.classList.add('block');const layersUl=document.createElement('ul');layersUl.classList.add('layers');layerGroup.forEach(layer=>{if(this._eyesCheck){const layerLi=document.createElement('li');layerLi.setAttribute('key',layer);layerLi.className=`layer-panel-layer item clickable {{${layer}Class}}`;const checkboxDiv=document.createElement('div');checkboxDiv.classList.add('eyes-checkbox');checkboxDiv.innerHTML=``;layerLi.append(checkboxDiv);const nameSpan=document.createElement('span');nameSpan.classList.add('small');nameSpan.textContent=this._categoriesDisplay[layer];layerLi.append(nameSpan);layerLi.addEventListener('click',this.toggleLayer);layersUl.append(layerLi)}else{const option=new _internal__WEBPACK_IMPORTED_MODULE_0__.Checkbox(this._app,{config:{key:layer,colorClass:this._class.boxColor.true,function:this.toggleLayer},isChecked:this._app.getManager('layer').getLayer(layer).defaultVisibility,text:this._categoriesDisplay[layer],checkboxClass:'layer-panel-layer item',textClass:'small'});option.init();this._components.push(option);layersUl.appendChild(option.element)}});blockDiv.append(layersUl);container.append(blockDiv)});layerPanelBody.append(container);this._setVariables(layerPanelBody)}} + _createAnimations(){this._fadeOutRight=_internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade(this._element,{direction:'right',fade:'out',yOffset:0});this._fadeInRight=_internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade(this._element,{direction:'right',fade:'in',yOffset:0});this._fadeOutBottom=_internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade(this._element,{direction:'down',fade:'out',yOffset:0});this._fadeInBottom=_internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade(this._element,{direction:'down',fade:'in',yOffset:0})} + _resetAnimations(){this._fadeInRight.currentTime=0;this._fadeOutRight.currentTime=0;this._fadeInBottom.currentTime=0;this._fadeOutBottom.currentTime=0;this._fadeInRight.pause();this._fadeOutRight.pause();this._fadeInBottom.pause();this._fadeOutBottom.pause()} + toggleLayer(key){const layerKey=key.target?.getAttribute('key')??key;this._app.getManager('layer').toggleLayer(layerKey,{category:this._categories[layerKey]})} + handleLayerToggle(id,visible,params){const keyClass=id+'Class';const colorClass=id+'ColorClass';if(this.getState(id)!==null){this.setState({[id]:visible,[keyClass]:this._class.checkbox[visible],[colorClass]:this._class.boxColor[visible]});if(this._eyesCheck){const layerCheckbox=document.getElementById(`layer-panel-checkbox-${id}`);if(layerCheckbox)layerCheckbox.checked=visible}} + const checkbox=this._components.find(component=>component.getConfig().key===id);if(checkbox&&checkbox.getState('isChecked')!==visible){checkbox.toggle(null,!0)}} + isCategoryEnabled(categoryName){return!this._children[categoryName]?.classList.contains('disabled')} + setCategoryEnabled(categoryName,enabled=!0){this._children[categoryName]?.classList.toggle('disabled',!enabled)} + hide(){if(!this.getState('isVisible')){return} + super.hide();if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode()){this._fadeOutBottom=_internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade(this._element,{direction:'down',fade:'out',yOffset:0});this._fadeOutBottom.play()}else{this._fadeOutRight=_internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade(this._element,{direction:'right',fade:'out',yOffset:0});this._fadeOutRight.play()}} + show(){super.show();if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode()){this._fadeInBottom=_internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade(this._element,{direction:'down',fade:'in',yOffset:0});this._fadeInBottom.play()}else{this._fadeInRight=_internal__WEBPACK_IMPORTED_MODULE_0__.AnimationUtils.directionalFade(this._element,{direction:'right',fade:'in',yOffset:0});this._fadeInRight.play()}} + _updatePosition(){const currentMode=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobileMode();if(currentMode!==this._lastMode){this._lastMode=currentMode;if(this._state.isVisible){this.show()}}} + __enable(){super.__enable();this._createAnimations()} + __disable(){super.__disable();this._fadeInRight=null;this._fadeOutRight=null;this._fadeInBottom=null;this._fadeOutBottom=null}} + LayerPanel.html=(_layer_panel_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/load_icon/index.js": + /*!*************************************************!*\ + !*** ../eyes/src/components/load_icon/index.js ***! + \*************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _load_icon_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./load_icon.js */"../eyes/src/components/load_icon/load_icon.js");__webpack_exports__["default"]=(_load_icon_js__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/load_icon/load_icon.js": + /*!*****************************************************!*\ + !*** ../eyes/src/components/load_icon/load_icon.js ***! + \*****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _load_icon_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./load_icon.html */"../eyes/src/components/load_icon/load_icon.html");var _load_icon_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_load_icon_html__WEBPACK_IMPORTED_MODULE_1__);class LoadIcon extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{init(){super.init();this._callbackRegistry.push({emitter:this._app.getManager('scene'),event:'loading',callback:this.show},{emitter:this._app.getManager('scene'),event:'loaded',callback:this.hide});this.hide()}} + LoadIcon.html=(_load_icon_html__WEBPACK_IMPORTED_MODULE_1___default());__webpack_exports__["default"]=(LoadIcon)}),"../eyes/src/components/overlay/index.js": + /*!***********************************************!*\ + !*** ../eyes/src/components/overlay/index.js ***! + \***********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _overlay_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./overlay.js */"../eyes/src/components/overlay/overlay.js");__webpack_exports__["default"]=(_overlay_js__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/overlay/overlay.js": + /*!*************************************************!*\ + !*** ../eyes/src/components/overlay/overlay.js ***! + \*************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _internal__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _overlay_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./overlay.html */"../eyes/src/components/overlay/overlay.html");var _overlay_html__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_overlay_html__WEBPACK_IMPORTED_MODULE_2__);class Overlay extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseComponent{constructor(app,options={}){super(app,null,{isVisible:!1,isOpenButtonVisible:!0,content:null,...options});this._class.isOpenButtonVisibleClass={true:'',false:'hidden'};Object.assign(this._state,{isOpenButtonVisibleClass:this._class.isOpenButtonVisibleClass[this._state.isOpenButtonVisible]});this._scrollbar=null} + init(){super.init();if(this._state.content!==null){this._children.overlayContent.appendChild(this._state.content)} + this._element.addEventListener('click',this.hide);this._element.addEventListener('animationend',()=>{if(this._children.overlay.classList.contains('hidden')){this._children.overlay.style.display='none'}})} + setContent(element){if(this._state.content===null){this._children.overlayContent.appendChild(element)}else{this._children.overlayContent.replaceChild(element,this._state.content)} + this._state.content=element} + show(){this._element.classList.add('initialized');this._children.overlay.style.display='';super.show()} + __enable(){super.__enable();if(this._scrollbar===null){_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.onAttachElement(this._children.overlay,()=>{this._scrollbar=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.addScrollbar(this._children.overlay)})}else{this._scrollbar.scroll(0)}}} + Overlay.html=(_overlay_html__WEBPACK_IMPORTED_MODULE_2___default());__webpack_exports__["default"]=(Overlay)}),"../eyes/src/components/search/index.js": + /*!**********************************************!*\ + !*** ../eyes/src/components/search/index.js ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _search_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./search.js */"../eyes/src/components/search/search.js");__webpack_exports__["default"]=(_search_js__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/search/search.js": + /*!***********************************************!*\ + !*** ../eyes/src/components/search/search.js ***! + \***********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _search_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./search.html */"../eyes/src/components/search/search.html");var _search_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_search_html__WEBPACK_IMPORTED_MODULE_1__);class Search extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={config:{}}){options.config={initialOpen:!1,allowFeatured:!1,allowDetail:!0,allowInfo:!1,stopOnExactMatch:!1,infoText:{default:'most popular',results:'result',suggestions:'suggestion',nomatches:'no matches'},maxSuggestions:1,placeholderText:'Search...',nameSearch:['iauName','displayName'],nameDisplay:['displayName','iauName'],...options.config};super(app,null,{text:'',searchInfo:options.config?.infoText?.default||'',alwaysOpen:!1,magClass:'mag-open',searchClass:'search-close',focusedClass:'',isFeaturedVisible:!1,...options});this._class.isItemVisible={true:'',false:'hidden'};Object.assign(this._state,{allowFeaturedClass:this._class.isItemVisible[this._config.allowFeatured],isFeaturedVisibleClass:this._class.isItemVisible[this._config.allowFeatured&&this._state.isFeaturedVisible],allowInfoClass:this._class.isItemVisible[this._config.allowInfo]});this._eventNames.push('resultselected');this._initCallbacks();this._resultsScrollbar=null;this._featuredScrollbar=null;this.onResize=null;this.results=[];this._excludeResults=[];this._suggestionsThreshold=0.05;this.index=-1;this.bindFunctions(['_find','renderResults','open','close','eraseInput','onIconClick','reset','keydown','onInputFocus','_getDetails','_handleClick']);window.addEventListener('setupSearch',this.resize)} + init(){super.init();const size=this._children.input.getAttribute('placeholder').length*0.9;this._children.input.style.minWidth=`${size}ch`;this._children.input.onkeyup=event=>{const isFeaturedVisible=this._children.input.value.length===0;if(this._config.allowFeatured&&isFeaturedVisible!==this._state.isFeaturedVisible){this._featuredScrollbar?.scroll(0);this.setState({isFeaturedVisible,isFeaturedVisibleClass:this._class.isItemVisible[isFeaturedVisible],...isFeaturedVisible&&{searchInfo:this._config.infoText.default}})}};this.resize();this.registerManager(this._app.getManager('search'))} + onIconClick(){const currentlyClosed=this._state.searchClass==='search-close';if(currentlyClosed){this._scrollbar?.scroll(0);this.open();this._children.input.focus()}else{if(this._children.input.value===''){this.reset()}else{this._children.results.querySelector('.active')?.firstChild.click()}}} + resize(){super.resize();if(typeof this.onResize==='function'){this.onResize()}} + reset(){this.eraseInput();if(!this._config.initialOpen){this.close()}} + keydown(e){const key=e.key;if(key==='Escape'){this.eraseInput();this.close()} + const total=this.results.length;if(!total){return} + if(key==='ArrowDown'){this.index=(this.index+1)%total;e.preventDefault()}else if(key==='ArrowUp'){this.index-=1;if(this.index<0){this.index=total-1} + e.preventDefault()}else if(key==='Enter'){this._handleClick(this.results[this.index]?.link||this.results[0]?.link,this._searchString);e.preventDefault()} + this.setSelected(this.index)} + setSelected(index){this.index=index;for(let i=0;i{if(this._searchManager){const results=this._searchManager.find(text,maxEntries);const filteredResults=results?.length&&this._excludeResults?.length?results.filter(({item})=>!this._excludeResults.includes(item.id)):results;await this.renderResults(filteredResults,text)}},100)} + async renderResults(results,text){this.index=-1;this.results=[];this._searchString=text;this._resultsScrollbar?.destroy();this._resultsScrollbar=null;this._children.results.innerHTML='';this._children.results.classList.remove('no-results');if(!results||!Array.isArray(results)){return} + const suggestions=[];const candidates=[];for(let i=0;iresult.item[key]!==undefined)];if(this._config.stopOnExactMatch&&text.toLowerCase()===name.toLowerCase()){candidates.length=0;suggestions.length=0;candidates.push(result);break} + if(result.score3){this._resultsScrollbar??=this._createScrollbar(this._children.results)} + const{allowInfo,infoText,maxSuggestions}=this._config;if(allowInfo){let searchInfo=infoText.nomatches;if(candidates.length){searchInfo=`${candidates.length} ${infoText.results}${candidates.length > 1 ? 's' : ''}`}else if(suggestions.length){searchInfo=`${Math.min(suggestions.length, maxSuggestions)} ${infoText.suggestions}${suggestions.length > 1 ? 's' : ''}`} + this.setState({searchInfo})} + this.setSelected(0)} + async _renderResultCard(result,text){try{let details=await this._getDetails(result);if(!details&&result&&result.item){const{nameDisplay}=this._config;details={title:result.item[nameDisplay.find(key=>result.item[key]!==undefined)]}} + const div=document.createElement('div');div.className='card-title result-div';const h4=document.createElement('h4');h4.className='semi clickable';let innerHTML=details.title;if(typeof innerHTML==='string'){const index=innerHTML.toUpperCase().indexOf(text.toUpperCase());if(index>-1){const sub=innerHTML.substring(index,index+text.length);const splitted=innerHTML.split(sub);if(splitted&&splitted.length===2){innerHTML='';if(splitted[0].length>0){innerHTML+=`${splitted[0]}`} + innerHTML+=sub;if(splitted[1].length>0){innerHTML+=`${splitted[1]}`}}}}else{innerHTML=''} + h4.innerHTML=innerHTML;const link=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addStartToPath(result.item.id);h4.addEventListener('mouseover',()=>{this.setSelected(0)},!1);h4.addEventListener('click',e=>{if(result.item){this._handleClick(result.item.id,text)} + e?.stopPropagation?.()},!1);div.appendChild(h4);this.results.push({link,element:div});this._children.results.innerHTML='';this._children.results.appendChild(div);if(details.cards){this._createStoryBlock(details.cards)} + if(details.featuredEvents&&details.featuredEvents.initial){this._createEventsBlock(details.featuredEvents.initial,result.item.id)} + if(details.exploration&&details.exploration.initial){this._createExplorationBlock(details.exploration.initial)} + if(details.featuredMoons){this._createMoonsBlock(details.featuredMoons,result.item.id)}}catch(err){if(err.status!==undefined&&err.status===404){this._renderResultList([result],text)}else if(err){console.error(err)}}} + _createEventsBlock(featuredItems,result){if(!Array.isArray(featuredItems)||featuredItems.length===0){return} + const entityInfo=this._app.getManager('content').getEntityInfo(result);if(entityInfo===null||!entityInfo.hasEvents){return} + const container=this._createBlockContainer();container.classList.add('events');const title='Featured Events';this._createHeaderBlock(title,container);for(let i=0;i{this._handleClick(link,this._searchString);e?.stopPropagation?.()},!1);entryDiv.addEventListener('mouseover',()=>{this.setSelected(index)},!1);entryDiv.appendChild(entryButton);container.appendChild(entryDiv);return entryDiv} + _renderResultList(results,text){for(let i=0;iresult[key]!==undefined)];if(!generalName){continue} + const button=document.createElement('button');button.className='entries clickable thin small';const url=result.url||result.id;let innerHTML=generalName;const index=generalName.toUpperCase().indexOf(text.toUpperCase());if(index>-1){const sub=innerHTML.substring(index,index+text.length);innerHTML=innerHTML.replace(sub,`${sub}`)} + button.innerHTML=innerHTML;const link=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addStartToPath(url);const div=document.createElement('div');div.className='result-div';div.appendChild(button);div.addEventListener('mouseover',()=>{this.setSelected(i)},!1);div.addEventListener('click',e=>{this._handleClick(url,text);e?.stopPropagation?.()},!1);this.results.push({link,element:div});this._children.results.appendChild(div)}} + _renderSuggestions(results,text){const div=document.createElement('div');div.className='suggestion';if(results.length>0){const label=document.createElement('label');label.className='title small semi';label.innerHTML='Did you mean...?';div.appendChild(label);for(let i=0;iresult[key]!==undefined)];if(generalName){const url=result.url||result.id;button.innerHTML=generalName;const link=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addStartToPath(url);button.addEventListener('mouseover',()=>{this.setSelected(i)},!1);button.addEventListener('click',e=>{this._handleClick(url,text);e?.stopPropagation?.()},!1);const buttonDiv=document.createElement('div');buttonDiv.className='result-div small';buttonDiv.appendChild(button);div.appendChild(buttonDiv);this.results.push({link,element:buttonDiv})}}}else if(!this._config.allowInfo){const label=document.createElement('label');label.className='title no-match small';label.innerHTML='No matches.';div.appendChild(label);this._children.results.classList.add('no-results')} + this._children.results.appendChild(div)} + open(){this.setState({magClass:'mag-close',searchClass:'search-open',isFeaturedVisible:this._config.allowFeatured,isFeaturedVisibleClass:this._class.isItemVisible[this._config.allowFeatured],...this._config.allowFeatured&&{searchInfo:this._config.infoText.default}});this.app.isSearching=!0} + close(){if(this.getState('alwaysOpen')){this.setState({magClass:'mag-close',searchClass:'search-open',focusedClass:'',isFeaturedVisible:!1,isFeaturedVisibleClass:this._class.isItemVisible.false})}else{this.setState({magClass:'mag-open',searchClass:'search-close',focusedClass:'',isFeaturedVisible:!1,isFeaturedVisibleClass:this._class.isItemVisible.false})} + this._children.input?.blur();this.app.isSearching=!1} + setupFeaturedSuggestion(info=[]){this._children.featured.innerHTML='';for(let i=0;i{this._handleClick(url,this._searchString);e?.stopPropagation?.()});this._children.featured.appendChild(li)}} + _createScrollbar(parentEl){return _internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addScrollbar(parentEl,{sizeAutoCapable:!0})} + _getLink(link){return link} + _handleClick(link,text){if(!link){return} + this.reset();this.triggerCallbacks('resultselected');const router=this._app.getManager('router');const parsedLink=this._getLink(link);const linkPath=typeof parsedLink==='string'?parsedLink:(parsedLink.path??'');if(linkPath.includes('events')){router.navigate({},linkPath,{__remove:'all'})}else{const{options={keepTime:!0},query={}}=typeof parsedLink==='object'&&parsedLink;router.navigate(query,linkPath,options)}} + simulate(text){const{input}=this._children;this.onIconClick();input.value=text;this._find({},text);input.onkeyup()} + async _getDetails(result){return this._app.getManager('content').getEntityDesc(result.item.id)} + setExcludeResults(excludeResults){this._excludeResults=excludeResults} + __enable(){super.__enable();const{allowFeatured}=this._config;if(allowFeatured){const{parentElement:featuredParentEl}=this._children.featured||{};const parentInDOM=document.body.contains(featuredParentEl);if(parentInDOM){this._featuredScrollbar??=this._createScrollbar(featuredParentEl)}}}} + Search.html=(_search_html__WEBPACK_IMPORTED_MODULE_1___default());__webpack_exports__["default"]=(Search)}),"../eyes/src/components/settings/index.js": + /*!************************************************!*\ + !*** ../eyes/src/components/settings/index.js ***! + \************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _settings_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./settings.js */"../eyes/src/components/settings/settings.js");__webpack_exports__["default"]=(_settings_js__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/settings/settings.js": + /*!***************************************************!*\ + !*** ../eyes/src/components/settings/settings.js ***! + \***************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var screenfull__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! screenfull */"../eyes/node_modules/screenfull/index.js");var tippy_js__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! tippy.js */"../eyes/node_modules/tippy.js/dist/tippy.esm.js");var _internal__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _settings_html__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ./settings.html */"../eyes/src/components/settings/settings.html");var _settings_html__WEBPACK_IMPORTED_MODULE_3___default=__webpack_require__.n(_settings_html__WEBPACK_IMPORTED_MODULE_3__);class Settings extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseComponent{constructor(app,options={}){const config={isCollapsible:!0,allowToggleUnit:!1,allowLayers:!0,allowZoom:!0,allowFullscreen:screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].isEnabled,allowPhotoMode:!1,allowInfoPanel:!0,allowLighting:!0,showLightOptions:!1,allowGuidedCamera:!1,zoomIn:app.getManager('camera').zoomIn,zoomOut:app.getManager('camera').zoomOut,...options.config};delete options.config;config.orientation={bigPortrait:{check:config.orientation?.bigPortrait?.check||(()=>_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isPortrait()&&!_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobilePortrait()&&!_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isTabletPortrait()),ori:config.orientation?.bigPortrait?.ori||'vertical'},tabletPortrait:{check:config.orientation?.tabletPortrait?.check||(()=>_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isTabletPortrait()),ori:config.orientation?.tabletPortrait?.ori||'vertical'},smallPortrait:{check:config.orientation?.smallPortrait?.check||(()=>_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobilePortrait()),ori:config.orientation?.smallPortrait?.ori||'vertical'},bigLandscape:{check:config.orientation?.bigLandscape?.check||(()=>_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isLandscape()&&!_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobileLandscape()&&!_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isTabletLandscape()),ori:config.orientation?.bigLandscape?.ori||'vertical'},tabletLandscape:{check:config.orientation?.tabletPortrait?.check||(()=>_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isTabletLandscape()||_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isPanorama()),ori:config.orientation?.tabletPortrait?.ori||'vertical'},smallLandscape:{check:config.orientation?.smallLandscape?.check||(()=>_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobileLandscape()),ori:config.orientation?.smallLandscape?.ori||'horizontal'}};super(app,null,{isMetric:!1,isVisible:!0,isFullscreen:!1,isPhotoMode:!1,isGuidedCamera:!0,showOrbitLines:!0,showLabels:!0,lightType:'shadow',config,...options});this._ori='';this._isMobileMode=_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobileMode();this._isHorizontal=null;Object.assign(this._class,{container:{collapse:'hidden',expand:'active'},isItemVisible:{true:'',false:'hidden'},icon:{imperial:'icon-mi',metric:'icon-km',info:'icon-info'},fullscreen:{true:'fullscreen',false:'window'},photo:{true:'active',false:''},light:{natural:'icon-natural-light',shadow:'icon-shadow-light',flood:'icon-flood-light'},camera:{true:'icon-free-cam',false:'icon-auto-cam'},isHorizontal:{true:'horizontal',false:'vertical'}});const isVisible=!this._isMobileMode;const isCollapsed=this._isMobileMode;const isHorizontal=this.isHorizontal();const CameraManager=this.app.getManager('camera');this._fullLightColor=CameraManager.getFullLightColor();this._shadowLightColor=CameraManager.getShadowLightColor();Object.assign(this._state,{isVisible,isCollapsed,isVisibleClass:this._class.isVisible[isVisible],containerClass:isCollapsed?this._class.container.collapse:this._class.container.expand,isCollapsibleClass:this._class.isItemVisible[this._config.isCollapsible],allowInfoPanelClass:this._class.isItemVisible[this._config.allowInfoPanel],allowToggleUnitClass:this._class.isItemVisible[this._config.allowToggleUnit],allowPhotoModeClass:this._class.isItemVisible[this._config.allowPhotoMode],allowZoomClass:this._class.isItemVisible[this._config.allowZoom],allowLightingClass:this._class.isItemVisible[this._config.allowLighting],showLightingOptionsClass:this._class.isItemVisible[this._config.showLightOptions],allowGuidedCameraClass:this._class.isItemVisible[this._config.allowGuidedCamera],allowFullscreenClass:this._class.isItemVisible[this._config.allowFullscreen],allowLayersClass:this._class.isItemVisible[this._config.allowLayers],unitButton:this._state.isMetric?this._class.icon.imperial:this._class.icon.metric,infoButton:this._class.icon.info,fullscreenClass:this._class.fullscreen[this._state.isFullscreen],photoModeClass:this._class.photo[this._state.isPhotoMode],lightClass:this._class.light[this._state.lightType],guidedClass:this._class.camera[this._state.isGuidedCamera],isHorizontal,orientationClass:this._class.isHorizontal[isHorizontal]});this._eventNames.push('unitchange','photomodechange','guidedcamerachange','expandtoggle');this._initCallbacks();this._isMouseHold=!1;this._isContinuousZoom=!1;this._zoomInterval=null;this._zoomTimeout=null;this._tooltips=[];tippy_js__WEBPACK_IMPORTED_MODULE_4__["default"].setDefaultProps({theme:'default',touch:['hold',2000],delay:[600,null],plugins:[tippy_js__WEBPACK_IMPORTED_MODULE_4__.followCursor]});this.bindFunctions(['toggleCollapse','toggleUnit','toggleLayers','toggleFullscreen','togglePhotoMode','hideLightingOptions','toggleLightOptions','toggleLight','toggleGuidedCamera','toggleInfoPanel','startGuidedCamera','stopGuidedCamera','_zoomIn','_zoomOut','_stopZooming','_updateSize'])} + init(){super.init();const{isCollapsible,allowToggleUnit,allowLayers,allowZoom,allowFullscreen,allowPhotoMode,allowInfoPanel,allowLighting,allowGuidedCamera}=this._config;const newState={};if(isCollapsible){newState.isCollapsibleClass=this._class.isItemVisible[isCollapsible]} + if(allowInfoPanel){newState.allowInfoPanelClass=this._class.isItemVisible[allowInfoPanel]} + if(allowToggleUnit){newState.allowToggleUnitClass=this._class.isItemVisible[allowToggleUnit]} + if(allowPhotoMode){newState.allowPhotoModeClass=this._class.isItemVisible[allowPhotoMode]} + if(allowZoom){newState.allowZoomClass=this._class.isItemVisible[allowZoom];this._children.zoomInButton.addEventListener('mousedown',()=>{this._stopZooming();this._zoomIn(!0)});this._children.zoomInButton.addEventListener('mouseleave',this._stopZooming);this._children.zoomInButton.addEventListener('mouseup',()=>{if(!this._isContinuousZoom){this._zoomIn()} + this._stopZooming()});this._children.zoomInButton.addEventListener('touchstart',event=>{event.preventDefault();this._stopZooming();this._zoomIn(!0)});this._children.zoomInButton.addEventListener('touchmove',event=>{event.preventDefault();const element=document.elementFromPoint(event.changedTouches[0].clientX,event.changedTouches[0].clientY);if(element.getAttribute('key')!=='zoomInButton'){this._stopZooming()}});this._children.zoomInButton.addEventListener('touchend',event=>{event.preventDefault();if(!this._isContinuousZoom){this._zoomIn()} + this._stopZooming()});this._children.zoomOutButton.addEventListener('mousedown',()=>{this._stopZooming();this._zoomOut(!0)});this._children.zoomOutButton.addEventListener('mouseleave',this._stopZooming);this._children.zoomOutButton.addEventListener('mouseup',()=>{if(!this._isContinuousZoom){this._zoomOut()} + this._stopZooming()});this._children.zoomOutButton.addEventListener('touchstart',event=>{event.preventDefault();this._stopZooming();this._zoomOut(!0)});this._children.zoomOutButton.addEventListener('touchmove',event=>{event.preventDefault();const element=document.elementFromPoint(event.changedTouches[0].clientX,event.changedTouches[0].clientY);if(element.getAttribute('key')!=='zoomOutButton'){this._stopZooming()}});this._children.zoomOutButton.addEventListener('touchend',event=>{event.preventDefault();if(!this._isContinuousZoom){this._zoomOut()} + this._stopZooming()})} + if(allowLighting){newState.allowLightingClass=this._class.isItemVisible[allowLighting];this._children.flood.onclick=this.toggleLightOptions.bind(this._children.flood,'flood');this._children.shadow.onclick=this.toggleLightOptions.bind(this._children.shadow,'shadow');this._children.natural.onclick=this.toggleLightOptions.bind(this._children.natural,'natural');this._children.shadow.classList.add('selected-lighting');this.toggleLightOptions('shadow')} + if(allowGuidedCamera){newState.allowGuidedCameraClass=this._class.isItemVisible[allowGuidedCamera]} + if(allowFullscreen&&screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].isEnabled){newState.allowFullscreenClass=this._class.isItemVisible[allowFullscreen];screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].on('change',()=>{const isFullscreen=screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].isFullscreen;this.setState({isFullscreen,fullscreenClass:this._class.fullscreen[isFullscreen]})})} + if(allowLayers){newState.allowLayersClass=this._class.isItemVisible[allowLayers]} + this.setState(newState);const tooltipElements=this._element.querySelectorAll('.settings button:not(.zoom), span[key="zoomInButton"], span[key="zoomOutButton"]');this.addTooltips(tooltipElements,{update:function(isHorizontal){this.setProps({placement:isHorizontal?'top':'left'})}});this._updateSize();this._callbackRegistry.push({emitter:this._app.getManager('time'),event:'ratechange',callback:this.onRateChange})} + addTooltips(elements,params){const props=params.props||{};const tippys=(0,tippy_js__WEBPACK_IMPORTED_MODULE_4__["default"])(elements,props);if(typeof params.update==='function'){for(const tip of tippys){tip.update=params.update}} + if(typeof params.onclick==='function'){for(const tip of tippys){tip.popper.onclick=params.onclick}} + this._tooltips.push(...tippys);return tippys.length===1?tippys[0]:tippys} + updateTooltips(isHorizontal){for(const tooltip of this._tooltips){if(typeof tooltip.update==='function'){tooltip.update(isHorizontal)}}} + setConfig(config){const{collapseSettingsOptions,hideFullScreenToggle,lighting}=this.app.getManager('router').configs;if(config.allowFullscreen&&hideFullScreenToggle!==!0){config.allowFullscreen=screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].isEnabled} + if(config.orientation){const oriConfig=this._config.orientation;const orientations=['bigPortrait','tabletPortrait','smallPortrait','bigLandscape','tabletLandscape','smallLandscape'];for(let i=0;i button'));for(let i=0;i{if(this._isMouseHold){this._isContinuousZoom=!0;if(this._zoomInterval!==null){clearInterval(this._zoomInterval)} + this._zoomInterval=setInterval(()=>{if(this._isMouseHold){zoomFunction(!0)}else{clearInterval(this._zoomInterval)}},30)}},200)} + _zoomIn(isContinuous=!1){if(isContinuous){this._zoomContinuously(this._config.zoomIn)}else{this._config.zoomIn()}} + _zoomOut(isContinuous=!1){if(isContinuous){this._zoomContinuously(this._config.zoomOut)}else{this._config.zoomOut()}} + _stopZooming(){clearInterval(this._zoomInterval);this._isMouseHold=!1;this._isContinuousZoom=!1} + show(){this.setState({isVisible:!0,isVisibleClass:this._class.isVisible.true})} + hide(){this.setState({isVisible:!1,isVisibleClass:this._class.isVisible.false,showLightingOptionsClass:this._class.isVisible.false})} + isVisible(){return this._state.isVisible} + expand(){this.setState({isCollapsed:!1,containerClass:this._class.container.expand})} + collapse(){this.setState({isCollapsed:!0,showLightingOptionsClass:this._class.isVisible.false,containerClass:this._class.container.collapse})} + toggleCollapse(){if(this._state.isCollapsed){this.expand()}else{this.collapse()} + this.triggerCallbacks('expandtoggle',[!this._state.isCollapsed,this._state.isPhotoMode])} + toggleUnit(){const isMetric=!this._state.isMetric;this.setState({isMetric,unitButton:isMetric?this._class.icon.imperial:this._class.icon.metric},()=>{this.triggerCallbacks('unitchange',[this._state.isMetric])})} + toggleFullscreen(){if(screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].isEnabled){screenfull__WEBPACK_IMPORTED_MODULE_0__["default"].toggle()}} + toggleLayers(){const layersPanelOpen=!this._app.getComponent('layerPanel').getState('isVisible');if(layersPanelOpen){this._app.getComponent('layerPanel').show();this.collapse()}else{this._app.getComponent('layerPanel').hide()}} + togglePhotoMode(){const isPhotoMode=!this._state.isPhotoMode;this.setState({isPhotoMode,photoModeClass:this._class.photo[isPhotoMode]},()=>{if(this._state.isPhotoMode){this.collapse()}else{this.expand()} + this.triggerCallbacks('photomodechange',[this._state.isPhotoMode])})} + hideLightingOptions(e){const checkList=[this._children.lightToggle,this._children.lightOptions,this._children.flood,this._children.natural,this._children.shadow];if(!checkList.includes(e.target)){this.setState({showLightingOptionsClass:this._class.isVisible.false})} + window.removeEventListener('mousedown',this.hideLightingOptions);window.removeEventListener('touchstart',this.hideLightingOptions)} + hideFullScreenOption(){const newState={};newState.allowFullscreenClass=this._class.isItemVisible[!1];this.setState(newState)} + toggleLightOptions(type){this.setState({lightType:type,lightClass:this._class.light[type],showLightingOptionsClass:this._class.isVisible.false},()=>{if(type==='flood'){this._app.getManager('camera')?.toggleCameraLight(!0,this._fullLightColor);this._app.getManager('comparison')?.setCameraLight(!0,this._fullLightColor)}else if(type==='natural'){this._app.getManager('camera')?.toggleCameraLight(!1);this._app.getManager('comparison')?.setCameraLight(!1)}else if(type==='shadow'){this._app.getManager('camera')?.toggleCameraLight(!0,this._shadowLightColor);this._app.getManager('comparison')?.setCameraLight(!0,this._shadowLightColor)} + for(const key in this._children){if(key!==type&&(key==='flood'||key==='natural'||key==='shadow')){this._children[key].classList.remove('selected-lighting')}} + this._children[`${type}`].classList.add('selected-lighting')})} + toggleLight(){this.setState({showLightingOptionsClass:this.getState('showLightingOptionsClass')===this._class.isVisible.true?this._class.isVisible.false:this._class.isVisible.true});if(this.getState('showLightingOptionsClass')===this._class.isVisible.true){window.addEventListener('mousedown',this.hideLightingOptions);window.addEventListener('touchstart',this.hideLightingOptions)}else{window.removeEventListener('mousedown',this.hideLightingOptions);window.removeEventListener('touchstart',this.hideLightingOptions)}} + startGuidedCamera(){this.setState({isGuidedCamera:!0,guidedClass:this._class.camera.true},()=>this.triggerCallbacks('guidedcamerachange',[this._state.isGuidedCamera]))} + stopGuidedCamera(){this.setState({isGuidedCamera:!1,guidedClass:this._class.camera.false},()=>this.triggerCallbacks('guidedcamerachange',[this._state.isGuidedCamera]))} + toggleGuidedCamera(){if(this._state.isGuidedCamera){this.stopGuidedCamera()}else{this.startGuidedCamera()}} + toggleInfoPanel(){if(this._app.getComponent('infoPanel')!==null){this._app.getComponent('infoPanel').openPanel()}} + resize(){super.resize();const isHorizontal=this.isHorizontal();if(this._isHorizontal!==isHorizontal){this.setState({isHorizontal,orientationClass:this._class.isHorizontal[isHorizontal]})} + this._updateSize()}} + Settings.html=(_settings_html__WEBPACK_IMPORTED_MODULE_3___default());__webpack_exports__["default"]=(Settings)}),"../eyes/src/components/share_modal/index.js": + /*!***************************************************!*\ + !*** ../eyes/src/components/share_modal/index.js ***! + \***************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _share_modal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./share_modal */"../eyes/src/components/share_modal/share_modal.js");__webpack_exports__["default"]=(_share_modal__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/share_modal/share_modal.js": + /*!*********************************************************!*\ + !*** ../eyes/src/components/share_modal/share_modal.js ***! + \*********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _share_modal_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./share_modal.html */"../eyes/src/components/share_modal/share_modal.html");var _share_modal_html__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_share_modal_html__WEBPACK_IMPORTED_MODULE_2__);var tippy_js__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! tippy.js */"../eyes/node_modules/tippy.js/dist/tippy.esm.js");var _data_embed_controls__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ../../data/embed_controls */"../eyes/src/data/embed_controls.js");class ShareModal extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options){super(app,null,{isVisible:!1,iframeElements:!0,linkTitle:'',previewDevice:'',previewResolution:'',previewVisibleClass:_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isiPhone()?'hidden':'',isWide:null,...options,config:{title:'Share',shareBtnParent:{selector:'.header',wideSelector:'.header',threshold:1025},linkAltText:'Eyes',linkImageSrc:'',paramsToKeep:['time','rate','slide','followId',...options?.paramsToKeep??[]],resetOnClose:!0,deviceResolutions:{desktop:{width:1280,height:720},tablet:{width:1024,height:1366},phone:{width:375,height:667}},...options?.config}});this._activeTab=null;this._srcURL=null;this._embedOptionsScrollbar=null;this._tippySingleton=null;this._tippyItems=null;this._tippyTimeout=null;this._embedQueries={};this._inputElements={};this.bindFunctions(['_iframeLoadEventListener'])} + mergeEmbedControls(){const{controls}=this._config;const mergedControls=_data_embed_controls__WEBPACK_IMPORTED_MODULE_3__["default"].map(defaultControl=>{const{groupName:defaultGroupName,items:defaultItems}=defaultControl;const newControl=controls.find(control=>control.groupName===defaultGroupName);if(newControl){const{items:newItems}=newControl;const mergedItems=defaultItems.filter(({name})=>!newItems.some(({name:newName})=>newName===name));return{...defaultControl,items:[...newItems,...mergedItems]}} + return defaultControl});const newControls=controls.filter(control=>!mergedControls.some(({groupName})=>groupName===control.groupName));this._config.embedOptions=[...mergedControls,...newControls]} + init(){super.init();const{canHover}=this._app;this.mergeEmbedControls();this.setEmbedParams();this.generateEmbedContent();this.setIsWide();this.createScrollbars();this.createShareButton();this.addShareButtonToParent();tippy_js__WEBPACK_IMPORTED_MODULE_4__["default"].setDefaultProps({theme:'default',touch:!0,hideOnClick:!1,delay:[300,null],placement:'top',trigger:'mouseenter click',onTrigger:instance=>{clearTimeout(this._tippyTimeout);if(!canHover){this._tippyTimeout=setTimeout(()=>{instance?.hide()},3000)}},onClickOutside:instance=>{instance.hide()},onHidden:_=>{this._tippyItems?.forEach(({reference})=>reference.blur())}})} + createScrollbars(){const{embedOptsContent}=this._children;const sectionParent=embedOptsContent.parentElement;_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.onAttachElement(sectionParent,()=>{this._embedOptionsScrollbar=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.addScrollbar(sectionParent)})} + getCurrentDevice(){if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isTablet()){return'tablet'} + if(_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isMobile()){return'phone'} + return'desktop'} + createShareButton(){this.shareButton=document.createElement('button');this.shareButton.className='share-button clickable';this.shareButton.innerText='Share';const shareIcon=document.createElement('span');shareIcon.className='icon icon-share';this.shareButton.prepend(shareIcon);this.shareButton.addEventListener('click',()=>{this.setSrcURL();this.setPreviewDevice({target:{value:this.getCurrentDevice()}});this.setActiveTab('link');const{linkImage}=this._children;const{linkAltText:backupAltText,linkImageSrc:backupImageSrc}=this._config;const title=document.querySelector('title')?.innerText;const ogImage=document.querySelector('meta[property="og:image"]')?.getAttribute('content');const altText=title||backupAltText;const src=(ogImage!=='$OG_IMAGE'&&ogImage)||backupImageSrc;linkImage.setAttribute('alt',altText);linkImage.setAttribute('src',src);const{fullTitle}=this._app.getManager('title');const linkTitle=fullTitle??altText;this.setState({linkTitle});this.show()})} + setIsWide(){const{isWide:currentIsWide}=this._state;const{shareBtnParent}=this._config;const{threshold}=shareBtnParent;const newIsWide=window.innerWidth>=threshold;if(currentIsWide!==newIsWide){this.setState({isWide:newIsWide});return!0} + return!1} + addShareButtonToParent(){const{shareBtnParent}=this._config;const{isWide}=this._state;const{selector,wideSelector}=shareBtnParent;this.shareButton.parentNode?.removeChild(this.shareButton);const shareBtnParentSelector=isWide?wideSelector:selector;_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.elementReady(shareBtnParentSelector,3000).then(shareButtonParent=>{shareButtonParent.appendChild(this.shareButton);return!0}).catch(e=>e)} + setSrcURL(href=window.location.href,updateCode=!0){const{linkCode}=this._children;const{paramsToKeep}=this._config;const splitHref=href.split('?');const params=splitHref[1]?new URLSearchParams(splitHref[1]):new URLSearchParams();const paramKeysArray=Array.from(params.keys());for(const key of paramKeysArray){if(!paramsToKeep.includes(key)){params.delete(key)}} + this._srcURL=`${splitHref[0]}${params.size ? '?' : ''}${params.toString()}`;if(updateCode){linkCode.textContent=href}} + setEmbedParams(){const{embedOptions}=this._config;embedOptions.forEach(({items})=>{items.forEach(option=>{const{query,inputDefault,invert}=option;const value=invert?!inputDefault:inputDefault;this._embedQueries[query]=value})})} + updateEmbedParams(query,value){if(this._embedQueries[query]===value||this._embedQueries[query]===undefined){return} + this._embedQueries[query]=value;this.updateEmbedCode()} + updateEmbedCode(params){const{force=!1,updatePreview=!0}=params||{};const{embedCode,embedPreviewParent}=this._children;const{iframeElements}=this._state;const{srcURL,iframeString,noTrackingIframeString}=this.getEmbedCodeFromParams();const embedCodeString=iframeElements?iframeString:srcURL;if(embedCodeString!==embedCode.textContent||force){embedCode.textContent=embedCodeString} + if(updatePreview&&!_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isiPhone()&&(embedPreviewParent?.innerHTML.replace(/&/g,'&')!==noTrackingIframeString||force)){const iframe=embedPreviewParent.querySelector('iframe');iframe?.removeEventListener('load',this._iframeLoadEventListener);embedPreviewParent.innerHTML=noTrackingIframeString;const newIframe=embedPreviewParent.querySelector('iframe');newIframe.addEventListener('load',this._iframeLoadEventListener)} + this.resize()} + calcTemplateWidth(){const{deviceResolutions}=this._config;const{embedPreviewParent}=this._children;const{previewDevice,useBrowserTemplate}=this._state;if(!useBrowserTemplate){return} + const{width,height}=deviceResolutions[previewDevice]||deviceResolutions.desktop;console.log('\ncalculating template size for',previewDevice);console.log('width:',width);console.log('height:',height)} + calcIframeTransform(){console.log('calcIframeTransform: ');const{previewResolution}=this._state;const{width,height}=previewResolution;this.resize()} + _iframeLoadEventListener(e){const{contentWindow}=e.target;if(contentWindow){contentWindow.onhashchange=()=>{this.setSrcURL(contentWindow.location.href,!1);this.updateEmbedCode({updatePreview:!1})}}} + calcIframeTransforms(){const{embedPreviewParent}=this._children;const{deviceResolutions}=this._config;const{width,height}=deviceResolutions.desktop;const{paddingTop,paddingRight,paddingBottom,paddingLeft}=getComputedStyle(embedPreviewParent);const{clientWidth:parentWidth,clientHeight:parentHeight}=embedPreviewParent;const paddedParentWidth=parentWidth-parseFloat(paddingLeft)-parseFloat(paddingRight);const paddedParentHeight=parentHeight-parseFloat(paddingTop)-parseFloat(paddingBottom);this._element.style.setProperty('--iframe-width',`${width}px`);this._element.style.setProperty('--iframe-height',`${height}px`);const widthScale=paddedParentWidth/width;const heightScale=paddedParentHeight/height;const iframeScale=Math.min(widthScale,heightScale);this._element.style.setProperty('--iframe-scale',iframeScale);const offsetX=(paddedParentWidth-(width*iframeScale))/2;const scaledOffsetX=offsetX/iframeScale;this._element.style.setProperty('--iframe-offset-x',`${scaledOffsetX}px`)} + setPreviewDevice(e){const{value:previewDevice}=e.target;const{previewDevice:currPreviewDevice}=this._state;if(previewDevice===currPreviewDevice){return} + this.setState({previewDevice});this.updateEmbedCode({force:!0})} + toggleIframeElements(e){const{checked}=e.target;this.setState({iframeElements:checked});this.updateEmbedCode({updatePreview:!1})} + getEmbedCodeFromParams(){const{embedOptions}=this._config;const flattenedOptions=embedOptions.flatMap(({items})=>items);const splitUrl=this._srcURL.split('?');const urlParams=new URLSearchParams(splitUrl[1]);const noTrackingUrlParams=new URLSearchParams(splitUrl[1]);const embedParamEntries=Object.entries(this._embedQueries).filter(([currQuery,currValue])=>{const{appQueryDefault,dependencies}=flattenedOptions.find(({query})=>query===currQuery)??{};const dependenciesSatisfied=!dependencies||(dependencies?.length&&dependencies.every(([depQuery,depValidFunc])=>depValidFunc(this._embedQueries[depQuery])));return currValue!==appQueryDefault&&dependenciesSatisfied});const embedParams=Object.fromEntries(embedParamEntries);const noTrackingParams={...embedParams,tracking:'false'};Object.keys(embedParams).forEach(key=>urlParams.set(key,embedParams[key]));Object.keys(noTrackingParams).forEach(key=>noTrackingUrlParams.set(key,noTrackingParams[key]));const srcURL=`${splitUrl[0]}${urlParams.size ? '?' : ''}${urlParams.toString()}`;const noTrackingSrcURL=`${splitUrl[0]}${noTrackingUrlParams.size ? '?' : ''}${noTrackingUrlParams.toString()}`;const iframeString=``;const noTrackingIframeString=``;return{srcURL,iframeString,noTrackingIframeString}} + generateEmbedContent(){const{embedOptions}=this._config;const{embedOptsContent,embedAdvOptsContent}=this._children;embedOptions.forEach(({isAdvanced,groupName,items})=>{const containerType=groupName?'fieldset':'div';const groupContainer=document.createElement(containerType);groupContainer.className='embed-group';if(groupName){const groupLegend=document.createElement('legend');groupLegend.innerText=groupName;groupContainer.appendChild(groupLegend)} + this.createGroupInputs(items,groupContainer);const optionsParent=isAdvanced?embedAdvOptsContent:embedOptsContent;optionsParent.appendChild(groupContainer)})} + createGroupInputs(items,groupContainer){items.forEach(option=>{const{name,description,query,type,values,inputDefault,greyValue,appQueryDefault,invert,onChange}=option;const singleInput=type==='checkbox'||type==='number';const radioInput=type==='radio';const greyedOut=inputDefault===greyValue;if(singleInput){const inputContainer=document.createElement('div');inputContainer.className=`input-container ${type}-container ${greyedOut ? 'greyed-out' : ''}`;const embedId=`input-${query}`;const label=document.createElement('label');label.className='clickable';label.innerText=name;label.setAttribute('for',embedId);const input=document.createElement('input');input.className='clickable';input.setAttribute('id',embedId);input.setAttribute('type',type);input.setAttribute('name',query);if(type==='checkbox'&&inputDefault===!0){input.setAttribute('checked','')}else if(type==='number'){const[min,max,step]=values;input.setAttribute('min',min);input.setAttribute('max',max);input.setAttribute('step',step??1);input.setAttribute('value',inputDefault);input.setAttribute('inputmode','decimal');input.setAttribute('required','')}else{input.setAttribute('value',inputDefault)} + input.addEventListener('click',e=>e.stopPropagation());input.addEventListener('change',e=>{const{checked,value,validity}=e.target;if(type==='checkbox'){const invertedValue=invert?!checked:checked;this.updateEmbedParams(query,invertedValue);typeof onChange==='function'&&onChange(checked)}else if(type==='number'){const valueFloat=parseFloat(value);const setValue=validity.valid?valueFloat:appQueryDefault;this.updateEmbedParams(query,setValue);const isGreyedOut=!validity.valid||valueFloat===greyValue;inputContainer.classList.toggle('greyed-out',isGreyedOut);typeof onChange==='function'&&onChange(value)}});const helpIcon=document.createElement('span');helpIcon.className='clickable icon icon-help';helpIcon.setAttribute('data-tippy-content',description);helpIcon.setAttribute('aria-label',`Help: ${description}`);helpIcon.setAttribute('tabindex','0');inputContainer.appendChild(input);inputContainer.appendChild(label);inputContainer.appendChild(helpIcon);groupContainer.appendChild(inputContainer)}else if(radioInput){const radioFieldset=document.createElement('fieldset');radioFieldset.className=`radio-fieldset ${type}-option`;const radioLegend=document.createElement('legend');radioLegend.innerText=name;radioFieldset.appendChild(radioLegend);values.forEach(({title,value,description})=>{const inputContainer=document.createElement('div');inputContainer.className=`input-container ${type}-container`;const radioId=`input-${query}-${value}`;const radioLabel=document.createElement('label');radioLabel.className='clickable';radioLabel.innerText=title;radioLabel.setAttribute('for',radioId);const radioInput=document.createElement('input');radioInput.className='clickable';radioInput.setAttribute('id',radioId);radioInput.setAttribute('type',type);radioInput.setAttribute('name',query);radioInput.setAttribute('value',value);if(value===inputDefault){radioInput.setAttribute('checked','')} + radioInput.addEventListener('change',e=>{const{value}=e.target;this.updateEmbedParams(query,value)});const helpIcon=document.createElement('span');helpIcon.className='clickable icon icon-help';helpIcon.setAttribute('data-tippy-content',description);helpIcon.setAttribute('aria-label',`Help: ${description}`);helpIcon.setAttribute('tabindex','0');inputContainer.appendChild(radioInput);inputContainer.appendChild(radioLabel);inputContainer.appendChild(helpIcon);radioFieldset.appendChild(inputContainer)});groupContainer.appendChild(radioFieldset)}})} + destroyEmbedContent(){const{embedOptsContent,embedAdvOptsContent}=this._children;embedOptsContent.innerHTML='';embedAdvOptsContent.innerHTML=''} + setActiveTab(tabName){const{tabHeaders,tabContent}=this._children;tabHeaders.childNodes.forEach(tabHeaderEl=>{const active=tabHeaderEl.classList.contains(tabName);tabHeaderEl.classList.toggle('active',active)});tabContent.childNodes.forEach(tabContentEl=>{const active=tabContentEl.classList.contains(tabName);tabContentEl.classList.toggle('active',active)});if(tabName==='embed'){this.updateEmbedCode();if(this._tippySingleton===null){this._tippyItems=(0,tippy_js__WEBPACK_IMPORTED_MODULE_4__["default"])('.icon-help');this._tippySingleton=(0,tippy_js__WEBPACK_IMPORTED_MODULE_4__.createSingleton)(this._tippyItems,{moveTransition:'transform 0.2s ease-out'})}} + this._activeTab=tabName} + copyToClipboard(e){const{linkCode,linkContainer,embedCode,copiedOverlay}=this._children;const isLink=e.currentTarget.parentElement===linkContainer;const codeText=isLink?linkCode.textContent:embedCode?.textContent;if(!codeText){return} + navigator.clipboard.writeText(codeText).then(()=>{copiedOverlay.classList.remove('flash');void copiedOverlay.offsetWidth;copiedOverlay.classList.add('flash');return!0}).catch(err=>{console.error('Could not copy text: ',err)})} + handleClick(e){const{resetOnClose}=this._config;const shouldClose=e.target===this._element||e.target===this._children.closeButton;if(shouldClose){this.hide();this.resetScrollbar();resetOnClose&&this.resetEmbedOptions();this.destroyTooltips()} + const shouldDeselectText=e.target?.nodeName!=='CODE';shouldDeselectText&&window.getSelection().removeAllRanges()} + handleTabClick(e){const tabName=e.target?.innerText?.toLowerCase();const setActive=tabName==='link'||tabName==='embed';setActive&&this.setActiveTab(tabName)} + destroyTooltips(){this._tippyItems=null;this._tippySingleton?.destroy();this._tippySingleton=null} + resetEmbedOptions(){this.setEmbedParams();this.destroyEmbedContent();this.generateEmbedContent()} + resetScrollbar(){this._embedOptionsScrollbar.scroll(0)} + resize(){this.calcIframeTransforms();const isWideHasUpdated=this.setIsWide();if(isWideHasUpdated){this.addShareButtonToParent();this.resetScrollbar()}} + setEnabled(enabled){super.setEnabled(enabled);this.shareButton.classList.toggle('hidden',!enabled);const addToParent=enabled&&!this.shareButton.parentNode;addToParent&&this.addShareButtonToParent()} + __destroy(){super.__disable();this.shareButton.parentNode?.removeChild(this.shareButton);this.shareButton=null}} + ShareModal.html=(_share_modal_html__WEBPACK_IMPORTED_MODULE_2___default());__webpack_exports__["default"]=(ShareModal)}),"../eyes/src/components/story/blocks/buttons_block/buttons_block.js": + /*!**************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/buttons_block/buttons_block.js ***! + \**************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ButtonsBlock":function(){return ButtonsBlock}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../../../internal */"../eyes/src/internal.js");var _buttons_block_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./buttons_block.html */"../eyes/src/components/story/blocks/buttons_block/buttons_block.html");var _buttons_block_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_buttons_block_html__WEBPACK_IMPORTED_MODULE_1__);class ButtonsBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock{constructor(app,options={}){super(app,{...options});this._app=app;this._options=options;const scene=app.pioneer.get('main');scene.getLoadedPromise().then(()=>{this.setUpHTML(options);return!0}).catch(error=>{console.warn(error)})} + async setUpHTML(options){const{buttonContent}=options.config.info;const buttonBlock=document.getElementsByClassName('buttons-block');buttonContent.forEach((buttonInfo,index)=>{const{id,iconSrc,label}=buttonInfo;const button=document.createElement('button');buttonBlock[0].appendChild(button);button.classList.add('clickable');button.classList.add('custom-button');button.classList.add(`${id}`);if(index===0){button.classList.add('focused')} + const buttonIcon=document.createElement('img');button.appendChild(buttonIcon);buttonIcon.classList.add('button-icon');buttonIcon.src=iconSrc;const buttonLabel=document.createTextNode(label);button.appendChild(buttonLabel);button.onclick=this.buttonClick})} + buttonClick=async e=>{const{buttonContent}=this._options.config.info;const timeManager=this._app.getManager('time');const selectedButton=Object.values(buttonContent).find(button=>e.target.classList.contains(button.id));const allButtons=document.querySelectorAll('.custom-button');allButtons.forEach(button=>button.classList.remove('focused'));if(selectedButton.timeLimits){timeManager.setMin(selectedButton.timeLimits.min);timeManager.setMax(selectedButton.timeLimits.max)}else{timeManager.resetLimits()} + const{_id:storyId}=this._app.getComponent('story');const currentStory=this._app.getManager('content').getStory(storyId);const defaultTime=currentStory.slides[0].time;timeManager.setTime(selectedButton.startTime??defaultTime);timeManager.setTimeRate(300);e.target.classList.add('focused');selectedButton.onClick(this._app)}} + ButtonsBlock.html=(_buttons_block_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/story/blocks/checkbox_block/checkbox_block.js": + /*!****************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/checkbox_block/checkbox_block.js ***! + \****************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"CheckboxBlock":function(){return CheckboxBlock}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../../../internal */"../eyes/src/internal.js");var _checkbox_block_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./checkbox_block.html */"../eyes/src/components/story/blocks/checkbox_block/checkbox_block.html");var _checkbox_block_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_checkbox_block_html__WEBPACK_IMPORTED_MODULE_1__);class CheckboxBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock{constructor(app,options={}){super(app,{...options});const scene=app.pioneer.get('main');scene.getLoadedPromise().then(()=>{this.setUpHTML(options);return!0}).catch(error=>{console.warn(error)});this.options=options} + async setUpHTML(options){const{checkboxContent}=options.config.info;const checkboxBlock=document.getElementsByClassName('checkboxes-block')[0];checkboxContent.forEach(checkboxInfo=>{const{id,label,onChange}=checkboxInfo;const labelElement=document.createElement('label');labelElement.classList.add('cb-container');labelElement.classList.add('clickable');const checkbox=document.createElement('input');checkbox.type='checkbox';checkbox.checked=!0;checkbox.id=`${id}-checkbox`;const span=document.createElement('span');span.classList.add('checkmark');labelElement.appendChild(document.createTextNode(label));labelElement.appendChild(checkbox);labelElement.appendChild(span);checkboxBlock.appendChild(labelElement);checkbox.addEventListener('change',e=>{onChange(e,this._app)})})} + setChecked(checkboxId,checked){const checkbox=document.getElementById(`${checkboxId}-checkbox`);if(checkbox){checkbox.checked=checked}}} + CheckboxBlock.html=(_checkbox_block_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/story/blocks/description_block/description_block.js": + /*!**********************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/description_block/description_block.js ***! + \**********************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"DescriptionBlock":function(){return DescriptionBlock}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../../../internal */"../eyes/src/internal.js");var _description_block_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./description_block.html */"../eyes/src/components/story/blocks/description_block/description_block.html");var _description_block_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_description_block_html__WEBPACK_IMPORTED_MODULE_1__);class DescriptionBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock{constructor(app,options={}){super(app,{hasMore:!1,isMoreVisible:!1,...options});this._class.hasMoreClass={true:'',false:'hidden'};this._more={isVisible:{moreMessage:'Show Less',moreIcon:'icon-minus',moreClass:''},isHidden:{moreMessage:'Show More',moreIcon:'icon-plus',moreClass:'hidden'}};Object.assign(this._state,this._more.isHidden,{hasMoreClass:this._class.hasMoreClass[this._state.hasMore]})} + init(){super.init();const hasMore=Boolean(this._config.info.more);this.setState({hasMore,hasMoreClass:this._class.hasMoreClass[hasMore]})} + showMore(){this.setState({isMoreVisible:!0,...this._more.isVisible})} + hideMore(){this.setState({isMoreVisible:!1,...this._more.isHidden})} + toggleMore(){if(this._state.isMoreVisible){this.hideMore()}else{this.showMore()}}} + DescriptionBlock.html=(_description_block_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/story/blocks/hint_block/hint_block.js": + /*!********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/hint_block/hint_block.js ***! + \********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"HintBlock":function(){return HintBlock}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../../../internal */"../eyes/src/internal.js");var _hint_block_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./hint_block.html */"../eyes/src/components/story/blocks/hint_block/hint_block.html");var _hint_block_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_hint_block_html__WEBPACK_IMPORTED_MODULE_1__);class HintBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock{constructor(app,options={}){super(app,{iconBefore:'icon-greater',iconAfter:'icon-greater',...options});Object.assign(this._state,{text:this._config.info.text||'Scroll to continue',isIconBeforeVisibleClass:this._class.isVisible[this._config.info.iconBeforeText||!1],isIconAfterVisibleClass:this._class.isVisible[this._config.info.iconAfterText||!1]})}} + HintBlock.html=(_hint_block_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/story/blocks/image_block/image_block.js": + /*!**********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/image_block/image_block.js ***! + \**********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ImageBlock":function(){return ImageBlock}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../../../internal */"../eyes/src/internal.js");var _image_block_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./image_block.html */"../eyes/src/components/story/blocks/image_block/image_block.html");var _image_block_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_image_block_html__WEBPACK_IMPORTED_MODULE_1__);class ImageBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock{onClick(){const image=this._element.cloneNode(!0);image.classList.add('fullscreen');image.classList.remove('clickable');this._app.getComponent('overlay').setContent(image);this._app.getComponent('overlay').show()}} + ImageBlock.html=(_image_block_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/story/blocks/replay_button_block/replay_button_block.js": + /*!**************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/replay_button_block/replay_button_block.js ***! + \**************************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ReplayButtonBlock":function(){return ReplayButtonBlock}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../../../internal */"../eyes/src/internal.js");var _replay_button_block_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./replay_button_block.html */"../eyes/src/components/story/blocks/replay_button_block/replay_button_block.html");var _replay_button_block_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_replay_button_block_html__WEBPACK_IMPORTED_MODULE_1__);class ReplayButtonBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock{init(){if(!this._config.info.text){this._config.info.text=this._config.info.fromStart?'Restart Story':'Replay Animation'} + super.init(this._config.info)} + async onClick(){const router=this._app.getManager('router');if(this._config.info.fromStart){router.navigate(router.currentRoute.url)}else{router.reload()}}};ReplayButtonBlock.html=(_replay_button_block_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/story/blocks/story_base_content_block/story_base_content_block.js": + /*!************************************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/story_base_content_block/story_base_content_block.js ***! + \************************************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"StoryBaseContentBlock":function(){return StoryBaseContentBlock}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../../../internal */"../eyes/src/internal.js");class StoryBaseContentBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={config:{info:{}}}){options.isVisible=!0;super(app,null,options);if(this._config.info.onEnter){this.onEnter=async()=>await this._config.info.onEnter(app,this)} + if(this._config.info.onLeave){this.onLeave=async()=>await this._config.info.onLeave(app,this)} + this.bindFunctions(['onEnter','onLeave','onClick'])} + init(){super.init(this._config.info);this._element.classList.add('content-block','{{isVisibleClass}}');if(Array.isArray(this._config.info.classList)){this._element.classList.add(...this._config.info.classList)} + this._setVariables(this._element,!1);if(this._config.info.clickable||this._config.info.func){this._element.classList.add('clickable');this._element.addEventListener('click',this.onClick)}} + async onEnter(){} + async onLeave(){} + async onClick(){const{type}=this._config.info;if(type!=='buttons'){await this._config.info.func(this._app,this)}}}}),"../eyes/src/components/story/blocks/title_block/title_block.js": + /*!**********************************************************************!*\ + !*** ../eyes/src/components/story/blocks/title_block/title_block.js ***! + \**********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TitleBlock":function(){return TitleBlock}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../../../internal */"../eyes/src/internal.js");var _title_block_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./title_block.html */"../eyes/src/components/story/blocks/title_block/title_block.html");var _title_block_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_title_block_html__WEBPACK_IMPORTED_MODULE_1__);class TitleBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock{} + TitleBlock.html=(_title_block_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/story/blocks/toggle_block/toggle_block.js": + /*!************************************************************************!*\ + !*** ../eyes/src/components/story/blocks/toggle_block/toggle_block.js ***! + \************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ToggleBlock":function(){return ToggleBlock}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../../../internal */"../eyes/src/internal.js");var _toggle_block_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./toggle_block.html */"../eyes/src/components/story/blocks/toggle_block/toggle_block.html");var _toggle_block_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_toggle_block_html__WEBPACK_IMPORTED_MODULE_1__);class ToggleBlock extends _internal__WEBPACK_IMPORTED_MODULE_0__.StoryBaseContentBlock{constructor(app,options={}){super(app,{isSelected:!1,...options});this._class.isSelectedClass={true:'selected',false:''};this._config.info.selected=Boolean(this._config.info.selected);Object.assign(this._state,{isSelectedClass:this._class.isSelectedClass[this._state.isSelected]})} + async onEnter(){await super.onEnter();if(this._config.info.selected!==this._state.isSelected){await this.onClick()}} + async onLeave(){await super.onLeave();if(this._state.isSelected){await this.onClick()}} + async onClick(){await super.onClick();if(this._state.isSelected){this.unselect();console.log('unselect')}else{this.select();console.log('select')}} + select(){this.setState({isSelected:!0,isSelectedClass:this._class.isSelectedClass.true})} + unselect(){this.setState({isSelected:!1,isSelectedClass:this._class.isSelectedClass.false})}} + ToggleBlock.html=(_toggle_block_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/story/story.js": + /*!*********************************************!*\ + !*** ../eyes/src/components/story/story.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Story":function(){return Story}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");class Story extends _internal__WEBPACK_IMPORTED_MODULE_0__.Carousel{constructor(app,options){super(app,null,{isCloseButtonVisible:!0,closeButtonText:'Close',...options});this._id='';this._info=[];this._blocks={};this._config.navigationButtons.next.text=_internal__WEBPACK_IMPORTED_MODULE_0__.AppUtils.isPrimaryTouch()?'Swipe to continue':'Scroll to continue';this._onSlideChange=async(index,includeTime=!1)=>{const query={slide:this._children.slides[index].dataset.id};if(includeTime){query.time=this._app.getManager('time').getTimeUrl()}else{query.__remove=['time']} + const router=this._app.getManager('router');const currentRoute=router.currentRoute;await router.navigate(query,currentRoute.url)}} + init(){super.init();const closeBtn=this._element.querySelector('.close-button');closeBtn?.setAttribute('aria-label','Close story');this._setVariables(this._children.carousel,!1)} + _setExpandToggleAriaLabel(){const toggleBtns=this._element.querySelectorAll('.mobile-collapse');const labelText=this._state.isCollapsed?'Collapse story panel':'Expand story panel';toggleBtns.forEach(el=>el.setAttribute('aria-label',labelText))} + _toggleCollapse(){this._setExpandToggleAriaLabel();super._toggleCollapse()} + async onRouteChange(storyInfo,{cancelToken,slide,id}={}){if(cancelToken&&cancelToken.isCanceled){return} + this.clear();this._info=storyInfo;this._id=id;if(this._app.getManager('router').configs.locked){const isCloseButtonVisible=!1;this.setState({isCloseButtonVisible,isCloseButtonVisibleClass:this._class.isVisible[isCloseButtonVisible]})} + await this.setUp();this._setExpandToggleAriaLabel();const index=slide?this._children.slides.findIndex(x=>x.dataset.id===slide)||0:0;if(storyInfo[index]?.rate!==undefined){this._app.getManager('time').setTimeRate(storyInfo[index].rate)} + await this.goToSlide(index)} + async onQueryChange({cancelToken,slide}={}){if(cancelToken&&cancelToken.isCanceled){return} + const index=slide?this._children.slides.findIndex(x=>x.dataset.id===slide)||0:0;if(this._info[index]?.rate!==undefined){this._app.getManager('time').setTimeRate(this._info[index].rate)} + await this.goToSlide(index)} + async createBlockContent(blockInfo,slideIndex){const{hideExternalLinks}=this.app.getManager('router').configs;let block;switch(blockInfo.type){case 'title':{const storyBlockInfo={...blockInfo};storyBlockInfo.title=hideExternalLinks===!0?this.app.getManager('content').hideExternalLinksInText(storyBlockInfo.title):storyBlockInfo.title;block=new _internal__WEBPACK_IMPORTED_MODULE_0__.TitleBlock(this._app,{config:{info:storyBlockInfo}});break} + case 'description':{const storyBlockInfo={...blockInfo};storyBlockInfo.description=hideExternalLinks===!0?this.app.getManager('content').hideExternalLinksInText(storyBlockInfo.description):storyBlockInfo.description;block=new _internal__WEBPACK_IMPORTED_MODULE_0__.DescriptionBlock(this._app,{config:{info:storyBlockInfo}});break} + case 'image':case 'diagram':{block=new _internal__WEBPACK_IMPORTED_MODULE_0__.ImageBlock(this._app,{config:{info:blockInfo}});break} + case 'toggle':{block=new _internal__WEBPACK_IMPORTED_MODULE_0__.ToggleBlock(this._app,{config:{info:blockInfo}});break} + case 'hint':{block=new _internal__WEBPACK_IMPORTED_MODULE_0__.HintBlock(this._app,{config:{info:blockInfo}});break} + case 'replay':{block=new _internal__WEBPACK_IMPORTED_MODULE_0__.ReplayButtonBlock(this._app,{config:{info:blockInfo}});break} + case 'buttons':{block=new _internal__WEBPACK_IMPORTED_MODULE_0__.ButtonsBlock(this._app,{config:{info:blockInfo}});break} + case 'checkboxes':{block=new _internal__WEBPACK_IMPORTED_MODULE_0__.CheckboxBlock(this._app,{config:{info:blockInfo}});break} + default:break} + await block.init();this._onEnter[slideIndex].push(block.onEnter);this._onLeave[slideIndex].push(block.onLeave);this._blocks[blockInfo.type]=block;return block.element} + getStoryBlock(blockType){return this._blocks[blockType]||console.warn(`Block ${blockType} is not available`)} + async createSlideContent(slide,index){if(slide.htmlFile){}else{const content=document.createDocumentFragment();for(let i=0;ionEnter(this._app,this))} + const content=await this.createSlideContent(this._info[i],i);classList.push('grid-layout','simple-grid');if(onLeave){this._onLeave[i].push(()=>onLeave(this._app,this))} + this.addSlide({id,type,classList,content},{isFirst:i===0,isLast:i===this._info.length-1})}} + close(){const router=this._app.getManager('router');router.navigate(router.homeRoute)} + async onLeave(index){await super.onLeave(index);if(!(typeof index==='number')){const router=this._app.getManager('router');router.removeQuery(['slide'])}} + _updateTooltipsProps(){const{slideType}=this._state;const style=getComputedStyle(document.body);const offsetHeight=-(parseFloat(style.getPropertyValue('--gridHeaderHeight'))+20);if(this._progressTooltip!==null){this._progressTooltip.setProps({offset:slideType==='overlay'?[0,offsetHeight]:[0,10]})}}}}),"../eyes/src/components/time_controller/index.js": + /*!*******************************************************!*\ + !*** ../eyes/src/components/time_controller/index.js ***! + \*******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _time_controller_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./time_controller.js */"../eyes/src/components/time_controller/time_controller.js");__webpack_exports__["default"]=(_time_controller_js__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/time_controller/time_controller.js": + /*!*****************************************************************!*\ + !*** ../eyes/src/components/time_controller/time_controller.js ***! + \*****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var tippy_js__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! tippy.js */"../eyes/node_modules/tippy.js/dist/tippy.esm.js");var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _time_controller_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./time_controller.html */"../eyes/src/components/time_controller/time_controller.html");var _time_controller_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_time_controller_html__WEBPACK_IMPORTED_MODULE_1__);class TimeController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app){super(app,null,{isPlay:!1,playClass:'',rate:0,rateDisplay:0});this._class.fontSize.small='tiny';this._class.isPlay={true:'icon-pause',false:'icon-play'};this._rates=[-94608000,-31536000,-6048000,-604800,-86400,-36000,-3600,-600,-60,-10,-1,0,1,10,60,600,3600,36000,86400,604800,6048000,31536000,94608000];this._manager=this._app.getManager('time');this._router=this._app.getManager('router');this._manager.setDefaultTimeRate(1);const rate=this._manager.getTimeRate();const isPlay=rate!==0;this.setState({isPlay,playClass:this._class.isPlay[isPlay],rate,rateDisplay:this.getRateDisplay()});this.bindFunctions(['getRateLimits','setRateLimits','setRate','setDefaultRate','setRealRate','decreaseRate','increaseRate','togglePlayPause','onRateChange','onForcedPause','onForcedPauseResume'])} + init(){super.init();tippy_js__WEBPACK_IMPORTED_MODULE_2__["default"].setDefaultProps({theme:'default',touch:['hold',2000],delay:[600,null],plugins:[tippy_js__WEBPACK_IMPORTED_MODULE_2__.followCursor]});(0,tippy_js__WEBPACK_IMPORTED_MODULE_2__["default"])(this._children.toggleBtn,{placement:'top'});(0,tippy_js__WEBPACK_IMPORTED_MODULE_2__["default"])(this._children.increaseBtn,{placement:'top'});(0,tippy_js__WEBPACK_IMPORTED_MODULE_2__["default"])(this._children.decreaseBtn,{placement:'top'});this._children.decreaseContainer.classList.add('bg-color','gray','dark');this._children.increaseContainer.classList.add('bg-color','gray','dark');this._children.label.classList.add('semi');this._children.rateDisplay.classList.add('semi');this._callbackRegistry.push({emitter:this._app.getManager('time'),event:'ratechange',callback:this.onRateChange})} + getRateLimits(){return this._rates} + setRateLimits(rates){this._rates=rates} + setRate(rate){this._router.navigate({time:this._manager.getTimeUrl(),rate},this._router.currentRoute.url)} + decreaseRate(){if(this._rates.length===0){return} + const index=this._rates.indexOf(this._manager.getTimeRate());if(index===0){return} + this.setRate(this._rates[index-1])} + increaseRate(){if(this._rates.length===0){return} + const index=this._rates.indexOf(this._manager.getTimeRate());if(index===this._rates.length-1){return} + this.setRate(this._rates[index+1])} + togglePlayPause(){const isPlay=!this._state.isPlay;if(isPlay){this._manager.play()}else{this._manager.pause()} + this.setRate(this._manager.getTimeRate())} + setDefaultRate(){this.setRate(this._manager.getDefaultTimeRate())} + setRealRate(){this.setRate(1)} + onRateChange(){const rate=this._manager.getTimeRate();const isPlay=rate!==0;if(isPlay===this._state.isPlay&&this._state.rate===rate){return} + if(this._rates.length>0){if(!this._rates.includes(rate)){this.setRate(this._manager.getDefaultTimeRate());return}} + this.setState({isPlay,rate,playClass:this._class.isPlay[isPlay],rateDisplay:this.getRateDisplay(rate)})} + onForcedPause(){this.setRate(0)} + onForcedPauseResume(){this.setDefaultRate()} + getRateUnit(rate=null){if(rate===null){rate=this._manager.getTimeRate()} + const yrs=rate/31536000;const months=rate/2592000;const weeks=rate/604800;const days=rate/86400;const hrs=rate/3600;const mins=rate/60;let unit='';if((yrs>=1||yrs<=-1)&&yrs%1===0){rate=yrs;unit=' yr'}else if((months>=1||months<=-1)&&months%1===0){rate=months;unit=' mth'}else if((weeks>=1||weeks<=-1)&&weeks%1===0){rate=weeks;unit=' wk'}else if((days>=1||days<=-1)&&days%1===0){rate=days;unit=' day'}else if((hrs>=1||hrs<=-1)&&hrs%1===0){rate=hrs;unit=' hr'}else if((mins>=1||mins<=-1)&&mins%1===0){rate=mins;unit=' min'}else{rate%=60;unit=' sec'} + return{rate,unit}} + getRateDisplay(input){const{rate,unit}=this.getRateUnit(input);if(rate!==0){return rate+unit+'(s)/sec'}else{return'paused'}}} + TimeController.html=(_time_controller_html__WEBPACK_IMPORTED_MODULE_1___default());__webpack_exports__["default"]=(TimeController)}),"../eyes/src/components/toast/toast.js": + /*!*********************************************!*\ + !*** ../eyes/src/components/toast/toast.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Toast":function(){return Toast}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _toast_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./toast.html */"../eyes/src/components/toast/toast.html");var _toast_html__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_toast_html__WEBPACK_IMPORTED_MODULE_1__);class Toast extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(app,options={}){super(app,null,{isVisible:!1,iconClass:'icon-locked',toastContent:'TOAST!',hideDelay:2000,...options});this._hideTimeout=null} + setIcon(iconClass){this.setState({iconClass})} + setContent(content){this.setState({toastContent:content})} + show(){super.show();const{hideDelay}=this._state;if(hideDelay){clearTimeout(this._hideTimeout);this._hideTimeout=setTimeout(()=>{this.hide()},hideDelay)}} + hide(){super.hide();clearTimeout(this._hideTimeout)}} + Toast.html=(_toast_html__WEBPACK_IMPORTED_MODULE_1___default())}),"../eyes/src/components/tutorial_overlay/index.js": + /*!********************************************************!*\ + !*** ../eyes/src/components/tutorial_overlay/index.js ***! + \********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _tutorial_overlay_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./tutorial_overlay.js */"../eyes/src/components/tutorial_overlay/tutorial_overlay.js");__webpack_exports__["default"]=(_tutorial_overlay_js__WEBPACK_IMPORTED_MODULE_0__["default"])}),"../eyes/src/components/tutorial_overlay/tutorial_overlay.js": + /*!*******************************************************************!*\ + !*** ../eyes/src/components/tutorial_overlay/tutorial_overlay.js ***! + \*******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var swiper__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! swiper */"../eyes/node_modules/swiper/swiper.esm.js");var _internal__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(/*! ../../internal */"../eyes/src/internal.js");var _tutorial_overlay_html__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(/*! ./tutorial_overlay.html */"../eyes/src/components/tutorial_overlay/tutorial_overlay.html");var _tutorial_overlay_html__WEBPACK_IMPORTED_MODULE_6___default=__webpack_require__.n(_tutorial_overlay_html__WEBPACK_IMPORTED_MODULE_6__);swiper__WEBPACK_IMPORTED_MODULE_0__["default"].use([swiper__WEBPACK_IMPORTED_MODULE_0__.Navigation,swiper__WEBPACK_IMPORTED_MODULE_0__.Keyboard,swiper__WEBPACK_IMPORTED_MODULE_0__.Mousewheel]);const DISMISS_TEXT={DEFAULT:'OK, got it. Thanks!',LAST:"OK, let's go!"};class TutorialOverlay extends _internal__WEBPACK_IMPORTED_MODULE_5__.BaseComponent{constructor(app,options={}){options.config={direction:'horizontal',speed:600,slidesPerView:1,spaceBetween:100,keyboard:{enabled:!0},mousewheel:{forceToAxis:!0,thresholdDelta:100},navigation:{prevEl:'.tutorial-carousel-prev',nextEl:'.tutorial-carousel-next'},...options.config};super(app,null,{isVisible:!1,carouselClass:'tutorial-carousel',slideClass:'',dismissText:DISMISS_TEXT.DEFAULT,...options});this._swiper=null;this._allTutorials=null;this._elementMeasures=null;this._currIndex=null;this._slideViewedTimeout=null;this._initTimeout=null;this._bulletClass='swiper-pagination-bullet';this._activeBulletClass='swiper-pagination-bullet-active';this._swiperSlideClass='swiper-slide';this._storageName='EoA_Tutorials'} + setTutorials(tutorials){this._allTutorials=tutorials;this._createSlides()} + hideTutorialSlide(slideId){const{tutorials}=this.app;return tutorials.filter(({id})=>id!==slideId)} + _addEvents(){this._swiper.on('slideChange',({realIndex})=>{this._setHighlightedElement(realIndex);this._setActiveBullet(realIndex);if(this._currIndex!==realIndex){this.navigateToTutorial(realIndex)} + const{id:slideName}=this._allTutorials[realIndex]||{};const lastSlide=realIndex===this._allTutorials.length-1;const slideClass=slideName?`tutorial-slide-${slideName}`:'';this.setState({dismissText:lastSlide?DISMISS_TEXT.LAST:DISMISS_TEXT.DEFAULT,slideClass})});this._children.swiperSlides.addEventListener('click',event=>{const definition=event?.target?.dataset?.def;if(definition){this._app.getComponent('definitionOverlay').navigateToDefinition(definition)}})} + _createSlides(){const{isTouch}=this._app;this._allTutorials.forEach(({id,title,description,extra})=>{const slideElements=[];if(title){const titleEl=document.createElement('h2');titleEl.innerHTML=title;slideElements.push(titleEl)} + if(description){const html=typeof description==='object'?(isTouch?description.touch:description.desktop):description;if(typeof html==='string'){const descriptionEl=document.createElement('p');descriptionEl.innerHTML=html;slideElements.push(descriptionEl)}} + if(extra){const html=typeof extra==='object'?(isTouch?extra.touch:extra.desktop):extra;if(typeof html==='string'){const extraEl=document.createElement('div');extraEl.className='tutorial-extra';extraEl.innerHTML=html;slideElements.push(extraEl)}} + const slideClass=`${this._swiperSlideClass} tutorial-slide-${id}`;slideElements.length&&this._addSlide(slideElements,slideClass)})} + _addSlide(elements=[],slideClass){const slideEl=document.createElement('div');slideEl.className=slideClass;slideEl.replaceChildren(...elements);this._children.swiperSlides.append(slideEl)} + _createBullets(){const{bullets}=this._children;const{slides}=this._swiper;const allBullets=[...slides].map((slide,i)=>{const bullet=document.createElement('span');bullet.classList.add(this._bulletClass);bullet.addEventListener('click',e=>this._swiper.slideTo(i));return bullet});bullets.replaceChildren(...allBullets)} + _setActiveBullet(activeIndex=this._currIndex){const{bullets}=this._children;bullets.childNodes.forEach((bullet,i)=>{bullet.classList.remove(this._activeBulletClass);if(i===activeIndex){bullet.classList.add(this._activeBulletClass)}})} + _setHighlightedElement(highlightIndex=this._currIndex,forceMeasure=!1){const calcMeasures=!this._elementMeasures||forceMeasure;if(calcMeasures){this._elementMeasures=this._calcElementMeasures()} + const measures=this._elementMeasures[highlightIndex];const{mask}=this._allTutorials[highlightIndex];if(measures){const{xPos,yPos,relWidth,relHeight}=measures;const{xSizeMult=1,ySizeMult=1}=mask||{};const sizeCoeff=15;const sizeXaddition=relWidth*sizeCoeff*100;const sizeYaddition=relHeight*sizeCoeff*100;const xSize=(200+sizeXaddition)*xSizeMult;const ySize=(200+sizeYaddition)*ySizeMult;const xSizeValid=Math.max(200,xSize);const ySizeValid=Math.max(200,ySize);const rangeXcoeff=100/(xSizeValid-100);const rangeYcoeff=100/(ySizeValid-100);const relX=(0.5-rangeXcoeff*0.5)+xPos*rangeXcoeff;const relY=(0.5-rangeYcoeff*0.5)+yPos*rangeYcoeff;const percX=(relX*100).toFixed(2);const percY=(relY*100).toFixed(2);this._element.style.setProperty('--tutorial-mask-grad','radial-gradient(transparent, black 5%)');this._element.style.setProperty('--tutorial-mask-pos',`${percX}% ${percY}%`);this._element.style.setProperty('--tutorial-mask-size',`${xSizeValid}% ${ySizeValid}%`)}else{this._element.style.setProperty('--tutorial-mask-grad',null);this._element.style.setProperty('--tutorial-mask-pos',null);this._element.style.setProperty('--tutorial-mask-size',null)}} + onQueryChange({cancelToken,tutorial}={}){clearTimeout(this._slideViewedTimeout);const{currentRoute,homeRoute}=this.app.getManager('router');const notHome=currentRoute.url!==homeRoute;if(notHome||cancelToken?.isCanceled){return} + const newCurrIndex=this._getIndexByTutorialId(tutorial);if(newCurrIndex===this._currIndex){return} + this._currIndex=newCurrIndex;if(this._currIndex>-1){if(this._state.isVisible){this._swiper.slideTo(this._currIndex)}else{this.show()} + this._setSlideViewedTimeout(newCurrIndex)}else{this.hide()}} + _initSwiper(){const{carouselClass}=this._state;const selector=`.${carouselClass} .swiper-wrapper > div`;_internal__WEBPACK_IMPORTED_MODULE_5__.AppUtils.elementReady(selector).then(()=>{this._initTimeout=setTimeout(()=>{if(this._swiper){this._swiper.update();this._swiper.slideTo(this._currIndex)}else{this._swiper=new swiper__WEBPACK_IMPORTED_MODULE_0__["default"](`.${carouselClass}`,this._config);this._postSwiperInitFunction(this._swiper)} + if(this._currIndex===0){this._setActiveBullet();this._setHighlightedElement()} + super.show()},500)})} + _postSwiperInitFunction(){this._addEvents();this._createBullets();this._swiper.slideTo(this._currIndex)} + _getIndexByTutorialId(tutorialId){return this._allTutorials?.findIndex(({id})=>id===tutorialId)} + _setSlideViewedTimeout(viewIndex){this._slideViewedTimeout=setTimeout(()=>{const viewedTutorials=localStorage?.getItem(this._storageName)?.split(',')||[];if(!viewedTutorials.includes(viewIndex.toString())){viewedTutorials.push(viewIndex);viewedTutorials.sort();localStorage?.setItem(this._storageName,viewedTutorials)}},3000)} + _calcElementMeasures(){const{clientWidth,clientHeight}=document.body;return this._allTutorials.map(({targetSelector})=>{const elements=[...document.body.querySelectorAll(targetSelector)].filter(el=>el.offsetParent!==null);if(!elements.length){return!1} + const{left,width,top,height}=elements[0].getBoundingClientRect();return{xPos:1-((left+(width*0.5))/clientWidth),yPos:1-((top+(height*0.5))/clientHeight),relWidth:width/clientWidth,relHeight:height/clientHeight}})} + show(){const layerManager=this._app.getManager('layer');if(!layerManager.getLayer('ui').visible){layerManager.toggleLayer('ui')} + const hasSwiperContent=this._children.swiperSlides?.childNodes?.length;hasSwiperContent&&this._initSwiper();const routeManager=this._app.getManager('router');if(routeManager.configs.hideExternalLinks===!0){const smallprint=document.getElementsByClassName('tutorial-smallprint')[0].innerHTML;document.getElementsByClassName('tutorial-smallprint')[0].innerHTML=this._app.getManager('content').hideExternalLinksInText(smallprint)}} + hide(){clearTimeout(this._initTimeout);this._currIndex=null;super.hide()} + calcPriorityIndex(){const viewedTutorials=localStorage?.getItem(this._storageName)?.split(',')||[];const remainingTutorials=this._allTutorials.filter((_,index)=>!viewedTutorials.includes(index.toString()));return remainingTutorials.length?this._getIndexByTutorialId(remainingTutorials[0].id):null} + navigateToTutorial(tutorialIndex,goHome=!1){const{homeRoute,currentRoute,navigate}=this.app.getManager('router');const path=goHome?homeRoute:(currentRoute.url??'');const validIndex=typeof tutorialIndex==='number'&&tutorialIndex>-1&&tutorialIndexduration?1:sourceDiff/duration;if(sourceProgress!==1){const sourceProgressEased=this._applyEasing(sourceProgress);if(this._sourceMpIsSurface){if(this._switchStartPos){lineEnd.lerp(endCenterPos,endSurfacePos,sourceProgressEased)}else{lineStart.lerp(startCenterPos,startSurfacePos,sourceProgressEased)}}else{if(this._switchStartPos){lineEnd.lerp(endSurfacePos,endCenterPos,sourceProgressEased)}else{lineStart.lerp(startSurfacePos,startCenterPos,sourceProgressEased)}}}else{this._animation.isAnimating=!1;this._animation.sourceStartTime=null}} + if(targetStartTime){const targetDiff=Date.now()-targetStartTime;const targetProgress=targetDiff>duration?1:targetDiff/duration;if(targetProgress!==1){const targetProgressEased=this._applyEasing(targetProgress);if(this._targetMpIsSurface){if(this._switchStartPos){lineStart.lerp(startCenterPos,startSurfacePos,targetProgressEased)}else{lineEnd.lerp(endCenterPos,endSurfacePos,targetProgressEased)}}else{if(this._switchStartPos){lineStart.lerp(startSurfacePos,startCenterPos,targetProgressEased)}else{lineEnd.lerp(endSurfacePos,endCenterPos,targetProgressEased)}}}else{this._animation.isAnimating=!1;this._animation.targetStartTime=null}}} + __loadResources(){this._lineMesh=new pioneer__WEBPACK_IMPORTED_MODULE_0__.LineMesh(this);this._lineMesh.setColors([this._color,this._color]);this._lineMesh.setWidths([this._width,this._width]);this.setOpacity(1);return Promise.resolve()} + setOpacity(opacity){this._lineMesh.setAlphaMultiplier(opacity)} + setDepthTest(depthTest){this._depthTest=depthTest} + __unloadResources(){pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this);this._lineMesh=null} + __prepareForRender(camera){const[lineMesh]=this.getThreeJsObjects();if(this._targetEntity===null){if(lineMesh){lineMesh.visible=!1} + return} + if(lineMesh?.material){lineMesh.material.depthTest=this._depthTest} + this._calcStartPos(camera);this._updatePoints(camera);const startEntity=this._switchStartPos?this._targetEntity:this.getEntity();pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(lineMesh,startEntity,camera);this._lineMesh.prepareForRender(camera)} + _calcStartPos(camera){const switchThreshold=0.001;const targetToCamera=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();camera.getEntity().getPositionRelativeToEntity(targetToCamera,pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,this._targetEntity);const relDistance=targetToCamera.magnitude()/this._distance;const switchStartPos=relDistance0){this.getThreeJsObjects()[0].visible=!1} + return} + this._updatePoints(camera);let alphaMultiplier=1.0;if(!this._ignoreDistance){const cameraDistance=camera.getEntity().getPosition().magnitude();const f=(cameraDistance-this._distanceThreshold.min)/(this._distanceThreshold.max-this._distanceThreshold.min);alphaMultiplier*=f} + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0],this.getEntity(),camera);this._lineMesh.setAlphaMultiplier(alphaMultiplier);this._lineMesh.prepareForRender(camera)} + _updatePoints(){const targetAPos=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const targetBPos=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();this._targetA.getPositionRelativeToEntity(targetAPos,pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,this.getEntity());this._targetB.getPositionRelativeToEntity(targetBPos,pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,this.getEntity());this._positions=[];this._positions.push(targetAPos);this._positions.push(targetBPos);this._lineMesh.setPositions(this._positions);const color=this._color;this._colors=[];this._colors.push(color);this._colors.push(color);this._lineMesh.setColors(this._colors);this._widths=[];this._widths.push(this._width);this._widths.push(this._width);this._lineMesh.setWidths(this._widths);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(targetAPos);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(targetBPos)}}}),"../eyes/src/lib/quadtree.js": + /*!***********************************!*\ + !*** ../eyes/src/lib/quadtree.js ***! + \***********************************/ + (function(){;(function(window,Math){function Quadtree(bounds,max_objects,max_levels,level){this.max_objects=max_objects||10;this.max_levels=max_levels||4;this.level=level||0;this.bounds=bounds;this.objects=[];this.nodes=[]};Quadtree.prototype.split=function(){var nextLevel=this.level+1,subWidth=Math.round(this.bounds.width/2),subHeight=Math.round(this.bounds.height/2),x=Math.round(this.bounds.x),y=Math.round(this.bounds.y);this.nodes[0]=new Quadtree({x:x+subWidth,y:y,width:subWidth,height:subHeight},this.max_objects,this.max_levels,nextLevel);this.nodes[1]=new Quadtree({x:x,y:y,width:subWidth,height:subHeight},this.max_objects,this.max_levels,nextLevel);this.nodes[2]=new Quadtree({x:x,y:y+subHeight,width:subWidth,height:subHeight},this.max_objects,this.max_levels,nextLevel);this.nodes[3]=new Quadtree({x:x+subWidth,y:y+subHeight,width:subWidth,height:subHeight},this.max_objects,this.max_levels,nextLevel)};Quadtree.prototype.getIndex=function(pRect){var index=-1,verticalMidpoint=this.bounds.x+(this.bounds.width/2),horizontalMidpoint=this.bounds.y+(this.bounds.height/2),topQuadrant=(pRect.yhorizontalMidpoint);if(pRect.xverticalMidpoint){if(topQuadrant){index=0}else if(bottomQuadrant){index=3}} + return index};Quadtree.prototype.insert=function(pRect){var i=0,index;if(typeof this.nodes[0]!=='undefined'){index=this.getIndex(pRect);if(index!==-1){this.nodes[index].insert(pRect);return}} + this.objects.push(pRect);if(this.objects.length>this.max_objects&&this.level-1){this._callbacks[eventName].splice(index,1)}} + triggerCallbacks(eventName,params=[]){for(let i=this._callbacks[eventName].length-1;i>=0;i--){const callbackFn=this._callbacks[eventName][i];callbackFn(...params)}} + bindFunctions(fns=[]){const thisAsObject=(this);for(let i=0;i{this.setYawPitchLimits()});this._offsetObserver=new MutationObserver(mutations=>{mutations.forEach(mutation=>{if(mutation.attributeName==='class'){this.setYawPitchLimits()}})});this._sumParent=this._createSumParent();this._createReframeElement();this.bindFunctions(['update','setSearchOptions','goToPreviousCamView','updateOccludedEntities']);this.pioneer.addCallback(this.update,!0)} + setFollowVars(followId){const contentManager=this.app.getManager('content');const{input:searchInput}=this.search?._children||{};const{altName,displayName,iauName}=contentManager.getEntityInfo(followId)??{};const followName=altName||displayName||iauName||'';if(searchInput){searchInput.value=followName} + this.followId=followId;this.followEntity=followId?this.app.scene.get(followId):null;this.followName=followName} + setToastContent({reset=!1}={}){const toast=this.app.getComponent('toast');if(reset){toast.hide();toast.setContent('');return} + const prefix=['Sun','Moon','ISS'].includes(this.followName)?'the ':'';const textHtmlStr=`Camera is following ${prefix}${this.followName}`;const buttonHtmlStr='';toast.setContent(`
        ${textHtmlStr}${buttonHtmlStr}
        `);const{toastContent}=toast._children;const undoButton=toastContent.querySelector('button');undoButton?.addEventListener('click',()=>{this.setEnabled(!1)})} + showToast(){const toast=this.app.getComponent('toast');toast.show()} + validateTimeLimits(){const timeManager=this.app.getManager('time');const currentTime=timeManager.getTime();const{currentView}=this.app.getManager('router');const{min:targetMinET,max:targetMaxET}=this.targetEntity?.getPositionCoverage()||{};const{min:followMinET,max:followMaxET}=this.followEntity?.getPositionCoverage()||{};if(!targetMinET||!targetMaxET||!followMinET||!followMaxET){return{isValid:!1}} + let targetMin=isFinite(targetMinET)?timeManager.etToMoment(targetMinET):targetMinET;let targetMax=isFinite(targetMaxET)?timeManager.etToMoment(targetMaxET):targetMaxET;const followMin=isFinite(followMinET)?timeManager.etToMoment(followMinET):followMinET;const followMax=isFinite(followMaxET)?timeManager.etToMoment(followMaxET):followMaxET;const useEventLimits=currentView==='event'&&this.app.getView('event')._eventName;if(useEventLimits){const{min:limitMin,max:limitMax}=timeManager.getLimits()||{};targetMin=limitMin;targetMax=limitMax} + const minTime=Math.max(followMin,targetMin);const maxTime=Math.min(followMax,targetMax);const noOverlap=followMin>targetMax||followMaxfollowMax;if(updateTime){const time=timeManager.getTimeUrl(minTime);this.app.getManager('router').navigate({time})} + return{isValid:!0,minTime,maxTime}} + async follow(followId){const{currentRoute,previousRoute}=this.app.getManager('router');const{params:prevParams}=previousRoute||{};const{params}=currentRoute||{};const{spaceObject:prevTargetId}=prevParams||{};const{spaceObject:targetId}=params||{};const{cameraDuration}=this._options;this._isEnabled=!0;!this.search&&this.initSearch();this.followId&&this.setLabelWeight(this.followId,!0);this.setTimeLimits({reset:!0});if(prevTargetId&&prevTargetId!==targetId){this.setTargetNotClickable(prevTargetId,!0)} + this.app.getManager('scene').setEntitiesForceVisible([followId]);this.setFollowVars(followId);const divComponent=this.followEntity?.get('div');divComponent.setFadeWhenCloseToEntity(!1);this.triggerViewOptionUpdate();this.setToastContent();this._offsetObserver.observe(document.body,{attributes:!0});this._resizeObserver.observe(document.body);await this.entitiesInPlace();const{isValid,minTime,maxTime}=this.validateTimeLimits();if(!isValid||!this.isEnabled){return} + this.setParentsChangedCallbacks();const startAnimation=()=>{const timeManager=this.app.getManager('time');timeManager.pause();if(this.followName){this.showToast()} + this.animateCamera(cameraDuration).then(()=>{timeManager.play();if(!this._isEnabled){return!1} + this.setTimeLimits({minTime,maxTime});this.setYawPitchLimits();this.setLabelWeight(this.followId);this.updateOccludedEntities();this.setTargetNotClickable(this.targetId);_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isMobile()&&this.app.getComponent('contentPanel')?.hide();this.hideSearch();return!0}).catch(e=>e)};const{isLoaded,onLoaded}=this.app.getComponent('viewOptionsBlock');isLoaded?startAnimation():onLoaded.push(startAnimation)} + unfollow(){const{previousRoute,currentView}=this.app.getManager('router');const{params}=previousRoute||{};const{spaceObject:prevTargetId}=params||{};this.setToastContent({reset:!0});this.setLabelWeight(this.followId,!0);this.updateOccludedEntities({reset:!0});this.setTargetNotClickable(prevTargetId,!0);const prevTargetEntity=this.app.scene.get(prevTargetId);this.setParentsChangedCallbacks({targetEntity:prevTargetEntity,reset:!0});this.setFollowVars(null);this.setSearchOptions({reset:!0});this._offsetObserver.disconnect();this._resizeObserver.disconnect()} + animateCamera(duration){this._sumParent.clearControllers();const sumParentDist=this.targetEntity?.getExtentsRadius()||0.1;const psController=this._sumParent.addControllerByClass(pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.PositionSumController);psController.addEntity(this.targetId,1,0);psController.addEntity(this.followId,0,-sumParentDist);const alignController=this._sumParent.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController);alignController.setPrimaryAlignType('point');alignController.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis);alignController.setPrimaryTargetEntity(this.targetId);const transitionController=this._sumParent.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TransitionController);transitionController.setTransitionTime(duration);transitionController.setParent(this.targetId);const{_easeOutExpoTransition:transitionFunction}=this.app.cameraScripts;transitionController.setTransitionFunction(transitionFunction);const camManager=this.app.getManager('camera');return camManager.followTheEntity(this.targetId,this.followId,this._sumParent.getName(),duration)} + setParentsChangedCallbacks({targetEntity=this.targetEntity,reset=!1}={}){if(reset){targetEntity?.removeParentChangedCallback(this.updateOccludedEntities);this.followEntity?.removeParentChangedCallback(this.updateOccludedEntities);return} + targetEntity?.addParentChangedCallback(this.updateOccludedEntities);this.followEntity?.addParentChangedCallback(this.updateOccludedEntities)} + setLabelWeight(id,resetToPrevious=!1,weight='201'){const labelManager=this.app.getManager('label');const currWeight=labelManager.getWeight(id);if(currWeight===0){labelManager._weights[id]={}} + if(resetToPrevious){if(this._prevValues.weights[id]){labelManager._weights[id].weight=this._prevValues.weights[id];delete this._prevValues.weights[id]}}else{labelManager._weights[id].weight=weight;this._prevValues.weights[id]=currWeight}} + updateOccludedEntities({reset=!1}={}){const entitiesToUnocclude=!reset&&this.getEntitiesToUnocclude();this.setOcclusionProps(entitiesToUnocclude)} + getEntitiesToUnocclude(){const followParent=this.followEntity?.getParent()?.getName();const targetParent=this.app.scene.get(this.targetId)?.getParent()?.getName();const entitiesToSet=[this.followId,followParent,this.targetId,targetParent];return[...new Set(entitiesToSet)].filter(Boolean)} + setOcclusionProps(entitiesToUnocclude){const{occlusion}=this._prevValues;Object.keys(occlusion).forEach(entityId=>{const entity=this.app.scene.get(entityId);entity?.setCanOcclude(occlusion[entityId])});this._prevValues.occlusion={};entitiesToUnocclude?.length&&entitiesToUnocclude.forEach(entityId=>{const entity=this.app.scene.get(entityId);if(!entity){return} + this._prevValues.occlusion[entityId]=entity.canOcclude();entity.setCanOcclude(!1)})} + setTargetNotClickable(entityId,resetToPrevious=!1){const labelManager=this.app.getManager('label');const label=labelManager._labels[entityId];if(!label){return} + const{labelsClickable}=this._prevValues;if(resetToPrevious){if(labelsClickable[entityId]!==undefined){labelManager.setLabelClickable(entityId,labelsClickable[entityId]);delete labelsClickable[entityId]}}else{labelsClickable[entityId]=label.isClickable;labelManager.setLabelClickable(entityId,!1)}} + _createReframeElement(){const{staticElement}=this.app;const elementExists=staticElement.querySelector('.follow-reframe');if(elementExists){return} + this._reframeElement=document.createElement('div');this._reframeElement.classList.add('follow-reframe');staticElement.appendChild(this._reframeElement)} + _createSumParent(){const sumParentName='follow_sum_parent';const sumParentEntity=pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.Entity.createFromOptions(sumParentName,{parents:[]},this.app.scene);sumParentEntity.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero);sumParentEntity.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity);return sumParentEntity} + initSearch(optionElement){if(!this.search){this.search=this.app.getComponent('cameraFollowSearch');this.search.element.addEventListener('click',e=>{e.stopPropagation()});const{placeholder}=this._options;const{input:searchInput}=this.search._children;searchInput&&searchInput.setAttribute('placeholder',placeholder);const defaultInfo='related';this.search._config.infoText.default=defaultInfo;this.search.setState({searchInfo:defaultInfo})} + if(optionElement){optionElement.appendChild(this.search.element);this.search.setParent(optionElement)}} + showSearch(){this.stopHideTimeout();this.search?.show();this.search?.open()} + hideSearch(){this.search?.hide();this.search?.close()} + triggerViewOptionUpdate(){const viewOptionsBlock=this.app.getComponent('viewOptionsBlock');const{isLoaded,onLoaded}=viewOptionsBlock;const triggerSelection=()=>{const{_currentView:currentSelection,selectCameraView,setOptionInnerHTML}=viewOptionsBlock;currentSelection!=='cameraFollow'&&selectCameraView('cameraFollow');setOptionInnerHTML('cameraFollow',this.followInnerHtml)};isLoaded?triggerSelection():onLoaded.push(triggerSelection)} + setReturnToPreviousCamView(){const viewOptionsBlock=this.app.getComponent('viewOptionsBlock');const{_currentView:prevView}=viewOptionsBlock;if(prevView!=='cameraFollow'){const{optionTitle}=viewOptionsBlock._viewOptionsList.find(({id})=>id===prevView)||{};this._returnToPreviousCamView=()=>viewOptionsBlock.selectCameraView(optionTitle)}} + goToPreviousCamView(){typeof this._returnToPreviousCamView==='function'&&this._returnToPreviousCamView();this._returnToPreviousCamView=null} + setTimeLimits({minTime,maxTime,reset=!1}={}){const timeManager=this.app.getManager('time');if(!reset){const{min,max}=timeManager.getLimits();this._prevValues.timeLimits={min,max};timeManager.setMin(minTime);timeManager.setMax(maxTime)}else{const{min,max}=this._prevValues.timeLimits;if(min!==null&&max!==null){timeManager.setMin(min);timeManager.setMax(max)}}} + setYawPitchLimits(){const isOffsetRight=document.body.classList.contains('offset-right');const isOffsetUp=document.body.classList.contains('offset-up');const cameraEntity=this.app.scene.get('camera');const camComponent=cameraEntity.getComponentByType('camera');const hFov=camComponent.getHorizontalFieldOfView();const vFov=camComponent.getVerticalFieldOfView();const orbitController=cameraEntity.getControllerByType('orbit');if(!orbitController){return} + const yawOffset=isOffsetRight?hFov*0.05:0;const pitchOffset=isOffsetUp?vFov*0.2:0;const yawCP=Math.PI*-0.5;const yawLimitDiff=hFov*0.45;const pitchLimitDiff=vFov*0.4;const yawMin=yawCP-yawLimitDiff+yawOffset;const yawMax=yawCP+yawLimitDiff-yawOffset;const pitchMin=-pitchLimitDiff+pitchOffset;const pitchMax=pitchLimitDiff-pitchOffset;orbitController.setYawAngleLimits(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(yawMin,yawMax));orbitController.setPitchAngleLimits(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(pitchMin,pitchMax))} + async setSearchOptions({targetId=this.targetId,followId=this.followId,reset=!1}={}){if(reset){this.search?.setExcludeResults([]);return} + await this.entitiesInPlace();const entityList=[targetId,followId].filter(Boolean);const{maxFeatured}=this._options;const allRelated=[];const timeManager=this.app.getManager('time');const time=timeManager.getTime();const etTime=timeManager.momentToET(time);const targetEntity=this.targetEntity||this.app.scene.get(targetId);const ancestorId=this.followEntity?targetEntity.getLowestCommonAncestorAtTime(this.followEntity,etTime)?.getName():targetEntity.getParentAtTime(etTime);const contentManager=this.app.getManager('content');const{featuredMoons=[]}=ancestorId?await contentManager.getEntityDesc(ancestorId).catch(()=>({})):{};if(!entityList.length||!this.isEnabled){return} + allRelated.push(ancestorId,...featuredMoons);const{currentView}=this.app.getManager('router');const{_entityDesc,_eventDesc}=this.app.getView(currentView);const{related:descRelated=[]}=_entityDesc||{};const{related:eventRelated=[]}=_eventDesc||{};allRelated.push(...descRelated,...eventRelated);allRelated.push('sun');const uniqueRelated=[...new Set(allRelated)];const filteredRelated=uniqueRelated.filter(entityName=>![targetId,followId].includes(entityName));const limitedRelated=filteredRelated.slice(0,maxFeatured);const featuredItems=limitedRelated.map(entityName=>{const{id,iauName,displayName}=this.app.getManager('content')?.getEntityInfo(entityName)||{};const text=displayName||iauName;if(!id||!text){return!1} + return{text,url:`/${id}`}}).filter(Boolean);this.search?.setExcludeResults(entityList);this.search?.setupFeaturedSuggestion(featuredItems)} + async entitiesInPlace(){const entityList=[this.targetId,this.followId].filter(Boolean);await pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.SceneHelpers.waitTillEntitiesInPlace(this.app.scene,entityList)} + update(){const offset=this._pioneer.getInput().getDraggedOffset();const isDragging=!offset.isZero();const isFollowing=this.followId;if(!isFollowing){return} + const{staticElement}=this.app;staticElement.classList.toggle('follow-dragging',isDragging);isDragging&&this.showToast()} + setEnabled(enabled,{resetCam=!0,resetLimits=!0,removeQueries=!0}={}){const alreadyEnabled=this._isEnabled;this._isEnabled=enabled;const{currentRoute,currentView}=this.app.getManager('router');const{params}=currentRoute||{};!this.search&&this.initSearch();if(enabled){this.setReturnToPreviousCamView();const showSearch=!this.followId||alreadyEnabled;showSearch&&this.showSearch();this.followId&&this.setHideTimeout()}else if(alreadyEnabled){resetCam&&this.goToPreviousCamView();this.followId&&this.unfollow();resetLimits&&this.setTimeLimits({reset:!0});removeQueries&&this.app.getManager('router').navigate({__remove:['followId','time','rate']});this.hideSearch();this.app.getComponent('viewOptionsBlock').setOptionInnerHTML('cameraFollow',this.followInnerHtml)}} + setHideTimeout(){this.stopHideTimeout();this._hideSearchTimeout=setTimeout(()=>{this.hideSearch();this.stopHideTimeout()},this._options.hideSearchDelay)} + stopHideTimeout(){clearTimeout(this._hideSearchTimeout);this._hideSearchTimeout=null} + get targetId(){const{currentView}=this.app.getManager('router');const{_target}=this.app.getView(currentView);return _target} + get targetEntity(){return this.app.scene.get(this.targetId)} + get followInnerHtml(){return this.followName?`Following ${this.followName}`:'Follow Target'} + get isEnabled(){return this._isEnabled}}}),"../eyes/src/managers/camera_manager.js": + /*!**********************************************!*\ + !*** ../eyes/src/managers/camera_manager.js ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"CameraManager":function(){return CameraManager}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class CameraManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager{constructor(app,scene){super(app);this._viewport=null;this._defaultScene=scene;this._cameraEntity=null;this._id=null;this._previousId=null;this._context={id:''};this._isTransitioning=!1;this._defaultMaxDistance=2.0e18;this._selectionCallback=null;this._dynEnvMap=null;this._isFreeFly=!1;this._zoomSensitivity={click:0.3,hold:0.1};this._fullLightColor=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1,1,1,1);this._shadowLightColor=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(0.15,0.15,0.15,1);this.bindFunctions(['zoomIn','zoomOut','addDynamicEnvMap','getShadowLightColor','getFullLightColor'])} + createViewportAndCamera(scene){if(scene){this._defaultScene=scene} + if(this.pioneer.getViewport('main-viewport')===null){this._viewport=this.pioneer.addViewport('main-viewport');this._viewport.getDiv().style.width='100%';this._viewport.getDiv().style.height='100%';this._viewport.getDiv().style.left='0';this._viewport.getDiv().style.top='0'} + if(this._defaultScene.get('camera')===null){this._cameraEntity=this._defaultScene.addEntity('camera')} + this._cameraEntity.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity);let camera=(this._cameraEntity.getComponentByType('camera'));if(camera===null){camera=(this._cameraEntity.addComponent('camera'))} + this._viewport.setCamera(camera);this._cameraLight=(this._cameraEntity.get('lightSource'));if(this._cameraLight===null){this._cameraLight=(this._cameraEntity.addComponent('lightSource'));this._cameraLight.setEnabled(!1);this.toggleCameraLight(!0,this._shadowLightColor)} + if(this._dynEnvMap===null){this._dynEnvMap=(this._cameraEntity.addComponent('dynEnvMap'))}} + getContext(){return this._context} + getIsTransitioning(){return this._isTransitioning} + setIsTransitioning(isTransitioning){this._isTransitioning=isTransitioning} + waitForTransitionComplete(){return new Promise(resolve=>{let transitionCheckInterval=setInterval(()=>{if(!this._isTransitioning){clearInterval(transitionCheckInterval);transitionCheckInterval=null;resolve(!0)}},1000)})} + setContext(context){this._context=context;this._previousId=this._id;this._id=this._context.id;const event=new CustomEvent('cameraupdate',{detail:{target:this._id,context:this._context}});window.dispatchEvent(event)} + getCurrentId(){return this._id} + getShadowLightColor(){return this._shadowLightColor} + getFullLightColor(){return this._fullLightColor} + get defaultScene(){return this._defaultScene} + get cameraEntity(){return this._cameraEntity} + get cameraLight(){return this._cameraLight} + get dynamicEnvMap(){return this._dynEnvMap} + toggleCameraLight(active,color){if(this._cameraLight!==null){this._cameraLight.setEnabled(active);if(color!==undefined){this._cameraLight.setColor(color)}}} + getSelectionCallback(){return this._selectionCallback} + setSelectionCallback(callback){if(typeof callback==='function'){this._selectionCallback=callback}} + enterFreeFly(){if(this._context&&this._context.id&&this._context.id!="")cameraFreeFlyParameters.context=this._context;else cameraFreeFlyParameters.context.id="inner_solar_system";this._isFreeFly=!0;this._cameraEntity.clearControllers();this._cameraEntity.addController('freeFly');this._cameraEntity.addController('look');this._cameraEntity.addController('roll')} + exitFreeFly(){this._isFreeFly=!1;this._cameraEntity.clearControllers();flyTo(cameraFreeFlyParameters.context.id)} + toggleFreeFly(){if(this._isFreeFly){this.exitFreeFly()}else{this.enterFreeFly()}} + async goToEntity(id,{camera=undefined,scene=undefined,destination=undefined,distance=undefined,cinematic=!1,minRadius=0.001,maxRadius=this._defaultMaxDistance,duration=0.75,destinationUp=undefined,zoom=!0,select=!0,slowWhenCloseToParent=!0,useSpheroidRadiusForDistance=!1,roll=!1,keyframes=undefined,transitionFunction=undefined}={}){const cameraEntity=camera||this._cameraEntity;const currentScene=scene||this._defaultScene;await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(currentScene,[id]);this._isTransitioning=!0;if(destination!==undefined){const checkDist=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();checkDist.sub(cameraEntity.getPosition(),destination);const cameraParent=cameraEntity.getParent();if(cameraParent!==null){const cameraParentName=cameraParent.getName();if(!isNaN(checkDist.magnitude())){const factor=pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(checkDist.magnitude()/cameraEntity.getPosition().magnitude());duration=Math.max(duration/5,duration*factor)} + if(!isNaN(checkDist.magnitude())&&checkDist.magnitude()<=0.001&&id===cameraParentName){this._isTransitioning=!1;return}}} + try{if(keyframes!==undefined){cameraEntity.clearControllers();const orbitKeyframe=(cameraEntity.addController('orbitKeyframe'));if(keyframes.position){for(let i=0;i{cameraEntity.removeController(spin);cameraEntity.removeController(tap)})}}}catch(err){if(err){console.error(err)}}finally{this._isTransitioning=!1}} + async followTheEntity(targetId,followId,sumParentId,duration){const targetEntity=this._defaultScene.getEntity(targetId);const followEntity=this._defaultScene.getEntity(followId);this.cameraEntity.clearControllers();const dest=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();targetEntity.getPositionRelativeToEntity(dest,pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,followEntity);const camHeight=targetEntity.getExtentsRadius()*1.25;const distanceBetween=dest.magnitude();const angleRadians=Math.atan(camHeight/distanceBetween);const closestCamDistance=targetEntity.getExtentsRadius()*5;const camDistFromFollowed=distanceBetween+closestCamDistance;const upDistance=Math.tan(angleRadians)*camDistFromFollowed;dest.normalize(dest);const scUp=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,0,1);const scParent=targetEntity.getParent();if(scParent){scParent.getOrientation().getAxis(scUp,2);if(scParent.getName()===followId){const objectOrbitOri=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion();const dynController=(this.pioneer.get('main',followId,'dynamo'));if(dynController){dynController.getOrbitOrientation(objectOrbitOri,this.pioneer.getTime());objectOrbitOri.getAxis(scUp,2)} + scUp.isNaN()&&scUp.copy(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,0,1))}else{scParent.getOrientation().getAxis(scUp,2)}} + scUp.normalize(scUp);if(dest.magnitude()<0.0001){targetEntity.getOrientation().getAxis(dest,0);dest.normalize(dest)} + scUp.mult(scUp,upDistance);dest.mult(dest,closestCamDistance);dest.add(dest,scUp);scUp.normalize(scUp);const fixedController=this.cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.FixedController);fixedController.setPosition(dest);const destinationForward=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();const destUp=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();destinationForward.neg(dest);destinationForward.normalize(destinationForward);destUp.setNormalTo(destinationForward,scUp);const orientation=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion();orientation.setFromAxes(undefined,destinationForward,destUp);fixedController.setOrientation(orientation);pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.focusOnEntity(this.cameraEntity,followEntity,{up:!1});const transitionController=this.cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.TransitionController);transitionController.setTransitionTime(duration);transitionController.setParent(sumParentId);const{_easeOutExpoTransition:transitionFunction}=this.app.cameraScripts;if(transitionFunction){transitionController.setTransitionFunction(transitionFunction)} + await transitionController.getEndPromise();this.cameraEntity.clearControllers();const orbitController=this.cameraEntity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitController);orbitController.setDragSensitivity(0.0005);this.cameraEntity.addController('fixedToParent');this.cameraEntity.addController('roll');const zoomCoeff=10;const zoomMin=targetEntity.getExtentsRadius();const zoomMax=Math.max(targetEntity.getExtentsRadius()*zoomCoeff,followEntity.getExtentsRadius()*zoomCoeff,zoomMin*zoomCoeff);const zoomInterval=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(zoomMin,zoomMax);const zoomController=this.cameraEntity.addController('zoom');zoomController.setDistanceClamp(zoomInterval);const selectController=(this.cameraEntity.addController('select'));if(this._selectionCallback!==null){selectController.setCallback(this._selectionCallback)} + pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.focusOnEntity(this.cameraEntity,followEntity,{up:!1})} + async goToBetweenPos(betweenEntity,{duration,destination,destinationUp,transitionFunction,zoomInterval}){const cameraEntity=this._cameraEntity;cameraEntity.clearControllers();const fixedController=(cameraEntity.addController('fixed'));fixedController.setPosition(destination);const destinationForward=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();const destUp=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();destinationForward.neg(destination);destinationForward.normalize(destinationForward);destUp.setNormalTo(destinationForward,destinationUp);const orientation=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion();orientation.setFromAxes(undefined,destinationForward,destUp);fixedController.setOrientation(orientation);pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.focusOnEntity(cameraEntity,betweenEntity,{up:!1,orbiter:!1});const transitionController=(cameraEntity.addController('transition'));transitionController.setTransitionTime(duration);transitionController.setParent(betweenEntity.getName());if(transitionFunction){transitionController.setTransitionFunction(transitionFunction)} + await transitionController.getEndPromise();cameraEntity.clearControllers();const selectController=(cameraEntity.addController('select'));if(this._selectionCallback!==null){selectController.setCallback(this._selectionCallback)} + cameraEntity.addController('orbit');cameraEntity.addController('roll');const zoomController=(cameraEntity.addController('zoom'));zoomInterval&&zoomController.setDistanceClamp(zoomInterval);pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.focusOnEntity(cameraEntity,betweenEntity,{up:!1,orbiter:!1})} + zoom(zoomChange,cameraEntity=this._cameraEntity){let currentDistance=cameraEntity.getPosition().magnitude();if(Number.isNaN(currentDistance)){currentDistance=1.0} + currentDistance*=zoomChange;const currentPosition=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();currentPosition.normalize(cameraEntity.getPosition());currentPosition.mult(currentPosition,currentDistance);cameraEntity.setPosition(currentPosition);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(currentPosition)} + zoomIn(isContinuous=!1){let zoomChange=1.0;const zoomSensitivity=isContinuous?this._zoomSensitivity.hold:this._zoomSensitivity.click;zoomChange/=Math.pow(2,zoomSensitivity);this.zoom(zoomChange)} + zoomOut(isContinuous=!1){let zoomChange=1.0;const zoomSensitivity=isContinuous?this._zoomSensitivity.hold:this._zoomSensitivity.click;zoomChange*=Math.pow(2,zoomSensitivity);this.zoom(zoomChange)} + get defaultMaxDistance(){return this._defaultMaxDistance} + set defaultMaxDistance(distance){this._defaultMaxDistance=distance} + addDynamicEnvMap(entity){if(!this.dynamicEnvMap){return} + const model=(entity.get('model'));if(model!==null){model.setDynamicEnvironmentMapComponent(this.dynamicEnvMap)}}}}),"../eyes/src/managers/camera_scripts.js": + /*!**********************************************!*\ + !*** ../eyes/src/managers/camera_scripts.js ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"CameraScripts":function(){return CameraScripts}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class CameraScripts extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager{constructor(app){super(app);this._cameraManager=null;this._customSystemDistances={mercury:425648,venus:862136,earth:1040264,mars:80000,jupiter:7157638,saturn:4869142,uranus:1886367,neptune:2407045,'134340_pluto':122231,'136199_eris':180309,'1_ceres':87225,'136108_haumea':126609,'136472_makemake':118584};this._onCameraTransition=null;this._easeInOutExpoTransition=this._easeInOutExpoTransition.bind(this);this._easeOutExpoTransition=this._easeOutExpoTransition.bind(this)} + setCameraManager(cameraManager){this._cameraManager=cameraManager} + get scene(){return this._scene} + set scene(scene){this._scene=scene} + get cameraEntity(){return this._cameraEntity} + set cameraEntity(cameraEntity){this._cameraEntity=cameraEntity} + getNormalToEcliptic(outNormal,id){const objectOrbitOri=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion();(this._cameraManager.pioneer.get('main',id,'dynamo')).getOrbitOrientation(objectOrbitOri,this._cameraManager.pioneer.getTime());objectOrbitOri.getAxis(outNormal,2)} + isBarycenter(id){if(id.includes('_barycenter')){return!0} + return!1} + removeBarycenter(id){if(this.isBarycenter(id)){return id.replace('_barycenter','')} + return id} + async goToCelestialObject(id,{scene=undefined,starId='sun',cinematic=!0,duration=1.5,distance=1.3}={}){this._cameraManager.setContext({id,context:CameraScripts.CONTEXT.CELESTIAL_OBJECT});if(scene===undefined){scene=this._scene} + const planet=scene.getEntity(id);const star=scene.getEntity(starId);let dest=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();planet.getPositionRelativeToEntity(dest,pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,star);if(dest.magnitude()===0){dest=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,1,0)} + const planetUp=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();planet.getOrientation().getAxis(planetUp,2);dest.neg(dest);dest.normalize(dest);let radius=planet.getOcclusionRadius();const spheroid=planet.getComponentByType('spheroid');if(spheroid!==null){radius=(planet.getComponentByType('spheroid')).getEquatorialRadius()} + const minRadius=1.2*radius;const cameraOrientation=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion();cameraOrientation.setFromAxes(undefined,dest,planetUp);let dist=pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.getDistanceToFitEntities(this._cameraEntity,cameraOrientation,planet,[planet]);dist*=distance;dest.mult(dest,dist);await this._cameraManager.goToEntity(id,{distance:dist,duration:duration/2});await this._cameraManager.goToEntity(id,{destination:dest,cinematic,minRadius,destinationUp:planetUp,duration:duration/2})} + _easeOutExpoTransition(entity,initialPosition,finalPosition,initialOrientation,finalOrientation,u){const position=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const orientation=pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();const e=4;const easedT=1-Math.pow(1-u,e);position.lerp(initialPosition,finalPosition,easedT);orientation.slerp(initialOrientation,finalOrientation,easedT);this._onCameraTransition?.(easedT);entity.setPosition(position);entity.setOrientation(orientation);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position);pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation)} + _easeInOutExpoTransition(entity,initialPosition,finalPosition,initialOrientation,finalOrientation,u){const position=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const orientation=pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();const e=4;const easedT=((u*=2)<=1?Math.pow(u,e):2-Math.pow(2-u,e))/2;position.lerp(initialPosition,finalPosition,easedT);orientation.slerp(initialOrientation,finalOrientation,easedT);this._onCameraTransition?.(easedT);entity.setPosition(position);entity.setOrientation(orientation);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position);pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation)} + async goToSpacecraft(id,{scene=undefined,starId='sun',planeId='earth',distance=undefined,cinematic=!0,duration=1.5,verticalOffset=0,horizontalOffset=0}={}){this._cameraManager.setContext({id,context:CameraScripts.CONTEXT.SPACECRAFT});if(scene===undefined){scene=this._scene} + const entityInfo=this._app.getManager('content').getEntityInfo(id);const camDistance=entityInfo?.customDistance||distance;await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(scene,[id]);const sc=scene.getEntity(id);const scRadius=sc.getOcclusionRadius();const minRadius=1.2*scRadius;const dest=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();dest.normalize(sc.getPosition());const scUp=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();const scParent=sc.getParent();if(scParent){if(scParent.getName()===starId&&scene.get(planeId)!==null){this.getNormalToEcliptic(scUp,planeId);if(scUp.isNaN()){scUp.copy(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,0,1))}}else{scParent.getOrientation().getAxis(scUp,2)}} + scUp.normalize(scUp);if(dest.magnitude()<0.0001){sc.getOrientation().getAxis(dest,0);dest.normalize(dest)} + const horizontal=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();horizontal.cross(dest,scUp);horizontal.normalize(horizontal);const rotation=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion();rotation.setFromAxisAngle(horizontal,pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(verticalOffset));dest.rotate(rotation,dest);rotation.setFromAxisAngle(scUp,pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(horizontalOffset));dest.rotate(rotation,dest);let dist=0.0;if(camDistance!==undefined){dist=camDistance}else{const cameraOrientation=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion();cameraOrientation.setFromAxes(undefined,dest,scUp);const distToFit=pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.getDistanceToFitEntities(this._cameraEntity,cameraOrientation,sc,[sc]);dist=distToFit*1.3} + dest.mult(dest,dist);await this._cameraManager.goToEntity(id,{distance:dist});await this._cameraManager.goToEntity(id,{destination:dest,cinematic,minRadius,destinationUp:scUp,duration})} + async goToInstrument(id,{scene=undefined,distance=undefined,duration=1.5,upVector='z-axis',forwardVector='y-axis'}={}){this._cameraManager.setContext({id,context:CameraScripts.CONTEXT.INSTRUMENT});if(scene===undefined){scene=this._scene} + const entityInfo=this._app.getManager('content').getEntityInfo(id);const camDistance=entityInfo?.customDistance||distance;const instrument=scene.getEntity(id);const spacecraft=instrument.getParent();await pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(scene,[spacecraft.getName(),id]);const iRadius=instrument.getOcclusionRadius();const sRadius=spacecraft.getOcclusionRadius();const minRadius=1.2*iRadius;const dest=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();instrument.getPositionRelativeToEntity(dest,pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,spacecraft);const forward=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();const forwardVectorIndex=forwardVector.endsWith('y-axis')?1:forwardVector.endsWith('z-axis')?2:0;spacecraft.getOrientation().getAxis(forward,forwardVectorIndex);if(forwardVector.startsWith('-')){forward.mult(forward,-1)} + dest.mult(forward,-1);const scUp=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();let upVectorIndex=forwardVector.endsWith('y-axis')?2:1;if(upVector.endsWith('x-axis')){upVectorIndex=0}else if(upVector.endsWith('z-axis')){upVectorIndex=2} + spacecraft.getOrientation().getAxis(scUp,upVectorIndex);if(upVector.startsWith('-')){scUp.mult(scUp,-1)} + let dist=minRadius*4.0;if(camDistance!==undefined){dist=camDistance} + dest.mult(dest,dist);await this._cameraManager.goToEntity(spacecraft.getName(),{destinationUp:scUp,distance:sRadius*1.2});await this._cameraManager.goToEntity(id,{destination:dest,minRadius,destinationUp:scUp,duration})} + async compareObjects(left,right,{cameraLeft=undefined,cameraRight=undefined,cameraLeftPosition=undefined,cameraRightPosition=undefined,cameraUp=undefined,scene=undefined,minRadius=undefined,maxRadius=undefined,duration=0.75}){this._cameraManager.setContext({id:left,context:CameraScripts.CONTEXT.COMPARE,to:right});const event=new CustomEvent('cameracompare',{detail:{left,right}});window.dispatchEvent(event);const leftTransition=this._cameraManager.goToEntity(left,{minRadius,maxRadius,camera:cameraLeft,destination:cameraLeftPosition,destinationUp:cameraUp,scene,select:!1,duration,zoom:!0,cinematic:!0});const rightTransition=this._cameraManager.goToEntity(right,{minRadius,maxRadius,camera:cameraRight,destination:cameraRightPosition,destinationUp:cameraUp,scene,select:!1,duration,zoom:!0,cinematic:!0});await Promise.all([leftTransition,rightTransition])} + async showLocation(targetEntityName,forwardEntityName,upOrRightEntityName,mode='northPole',{duration=2,otherEntityNames=[],distance=undefined,rotateByScreenRatio=!0}={}){this._cameraManager.setContext({id:'',targetEntityName,context:CameraScripts.CONTEXT.LOCATION,options:{otherEntityNames}});const targetEntity=this._scene.getEntity(targetEntityName);const forwardEntity=this._scene.getEntity(forwardEntityName);const upOrRightEntity=this._scene.getEntity(upOrRightEntityName);if(targetEntity===null||forwardEntity===null||upOrRightEntity===null){return} + const entities=[];entities.push(targetEntity);entities.push(forwardEntity);entities.push(upOrRightEntity);for(let i=0,l=otherEntityNames.length;icameraComponent.getVerticalFieldOfView()){up.cross(up,forward)} + const orientation=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion();orientation.setFromAxes(undefined,forward,up);let dist=distance||pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Cameras.getDistanceToFitEntities(this._cameraEntity,orientation,targetEntity,entities);if(cameraComponent.getHorizontalFieldOfView()`no-select ${contentManager.getClassName(entityName, '') ?? ''}`,handleTouch:null,handleClick:null},[entityNameLeft],this._sceneLeft,this._cameraEntityLeft)} + if(!this._entityRight){this._entityRight=pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create(entityNameRight,this._sceneRight);this._entityRight.clearParentingTableEntries();this._entityRight.clearControllers();this._entityRight.setParent(this._anchorEntityRight);this._entityRight.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero);const orientation=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion();this._getCustomRotation(orientation,entityNameRight,'right');this._entityRight.setOrientation(orientation);this._entityRight.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent).setFadeWhenCloseToEntity('sun');labelManager.setLabelProps({getLabelClass:entityName=>`no-select ${contentManager.getClassName(entityName, '') ?? ''}`,handleTouch:null,handleClick:null},[entityNameRight],this._sceneRight,this._cameraEntityRight)} + this._updateSuns();if(!this._viewportLeft.isEnabled()){for(let i=0,l=this.pioneer.getNumViewports();i{const{category}=this._entityList[k];if(this._entitiesByCategory[category]){this._entitiesByCategory[category].push(this._entityList[k])}else{this._entitiesByCategory[category]=[this._entityList[k]]} + let{subcategory}=this._entityList[k];if(!subcategory||subcategory===''){subcategory=category} + if(this._entitiesBySubCategory[subcategory]){this._entitiesBySubCategory[subcategory].push(this._entityList[k])}else{this._entitiesBySubCategory[subcategory]=[this._entityList[k]]}})} + getEntityInfo(id){if(id in this._entityList){return this._entityList[id]}else{return null}} + async getEntityDesc(id){let entityDesc=null;try{entityDesc=await _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.loadJSON("https://eyes.nasa.gov/apps/asteroids/descriptions/"+id+'.json')}catch(err){entityDesc=null} + return entityDesc} + setFolders(folders={}){for(const key in folders){if(Object.prototype.hasOwnProperty.call(folders,key)){folders[key]=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.addEndToPath(folders[key]);this._folders[key]=folders[key]}}} + getStoryList(){return this._storyList} + setStoryList(allStories){this._storyList=allStories} + getStory(id){if(!id){throw new Error('[ContentManager.getStory]: id is required.')} + if(!this._stories[id]){throw new Error(`[ContentManager.getStory]: Cannot find story with id ${id}.`)} + this._context.story=this._stories[id];return this._context.story} + setStories(stories){this._stories=stories} + async loadDescriptions(itemsList,cancelToken){for(let i=0;ia.start.valueOf()-b.start.valueOf());this._context.orderedEvents=orderedEvents}else{this._context.orderedEvents=null}}} + if(fileNames.event){const event=this._context.events[fileNames.event];const eventFile=(event&&event.template)?event.template:fileNames.event;let eventDesc=null;try{eventDesc=await _internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.loadJSON(eventFolder+eventFile)}catch(err){eventDesc=null} + if(cancelToken&&cancelToken.isCanceled){return} + this._context.eventDesc=eventDesc} + this._target=target} + getSpheroidLayers(entityId){return this._entityShperoidLayersList[entityId]} + setSpheroidLayers(layersArray){this._entityShperoidLayersList=layersArray} + getSpheroidFeatures(entityId){return this._entityShperoidFeaturesList[entityId]||[]} + setSpheroidFeatures(featuresArray){this._entityShperoidFeaturesList=featuresArray} + getColorClass(entityId){let colorClass='';if(!this.getEntityInfo(entityId)){return colorClass} + const entityInfoCategory=this.getEntityInfo(entityId).category;switch(entityInfoCategory){case 'Asteroid':{colorClass='asteroid';break} + case 'Instrument':case 'Spacecraft':{colorClass='spacecraft';break} + case 'Planet':{colorClass=entityId;break} + case 'Dwarf Planet':{colorClass='dwarf-planet';break} + case 'Comet':{colorClass='comet';break} + case 'Barycenter':case 'Moon':{colorClass='moon';break} + case 'Universe':case 'Galaxy':case 'Star':{colorClass='sun';break} + default:{colorClass=''}} + return colorClass} + hasLanded(entityInfo){if(!entityInfo.landingDate||entityInfo.landingDate===''){return!1} + const categories=['Lander','Rover'];if(categories.indexOf(entityInfo.subcategory)<0){return!1} + const landing=this._app.getManager('time').parseTime(entityInfo.landingDate);const current=this._app.getManager('time').getTime();if(current.isSameOrAfter(landing)){return!0}else{return!1}} + getClassName(id,category){const entityInfo=this.getEntityInfo(id);let className=id;if(category){className+=' '+category.toLowerCase().replace(/ /g,'-')}else if(entityInfo!==null&&entityInfo.category!==undefined){const category=entityInfo.category.toLowerCase().replace(/ /g,'-');className+=' '+category} + if(className.match(/^\d/)){className='_'+className} + return className} + hasKeyword(id,keyword){if(this.getEntityInfo(id)!==undefined){return this.getEntityInfo(id).keywords.includes(keyword)}} + resetContext(){this._context={};this._context.events={};this._context.eventDesc={};this._context.orderedEvents={};this._context.story={}} + hideExternalLinksInText(text){return text.replaceAll(/]*>(.*?)<\/a>/g,'$2')} + hideExternalLinkStoryList(){const stories=this.getStoryList();const internalStories={};const externalStoryIds=stories.external?Object.keys(stories.external):[];for(const[category,storyListItems]of Object.entries(stories)){if(category!=='external'){internalStories[category]=storyListItems;const storyListIsArray=Array.isArray(storyListItems);if(storyListIsArray){const listWithoutExternal=storyListItems.filter(id=>!externalStoryIds.includes(id));if(listWithoutExternal.length>0){internalStories[category]=listWithoutExternal}}else{const externalStoriesInKeys=Object.keys(storyListItems).filter(key=>externalStoryIds.includes(key));for(let i=0;i=0;i--){const entity=entities.get(i);this.addEntity(entity)}} + addEntity(entity){if(entity.getComponentByType('div')){this._labels[entity.getName()]={name:entity.getName(),el:entity.getComponentByType('div').getDiv(),x:0,y:0,width:0,height:0,check:!1,collisions:[],isHidden:!1,isClickable:!0}}} + removeEntity(entity){if(this._labels[entity.getName()]!==undefined){delete this._labels[entity.getName()]}} + setAlgorithm(algo){this._algorithm=algo} + setScene(scene){this._scene=scene} + setWeights(weights,reset=!0){if(reset)this._weights={};for(const name of Object.keys(weights)){const category=weights[name].category;this._weights[name]={};if(this._weightMap[category]!==undefined){this._weights[name].weight=this._weightMap[category]}else{this._weights[name].weight=1}}} + removeWeights(weights){for(const name of Object.keys(weights)){if(this._weights[name]){delete this._weights[name]}}} + getWeight(name){if(Object.keys(this._weights).length<=0){return 0} + if(this._weights[name]!==undefined){return this._weights[name].weight} + return 0} + isExisting(name){if(this._labels[name]===undefined){delete this._labels[name];return!1} + return!0} + setUpLabel(entity){const contentManager=(this._app.getManager('content'));const layerManager=(this._app.getManager('layer'));this.addEntity(entity);this.setLabelProps({getLabelClass:entityName=>`no-select ${contentManager.getClassName(entityName) ?? ''}`},[entity.getName()]);const targetId=entity.getName();const labelsLayer=layerManager.getLayer('labels');if(labelsLayer!==null&&!labelsLayer.visible){this.toggleLabelForEntity(!1,targetId)}} + removeLabel(entity){this.removeEntity(entity)} + setUpIcon(entity){const layerManager=(this._app.getManager('layer'));const targetId=entity.getName();const iconsLayer=layerManager.getLayer('icons');if(iconsLayer!==null&&!iconsLayer.visible){this.toggleIconForEntity(!1,targetId)}} + setLabelClickable(labelName,clickable){if(this._labels[labelName]){this._labels[labelName].isClickable=clickable;this._labels[labelName].el.classList.toggle('clickable',clickable)}} + setClickable(isClickable){this._isClickable=isClickable;for(let i=0,l=this._scene.getNumEntities();ithis._exceptions.add(label))} + removeExceptions(labels){labels.forEach(label=>this._exceptions.delete(label))} + toggleLabels(active,{scene=undefined}={}){if(scene===undefined){scene=this._scene} + for(let i=0;i{const labelInfo=this._labels[name];if(!this._isClickable||!labelInfo?.isClickable){return} + if(this._clickCallback!==null){console.log(this._clickCallback) + this._clickCallback(entity);event.preventDefault();this.triggerCallbacks('labelclicked',[!0])}};const defaultOnTouchEnd=async event=>{const labelInfo=this._labels[name];if(!this._isClickable||!labelInfo?.isClickable){return} + if(!this.app.isDragging()&&!this.app.isTouchMax()&&this._clickCallback!==null){this._clickCallback(entity);event.preventDefault();this.triggerCallbacks('labelclicked',[!0])}};labelEl.addEventListener('mousedown',event=>{event.preventDefault();this.triggerCallbacks('labelclicked',[!1])});labelEl.addEventListener('touchstart',event=>{event.preventDefault();this.triggerCallbacks('labelclicked',[!1])});const defaultOnMouseEnter=()=>this.triggerCallbacks('hoverchange',[name,!0]);const defaultOnMouseLeave=()=>this.triggerCallbacks('hoverchange',[name,!1]);const onClick=typeof handleClick==='function'?event=>handleClick(event,name):defaultOnClick;const onTouchEnd=typeof handleTouch==='function'?event=>handleTouch(event,name):defaultOnTouchEnd;const onMouseEnter=typeof handleMouseEnter==='function'?event=>handleMouseEnter(event,name):defaultOnMouseEnter;const onMouseLeave=typeof handleMouseLeave==='function'?event=>handleMouseLeave(event,name):defaultOnMouseLeave;if(handleClick!==null&&labelEl.getAttribute('hasClickListener')!=='true'){labelEl.setAttribute('hasClickListener','true');labelEl.addEventListener('click',onClick)} + if(handleTouch!==null&&labelEl.getAttribute('hasTouchEndListener')!=='true'){labelEl.setAttribute('hasTouchEndListener','true');labelEl.addEventListener('touchend',onTouchEnd)} + if(handleMouseEnter!==null&&labelEl.getAttribute('hasMouseEnterListener')!=='true'){labelEl.setAttribute('hasMouseEnterListener','true');labelEl.addEventListener('mouseenter',onMouseEnter)} + if(handleMouseLeave!==null&&labelEl.getAttribute('hasMouseLeaveListener')!=='true'){labelEl.setAttribute('hasMouseLeaveListener','true');labelEl.addEventListener('mouseleave',onMouseLeave)} + if(labelEl.getAttribute('hasMouseMoveListener')!=='true'){labelEl.setAttribute('hasMouseMoveListener','true');labelEl.addEventListener('mousemove',event=>{event.preventDefault()},!0)}}} + addClassToLabels(className,labelNames){for(const name of labelNames){const entity=this._scene.getEntity(name);const labelEl=entity?.get('div')?.getDiv();labelEl?.classList.add(className)}} + removeClassFromLabels(className,labelNames){for(const name of labelNames){const entity=this._scene.getEntity(name);const labelEl=entity?.get('div')?.getDiv();labelEl?.classList.remove(className)}} + getItemAtCenter(){this._centerBoundingRect.x=(window.innerWidth/2-this._centerBoundingRect.width/2);this._centerBoundingRect.y=(window.innerHeight/2-this._centerBoundingRect.height/2);const candidates=this._quadTree.retrieve(this._centerBoundingRect);for(let i=0;i=this._overlapThreshold){this._addCollision(candidate.name,label.name)}}}}} + _addCollision(label1,label2){if(this._collidingLabels.indexOf(label1)<0){this._collidingLabels.push(label1)} + if(this._collidingLabels.indexOf(label2)<0){this._collidingLabels.push(label2)} + this._labels[label1]?.collisions.push(label2)} + _checkCollision(rect1,rect2){if(rect1.xrect2.x&&rect1.yrect2.y){return!0}else{return!1}} + _fixCollisions(){this._sort();for(let i=0;i{if(this.getWeight(b)-this.getWeight(a)!==0){return this.getWeight(b)-this.getWeight(a)}else{return this.getZ(a)-this.getZ(b)}})} + _overlap(rect1,rect2){const overlap=(Math.min(rect1.x+rect1.width,rect2.x+rect2.width)-Math.max(rect1.x,rect2.x))*(Math.min(rect1.y+rect1.height,rect2.y+rect2.height)-Math.max(rect1.y,rect2.y));const a1=rect1.width*rect1.height;const a2=rect2.width*rect2.height;const percentage=overlap/(a1+a2-overlap);return percentage} + _isOutOfWindow(rect){if(rect.x>window.innerWidth||rect.x+rect.width<0||rect.y>window.innerHeight||rect.y+rect.height<0){return!0}else{return!1}} + _restoreLabels(){if(this._allLabelsHidden===!0){return} + for(const key of Object.keys(this._labels)){const label=this._labels[key];if(!label.isHidden){this._showLabel(label.name)} + if(label.collisions.length===0){this._showLabel(label.name)}}} + _showLabel(label){const object=this.pioneer.get('main',label);const div=object?.getComponentByType('div').getDiv();div?.classList.add(this._activeClass);div?.classList.remove(this._hiddenClass);this._labels[label].isHidden=!1} + _hideLabel(label){if(this._exceptions.has(label)){return} + const object=this.pioneer.get('main',label);if(object===null){return} + const div=object.getComponentByType('div').getDiv();div.classList.add(this._hiddenClass);div.classList.remove(this._activeClass);this._labels[label].isHidden=!0} + getZ(name){if(this.isExisting(name)){return this._labels[name].z}} + stop(){this._isPaused=!0} + start(){this._isPaused=!1} + update(){if(this._isPaused){return} + if(this._frameCount===0){this._collidingLabels=[];this._buildQuadtree()}else if(this._frameCount===this._frameCycle/3){this._checkWithQuadtree()}else if(this._frameCount===2*this._frameCycle/3){this._fixCollisions()} + this._frameCount++;this._frameCount%=this._frameCycle}} + LabelManager.Quadtree=1;LabelManager.BruteForce=0}),"../eyes/src/managers/layer_manager.js": + /*!*********************************************!*\ + !*** ../eyes/src/managers/layer_manager.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"LayerManager":function(){return LayerManager}});var pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class LayerManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager{constructor(app){super(app);this._sceneManager=(app.getManager('scene'));this._contentManager=(app.getManager('content'));this._layers={};this._contextualLayersList=['majorMoons','minorMoons','landers','orbiters','satelliteGroup','heliosphere'];this._targetId='';this._previousTarget=([]);this._dependencies=new Set();this._previousDependencies=new Set();this.bindFunctions(['resetContextualVisibility','toggleLayer','changeSpheroidMap','resetContextualLayers']);this._eventNames.push('toggleLayer');this._initCallbacks()} + addLayer(id,{name='',group='',categories=[],defaultVisibility=!0,toggleCallback=[],sublayers=[]}){if(this._layers[id]===undefined){this._layers[id]=({})} + this._layers[id].name=name;this._layers[id].group=group;this._layers[id].defaultVisibility=defaultVisibility;this._layers[id].visible=defaultVisibility;if(!Array.isArray(categories)){categories=[categories]} + this._layers[id].categories=categories;if(!Array.isArray(sublayers)){sublayers=[sublayers]} + this._layers[id].sublayers=sublayers;for(let i=0;i{const url='$STATIC_ASSETS_URL/maps/'+textureDescription.textures[key].url;spheroidLOD.setTexture(key,url,textureDescription.textures[key].sizes)});await sceneManager.pioneer.waitUntilNextFrame();await spheroidLOD.getLoadedPromise();if(wmts!==null){wmts.setEnabled(!1)} + sceneManager.removeLoading(id,'spheroidLOD')}else if(textureDescription.type==='wmts'){if(wmts===null){await sceneManager.addWMTSComponent(id,textureDescription)}else if(wmts.isEnabled()===!1){await sceneManager.enableWMTSComponent(id,wmts)}} + if(atmosphere!==null&&atmosphere!==undefined){atmosphere.setEnabled(textureDescription.features.includes('atmosphere'))}(this.app.getComponent('contentPanel'))?.updateHDButton();if(id==='titan'){this.app.pioneer.get('main','titan','spheroidLOD').setLongitudeRotation(pioneer__WEBPACK_IMPORTED_MODULE_1__.MathUtils.degToRad(180))}} + async toggleLayer(id,params={},forceVisibility){const{spout,spoutFontSize}=this.app.getManager('router').configs;if(this._layers[id]===undefined){return} + params.layerId=id;if(forceVisibility!==undefined&&this._layers[id].visible===forceVisibility){return} + this._layers[id].visible=!this._layers[id].visible;for(let i=0;i{relevantEntities.push(this.app.pioneer.get('main').getEntity(`constellation_label_${name}`))})} + await this.app.getManager('spout').setUpSpoutLabels(spoutFontSize,relevantEntities?.[0]?.id)}} + setTarget(entityId){this._previousTarget.push(this._targetId);this._previousDependencies=new Set([...this._previousDependencies,...this._dependencies]);this._targetId=entityId;this._dependencies.clear();if(this._targetId!==''){const dependencies=this._sceneManager.getDependencies(this._targetId);this._dependencies=new Set(dependencies)}} + resetTarget(){for(let i=0;i{const moonEntityInfo=contentManager.getEntityInfo(moon);if(moonEntityInfo!==null){const category=moonEntityInfo.subcategory||moonEntityInfo.category;switch(category){case 'Major Moon':if(availableLayers.includes('majorMoons')===!1){availableLayers.push('majorMoons')} + break;case 'Minor Moon':if(availableLayers.includes('minorMoons')===!1){availableLayers.push('minorMoons')} + break;default:break}}});const time=this._app.pioneer.getTime();spacecraft.forEach(sc=>{const entityInfo=contentManager.getEntityInfo(sc);if(entityInfo!==null){const category=entityInfo.subcategory||entityInfo.category;switch(category){case 'Orbiter':if(availableLayers.includes('orbiters')===!1){if(pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.Parenting.getParentOfEntity(sc,time)===parent){availableLayers.push('orbiters')}} + break;case 'Landing Site':case 'Lander':case 'Rover':if(availableLayers.includes('landers')===!1){if(pioneer_scripts__WEBPACK_IMPORTED_MODULE_0__.Parenting.getParentOfEntity(sc,time)===parent){availableLayers.push('landers')}} + break;default:break}}});if(entityInfo?.constellation){availableLayers.push('satelliteGroup')} + availableLayers.sort((a,b)=>{const layers=Object.keys(this._layers);return layers.indexOf(a)-layers.indexOf(b)});return availableLayers} + resetContextualLayers(newParent,oldParent){const newLayers=this.getContextualLayers(newParent);this._contextualLayersList.forEach(layer=>{if(newLayers.includes(layer)===!1){if(layer==='heliosphere'){this.toggleLayer(layer,{parentId:undefined},!1)}else{this.toggleLayer(layer,{parentId:oldParent},this.getLayer(layer).defaultVisibility||!1)}}})} + isEntityVisibleWithCurrentLayers(entityName,satelliteGroup){const entityInfo=this._contentManager.getEntityInfo(entityName);if(entityInfo!==null){const layer=this.getLayerFromCategory(entityInfo.category);const sublayer=this.getLayerFromCategory(entityInfo.subcategory);const satelliteGroupLayer=this.getLayerFromSatelliteGroup(entityInfo.constellation);if(satelliteGroupLayer!==null&&entityInfo.constellation===satelliteGroup){return satelliteGroupLayer.visible} + if(sublayer!==null){return sublayer.visible} + if(layer!==null){return layer.visible} + if(layer===null&&sublayer===null){return!0} + return!1}else{return!0}}}}),"../eyes/src/managers/route_manager.js": + /*!*********************************************!*\ + !*** ../eyes/src/managers/route_manager.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"RouteManager":function(){return RouteManager}});var navigo__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! navigo */"../eyes/node_modules/navigo/lib/navigo.min.js");var navigo__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(navigo__WEBPACK_IMPORTED_MODULE_0__);var _internal__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class RouteManager extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseManager{constructor(app){super(app);this._router=new(navigo__WEBPACK_IMPORTED_MODULE_0___default())(null,!0);this._previousRoute=null;this._currentRoute={};this._firstLoad=!0;this._query={};this._configs={};this._validQueries=[];this._homeRoute='/home';this._queryCallbacks={};this._previousView=null;this._currentView=null;this._alwaysHiddenComponents=[];this.bindFunctions(['navigate','onRootRoute','onNotFound','leave'])} + get homeRoute(){return this._homeRoute} + get previousRoute(){return this._previousRoute} + get currentRoute(){return this._currentRoute} + get query(){return this._query} + get configs(){return this._configs} + get currentView(){return this._currentView} + set currentView(view){this._currentView=view} + get previousView(){return this._previousView} + init(onBefore,onAfter){this._router.hooks({before:async done=>{this._previousRoute={...this._currentRoute};this._currentRoute=this._router.lastRouteResolved()||{};if(this._currentRoute.url){this._currentRoute.url=this._currentRoute.url.replace(/(\/)+/,'/')} + this.addQuery(this.parseQuery(this.currentRoute.query));if(typeof onBefore==='function'){await onBefore(this._currentRoute,this._previousRoute)} + done()},after:async()=>{if(typeof onAfter==='function'){await onAfter(this._currentRoute,this._previousRoute)} + this._firstLoad=!1}});this._router.on(this.onRootRoute).notFound(this.onNotFound).on('milky_way',this.onNotFound).on('observable_universe',this.onNotFound)} + leave(params){params.cancelToken.cancel()} + onRootRoute(query){this.reroute(this._homeRoute,query)} + onNotFound(query){let newRoute=this._homeRoute;if(query){newRoute+='?'+query} + this._router.navigate(newRoute)} + replaceState(replaceStr){history.replaceState({},'',replaceStr)} + reroute(path,query=''){let queryString;if(typeof query==='string'){query=this.parseQuery(query)} + const configs=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.filterObject(this._configs,val=>val!==undefined);queryString=this.buildQuery({...query,...configs});const pathname=window.location.pathname;history.replaceState(queryString,'',`${pathname}#${path}${queryString}`);this._router.resolve()} + addCancelToken(params){const output=params||{};output.cancelToken=new _internal__WEBPACK_IMPORTED_MODULE_1__.CancelToken();return output} + lastRouteResolved(){return this._router.lastRouteResolved()} + lastPathResolved(){const lastRoute=this._router.lastRouteResolved();return lastRoute.query?lastRoute.url+'?'+lastRoute.query:lastRoute.url} + getOnlyURL(url){let onlyURL=url;const split=url.split('#');onlyURL=split.length>1?this._cleanGETParam(split[1]):this._cleanGETParam(split[0]);return onlyURL} + _cleanGETParam(url){return url.split(/\?(.*)?$/)[0]} + getValidQueries(){return this._validQueries} + setValidQueries(list){this._validQueries=list} + parseQuery(queryString){if(!queryString){return{}} + queryString.replace('?','');const query=queryString.split('&').reduce((obj,str)=>{const parts=str.split('=');if(parts.length>1){let val=decodeURIComponent(parts[1].trim());switch(val.toLowerCase()){case 'true':val=!0;break;case 'false':val=!1;break;case 'undefined':val=undefined;break;case 'null':val=null;break;case '':val=undefined;break;default:{const num=Number(val);if(!Number.isNaN(num)){val=num} + break}} + const key=decodeURIComponent(parts[0].trim());if(key in this._configs){if(this._configs[key]===undefined){this._configs[key]=val}}else{obj[key]=val}} + return obj},{});return query} + buildQuery(query){let queryString='';for(const[key,value]of Object.entries(query)){queryString+='&'+key+'='+value} + queryString=queryString.replace('&','?');return queryString} + addQuery(query){this._query={...this._query,...query};return this._query} + removeQuery(keys=[]){keys.forEach(key=>delete this._query[key]);return this._query} + addConfigs(configs){this._configs={...this._configs,...configs};return this._configs} + setConfig(key,value){this.configs[key]=value} + removeConfigs(keys=[]){keys.forEach(key=>delete this._configs[key]);return this._configs} + updateQuery(query){if(query.__remove){if(query.__remove==='all'){this._query={}}else{this.removeQuery(query.__remove)} + delete query.__remove} + const configs=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.filterObject(this._configs,val=>val!==undefined);return{...this.addQuery(query),...configs}} + updateQueryPath(query,pathname=''){const output=pathname||this._router.lastRouteResolved().url;return output.replace(/(\/)(?=\/*\1)/,'')+this.buildQuery(this.updateQuery(query))} + async resetView(currentView,params){this._previousView=this._currentView;this._currentView=currentView;if(this._currentView!==this._previousView){if(this._previousView!==null){await this._app.getView(this._previousView).onLeave(params)} + await this._app.getView(this._currentView).onEnter(params);const views=this._app.getViews();for(let i=views.length-1;i>=0;i--){const view=views[i];this._app.getView(view).setEnabled(view===currentView)}}} + async handleRoute(view,params,query){if(!params){params=this.addCancelToken(params);this._currentRoute.params=params} + let objectQuery={};if(query){objectQuery=this.parseQuery(query)} + await this.resetView(view,{...params,...objectQuery,...this._configs});await this.goToView(view,params,{...objectQuery,...this._configs})} + stillOnRoute(url){const regex=/^\/([^!/]*)/;const match=this._currentRoute.url.match(regex);if(match===null||match[1]===undefined){return!1} + return match[1]===url} + urlChanged(a,b){return this.getOnlyURL(a)!==this.getOnlyURL(b)} + routeChanged(current,previous){if(current===''&&!previous){return!0} + if(!previous||_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.isEmptyObject(previous)){return!0} + if(current.url){return current.url!==previous.url} + const currentRoute=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.deepCopy(current);const previousRoute=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.deepCopy(previous);return!_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.deepEqual(currentRoute,previousRoute)} + queryChanged(current,previous){if(!previous){return!0} + const currentQuery=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.deepCopy(current);const previousQuery={};for(const p in currentQuery){if(typeof currentQuery[p].toString==='function'){currentQuery[p]=currentQuery[p].toString()}} + previous.split('&').forEach(param=>{const paramSplit=param.split('=');previousQuery[paramSplit[0]]=paramSplit[1]});return!_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.deepEqual(currentQuery,previousQuery)} + async goToView(view,params,query){if(this.routeChanged(this.currentRoute,this.previousRoute)){await this._app.getView(view).onRouteChange({...params,...query})}else if(this.queryChanged(query,this.previousRoute.query)){await this._app.getView(view).onQueryChange({...params,...query})}} + addRoutes(routes){for(let i=0;i{await this.handleRoute(view,params,query)},{before:async(done,params)=>{await this.before(done,params,view)},leave:this.leave})}} + before(done,params,view){let objectQuery={};if(this._currentRoute.query){objectQuery=this.parseQuery(this._currentRoute.query)} + params=this.addCancelToken(params);const isValid=this._app.getView(view)?.validateQuery({...params,...objectQuery});if(!isValid){params.cancelToken.cancel();if(typeof done==='function'){done(!1)}} + if(typeof done==='function'){done()}} + subscribeToQuery(key,callback){if(typeof callback!=='function')return;if(!this._queryCallbacks[key]){this._queryCallbacks[key]=[]} + if(!this._queryCallbacks[key].includes(callback)){this._queryCallbacks[key].push(callback)} + return()=>{const i=this._queryCallbacks[key].indexOf(callback);this._queryCallbacks[key].splice(i,1)}} + start(){this._router.resolve();this.handleEmbedQueries()} + handleEmbedQueries(){const{hideFullScreenToggle,lighting,noKeyboard,search}=this._configs;const hideSearch=noKeyboard===!0||search===!1;const searchComponent=this.app.getComponent('search');const settingsComponent=this.app.getComponent('settings');let updatedTutorials=[];let tutorialsWithVariables=null;const tutorialOverlay=this.app.getComponent('tutorialOverlay');if(hideFullScreenToggle===!0){settingsComponent?.hideFullScreenOption?.()} + if(lighting==='flood'||lighting==='natural'){settingsComponent?.toggleLightOptions?.(lighting)} + if(hideSearch){this._alwaysHiddenComponents.push('search');searchComponent?.hide();updatedTutorials=tutorialOverlay?.hideTutorialSlide?.('search')} + if(this._configs.hideFullScreenToggle===!0){const settingsTutorial=this.app.tutorials?.find(slide=>slide.id==='settings');if(settingsTutorial){settingsTutorial.description=settingsTutorial.description.replace(settingsTutorial.description,settingsTutorial.alternateDescription)}} + tutorialsWithVariables=this.app.setTutorialVariables?.(updatedTutorials.length?updatedTutorials:this.app.tutorials);tutorialOverlay?.setTutorials?.(tutorialsWithVariables)} + navigate(route,base='',options={}){if(!_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.isEmptyObject(options)){if(typeof route==='string'){base=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.cleanPathDuplicate(`${base}/${route}`);route={}}} + if(options.__remove){route.__remove=options.__remove} + if(options.keepTime){const timeManager=this._app.getManager('time');if(this.query.time&&timeManager){if(!base.includes('time=')){route.time=route.time||timeManager.getTimeUrl()} + if(!base.includes('rate=')){route.rate=route.rate||timeManager.getTimeRate()}}} + return this._navigate(route,base)} + _navigate(route,base=''){if(typeof route==='string'){const current=this.lastPathResolved();let outputRoute=route;if(!route.startsWith('/')){outputRoute='/'+route} + if(!route.includes(base)){outputRoute=base+route} + if(current!==outputRoute){const parts=outputRoute.split('?');if(parts.length>1){this._query=this.parseQuery(parts[1])}else{this._query={};const configs=_internal__WEBPACK_IMPORTED_MODULE_1__.AppUtils.filterObject(this._configs,val=>val!==undefined);outputRoute+=this.buildQuery(configs)} + this._router.navigate(outputRoute);return!0} + return!1}else{return this.navigate(this.updateQueryPath(route,base),base)}} + returnHome(keepCurrentQuery=!0){const currentQuery=keepCurrentQuery?this.buildQuery(this.query):'';this.navigate(currentQuery)} + async reload(onQueryChange=!0,clearQuery=!1){const view=await this._app.getView(this._currentView);const{params,query}=this._router.lastRouteResolved();let objectQuery={};if(!clearQuery&&query){objectQuery=this.parseQuery(query)} + if(onQueryChange){view.onQueryChange({...params,...objectQuery})}else{view.onRouteChange({...params,...objectQuery})}}}}),"../eyes/src/managers/scene_manager.js": + /*!*********************************************!*\ + !*** ../eyes/src/managers/scene_manager.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SceneManager":function(){return SceneManager}});var moment_timezone__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! moment-timezone */"../eyes/node_modules/moment-timezone/index.js");var moment_timezone__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(moment_timezone__WEBPACK_IMPORTED_MODULE_0__);var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class SceneManager extends _internal__WEBPACK_IMPORTED_MODULE_3__.BaseManager{constructor(app){super(app);this._scenes={};this._scene=this.add('main');this._isHD=!1;this._hdWMTSMap={};this._loadingItems=[];this._loadedComponents=[];this._hdBreakpointSize=512;this._maxTextureSize=4096;this._eventNames.push('loading','loaded');this._initCallbacks();this._isLoading=!1;this._entityStatuses=new pioneer__WEBPACK_IMPORTED_MODULE_1__.FastMap();this._entityExtraOptions=undefined;this._entityLoadedCallbacks=[];this._entityWillBeUnloadedCallbacks=[];this._componentTypesNotVisible=new Set();this._mobileTextureSize=1024;this.bindFunctions(['addLoading','removeLoading','update','toggleStarfield','toggleHeliosphere','toggleConstellations','addWMTSComponent','tileIsReady','enableWMTSComponent','forceTextureSizeForEntity','toggleHDTextureForEntity','isEntityHD']);this._tempEntities=[]} + add(name){if(name==='main'&&this._scene){return this._scene} + this._scenes[name]=this.pioneer.addScene(name);this._scenes[name].setAmbientLightColor(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(0.005,0.005,0.005));return this._scenes[name]} + addEntity(entityName,dynamic){if(this._entityStatuses.has(entityName)){throw new Error(`Error adding entity: The entity ${entityName} has already been added.`)} + this._entityStatuses.set(entityName,{forceVisible:!1,layerVisibility:(this.app.getManager('layer')).isEntityVisibleWithCurrentLayers(entityName),dynamic,dependentEntities:[],entitiesForcingThisVisible:new Set(),visible:!0,componentTypesNotVisible:new Set()})} + removeEntity(entityName){if(!this._entityStatuses.delete(entityName)){throw new Error(`Error removing entity: The entity ${entityName} was not in the scene manager.`)} + const entity=this._scene.getEntity(entityName);if(entity!==null){for(let i=0,k=this._entityWillBeUnloadedCallbacks.length;ientityNames.set(entityName,!1))}else{sceneInfo.staticEntities.forEach(entityName=>entityNames.set(entityName,!1))}} + if(sceneInfo.staticEntityGroups!==undefined){sceneInfo.staticEntityGroups.forEach(entityGroupName=>{pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityNamesInGroup(entityGroupName).forEach(entityName=>entityNames.set(entityName,!1))})} + if(sceneInfo.dynamicEntities!==undefined){if(sceneInfo.dynamicEntities.length===1&&sceneInfo.dynamicEntities[0]==='all'){pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityNamesInGroup('').forEach(entityName=>{if(!entityNames.has(entityName)){entityNames.set(entityName,!0)}})}else{sceneInfo.dynamicEntities.forEach(entityName=>{if(!entityNames.has(entityName)){entityNames.set(entityName,!0)}})}} + if(sceneInfo.dynamicEntityGroups!==undefined){sceneInfo.dynamicEntityGroups.forEach(entityGroupName=>{pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.getEntityNamesInGroup(entityGroupName).forEach(entityName=>{if(!entityNames.has(entityName)){entityNames.set(entityName,!0)}})})} + const contentManager=(this.app.getManager('content'));for(const entityName of entityNames.keys()){if(contentManager.getEntityInfo(entityName)===null){entityNames.delete(entityName)}} + entityNames.forEach((dynamic,entityName)=>this.addEntity(entityName,dynamic));this.setExtraEntityOptions(sceneInfo.entityOptions);this.updateEntityLayerVisibility()} + addEntityLoadedCallback(callback){this._entityLoadedCallbacks.push(callback)} + removeEntityLoadedCallback(callback){for(let i=0,l=this._entityLoadedCallbacks.length;i0;if(entity!==null&&entityStatus.visible!==visible){this.setVisibility(visible,entityName)}}} + _createEntity(entityName){const entity=pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.Entity.create(entityName,this._scene,this._entityExtraOptions);if(!this._entityStatuses.get(entityName).visible){this.setVisibility(!1,entityName)} + const dependentEntityNames=pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.SceneHelpers.getDependentEntities(entityName);for(const dependentEntityName of dependentEntityNames){let entityStatus=this._entityStatuses.get(dependentEntityName);if(entityStatus===undefined){this.addEntity(dependentEntityName,this._entityStatuses.get(entityName).dynamic);entityStatus=this._entityStatuses.get(dependentEntityName)} + entityStatus.dependentEntities.push(entityName)} + for(let j=0,m=this._entityLoadedCallbacks.length;j=20} + get(name){if(this._scenes[name]!==undefined){return this._scenes[name]} + return null} + getEntitiesNames(){const entityNames=[];for(let i=0;i{const check=setInterval(()=>{if(!wmtsComponent.isEnabled()||!wmtsComponent.getEntity().isEnabled()){clearInterval(check);reject(new Error('disabled'))} + if(loadedPromise===null&&wmtsComponent.getTilesLoadedPromise()!==null){loadedPromise=wmtsComponent.getTilesLoadedPromise().then(()=>{clearInterval(check);resolve(!0)})}},30)});return promise} + async terrainIsReady(cmtsComponent){let loadedPromise=null;const promise=new Promise(resolve=>{const check=setInterval(()=>{if(!cmtsComponent.isEnabled()||!cmtsComponent.getEntity().isEnabled()){clearInterval(check);resolve(!0)} + if(loadedPromise===null&&cmtsComponent._loadedPromise!==null){loadedPromise=cmtsComponent.getTilesLoadedPromise().then(()=>{clearInterval(check);resolve(!0)})}},30)});return promise} + async componentIsReady(component){if(component.isEnabled()&&component.getLoadState()==='loaded'){return} + const promise=new Promise(resolve=>{const check=setInterval(()=>{if(!component.isEnabled()||!component.getEntity().isEnabled()){clearInterval(check);resolve(!0)} + if(component.getLoadState()==='loaded'){clearInterval(check);resolve(!0)}},30)});return promise} + toggleStarfield(visible){for(let i=0;i<7;i++){this._scene.get('sun','starfield',i).setEnabled(visible)}} + toggleHeliosphere(visible){this._scene.get('sun','model').setEnabled(visible)} + async toggleConstellations(visible){const sun=(this._scene.get('sun'));if(sun===null){return} + let constellations=(sun.getComponentByType('constellations'));if(visible&&constellations===null){constellations=(sun.addComponent('constellations'));if(constellations instanceof pioneer_scripts__WEBPACK_IMPORTED_MODULE_2__.ConstellationsComponent){constellations.setUrl('$STATIC_ASSETS_URL/stars/constellations.bin');constellations.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(0.35,0.7,1,0.5))} + await this.pioneer.waitUntilNextFrame();await constellations.getLoadedPromise();const labelManager=(this.app.getManager('label'));const contentManager=(this.app.getManager('content'));labelManager.stop();const highlightColor=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(0.35,0.7,1,1);const cameraComponent=(this.get('main').getEntity('camera').getComponentByType('camera'));constellations.getNames().forEach(name=>{const entityName=`constellation_label_${name}`;const entity=this._scene.getEntity(entityName);labelManager.addEntity(entity);labelManager.setLabelProps({getLabelClass:entityName=>`no-select ${contentManager.getClassName(entityName, 'constellation') ?? 'constellation'}`,handleTouch:null,handleMouseEnter:event=>{constellations.setHighlight(constellations.getNearestConstellationIndex(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector2(event.x,event.y),cameraComponent),highlightColor,2.5)},handleMouseLeave:()=>{constellations.setHighlight(undefined,highlightColor,2.5)},handleClick:null},[entityName])});labelManager.start()}else if(!visible&&constellations!==null){const labelManager=(this.app.getManager('label'));labelManager.stop();constellations.getNames().forEach(name=>{const entityName=`constellation_label_${name}`;const entity=this._scene.getEntity(entityName);labelManager.removeEntity(entity)});labelManager.start();sun.removeComponent(constellations)}} + isHD(){return this._isHD} + hasHD(id){const entity=this._scene.get(id);if(entity===null){return!1} + if(Object.prototype.hasOwnProperty.call(this._hdWMTSMap,id)){return!0} + if(entity.getParent()!==null&&Object.prototype.hasOwnProperty.call(this._hdWMTSMap,entity.getParent().getName())){return!0} + if(entity.get('spheroidLOD')!==null){const spheroidLOD=entity.get('spheroidLOD');const sizes=spheroidLOD.getTextureSizes('color');for(let i=0;ithis._hdBreakpointSize){return!0}}} + return!1} + setHDBreakpoints(breakPointSize,maxTextureSize){this._hdBreakpointSize=breakPointSize;this._maxTextureSize=maxTextureSize} + async toggleHD(){this._isHD=!this._isHD;if(!this._isHD){this.pioneer.getConfig().setValue('maxTextureSize',this._hdBreakpointSize)} + for(const name in this._hdWMTSMap){const wmts=this._hdWMTSMap[name];const entity=this._scene.get(name);const spheroidLOD=entity.getComponentByType('spheroidLOD');const wmtsComponent=entity.getComponent(wmts);if(_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.isMobileMode()){wmtsComponent.setMaxLevel(5)} + wmtsComponent.setEnabled(this._isHD);if(this._isHD){this.addLoading(name,'wmts');await this.pioneer.waitUntilNextFrame();const ready=await this.tileIsReady(wmtsComponent).catch(()=>{this.removeLoading(name,'wmts')});if(ready===!0){spheroidLOD.setEnabled(!1);this.removeLoading(name,'wmts')}}else{spheroidLOD.setEnabled(!0)} + if(this._isHD){this.pioneer.getConfig().setValue('maxTextureSize',this._maxTextureSize)}}} + async forceTextureSizeForEntity(entityId,size,textureName='color'){const spheroidLOD=(this.app.pioneer.get('main',entityId,'spheroidLOD'));if(spheroidLOD===null||spheroidLOD===undefined){return} + spheroidLOD.forceTextureSize(textureName,size)} + async isEntityHD(entityId){const spheroidLOD=(this.app.pioneer.get('main',entityId,'spheroidLOD'));if(spheroidLOD===null||spheroidLOD===undefined){return!1} + await spheroidLOD.getLoadedPromise();return spheroidLOD.getTextureCurrentSize('color',0)>this._hdBreakpointSize} + async toggleHDTextureForEntity(entityId){const spheroidLOD=(this.app.pioneer.get('main',entityId,'spheroidLOD'));if(await this.isEntityHD(entityId)===!1){let hdTextureSize=this._maxTextureSize;if(_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.isiPhone()){hdTextureSize=this._mobileTextureSize} + this.addLoading(entityId,'spheroidLOD');spheroidLOD.getTextureNames().forEach(element=>{this.forceTextureSizeForEntity(entityId,hdTextureSize,element)});await this.pioneer.waitUntilNextFrame();await spheroidLOD.getLoadedPromise();this.removeLoading(entityId,'spheroidLOD');return!0}else{this.addLoading(entityId,'spheroidLOD');spheroidLOD.getTextureNames().forEach(element=>{this.forceTextureSizeForEntity(entityId,this._hdBreakpointSize,element)});await this.pioneer.waitUntilNextFrame();await spheroidLOD.getLoadedPromise();this.removeLoading(entityId,'spheroidLOD');return!1}} + createRing(name,radius,entityName,{orbitPlaneEntityName,color,numCircles=1,numSpokes=0,labelPosition=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-radius,0,0),labelText='',isEnable=!0}={}){const ringEntity=this._scene.addEntity(name);ringEntity.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero);const entity=this._scene.getEntity(entityName);ringEntity.setParent(entity);const ring=(ringEntity.addComponent('discGrid'));ring.setLineWidth(6);ring.setSize(radius);ring.setNumCircles(numCircles);ring.setNumSpokes(numSpokes);ring.setIgnoreDistance(!0);if(orbitPlaneEntityName){this.setAlignPlane(ringEntity,orbitPlaneEntityName)} + if(color instanceof pioneer__WEBPACK_IMPORTED_MODULE_1__.Color){ring.setColor(color)} + const labelEntity=this._scene.addEntity(`${name}Label`);labelEntity.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero);labelEntity.setParent(entity);const fixed=(labelEntity.addController('fixed'));fixed.setPosition(labelPosition);const divComponent=(labelEntity.addComponent('div'));divComponent.setFadeWhenCloseToCamera(!1);const div=divComponent.getDiv();div.classList.add('ring-label');divComponent.getDiv().innerHTML=labelText;ringEntity.setEnabled(isEnable);labelEntity.setEnabled(isEnable)} + createTorus(name,innerRadius,outerRadius,entityName,{orbitPlaneEntityName,color,visibleDistance=[Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY],labelPosition=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-outerRadius,0,0),labelText='',isEnable=!0}={}){const torusEntity=this._scene.addEntity(name);torusEntity.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero);const parent=this._scene.getEntity(entityName);torusEntity.setParent(parent);const torus=(torusEntity.addComponent('torus'));torus.setInnerRadius(innerRadius);torus.setOuterRadius(outerRadius);torus.setVisibleDistanceInterval(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(...visibleDistance));if(orbitPlaneEntityName){this.setAlignPlane(torusEntity,orbitPlaneEntityName)} + if(color instanceof pioneer__WEBPACK_IMPORTED_MODULE_1__.Color){torus.setColor(color)} + const labelEntity=this._scene.addEntity(`${name}Label`);labelEntity.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero);labelEntity.setParent(parent);const fixed=(labelEntity.addController('fixed'));fixed.setPosition(labelPosition);const divComponent=(labelEntity.addComponent('div'));divComponent.setFadeWhenCloseToCamera(!1);const div=divComponent.getDiv();div.classList.add('ring-label');divComponent.getDiv().innerHTML=labelText;torusEntity.setEnabled(isEnable);labelEntity.setEnabled(isEnable)} + setEntityHDWMTS(id,wmts){this._hdWMTSMap[id]=wmts} + async enableWMTSComponent(entityId,wmtsComponent){if(_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.isMobileMode()){wmtsComponent.setMaxLevel(5)} + const spheroidLOD=this.get('main').getEntity(entityId).getComponentByType('spheroidLOD');this.addLoading(entityId,'wmts');wmtsComponent.setEnabled(!0);await this.pioneer.waitUntilNextFrame();const ready=await this.tileIsReady(wmtsComponent).catch(()=>{this.removeLoading(entityId,'wmts')});if(ready){spheroidLOD.setEnabled(!1);this.removeLoading(entityId,'wmts')}else{spheroidLOD.setEnabled(!0)}} + async addWMTSComponent(entityId,wmtsData){const entity=(this.app.pioneer.get('main',entityId));let wmts=(entity.getComponentByType('wmts'));if(wmts===null){wmts=(entity.addComponent('wmts',wmtsData.id))} + wmts.setEnabled(!1);wmts.setEndPoint(wmtsData.endPoint);wmts.setLayer(wmtsData.layer);if(wmtsData.tile){wmts.setTileMatrixSet(wmtsData.tile)} + const now=new Date();if(wmtsData.time==='yesterday'){now.setDate(now.getDate()-1);wmts.setDimensionValue('Time',now.getFullYear()+'-'+(String(now.getMonth()+1)).padStart(2,'0')+'-'+(String(now.getDate())).padStart(2,'0'))}else if(wmtsData.time==='now'){wmts.setDimensionValue('Time',now.getFullYear()+'-'+(String(now.getMonth()+1)).padStart(2,'0')+'-'+(String(now.getDate())).padStart(2,'0'))} + if(wmtsData.level){wmts.setMaxLevel(wmtsData.level)}else{wmts.setMaxLevel(Infinity)} + wmts.setMinLevel(2);await this.enableWMTSComponent(entityId,wmts)} + loadWMTSFromJSON(wmtsList){for(const entityId in wmtsList){let hdId='';for(const key in wmtsList[entityId]){if(key==='hd'||hdId===''){hdId=wmtsList[entityId][key];this._hdWMTSMap[entityId]=hdId}else{const wmtsData=wmtsList[entityId][key];const entity=this._scene.get(entityId);const wmts=entity.addComponent('wmts',key);wmts.setEnabled(!1);wmts.setEndPoint(wmtsData.endPoint);wmts.setLayer(wmtsData.layer);if(wmtsData.tile){wmts.setTileMatrixSet(wmtsData.tile)} + const now=new Date();if(wmtsData.time==='yesterday'){now.setDate(now.getDate()-1);wmts.setDimensionValue('Time',now.getFullYear()+'-'+(String(now.getMonth()+1)).padStart(2,'0')+'-'+(String(now.getDate())).padStart(2,'0'))}else if(wmtsData.time==='now'){wmts.setDimensionValue('Time',now.getFullYear()+'-'+(String(now.getMonth()+1)).padStart(2,'0')+'-'+(String(now.getDate())).padStart(2,'0'))} + if(wmtsData.level){wmts.setMaxLevel(wmtsData.level)}else{wmts.setMaxLevel(Infinity)}}}}} + setAlignPlane(entity,orbitPlaneEntityName){const orbitPlaneEntity=this._scene.getEntity(orbitPlaneEntityName);const ori=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion();const dynamoController=(orbitPlaneEntity.getControllerByType('dynamo'));dynamoController.getOrbitOrientation(ori,this.app.pioneer.getTime());entity.setOrientation(ori)} + clearTempEntities(){const cameraManager=(this.app.getManager('camera'));const cameraEntity=cameraManager.cameraEntity;if(cameraEntity===null||cameraEntity.getParent()===null){return} + const camParent=cameraEntity.getParent().getName();this._tempEntities=this._tempEntities.filter(tempEntity=>{if(camParent===tempEntity.getName()){return!0} + const labelManager=(this.app.getManager('label'));labelManager.removeEntity(tempEntity);this._scene.removeEntity(tempEntity?.getName());return!1})} + addTempEntity(entity){this._tempEntities.push(entity)} + addLoading(id,type){const itemId=id+'_'+type;if(this._loadingItems.indexOf(itemId)<0){this._loadingItems.push(itemId)} + if(this._loadingItems.length>0){this._isLoading=!0;this.triggerCallbacks('loading')}} + removeLoading(id,type){const itemId=id+'_'+type;const index=this._loadingItems.indexOf(itemId);if(index>=0){this._loadingItems.splice(index,1)} + if(this._loadingItems.length===0){this._isLoading=!1;this.triggerCallbacks('loaded',[id])}} + forceLoad(component){component.setForceLoaded(!0);this._loadedComponents.push(component)} + removeForceLoad(component){this._loadedComponents=this._loadedComponents.filter(value=>{if(value===component){component.setForceLoaded(!1);return!1} + return!0})} + clearForceLoad(){for(let i=0;i0){const f=Math.pow(10,Math.floor(Math.log10(distance))-precision);distance=Math.round(distance/f)*f} + pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.release(positionRel);return distance} + getSpeed(objectA,objectB,{time=undefined}={}){const speed=pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.get();const entityA=this._scene.get(objectA);let entityB=null;if(objectB===undefined){entityB=entityA.getParent()}else{entityB=this._scene.get(objectB)} + if(time!==undefined){const pioneerTime=this.app.getManager('time').momentToET(time);entityA.getVelocityRelativeToEntity(speed,pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero,entityB,pioneerTime)}else{entityA.getVelocityRelativeToEntity(speed,pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero,entityB)} + pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.pool.release(speed);return speed.magnitude()} + getCoverage(entityId,checkOrientation=!0){const coverage={min:_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.constants.maxDate,max:_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.constants.minDate};const entity=this.pioneer.get('main',entityId);const margin=0.001;let posOriMin=entity.getPositionCoverage().min;let posOriMax=entity.getPositionCoverage().max;if(checkOrientation){posOriMin=Math.max(entity.getPositionCoverage().min,entity.getOrientationCoverage().min);posOriMax=Math.min(entity.getPositionCoverage().max,entity.getOrientationCoverage().max)} + coverage.min=entity?Math.min(posOriMin,coverage.min):coverage.min;coverage.max=entity?Math.max(posOriMax-margin,coverage.max):coverage.max;if(coverage.min===-Infinity||coverage.min<_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.minDate){coverage.min=moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.constants.minDate)}else{coverage.min=Math.ceil(coverage.min*1000)/1000;let unix=pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.etToUnix(coverage.min)*1000;unix=Math.ceil(unix*1000)/1000;coverage.min=moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().tz(unix,'ETC/Utc')} + if(coverage.max===Infinity||coverage.max>_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.maxDate){coverage.max=moment_timezone__WEBPACK_IMPORTED_MODULE_0___default()(_internal__WEBPACK_IMPORTED_MODULE_3__.AppUtils.constants.maxDate)}else{coverage.max=Math.floor(coverage.max*1000)/1000;let unix=pioneer__WEBPACK_IMPORTED_MODULE_1__.TimeUtils.etToUnix(coverage.max)*1000;unix=Math.floor(unix*1000)/1000;coverage.max=moment_timezone__WEBPACK_IMPORTED_MODULE_0___default().tz(unix,'ETC/Utc')} + return coverage} + async toggleRing(target){console.log('toggleRing',target)} + get main(){return this._scene} + get isLoading(){return this._isLoading}}}),"../eyes/src/managers/search_manager.js": + /*!**********************************************!*\ + !*** ../eyes/src/managers/search_manager.js ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SearchManager":function(){return SearchManager}});var fuse_js__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! fuse.js */"../eyes/node_modules/fuse.js/dist/fuse.esm.js");var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class SearchManager extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseManager{constructor(app,options={}){super(app);this._maxEntries=10;this._fuse=null;this._database=null;this._options={threshold:0.4,keys:[{name:'id',weight:0.99},{name:'name',weight:0.98}],includeScore:!0,includeMatches:!0,ignoreLocation:!0,...options}} + setOptions(options){Object.assign(this._options,options);this._fuse=new fuse_js__WEBPACK_IMPORTED_MODULE_1__["default"](this._database,this._options)} + setDatabase(database,options={}){if(!database){console.error('[SearchManager.setDatabase] Missing database.');return} + Object.assign(this._options,options);this._database=Object.keys(database).filter(key=>database[key].searchable!==!1).map(key=>{const keywords=database[key].keywords||[];keywords.map(keyword=>({value:keyword}));database[key].keywords=keywords;return database[key]});if(!Array.isArray(this._database)){console.error('[SearchManager.setDatabase] Database is not an array.');return} + this._fuse=new fuse_js__WEBPACK_IMPORTED_MODULE_1__["default"](this._database,this._options)} + getEntry(id){return this._database.find(entry=>entry.id===id)} + find(text,maxEntries=this._maxEntries){if(text===''||text===null||text===undefined||!this._fuse){return null} + let results=this._fuse.search(text);results=results.slice(0,maxEntries);return results}}}),"../eyes/src/managers/selection_manager.js": + /*!*************************************************!*\ + !*** ../eyes/src/managers/selection_manager.js ***! + \*************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SelectionManager":function(){return SelectionManager}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class SelectionManager extends _internal__WEBPACK_IMPORTED_MODULE_1__.BaseManager{constructor(app,scene){super(app);this._scene=scene;this._id=null;this._isClickable=!0;this._isSuppressed=!1;this._eventNames.push('3dselection');this._initCallbacks();this.bindFunctions(['setSuppress','handle3DSelection'])} + setScene(scene){this._scene=scene} + selectEntity(id){const oldId=this._id;if(id!==oldId){const event=new CustomEvent('selectionupdate',{detail:{new:id,old:this._id}});window.dispatchEvent(event);this._id=id;this._switchSelectionClass(this._id,oldId)}} + unselect(){const oldId=this._id;if(oldId!==null){const event=new CustomEvent('unselect',{old:this._id});window.dispatchEvent(event)} + this._id=null;this._switchSelectionClass(this._id,oldId)} + getCurrentId(){return this._id} + setClickable(isClickable){this._isClickable=isClickable} + init3Dcallback(cameraManager){cameraManager.setSelectionCallback(this.handle3DSelection)} + _getLink(entityName){return `/${entityName}`} + setSuppress(suppress){this._isSuppressed=suppress} + handle3DSelection(entity){if(!this._isClickable){return} + if(!this._isSuppressed&&entity!==null){const router=this._app.getManager('router');const entityName=entity.getName();const parsedLink=this._getLink(entityName);const linkPath=typeof parsedLink==='string'?parsedLink:(parsedLink.path??'');const{options={keepTime:!0},query={}}=typeof parsedLink==='object'&&parsedLink;const navigated=router.navigate(query,linkPath,options);this.triggerCallbacks('3dselection',[navigated,entity])} + this._isSuppressed=!1} + _switchSelectionClass(newId,oldId){if(oldId!==null){const entity=this._scene.get(oldId);if(entity!==null){const label=entity.getComponentByType('div').getDiv();if(label){label.classList.remove('selection')}}} + if(newId!==null){const entity=this._scene.get(newId);if(entity!==null){const label=entity.getComponentByType('div').getDiv();if(label){label.classList.add('selection')}}}}}}),"../eyes/src/managers/spout_manager.js": + /*!*********************************************!*\ + !*** ../eyes/src/managers/spout_manager.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SpoutManager":function(){return SpoutManager}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class SpoutManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager{constructor(app){super(app);this._scene=this.app.pioneer.get('main');this._defaultTarget=this.getSpoutCameraTargetEntity(this.app.getManager('router').currentRoute.params);this._defaultTargetRadius=this._defaultTarget?this._scene.getEntity(this._defaultTarget)?.getExtentsRadius():this._scene.getEntity('earth').getExtentsRadius()} + async enableSpout(globe=!1,renderWidth=2048,globeDistance=this._defaultTargetRadius*2,target=this._defaultTarget,fontSize=25,lonAngleOffset=0,alignToNorthPole=!1){const spoutViewport=this.app.pioneer.getViewport('spoutViewport')||this.app.pioneer.addViewport('spoutViewport');spoutViewport.getDiv().style.display='none';spoutViewport.getDiv().style.width='100%';spoutViewport.getDiv().style.height='100%';const targetEntity=this._scene.getEntity(target)||this._scene.getEntity('earth');const spoutCamera=this.setUpSpoutCamera(globe,targetEntity,alignToNorthPole,lonAngleOffset);const spoutComponent=spoutCamera.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpoutComponent)||spoutCamera.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpoutComponent);spoutViewport.setCamera(spoutComponent);spoutComponent.setRenderWidth(renderWidth);this._scene.setAmbientLightColor(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1,1,1));if(globe===!0){spoutComponent.setForGlobe(!0,globeDistance||targetEntity.getExtentsRadius()*2);spoutComponent.setNearDistance(targetEntity.getExtentsRadius()*0.5);targetEntity.get('atmosphere')?.setExcludedFromCamera(spoutComponent,!0)} + await this.setUpSpoutLabels(fontSize,targetEntity)} + setUpSpoutCamera(globe,targetEntity=this._defaultTarget,alignToNorthPole=!1,lonAngleOffset=0){let spoutCamera;if(globe===!0){spoutCamera=this._scene.getEntity('spoutCamera')||this._scene.addEntity('spoutCamera');spoutCamera.clearControllers();spoutCamera.setParent(targetEntity);spoutCamera.setPosition(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero);spoutCamera.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity);const align=spoutCamera.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.AlignController);align.setPrimaryAlignType('align');align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis);align.setPrimaryTargetAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis);if(alignToNorthPole){align.setPrimaryTargetEntity(targetEntity.getName())}else{align.setPrimaryTargetEntity('camera')} + const xAxis=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();pioneer__WEBPACK_IMPORTED_MODULE_0__.Geometry.getXYZFromLLAOnSphere(xAxis,new pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt(0,pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(180+lonAngleOffset),1),1);align.setSecondaryAlignType('align');align.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis);align.setSecondaryTargetEntity('camera');align.setSecondaryTargetAxis(xAxis)}else{spoutCamera=this._scene.getEntity('camera')} + return spoutCamera} + async setUpSpoutLabels(fontSize=25,targetEntity=null){let target=targetEntity;if(!target){target=await this.getSpoutCameraTargetEntity(this.app.getManager('router').currentRoute.params)||'sun'} + pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.waitTillEntitiesInPlace(this._scene,[target],this.app.pioneer.getTime(),10.0,3.0).then(()=>{for(let i=0;i{console.log(error)})} + async getSpoutCameraTargetEntity(params){let spaceObject=null;const contentManager=this.app.getManager('content');if(params){const onMoon='feature' in params&¶ms.feature==='moons';const currentObjectId=onMoon?params.child:params.spaceObject;const currentObjectEntity=this.pioneer.get('main',currentObjectId)||this.pioneer.get('main','earth');const entityInfo=contentManager.getEntityInfo(currentObjectId)||{};const entityDesc=await contentManager.getEntityDesc(currentObjectId);const spaceObjParentId=currentObjectId&&this.pioneer.get('main',currentObjectId)?.getParent()?.getName();switch(entityInfo.category){case 'Spacecraft':spaceObject=_internal__WEBPACK_IMPORTED_MODULE_2__.AppUtils.isFutureMission(entityDesc?.dates?.start)?'earth':currentObjectEntity?.getParent()?.getName();if(entityInfo.keywords.includes('lander')&¤tObjectEntity.getParent().getName().includes('landing_site')){spaceObject=this.pioneer.get('main',currentObjectId)?.getParent()?.getParent()?.getName()} + break;case 'Landing site':spaceObject=spaceObjParentId;break;default:spaceObject=currentObjectId;break}} + return spaceObject}}}),"../eyes/src/managers/time_manager.js": + /*!********************************************!*\ + !*** ../eyes/src/managers/time_manager.js ***! + \********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TimeManager":function(){return TimeManager}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var moment_timezone__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! moment-timezone */"../eyes/node_modules/moment-timezone/index.js");var moment_timezone__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(moment_timezone__WEBPACK_IMPORTED_MODULE_1__);var _internal__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class TimeManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager{constructor(app){super(app);this._dateFormats={utc:{full:'YYYY-MM-D HH[:]mm[:]ss',datetime:'YYYY-MM-D HH[:]mm',date:'YYYY MMMM D',time:'HH[:]mm[:]ss',url:'YYYY-MM-DDTHH:mm:ss.SSSZ'},local:{full:'M/D/YY hh[:]mm[:]ss',datetime:'M/D/YY hh[:]mm',date:'MMMM D, YYYY',time:'hh[:]mm[:]ss',meridiem:'a'}};this._timeLimits={min:null,max:null};this._defaultLimits={min:null,max:null};this._startTime=null;this._forcedPause=!1;this._isUTC=!0;this._ertMgr=null;this._rate=0;this._defaultRate=1.0;this._utcTimezone='Etc/UTC';this._localTimezone=moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz.guess();this._previousTimeRate=this.pioneer.getTimeRate();this._timezone=this._utcTimezone;this._eventNames.push('update','change','timezone','ratechange','forcedpause','forcedpauseresume','getnow');this._initCallbacks();this.setToNow();this.pioneer.addCallback(()=>{const time=this.pioneer.getTime();const rate=this.pioneer.getTimeRate();this._time=moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(time)*1000,this._timezone);let nextTime=moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(time+rate/this.pioneer.getFPS())*1000,this._timezone);if(isNaN(nextTime)){nextTime=this._time} + if(this._timeLimits.max&&nextTime.valueOf()>this._timeLimits.max.valueOf()){console.warn('[Time Manager]: Clock has reached maximum limit.');this._onLimitReach('max')}else if(this._timeLimits.min&&nextTime.valueOf()this._timeLimits.min.valueOf())){if(this._forcedPause){this._forcedPause=!1;if(this.getTimeRate()===0){this.play();this.triggerCallbacks('forcedpauseresume',[this._time])}}} + this.triggerCallbacks('update',[this._time])},!0)} + _onLimitReach(limit){if(this.getTimeRate()!==0){this._forcedPause=!0;this.pause();this._previousTimeRate=0;this.triggerCallbacks('forcedpause',[this._time,limit])} + this.setTime(this._timeLimits[limit])} + setERTManager(ertMgr){this._ertMgr=ertMgr} + isNow(){return this._rate===1&&Math.abs(this._time.valueOf()-this.getNow().valueOf())<1000} + getNow(){let time=moment_timezone__WEBPACK_IMPORTED_MODULE_1___default()().tz(this._timezone);for(let i=this._callbacks.getnow.length-1;i>=0;i--){const callback=this._callbacks.getnow[i];time=callback(time)} + return time} + setToNow(){this.setTime(this.getNow())} + setStartTime(time){this._startTime=time} + setToStart(){if(this._startTime!==null){this.setTime(this._startTime)}} + getTime(){return this._time} + setTime(time){time=this.parseTime(time);const etTime=this.momentToET(time);this.pioneer.setTime(etTime);this._time=moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(this.pioneer.getTime())*1000,this._timezone);this.triggerCallbacks('change',[this._time])} + parseTime(time,dateFormat='url'){let isUTC=this._isUTC;let format=(moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().ISO_8601);if(typeof time==='string'&&time!==''){const reg=/^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d(?:|:[0-5]\d)(?:\.\d{1,6})?(?:|Z|[+-][01]\d:[0-5]\d)$/;isUTC=time.match(reg)!==null;const isUTCFormat=isUTC?'utc':'local';const urlFormat=this.getDateFormat(dateFormat,isUTCFormat);if(urlFormat){format=urlFormat}}else if(typeof time==='number'){isUTC=!0} + return isUTC?moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().utc(time):moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(time,format,!0,this._localTimezone)} + etToMoment(time){return moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(time)*1000,'Etc/UTC')} + momentToET(time){const unix=time.valueOf()/1000;const etTime=pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.unixToEt(unix);return Math.round(etTime*1000)/1000} + getTimezone(){return this._timezone} + getUTCTimezone(){return this._utcTimezone} + getLocalTimezone(){return this._localTimezone} + isUTC(){return this._isUTC} + setDisplayUTC(val){this._isUTC=val;this._timezone=this._isUTC?this._utcTimezone:this._localTimezone;this.triggerCallbacks('timezone',[val])} + getDateFormats(){return this._dateFormats} + setDateFormats(formats){for(const[key,value]of Object.entries(formats)){if(this._dateFormats[key]!==undefined){Object.assign(this._dateFormats[key],value)}else{this._dateFormats[key]=value}}} + getDateFormat(format,utcLocal){if(!utcLocal){utcLocal=this._isUTC?'utc':'local'} + return this._dateFormats[utcLocal][format]} + setDateFormat(name,format){this._dateFormats[name]=format} + getLimits(){return this._timeLimits} + setLimits(limits){this._timeLimits.min=limits.min.clone();this._timeLimits.max=limits.max.clone()} + getDefaultLimits(){return this._defaultLimits} + setDefaultLimits(limits){this._defaultLimits.min=limits.min.clone();this._defaultLimits.max=limits.max.clone()} + resetLimits(){this._timeLimits.min=this._defaultLimits.min.clone();this._timeLimits.max=this._defaultLimits.max.clone()} + setMin(time){this._timeLimits.min=moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(time,this._timezone)} + resetMin(){this._timeLimits.min=this._defaultLimits.min.clone()} + setMax(time){this._timeLimits.max=moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(time,this._timezone)} + resetMax(){this._timeLimits.max=this._defaultLimits.max.clone()} + getTimeUrl(time){let utcTime;if(!time){utcTime=moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().utc(this._time)}else{utcTime=moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().utc(moment_timezone__WEBPACK_IMPORTED_MODULE_1___default().tz(time,this._timezone))} + return utcTime.utc().format(this._dateFormats.utc.url)} + getDefaultTimeRate(){return this._defaultRate} + setDefaultTimeRate(rate){this._defaultRate=rate} + resetTimeRate(){this.setTimeRate(this._defaultRate)} + getTimeRate(){return this.pioneer.getTimeRate()} + setTimeRate(rate){this._rate=rate;this.pioneer.setTimeRate(rate);this.triggerCallbacks('ratechange',[this._rate])} + play(){const rate=this._previousTimeRate===0?this._defaultRate:this._previousTimeRate;this.setTimeRate(rate)} + pause(){this._previousTimeRate=this.getTimeRate();this.setTimeRate(0)} + getMidTime(a,b){const midTime=(a.unix()+b.unix())/2;const m=moment_timezone__WEBPACK_IMPORTED_MODULE_1___default()(midTime,'X');return m} + getEventNames(){return this._eventNames} + isWithinLimits(time){if(this._timeLimits.min&&time.isBefore(this._timeLimits.min)){return-1} + if(this._timeLimits.max&&time.isAfter(this._timeLimits.max)){return 1} + return 0} + get timeLimits(){return this._timeLimits} + get forcedPause(){return this._forcedPause} + get previousTimeRate(){return this._previousTimeRate}}}),"../eyes/src/managers/title_manager.js": + /*!*********************************************!*\ + !*** ../eyes/src/managers/title_manager.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TitleManager":function(){return TitleManager}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class TitleManager extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseManager{constructor(app,options){super(app);this._options=options;this._currentTitle=null;this._fullTitle=null;this._parseFn=this._options.parseFn??null} + updateTitle(currentRoute){const{prefix,suffix}=this._options||{};this._currentTitle=this._parseRoute(currentRoute);this._fullTitle=`${prefix} - ${this._currentTitle} - ${suffix}`;document.title=this._fullTitle} + _parseRoute(routeStr){if(this._parseFn){return this._parseFn(routeStr)} + return'Home'} + setParseFunction(parseFn){if(typeof parseFn==='function'){this._parseFn=parseFn}} + get currentTitle(){return this._currentTitle} + get fullTitle(){return this._fullTitle}}}),"../eyes/src/managers/trail_manager.js": + /*!*********************************************!*\ + !*** ../eyes/src/managers/trail_manager.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TrailManager":function(){return TrailManager}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer-scripts */"../pioneer/scripts/src/index.js");var _internal__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ../internal */"../eyes/src/internal.js");class TrailManager extends _internal__WEBPACK_IMPORTED_MODULE_2__.BaseManager{constructor(app,scene){super(app);this._scene=scene;this._ids=[];this._hiddenIds=[];this._opacity={primary:0.75,secondary:0.35,hover:1.0};this._width={default:[0,2],hover:[2,4]};this._orbitLinesOpts={lineWidth:{default:1.2,hover:2},glowWidth:{default:0,hover:0},alphaFade:[22,8]};this._orbitLineEntityNames=pioneer_scripts__WEBPACK_IMPORTED_MODULE_1__.Entity.getEntityNamesInGroup('planets').add('moon');this._colors={default:new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1,1,1,this._opacity.secondary),mercury:new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(151/255,104/255,172/255,this._opacity.primary),venus:new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(176/255,121/255,25/255,this._opacity.primary),earth:new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(0/255,153/255,204/255,this._opacity.primary),mars:new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(154/255,78/255,25/255,this._opacity.primary),jupiter:new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(218/255,139/255,114/255,this._opacity.primary),saturn:new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(213/255,193/255,135/255,this._opacity.primary),uranus:new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(104/255,204/255,218/255,this._opacity.primary),neptune:new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(112/255,140/255,227/255,this._opacity.primary)};this.bindFunctions(['onHoverChange','setUpTrail','toggleTrails','toggleOrbits'])} + setScene(scene){this._scene=scene} + create(id){const trail=this._scene.get(id,'trail');if(trail){console.warn('Trail already exists for',id);return} + const entity=this._scene.get(id);const result=entity.addComponent('trail');this._ids.push(id);return result} + setStartTime(ids,start){if(!Array.isArray(ids)){ids=[ids]} + for(let i=0;i0?this._hiddenIds:this._ids}else if(!Array.isArray(ids)){ids=[ids]} + for(let i=0;i{const orbitLine=this._scene.get(entityName,'orbitLine');orbitLine?.setEnabled(active)})} + get ids(){return this._ids} + set ids(ids){if(!Array.isArray(ids)){ids=[ids]} + for(let i=0;i{const kEffect=new KeyframeEffect(element,keyframes,timings);return new Animation(kEffect,element.ownerDocument.timeline)};AnimationUtils.directionalFade=(element,{direction='up',fade='in',yOffset=0,xOffset=0,timings=AnimationUtils.defaultTimings})=>{const v={x:{ori:0,dest:0},y:{ori:0,dest:0},opacity:{ori:1.0,dest:0.0}};if(direction==='up'||direction==='down'){v.y.ori=(fade==='in')?100:0;v.y.dest=100-v.y.ori;if(direction==='up'){v.y.ori*=-1;v.y.dest*=-1}}else{v.x.ori=(fade==='in')?100:0;v.x.dest=100-v.x.ori;if(direction==='left'){v.x.ori*=-1;v.x.dest*=-1}} + if(fade==='in'){v.opacity.ori=0.0;v.opacity.dest=1.0} + v.x.ori+=xOffset;v.x.dest+=xOffset;v.y.ori+=yOffset;v.y.dest+=yOffset;const keyframes=[{transform:'translate('+v.x.ori+'%, '+v.y.ori+'%)',opacity:v.opacity.ori},{transform:'translate('+v.x.dest+'%, '+v.y.dest+'%)',opacity:v.opacity.dest}];return AnimationUtils.createAnimation(element,keyframes,timings)};AnimationUtils.defaultTimings={duration:1000,iteration:1,fill:'forwards',easing:'ease'}}),"../eyes/src/utils/app_utils.js": + /*!**************************************!*\ + !*** ../eyes/src/utils/app_utils.js ***! + \**************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"AppUtils":function(){return AppUtils}});var deepmerge__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! deepmerge */"../eyes/node_modules/deepmerge/dist/cjs.js");var deepmerge__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(deepmerge__WEBPACK_IMPORTED_MODULE_0__);var lodash_debounce__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! lodash.debounce */"../eyes/node_modules/lodash.debounce/index.js");var lodash_debounce__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_1__);var lodash_throttle__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! lodash.throttle */"../eyes/node_modules/lodash.throttle/index.js");var lodash_throttle__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(lodash_throttle__WEBPACK_IMPORTED_MODULE_2__);var overlayscrollbars__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! overlayscrollbars */"../eyes/node_modules/overlayscrollbars/js/OverlayScrollbars.js");var overlayscrollbars__WEBPACK_IMPORTED_MODULE_3___default=__webpack_require__.n(overlayscrollbars__WEBPACK_IMPORTED_MODULE_3__);var overlayscrollbars_css_OverlayScrollbars_css__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! overlayscrollbars/css/OverlayScrollbars.css */"../eyes/node_modules/overlayscrollbars/css/OverlayScrollbars.css");var _tweenjs_tween_js__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(/*! @tweenjs/tween.js */"../eyes/node_modules/@tweenjs/tween.js/dist/tween.esm.js");class AppUtils{static conversionTable={kmToMi:0.621371,kmToFt:3280.84,miToFt:5280,kmToM:1000,auToKm:149597871,ldToKm:384398};static constants={speedOfLight:299792.458,minDate:-8e+15,maxDate:8e+15};static isEmptyObject(obj){return obj.constructor===Object&&Object.keys(obj).length===0} + static addStartToPath(pathName,start='/'){if(!pathName.startsWith(start)){return start+pathName} + return pathName} + static cleanPathDuplicate(pathName,duplicate='/',replacement='/'){const re=new RegExp(`${duplicate}+`,'g');return pathName.replace(re,replacement)} + static addEndToPath(pathName,end='/'){if(!pathName.endsWith(end)){return pathName+end} + return pathName} + static isElement(obj){return obj instanceof Element||obj instanceof Document} + static isHTML(str){if(typeof str!=='string'){return!1} + return str.match(/<[^/>]+>/gm)!==null&&str.match(/<\/[^>]+>/gm)!==null} + static hasHTML(str){if(typeof str!=='string'){return!1} + const doc=new DOMParser().parseFromString(str,'text/html');return Array.from(doc.body.childNodes).some(node=>node.nodeType===1)} + static async loadJSON(fileName){fileName=AppUtils.addEndToPath(fileName,'.json');const response=await fetch(fileName);if(response.status===200){return response.json()}else{const err=new Error(response.status+' ('+response.statusText+') when trying to fetch "'+fileName+'"');err.name='NotFound';throw err}} + static msToTime(ms=0){const millisecond=ms%1000;ms=(ms-millisecond)/1000;const second=ms%60;ms=(ms-second)/60;const minute=ms%60;const hour=(ms-minute)/60;return{hour,minute,second,millisecond}} + static formatCountdownTime(maxSessionTime,incomingTime){const oneHour=60*60*1000;const time=this.msToTime(incomingTime);time.hour=time.hour.toString().padStart(2,'0');time.minute=time.minute.toString().padStart(2,'0');time.second=time.second.toString().padStart(2,'0');return `${maxSessionTime >= oneHour ? time.hour + ':' : ''}${time.minute || '00'}:${time.second}`} + static minToSec(minutes){return minutes*60} + static minToMS(minutes){return minutes*60000} + static isFutureMission(startDate){const today=new Date();const missionStartDate=new Date(startDate);return missionStartDate>today} + static deepCopy(object1){return JSON.parse(JSON.stringify(object1))} + static deepClone(obj){const out=(Array.isArray(obj)?[]:{});for(const key in obj){const value=(obj[key]);out[key]=(typeof value==='object'&&value!==null)?AppUtils.deepClone(value):value} + return out} + static deepMerge(object1,object2){const options={isMergeableObject:(value)=>(value&&value._isAMomentObject?!1:Boolean(value)&&typeof value==='object')};return deepmerge__WEBPACK_IMPORTED_MODULE_0___default()(object1,object2,options)} + static deepEqual(object1,object2){if(!object1||!object2){return!1} + const keys1=Object.keys(object1);const keys2=Object.keys(object2);if(keys1.length!==keys2.length){return!1} + for(const key of keys1){const val1=object1[key];const val2=object2[key];const areObjects=AppUtils.isObject(val1)&&AppUtils.isObject(val2);if(areObjects&&!AppUtils.deepEqual(val1,val2)){return!1}else if(!areObjects&&val1!==val2){return!1}} + return!0} + static isObject(object){return object!==null&&typeof object==='object'} + static filterObject(obj,callback){return Object.fromEntries(Object.entries(obj).filter(([key,val])=>callback(val,key)))} + static debounce(){return lodash_debounce__WEBPACK_IMPORTED_MODULE_1___default()(...arguments)} + static throttle(){return lodash_throttle__WEBPACK_IMPORTED_MODULE_2___default()(...arguments)} + static waitFor(n){return new Promise(resolve=>{setTimeout(()=>{resolve()},n)})} + static isPortrait(){return window.matchMedia('(orientation: portrait)').matches} + static isLandscape(){return window.matchMedia('(orientation: landscape)').matches} + static isMobileLandscape(){return window.matchMedia('(min-width: 320px) and (max-width: 915px) and (orientation: landscape)').matches} + static isMobilePortrait(){return window.matchMedia('(min-width: 320px) and (max-width: 640px) and (orientation: portrait)').matches} + static isMobile(){return AppUtils.isMobileLandscape()||AppUtils.isMobilePortrait()} + static isiPhone(){const platform=window.navigator?.userAgentData?.platform||window.navigator?.platform||'unknown';return platform==='iPhone'} + static isiPad(){const platform=window.navigator?.userAgentData?.platform||window.navigator?.platform||'unknown';const touchPoints=window.navigator.maxTouchPoints>1;return(platform==='MacIntel'&&touchPoints)} + static isTabletPortrait(){return window.matchMedia('(min-width: 641px) and (max-width: 1024px) and (orientation: portrait)').matches} + static isTabletLandscape(){return window.matchMedia('(min-width: 916px) and (max-width: 1024px) and (orientation: landscape)').matches} + static isTablet(){return AppUtils.isTabletLandscape()||AppUtils.isTabletPortrait()} + static isMobileMode(){return AppUtils.isMobilePortrait()||AppUtils.isMobileLandscape()||AppUtils.isTabletLandscape()||AppUtils.isTabletPortrait()||AppUtils.isPanorama()} + static isDesktop(){return window.matchMedia('(min-width: 1025px) and (min-height: 600px)').matches} + static isPanorama(){return window.matchMedia('(min-width: 1025px) and (max-height: 599px) and (orientation: landscape)').matches} + static is2K(){return window.matchMedia('(min-width: 2880px) and (min-height: 1620px)').matches} + static is4K(){return window.matchMedia('(min-width: 3200px) and (min-height: 1800px)').matches} + static isTouch(){return('ontouchstart' in window)||window.navigator.maxTouchPoints>0} + static isPrimaryTouch(){return window.matchMedia('(pointer: coarse)').matches} + static canHover(){return!(matchMedia('(hover: none)').matches)} + static htmlToElement(html){const template=document.createElement('template');template.innerHTML=html.replace(/[\t\n]+/g,'').trim();return template.content.firstElementChild} + static htmlToElements(html){const template=document.createElement('template');template.innerHTML=html.replace(/[\t\n]+/g,'').trim();return template.content.cloneNode(!0).childNodes} + static insertParamsToHTML(html,params={}){html=html.replace(/[\t\n]+/g,'').trim();const keys=Object.keys(params);for(let i=keys.length-1;i>=0;i--){const key=keys[i];const param=`{$${key}}`;html=html.replaceAll(param,params[key])} + html=html.replaceAll(/{\$([A-Z])\w+}/gi,'');return html} + static htmlWithParamsToElement(html,params={}){html=AppUtils.insertParamsToHTML(html,params);return AppUtils.htmlToElement(html)} + static onAttachElement(elementQuery,callback,{interval=100,timeout=5000}={}){const myInterval=setInterval(()=>{const attached=typeof elementQuery==='string'?document.querySelector(elementQuery)!==null:document.body.contains(elementQuery);if(attached){clearInterval(myInterval);clearTimeout(myTimeout);callback()}},interval);const myTimeout=setTimeout(()=>{clearInterval(myInterval);console.error(`[AppUtils.onAttachElement] Timeout exceeded for "${elementQuery}".`)},timeout)} + static appendWithCallback(parent,element,selector,callback){const promise=new Promise(resolve=>{if(document.querySelector(selector)){return resolve(document.querySelector(selector))} + const observer=new MutationObserver(()=>{if(document.querySelector(selector)){resolve(document.querySelector(selector));observer.disconnect()}});observer.observe(document.body,{childList:!0,subtree:!0})});promise.then(callback);parent.appendChild(element)} + static elementReady(selector,timeout=1000){return new Promise((resolve,reject)=>{const element=document.querySelector(selector);if(element){resolve(element);return} + const observer=new MutationObserver(()=>{const element=document.querySelector(selector);if(element){observer.disconnect();clearTimeout(timer);resolve(element)}});observer.observe(document.body,{childList:!0,subtree:!0});const timer=setTimeout(()=>{observer.disconnect();reject(console.warn(`${selector} not found in DOM`))},timeout)})} + static addScrollbar(element,options={}){const opts=({className:'os-theme-dark',resize:'none',clipAlways:!1,normalizeRTL:!1,paddingAbsolute:!0,autoUpdate:!1,sizeAutoCapable:!1,overflowBehavior:{x:'hidden',y:'scroll'},scrollbars:{clickScrolling:!0,autoHide:'move'},...options});return overlayscrollbars__WEBPACK_IMPORTED_MODULE_3___default()(element,opts)} + static formatNumber(number,maxDps=3,minDps=undefined){return number.toLocaleString(undefined,{maximumFractionDigits:maxDps,minimumFractionDigits:minDps})} + static formatDate(date,options={}){return date.toLocaleString(undefined,{year:'numeric',month:'long',day:'numeric',...options})} + static tween(from,to,{onUpdate,onComplete,duration=2000}={}){let request=(0);const tween=new _tweenjs_tween_js__WEBPACK_IMPORTED_MODULE_5__.Tween(from).to(to,duration).onUpdate(obj=>{if(onUpdate!==undefined){onUpdate(obj)}}).onComplete(()=>{if(typeof onComplete==='function'){onComplete()} + cancelAnimationFrame(request)}).start();const tweenAnimationFrame=(time)=>{request=requestAnimationFrame(tweenAnimationFrame);(0,_tweenjs_tween_js__WEBPACK_IMPORTED_MODULE_5__.update)(time)};tweenAnimationFrame();return tween} + static convertObjType(obj){Object.entries(obj).forEach(([key,value])=>{let outValue;switch(value.trim()){case 'undefined':outValue=undefined;break;case 'null':outValue=null;break;case 'true':outValue=!0;break;case 'false':outValue=!1;break;case 'NaN':outValue=NaN;break;case '':break;default:outValue=isNaN(value)?value:parseFloat(value);break} + obj[key]=outValue});return obj}}}),"../eyes/src/utils/cancel_token.js": + /*!*****************************************!*\ + !*** ../eyes/src/utils/cancel_token.js ***! + \*****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"CancelToken":function(){return CancelToken}});class CancelToken{constructor(){this._isCanceled=!1} + cancel(){this._isCanceled=!0} + get isCanceled(){return this._isCanceled}}}),"../eyes/src/version.js": + /*!******************************!*\ + !*** ../eyes/src/version.js ***! + \******************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"version":function(){return version}});const version='2.4.0'}),"../pioneer/engine/src/capabilities.js": + /*!*********************************************!*\ + !*** ../pioneer/engine/src/capabilities.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Capabilities":function(){return Capabilities}});class Capabilities{static isWebGL2(){return typeof WebGL2RenderingContext!=='undefined'&&_context instanceof WebGL2RenderingContext} + static hasFragDepth(){return this.isWebGL2()||this.hasGLExtension('EXT_frag_depth')} + static hasGLExtension(extensionName){if(_context===null){return!1} + let value=_cache.get(extensionName);if(value===undefined){value=_context.getExtension(extensionName)!==null;_cache.set(extensionName,value)} + return value} + static __getCompressedTextureExtension(){return _compressedTextureExtension} + static __setContext(context){_context=context;_compressedTextureFormats.forEach((value,key)=>{if(this.hasGLExtension('WEBGL_compressed_texture_'+key)===!0||this.hasGLExtension('WEBKIT_WEBGL_compressed_texture_'+key)===!0){if(_compressedTextureExtension===''){_compressedTextureExtension=value}}})}} + const _cache=new Map();let _context=null;let _compressedTextureExtension='';const _compressedTextureFormats=new Map([['astc','astc'],['s3tc','dxt'],['pvrtc','pvrtc'],['etc','etc2'],['etc1','etc1']])}),"../pioneer/engine/src/config.js": + /*!***************************************!*\ + !*** ../pioneer/engine/src/config.js ***! + \***************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Config":function(){return Config}});class Config{constructor(){this._valueMap=new Map();this._callbacksMap=new Map();this.setValue('maxTextureSize',512);this.setValue('useTextureCompression',!0);this.setValue('fontFamily','Arial');this.setValue('fontSize',16);this.setValue('gammaCorrection',1.0)} + getValue(key){return this._valueMap.get(key)} + setValue(key,value){const changed=this._valueMap.get(key)!==value;if(changed){this._valueMap.set(key,value);const callbacks=this._callbacksMap.get(key);if(callbacks){for(let i=0;idownloadData.download.actualUrl===actualUrl);if(queueIndex!==-1){const downloadData=this._downloadQueue[queueIndex][1];downloadData.download.content=undefined;downloadData.download.status='cancelled';this._downloadQueue.splice(queueIndex,1);downloadData.resolve(downloadData.download)}}} + processUrl(url){let processedUrl=url;for(const[name,replacement]of this._replacements){processedUrl=processedUrl.replace('$'+name,replacement)} + return processedUrl} + download(url,binary,progressCallback){const actualUrl=this.processUrl(url);let downloadData=this._currentDownloads.get(actualUrl);if(downloadData!==undefined&&downloadData.promise!==null){if(progressCallback){downloadData.progressCallbacks.push(progressCallback)} + return downloadData.promise} + const queueIndex=this._downloadQueue.findIndex(([_,downloadData])=>downloadData.download.actualUrl===actualUrl);if(queueIndex!==-1){downloadData=this._downloadQueue[queueIndex][1];if(progressCallback){downloadData.progressCallbacks.push(progressCallback)} + return downloadData.promise} + downloadData=new DownloadData(url,actualUrl,binary);downloadData.promise=new Promise((resolve)=>{downloadData.resolve=resolve;_internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add([0,downloadData],this._downloadQueue,(a,b)=>a[0]a[0]===b[0]);this.checkDownloadQueue()});return downloadData.promise} + doRequest(downloadData){const request=new XMLHttpRequest();request.addEventListener('load',()=>{if(200<=request.status&&request.status<=299){downloadData.download.content=request.response;downloadData.download.status='completed'}else{downloadData.download.content=undefined;downloadData.download.status='failed'} + this._currentDownloads.delete(downloadData.download.actualUrl);this.checkDownloadQueue();downloadData.resolve(downloadData.download)});request.addEventListener('progress',(event)=>{downloadData.download.progress=event.lengthComputable?(event.loaded/event.total):0;downloadData.download.totalBytes=event.lengthComputable?event.total:0;for(const progressCallback of downloadData.progressCallbacks){progressCallback(downloadData.download)}});request.addEventListener('abort',()=>{downloadData.download.content=undefined;downloadData.download.status='cancelled';this._currentDownloads.delete(downloadData.download.actualUrl);this.checkDownloadQueue();downloadData.resolve(downloadData.download)});request.addEventListener('error',()=>{downloadData.download.content=undefined;downloadData.download.status='failed';downloadData.download.errorMessage=request.statusText;this._currentDownloads.delete(downloadData.download.actualUrl);this.checkDownloadQueue();downloadData.resolve(downloadData.download)});if(downloadData.download.binary){request.responseType='arraybuffer'}else{request.responseType='text'} + downloadData.request=request;request.open('GET',downloadData.download.actualUrl);request.send()} + checkDownloadQueue(){if(this._currentDownloads.size0){const[_,downloadData]=this._downloadQueue.shift();this._currentDownloads.set(downloadData.download.actualUrl,downloadData);this.doRequest(downloadData)}}}}),"../pioneer/engine/src/engine.js": + /*!***************************************!*\ + !*** ../pioneer/engine/src/engine.js ***! + \***************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Engine":function(){return Engine}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./internal */"../pioneer/engine/src/internal.js");class Engine{constructor(rootDiv){if(!(rootDiv instanceof HTMLDivElement)){throw new Error('The root div param is not an actual div element.')} + this._rootDiv=rootDiv;this._canvas=null;this._renderSize=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2();this._renderSize.freeze();this._input=new _internal__WEBPACK_IMPORTED_MODULE_0__.Input(this);this._config=new _internal__WEBPACK_IMPORTED_MODULE_0__.Config();this._downloader=new _internal__WEBPACK_IMPORTED_MODULE_0__.Downloader();this._textureLoader=null;this._textureLoaderCompressed=null;this._materialManager=null;this._scenes=new _internal__WEBPACK_IMPORTED_MODULE_0__.Collection(this,new Map([['scene',_internal__WEBPACK_IMPORTED_MODULE_0__.Scene]]));this._viewports=new _internal__WEBPACK_IMPORTED_MODULE_0__.Collection(this,new Map([['viewport',_internal__WEBPACK_IMPORTED_MODULE_0__.Viewport]]));this._lastAppTime=Date.now();this._realDeltaTime=0;this._fps=new _internal__WEBPACK_IMPORTED_MODULE_0__.FPS();this._fpsLimit=Number.POSITIVE_INFINITY;this._time=0;this._timeRate=0;this._callbacks=[];this._callbacksToRemove=[];this._thisLoop=this._loop.bind(this);this._threeJsRenderer=null;this._viewportDiv=null;if(this._rootDiv.style.position!=='relative'&&this._rootDiv.style.position!=='absolute'){this._rootDiv.style.position='relative'} + this._rootDiv.style.userSelect='none';this._rootDiv.style.webkitUserSelect='none';this._rootDiv.style.touchAction='none';this._canvas=document.createElement('canvas');this._canvas.style.position='absolute';this._canvas.style.left='0px';this._canvas.style.top='0px';this._canvas.style.width='100%';this._canvas.style.height='100%';this._rootDiv.appendChild(this._canvas);this._viewportDiv=document.createElement('div');this._viewportDiv.style.position='absolute';this._viewportDiv.style.left='0px';this._viewportDiv.style.top='0px';this._viewportDiv.style.width='100%';this._viewportDiv.style.height='100%';this._viewportDiv.style.overflow='hidden';this._rootDiv.appendChild(this._viewportDiv);try{this._threeJsRenderer=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderer({canvas:this._canvas,antialias:!0});this._threeJsRenderer.setScissorTest(!0);this._threeJsRenderer.setPixelRatio(window.devicePixelRatio);this._textureLoader=new _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLoader(this._downloader,this._threeJsRenderer);this._textureLoaderCompressed=new _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLoaderCompressed(this._downloader,this._config,this._threeJsRenderer);_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Cache.enabled=!1;const origGetShaderInfoLog=this._threeJsRenderer.getContext().getShaderInfoLog.bind(this._threeJsRenderer.getContext());this._threeJsRenderer.getContext().getShaderInfoLog=(shader)=>{const t=origGetShaderInfoLog(shader);if(t.includes('GL_ARB_gpu_shader5')){return''}else{return t}};_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.__setContext(this._threeJsRenderer.getContext());this._materialManager=new _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialManager(this._downloader)}catch(error){console.log(error);throw error} + requestAnimationFrame(this._thisLoop)} + getVersion(){return _internal__WEBPACK_IMPORTED_MODULE_0__.Version} + getRootDiv(){return this._rootDiv} + getRenderSize(){return this._renderSize} + getCanvas(){return this._canvas} + getViewportDiv(){return this._viewportDiv} + getConfig(){return this._config} + getInput(){return this._input} + getDownloader(){return this._downloader} + getTextureLoader(){return this._textureLoader} + getTextureLoaderCompressed(){return this._textureLoaderCompressed} + getMaterialManager(){return this._materialManager} + getScene(nameOrIndex){return this._scenes.get(nameOrIndex)} + getNumScenes(){return this._scenes.size} + addScene(name){return this._scenes.add('scene',name)} + removeScene(sceneOrNameOrIndex){this._scenes.remove(sceneOrNameOrIndex)} + get(sceneNameOrIndex,entityNameOrIndex=undefined,componentOrControllerType=undefined,componentOrControllerTypeIndex=0){const scene=this._scenes.get(sceneNameOrIndex);if(entityNameOrIndex===undefined||scene===null){return scene} + return scene.get(entityNameOrIndex,componentOrControllerType,componentOrControllerTypeIndex)} + getViewport(nameOrIndex){return this._viewports.get(nameOrIndex)} + getNumViewports(){return this._viewports.size} + addViewport(name=''){return this._viewports.add('viewport',name)} + removeViewport(viewportOrNameOrIndex){this._viewports.remove(viewportOrNameOrIndex)} + getTime(){return this._time} + setTime(time){this._time=time} + getTimeRate(){return this._timeRate} + setTimeRate(timeRate){this._timeRate=timeRate} + getFPS(){return this._fps.getFPS()} + getFPSLimit(){return this._fpsLimit} + setFPSLimit(limit){this._fpsLimit=limit} + getDeltaTime(){return this._realDeltaTime} + isComponentTypeRegistered(type){return _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Components.has(type)} + registerComponentType(type,typeConstructor){if(_internal__WEBPACK_IMPORTED_MODULE_0__.Types.Components.has(type)){throw new Error('Already registered component type \''+type+'\'.')} + _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Components.set(type,typeConstructor)} + unregisterComponentType(type){_internal__WEBPACK_IMPORTED_MODULE_0__.Types.Components["delete"](type)} + isControllerTypeRegistered(type){return _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Controllers.has(type)} + registerControllerType(type,typeConstructor){if(_internal__WEBPACK_IMPORTED_MODULE_0__.Types.Controllers.has(type)){throw new Error('Already registered controller type \''+type+'\'.')} + _internal__WEBPACK_IMPORTED_MODULE_0__.Types.Controllers.set(type,typeConstructor)} + unregisterControllerType(type){_internal__WEBPACK_IMPORTED_MODULE_0__.Types.Controllers["delete"](type)} + waitUntilNextFrame(){return new Promise((resolve)=>{this.addCallback(()=>{resolve()},!1)})} + addCallback(callback,recurring){this._callbacks.push({callback:callback,recurring:recurring})} + removeCallback(callback){this._callbacksToRemove.push(callback)} + __getThreeJsRenderer(){return this._threeJsRenderer} + _loop(){try{const thisAppTime=Date.now();this._realDeltaTime=(thisAppTime-this._lastAppTime)/1000.0;if(this._realDeltaTime<1.0/this._fpsLimit){requestAnimationFrame(this._thisLoop);return} + this._lastAppTime=thisAppTime;this._fps.update(this._realDeltaTime);this._time+=this._timeRate*this._realDeltaTime;if(this._renderSize.x!==this._rootDiv.clientWidth||this._renderSize.y!==this._rootDiv.clientHeight){this._renderSize.thaw();this._renderSize.set(this._rootDiv.clientWidth,this._rootDiv.clientHeight);this._renderSize.freeze();this._threeJsRenderer.setSize(this._renderSize.x,this._renderSize.y,!1)} + for(let i=0;i{this._touches=[];this._keysPressed.clear();this._modifierKeysPressed.clear();this._shiftPressed=!1});window.addEventListener('keydown',event=>{if(event.target instanceof HTMLElement&&['INPUT','SELECT','TEXTAREA'].includes(event.target.tagName)){return} + if(event.key==='Shift'){this._shiftPressed=!0}else if(modifierKeys.has(event.key)){this._modifierKeysPressed.add(event.key.toLowerCase());this._keysPressed.clear();this._shiftPressed=!1}else if(this._modifierKeysPressed.size===0){this._keysPressed.add(event.key.toLowerCase())}});window.addEventListener('keyup',event=>{if(event.key==='Shift'){this._shiftPressed=!1}else if(modifierKeys.has(event.key)){this._modifierKeysPressed.delete(event.key.toLowerCase())}else{this._keysPressed.delete(event.key.toLowerCase())}});this._engine.getRootDiv().addEventListener('mousedown',event=>{if(event.button===0){if(document.activeElement instanceof HTMLElement){document.activeElement.blur()} + if(this._touches.length===0){const rootDivBounds=this._engine.getRootDiv().getBoundingClientRect();let touch=null;for(let j=0;j{const rootDivBounds=this._engine.getRootDiv().getBoundingClientRect();if(this._touches.length===1&&this._touches[0].identifier===0){const touch=this._touches[0];touch.thisFramePosition.set(event.clientX-rootDivBounds.left,event.clientY-rootDivBounds.top);this._draggedOffset.thaw();this._draggedOffset.sub(touch.thisFramePosition,touch.lastFramePosition);const pressedPositionDistance=Math.max(Math.abs(touch.thisFramePosition.x-touch.pressedPosition.x),Math.abs(touch.thisFramePosition.y-touch.pressedPosition.y));if((Date.now()-touch.pressedTime)/1000<=this._maxSelectTime&&pressedPositionDistance<=this._maxSelectDistance){this._draggedOffset.set(0,0)} + this._draggedOffset.freeze()} + if(this._touches.length<=1){this._cursorPosition.set(event.clientX-rootDivBounds.left,event.clientY-rootDivBounds.top)}});window.addEventListener('mouseup',event=>{if(event.button===0){if(this._touches.length===1&&this._touches[0].identifier===0){const rootDivBounds=this._engine.getRootDiv().getBoundingClientRect();const touch=this._touches[0];touch.thisFramePosition.set(event.clientX-rootDivBounds.left,event.clientY-rootDivBounds.top);const pressedPositionDistance=Math.max(Math.abs(touch.thisFramePosition.x-touch.pressedPosition.x),Math.abs(touch.thisFramePosition.y-touch.pressedPosition.y));if((Date.now()-touch.pressedTime)/1000<=this._maxSelectTime&&pressedPositionDistance<=this._maxSelectDistance){this._selected=!0;this._selectedPosition.thaw();this._selectedPosition.copy(touch.thisFramePosition);this._selectedPosition.freeze()} + this._touches.splice(0,1)}}});this._engine.getRootDiv().addEventListener('wheel',event=>{if(event.deltaY){this._zoomedOffset+=event.deltaY*0.1} + event.preventDefault()},{passive:!1});this._engine.getRootDiv().addEventListener('touchstart',event=>{const rootDivBounds=this._engine.getRootDiv().getBoundingClientRect();for(let i=0;i{const rootDivBounds=this._engine.getRootDiv().getBoundingClientRect();for(let i=0;i0.7){this._zoomedOffset+=-(dot-0.7)*touchOffset.magnitude()}else if(Math.abs(cross)>0.3){this._rotatedOffset+=cross*touchOffset.magnitude()} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(touchOffset);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(touchDiff);const pressedPositionDistance=Math.max(Math.abs(touch.thisFramePosition.x-touch.pressedPosition.x),Math.abs(touch.thisFramePosition.y-touch.pressedPosition.y));if((Date.now()-touch.pressedTime)/1000<=this._maxSelectTime&&pressedPositionDistance<=this._maxSelectDistance){this._zoomedOffset=0;this._rotatedOffset=0}}}}}});window.addEventListener('touchend',event=>{const rootDivBounds=this._engine.getRootDiv().getBoundingClientRect();for(let i=0;i{})} + getActiveViewport(){return this._activeViewport} + getDraggedOffset(){return this._draggedOffset} + getZoomedOffset(){return this._zoomedOffset} + getRotatedOffset(){return this._rotatedOffset} + isShiftPressed(){return this._shiftPressed} + isKeyPressed(key){return this._keysPressed.has(key)} + isSelected(){return this._selected} + getSelectedPosition(){return this._selectedPosition} + getCursorPosition(){return this._cursorPosition} + __setActiveViewport(viewport){this._activeViewport=viewport} + __resetStatesForNextFrame(){for(let i=0;i=0;i--){const pixelBounds=this._engine.getViewport(i).getBounds();if(this._engine.getViewport(i).isEnabled()&&pixelBounds.contains(this._touches[0].pressedPosition)){this._activeViewport=this._engine.getViewport(i);break}}}} + const modifierKeys=new Set(['Alt','AltGraph','CapsLock','Control','Fn','FnLock','Hyper','Meta','NumLock','ScrollLock','Shift','Super','Symbol','SymbolLock'])}),"../pioneer/engine/src/internal.js": + /*!*****************************************!*\ + !*** ../pioneer/engine/src/internal.js ***! + \*****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"THREE":function(){return three__WEBPACK_IMPORTED_MODULE_0__},"ThreeJsEffectComposer":function(){return three_examples_jsm_postprocessing_EffectComposer_js__WEBPACK_IMPORTED_MODULE_1__.EffectComposer},"ThreeJsGLTFLoader":function(){return three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_2__.GLTFLoader},"ThreeJsKTXLoader":function(){return three_examples_jsm_loaders_KTXLoader__WEBPACK_IMPORTED_MODULE_3__.KTXLoader},"ThreeJsOutlinePass":function(){return three_examples_jsm_postprocessing_OutlinePass_js__WEBPACK_IMPORTED_MODULE_4__.OutlinePass},"ThreeJsRenderPass":function(){return three_examples_jsm_postprocessing_RenderPass_js__WEBPACK_IMPORTED_MODULE_5__.RenderPass},"ThreeJsUnrealBloomPass":function(){return three_examples_jsm_postprocessing_UnrealBloomPass_js__WEBPACK_IMPORTED_MODULE_6__.UnrealBloomPass},"ShaderChunkLogDepth":function(){return _shaders_log_depth__WEBPACK_IMPORTED_MODULE_7__.ShaderChunkLogDepth},"BaseRef":function(){return _utils_base_ref__WEBPACK_IMPORTED_MODULE_8__.BaseRef},"Collection":function(){return _utils_collection__WEBPACK_IMPORTED_MODULE_9__.Collection},"CollectionItem":function(){return _utils_collection__WEBPACK_IMPORTED_MODULE_9__.CollectionItem},"DependencyGraph":function(){return _utils_dependency_graph__WEBPACK_IMPORTED_MODULE_10__.DependencyGraph},"FastIterable":function(){return _utils_fast_iterable__WEBPACK_IMPORTED_MODULE_11__.FastIterable},"FPS":function(){return _utils_fps__WEBPACK_IMPORTED_MODULE_12__.FPS},"Freezable":function(){return _utils_freezable__WEBPACK_IMPORTED_MODULE_13__.Freezable},"MathUtils":function(){return _utils_math_utils__WEBPACK_IMPORTED_MODULE_14__.MathUtils},"Pool":function(){return _utils_pool__WEBPACK_IMPORTED_MODULE_15__.Pool},"Reader":function(){return _utils_reader__WEBPACK_IMPORTED_MODULE_16__.Reader},"Sort":function(){return _utils_sort__WEBPACK_IMPORTED_MODULE_17__.Sort},"Tile":function(){return _utils_tile__WEBPACK_IMPORTED_MODULE_18__.Tile},"TimeUtils":function(){return _utils_time_utils__WEBPACK_IMPORTED_MODULE_19__.TimeUtils},"waitUntil":function(){return _utils_wait_until__WEBPACK_IMPORTED_MODULE_20__.waitUntil},"AER":function(){return _utils_aer__WEBPACK_IMPORTED_MODULE_21__.AER},"Color":function(){return _utils_color__WEBPACK_IMPORTED_MODULE_22__.Color},"FastMap":function(){return _utils_fast_map__WEBPACK_IMPORTED_MODULE_23__.FastMap},"FastMapEntry":function(){return _utils_fast_map__WEBPACK_IMPORTED_MODULE_23__.FastMapEntry},"FastSet":function(){return _utils_fast_set__WEBPACK_IMPORTED_MODULE_24__.FastSet},"Geometry":function(){return _utils_geometry__WEBPACK_IMPORTED_MODULE_25__.Geometry},"Interval":function(){return _utils_interval__WEBPACK_IMPORTED_MODULE_26__.Interval},"OrbitalElements":function(){return _utils_orbital_elements__WEBPACK_IMPORTED_MODULE_27__.OrbitalElements},"Rect":function(){return _utils_rect__WEBPACK_IMPORTED_MODULE_28__.Rect},"Quaternion":function(){return _utils_quaternion__WEBPACK_IMPORTED_MODULE_29__.Quaternion},"Vector2":function(){return _utils_vector2__WEBPACK_IMPORTED_MODULE_30__.Vector2},"Vector3":function(){return _utils_vector3__WEBPACK_IMPORTED_MODULE_31__.Vector3},"Cache":function(){return _utils_cache__WEBPACK_IMPORTED_MODULE_32__.Cache},"ComponentRef":function(){return _utils_component_ref__WEBPACK_IMPORTED_MODULE_33__.ComponentRef},"ControllerRef":function(){return _utils_controller_ref__WEBPACK_IMPORTED_MODULE_34__.ControllerRef},"CubeMap":function(){return _utils_cube_map__WEBPACK_IMPORTED_MODULE_35__.CubeMap},"EntityRef":function(){return _utils_entity_ref__WEBPACK_IMPORTED_MODULE_36__.EntityRef},"LatLonAlt":function(){return _utils_lat_lon_alt__WEBPACK_IMPORTED_MODULE_37__.LatLonAlt},"LineMesh":function(){return _utils_line_mesh__WEBPACK_IMPORTED_MODULE_38__.LineMesh},"MaterialUtilsPhong":function(){return _utils_material_utils_phong__WEBPACK_IMPORTED_MODULE_39__.MaterialUtilsPhong},"MaterialUtilsStandard":function(){return _utils_material_utils_standard__WEBPACK_IMPORTED_MODULE_40__.MaterialUtilsStandard},"MaterialUtils":function(){return _utils_material_utils__WEBPACK_IMPORTED_MODULE_41__.MaterialUtils},"ShaderFix":function(){return _utils_shader_fix__WEBPACK_IMPORTED_MODULE_42__.ShaderFix},"SpriteParticles":function(){return _utils_sprite_particles__WEBPACK_IMPORTED_MODULE_43__.SpriteParticles},"TextureLOD":function(){return _utils_texture_lod__WEBPACK_IMPORTED_MODULE_44__.TextureLOD},"ThreeJsHelper":function(){return _utils_three_js_helper__WEBPACK_IMPORTED_MODULE_45__.ThreeJsHelper},"Capabilities":function(){return _capabilities__WEBPACK_IMPORTED_MODULE_46__.Capabilities},"Config":function(){return _config__WEBPACK_IMPORTED_MODULE_47__.Config},"Download":function(){return _downloader__WEBPACK_IMPORTED_MODULE_48__.Download},"Downloader":function(){return _downloader__WEBPACK_IMPORTED_MODULE_48__.Downloader},"Engine":function(){return _engine__WEBPACK_IMPORTED_MODULE_49__.Engine},"Entity":function(){return _scene_entity__WEBPACK_IMPORTED_MODULE_50__.Entity},"EntityItem":function(){return _scene_entity_item__WEBPACK_IMPORTED_MODULE_51__.EntityItem},"Input":function(){return _input__WEBPACK_IMPORTED_MODULE_52__.Input},"MaterialManager":function(){return _material_manager__WEBPACK_IMPORTED_MODULE_53__.MaterialManager},"Scene":function(){return _scene_scene__WEBPACK_IMPORTED_MODULE_54__.Scene},"TextureLoader":function(){return _texture_loader__WEBPACK_IMPORTED_MODULE_55__.TextureLoader},"TextureLoaderCompressed":function(){return _texture_loader_compressed__WEBPACK_IMPORTED_MODULE_56__.TextureLoaderCompressed},"Version":function(){return _version__WEBPACK_IMPORTED_MODULE_57__.Version},"Viewport":function(){return _viewport__WEBPACK_IMPORTED_MODULE_58__.Viewport},"BaseComponent":function(){return _scene_components_base_component__WEBPACK_IMPORTED_MODULE_59__.BaseComponent},"AtmosphereComponent":function(){return _scene_components_atmosphere_component__WEBPACK_IMPORTED_MODULE_60__.AtmosphereComponent},"CameraComponent":function(){return _scene_components_camera_component__WEBPACK_IMPORTED_MODULE_61__.CameraComponent},"CMTSComponent":function(){return _scene_components_cmts_component__WEBPACK_IMPORTED_MODULE_62__.CMTSComponent},"CometTailComponent":function(){return _scene_components_comet_tail_component__WEBPACK_IMPORTED_MODULE_63__.CometTailComponent},"ConnectedSpriteComponent":function(){return _scene_components_connected_sprite_component__WEBPACK_IMPORTED_MODULE_64__.ConnectedSpriteComponent},"DivComponent":function(){return _scene_components_div_component__WEBPACK_IMPORTED_MODULE_65__.DivComponent},"DynamicEnvironmentMapComponent":function(){return _scene_components_dynamic_environment_map_component__WEBPACK_IMPORTED_MODULE_66__.DynamicEnvironmentMapComponent},"GizmoComponent":function(){return _scene_components_gizmo_component__WEBPACK_IMPORTED_MODULE_67__.GizmoComponent},"LabelComponent":function(){return _scene_components_label_component__WEBPACK_IMPORTED_MODULE_68__.LabelComponent},"LightSourceComponent":function(){return _scene_components_light_source_component__WEBPACK_IMPORTED_MODULE_69__.LightSourceComponent},"ModelComponent":function(){return _scene_components_model_component__WEBPACK_IMPORTED_MODULE_70__.ModelComponent},"OrbitalParticlesComponent":function(){return _scene_components_orbital_particles_component__WEBPACK_IMPORTED_MODULE_71__.OrbitalParticlesComponent},"ParticleSprayComponent":function(){return _scene_components_particle_spray_component__WEBPACK_IMPORTED_MODULE_72__.ParticleSprayComponent},"RingsComponent":function(){return _scene_components_rings_component__WEBPACK_IMPORTED_MODULE_73__.RingsComponent},"SkyboxComponent":function(){return _scene_components_skybox_component__WEBPACK_IMPORTED_MODULE_74__.SkyboxComponent},"SpheroidComponent":function(){return _scene_components_spheroid_component__WEBPACK_IMPORTED_MODULE_75__.SpheroidComponent},"SpheroidLODComponent":function(){return _scene_components_spheroid_lod_component__WEBPACK_IMPORTED_MODULE_76__.SpheroidLODComponent},"SpoutComponent":function(){return _scene_components_spout_component__WEBPACK_IMPORTED_MODULE_77__.SpoutComponent},"SpriteComponent":function(){return _scene_components_sprite_component__WEBPACK_IMPORTED_MODULE_78__.SpriteComponent},"StarfieldComponent":function(){return _scene_components_starfield_component__WEBPACK_IMPORTED_MODULE_79__.StarfieldComponent},"TrailComponent":function(){return _scene_components_trail_component__WEBPACK_IMPORTED_MODULE_80__.TrailComponent},"BaseController":function(){return _scene_controllers_base_controller__WEBPACK_IMPORTED_MODULE_81__.BaseController},"AlignController":function(){return _scene_controllers_align_controller__WEBPACK_IMPORTED_MODULE_82__.AlignController},"AnimdataController":function(){return _scene_controllers_animdata_controller__WEBPACK_IMPORTED_MODULE_83__.AnimdataController},"CoverageController":function(){return _scene_controllers_coverage_controller__WEBPACK_IMPORTED_MODULE_84__.CoverageController},"DynamoController":function(){return _scene_controllers_dynamo_controller__WEBPACK_IMPORTED_MODULE_85__.DynamoController},"FixedController":function(){return _scene_controllers_fixed_controller__WEBPACK_IMPORTED_MODULE_86__.FixedController},"FixedToParentController":function(){return _scene_controllers_fixed_to_parent_controller__WEBPACK_IMPORTED_MODULE_87__.FixedToParentController},"FreeFlyController":function(){return _scene_controllers_free_fly_controller__WEBPACK_IMPORTED_MODULE_88__.FreeFlyController},"GroundClampController":function(){return _scene_controllers_ground_clamp_controller__WEBPACK_IMPORTED_MODULE_89__.GroundClampController},"KeyframeController":function(){return _scene_controllers_keyframe_controller__WEBPACK_IMPORTED_MODULE_90__.KeyframeController},"LookController":function(){return _scene_controllers_look_controller__WEBPACK_IMPORTED_MODULE_91__.LookController},"ModelAnimateController":function(){return _scene_controllers_model_animate_controller__WEBPACK_IMPORTED_MODULE_92__.ModelAnimateController},"OrbitController":function(){return _scene_controllers_orbit_controller__WEBPACK_IMPORTED_MODULE_93__.OrbitController},"OrbitKeyframeController":function(){return _scene_controllers_orbit_keyframe_controller__WEBPACK_IMPORTED_MODULE_94__.OrbitKeyframeController},"OrbitalElementsController":function(){return _scene_controllers_orbital_elements_controller__WEBPACK_IMPORTED_MODULE_95__.OrbitalElementsController},"OrbitalElementsKeyFrame":function(){return _scene_controllers_orbital_elements_controller__WEBPACK_IMPORTED_MODULE_95__.OrbitalElementsKeyFrame},"PickController":function(){return _scene_controllers_pick_controller__WEBPACK_IMPORTED_MODULE_96__.PickController},"RollController":function(){return _scene_controllers_roll_controller__WEBPACK_IMPORTED_MODULE_97__.RollController},"RotateController":function(){return _scene_controllers_rotate_controller__WEBPACK_IMPORTED_MODULE_98__.RotateController},"RotateByEntityOrientationController":function(){return _scene_controllers_rotate_by_entity_orientation_controller__WEBPACK_IMPORTED_MODULE_99__.RotateByEntityOrientationController},"ScaleController":function(){return _scene_controllers_scale_controller__WEBPACK_IMPORTED_MODULE_100__.ScaleController},"SelectController":function(){return _scene_controllers_select_controller__WEBPACK_IMPORTED_MODULE_101__.SelectController},"SetParentController":function(){return _scene_controllers_set_parent_controller__WEBPACK_IMPORTED_MODULE_102__.SetParentController},"SpinController":function(){return _scene_controllers_spin_controller__WEBPACK_IMPORTED_MODULE_103__.SpinController},"TapController":function(){return _scene_controllers_tap_controller__WEBPACK_IMPORTED_MODULE_104__.TapController},"TransitionController":function(){return _scene_controllers_transition_controller__WEBPACK_IMPORTED_MODULE_105__.TransitionController},"TranslateController":function(){return _scene_controllers_translate_controller__WEBPACK_IMPORTED_MODULE_106__.TranslateController},"ZoomController":function(){return _scene_controllers_zoom_controller__WEBPACK_IMPORTED_MODULE_107__.ZoomController},"Types":function(){return _scene_types__WEBPACK_IMPORTED_MODULE_108__.Types}});var three__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! three */"../pioneer/engine/node_modules/three/build/three.module.js");var three_examples_jsm_postprocessing_EffectComposer_js__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! three/examples/jsm/postprocessing/EffectComposer.js */"../pioneer/engine/node_modules/three/examples/jsm/postprocessing/EffectComposer.js");var three_examples_jsm_loaders_GLTFLoader__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! three/examples/jsm/loaders/GLTFLoader */"../pioneer/engine/node_modules/three/examples/jsm/loaders/GLTFLoader.js");var three_examples_jsm_loaders_KTXLoader__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! three/examples/jsm/loaders/KTXLoader */"../pioneer/engine/node_modules/three/examples/jsm/loaders/KTXLoader.js");var three_examples_jsm_postprocessing_OutlinePass_js__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! three/examples/jsm/postprocessing/OutlinePass.js */"../pioneer/engine/node_modules/three/examples/jsm/postprocessing/OutlinePass.js");var three_examples_jsm_postprocessing_RenderPass_js__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(/*! three/examples/jsm/postprocessing/RenderPass.js */"../pioneer/engine/node_modules/three/examples/jsm/postprocessing/RenderPass.js");var three_examples_jsm_postprocessing_UnrealBloomPass_js__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(/*! three/examples/jsm/postprocessing/UnrealBloomPass.js */"../pioneer/engine/node_modules/three/examples/jsm/postprocessing/UnrealBloomPass.js");var _shaders_log_depth__WEBPACK_IMPORTED_MODULE_7__=__webpack_require__(/*! ./shaders/log_depth */"../pioneer/engine/src/shaders/log_depth.js");var _utils_base_ref__WEBPACK_IMPORTED_MODULE_8__=__webpack_require__(/*! ./utils/base_ref */"../pioneer/engine/src/utils/base_ref.js");var _utils_collection__WEBPACK_IMPORTED_MODULE_9__=__webpack_require__(/*! ./utils/collection */"../pioneer/engine/src/utils/collection.js");var _utils_dependency_graph__WEBPACK_IMPORTED_MODULE_10__=__webpack_require__(/*! ./utils/dependency_graph */"../pioneer/engine/src/utils/dependency_graph.js");var _utils_fast_iterable__WEBPACK_IMPORTED_MODULE_11__=__webpack_require__(/*! ./utils/fast_iterable */"../pioneer/engine/src/utils/fast_iterable.js");var _utils_fps__WEBPACK_IMPORTED_MODULE_12__=__webpack_require__(/*! ./utils/fps */"../pioneer/engine/src/utils/fps.js");var _utils_freezable__WEBPACK_IMPORTED_MODULE_13__=__webpack_require__(/*! ./utils/freezable */"../pioneer/engine/src/utils/freezable.js");var _utils_math_utils__WEBPACK_IMPORTED_MODULE_14__=__webpack_require__(/*! ./utils/math_utils */"../pioneer/engine/src/utils/math_utils.js");var _utils_pool__WEBPACK_IMPORTED_MODULE_15__=__webpack_require__(/*! ./utils/pool */"../pioneer/engine/src/utils/pool.js");var _utils_reader__WEBPACK_IMPORTED_MODULE_16__=__webpack_require__(/*! ./utils/reader */"../pioneer/engine/src/utils/reader.js");var _utils_sort__WEBPACK_IMPORTED_MODULE_17__=__webpack_require__(/*! ./utils/sort */"../pioneer/engine/src/utils/sort.js");var _utils_tile__WEBPACK_IMPORTED_MODULE_18__=__webpack_require__(/*! ./utils/tile */"../pioneer/engine/src/utils/tile.js");var _utils_time_utils__WEBPACK_IMPORTED_MODULE_19__=__webpack_require__(/*! ./utils/time_utils */"../pioneer/engine/src/utils/time_utils.js");var _utils_wait_until__WEBPACK_IMPORTED_MODULE_20__=__webpack_require__(/*! ./utils/wait_until */"../pioneer/engine/src/utils/wait_until.js");var _utils_aer__WEBPACK_IMPORTED_MODULE_21__=__webpack_require__(/*! ./utils/aer */"../pioneer/engine/src/utils/aer.js");var _utils_color__WEBPACK_IMPORTED_MODULE_22__=__webpack_require__(/*! ./utils/color */"../pioneer/engine/src/utils/color.js");var _utils_fast_map__WEBPACK_IMPORTED_MODULE_23__=__webpack_require__(/*! ./utils/fast_map */"../pioneer/engine/src/utils/fast_map.js");var _utils_fast_set__WEBPACK_IMPORTED_MODULE_24__=__webpack_require__(/*! ./utils/fast_set */"../pioneer/engine/src/utils/fast_set.js");var _utils_geometry__WEBPACK_IMPORTED_MODULE_25__=__webpack_require__(/*! ./utils/geometry */"../pioneer/engine/src/utils/geometry.js");var _utils_interval__WEBPACK_IMPORTED_MODULE_26__=__webpack_require__(/*! ./utils/interval */"../pioneer/engine/src/utils/interval.js");var _utils_orbital_elements__WEBPACK_IMPORTED_MODULE_27__=__webpack_require__(/*! ./utils/orbital_elements */"../pioneer/engine/src/utils/orbital_elements.js");var _utils_rect__WEBPACK_IMPORTED_MODULE_28__=__webpack_require__(/*! ./utils/rect */"../pioneer/engine/src/utils/rect.js");var _utils_quaternion__WEBPACK_IMPORTED_MODULE_29__=__webpack_require__(/*! ./utils/quaternion */"../pioneer/engine/src/utils/quaternion.js");var _utils_vector2__WEBPACK_IMPORTED_MODULE_30__=__webpack_require__(/*! ./utils/vector2 */"../pioneer/engine/src/utils/vector2.js");var _utils_vector3__WEBPACK_IMPORTED_MODULE_31__=__webpack_require__(/*! ./utils/vector3 */"../pioneer/engine/src/utils/vector3.js");var _utils_cache__WEBPACK_IMPORTED_MODULE_32__=__webpack_require__(/*! ./utils/cache */"../pioneer/engine/src/utils/cache.js");var _utils_component_ref__WEBPACK_IMPORTED_MODULE_33__=__webpack_require__(/*! ./utils/component_ref */"../pioneer/engine/src/utils/component_ref.js");var _utils_controller_ref__WEBPACK_IMPORTED_MODULE_34__=__webpack_require__(/*! ./utils/controller_ref */"../pioneer/engine/src/utils/controller_ref.js");var _utils_cube_map__WEBPACK_IMPORTED_MODULE_35__=__webpack_require__(/*! ./utils/cube_map */"../pioneer/engine/src/utils/cube_map.js");var _utils_entity_ref__WEBPACK_IMPORTED_MODULE_36__=__webpack_require__(/*! ./utils/entity_ref */"../pioneer/engine/src/utils/entity_ref.js");var _utils_lat_lon_alt__WEBPACK_IMPORTED_MODULE_37__=__webpack_require__(/*! ./utils/lat_lon_alt */"../pioneer/engine/src/utils/lat_lon_alt.js");var _utils_line_mesh__WEBPACK_IMPORTED_MODULE_38__=__webpack_require__(/*! ./utils/line_mesh */"../pioneer/engine/src/utils/line_mesh.js");var _utils_material_utils_phong__WEBPACK_IMPORTED_MODULE_39__=__webpack_require__(/*! ./utils/material_utils_phong */"../pioneer/engine/src/utils/material_utils_phong.js");var _utils_material_utils_standard__WEBPACK_IMPORTED_MODULE_40__=__webpack_require__(/*! ./utils/material_utils_standard */"../pioneer/engine/src/utils/material_utils_standard.js");var _utils_material_utils__WEBPACK_IMPORTED_MODULE_41__=__webpack_require__(/*! ./utils/material_utils */"../pioneer/engine/src/utils/material_utils.js");var _utils_shader_fix__WEBPACK_IMPORTED_MODULE_42__=__webpack_require__(/*! ./utils/shader_fix */"../pioneer/engine/src/utils/shader_fix.js");var _utils_sprite_particles__WEBPACK_IMPORTED_MODULE_43__=__webpack_require__(/*! ./utils/sprite_particles */"../pioneer/engine/src/utils/sprite_particles.js");var _utils_texture_lod__WEBPACK_IMPORTED_MODULE_44__=__webpack_require__(/*! ./utils/texture_lod */"../pioneer/engine/src/utils/texture_lod.js");var _utils_three_js_helper__WEBPACK_IMPORTED_MODULE_45__=__webpack_require__(/*! ./utils/three_js_helper */"../pioneer/engine/src/utils/three_js_helper.js");var _capabilities__WEBPACK_IMPORTED_MODULE_46__=__webpack_require__(/*! ./capabilities */"../pioneer/engine/src/capabilities.js");var _config__WEBPACK_IMPORTED_MODULE_47__=__webpack_require__(/*! ./config */"../pioneer/engine/src/config.js");var _downloader__WEBPACK_IMPORTED_MODULE_48__=__webpack_require__(/*! ./downloader */"../pioneer/engine/src/downloader.js");var _engine__WEBPACK_IMPORTED_MODULE_49__=__webpack_require__(/*! ./engine */"../pioneer/engine/src/engine.js");var _scene_entity__WEBPACK_IMPORTED_MODULE_50__=__webpack_require__(/*! ./scene/entity */"../pioneer/engine/src/scene/entity.js");var _scene_entity_item__WEBPACK_IMPORTED_MODULE_51__=__webpack_require__(/*! ./scene/entity_item */"../pioneer/engine/src/scene/entity_item.js");var _input__WEBPACK_IMPORTED_MODULE_52__=__webpack_require__(/*! ./input */"../pioneer/engine/src/input.js");var _material_manager__WEBPACK_IMPORTED_MODULE_53__=__webpack_require__(/*! ./material_manager */"../pioneer/engine/src/material_manager.js");var _scene_scene__WEBPACK_IMPORTED_MODULE_54__=__webpack_require__(/*! ./scene/scene */"../pioneer/engine/src/scene/scene.js");var _texture_loader__WEBPACK_IMPORTED_MODULE_55__=__webpack_require__(/*! ./texture_loader */"../pioneer/engine/src/texture_loader.js");var _texture_loader_compressed__WEBPACK_IMPORTED_MODULE_56__=__webpack_require__(/*! ./texture_loader_compressed */"../pioneer/engine/src/texture_loader_compressed.js");var _version__WEBPACK_IMPORTED_MODULE_57__=__webpack_require__(/*! ./version */"../pioneer/engine/src/version.js");var _viewport__WEBPACK_IMPORTED_MODULE_58__=__webpack_require__(/*! ./viewport */"../pioneer/engine/src/viewport.js");var _scene_components_base_component__WEBPACK_IMPORTED_MODULE_59__=__webpack_require__(/*! ./scene/components/base_component */"../pioneer/engine/src/scene/components/base_component.js");var _scene_components_atmosphere_component__WEBPACK_IMPORTED_MODULE_60__=__webpack_require__(/*! ./scene/components/atmosphere_component */"../pioneer/engine/src/scene/components/atmosphere_component.js");var _scene_components_camera_component__WEBPACK_IMPORTED_MODULE_61__=__webpack_require__(/*! ./scene/components/camera_component */"../pioneer/engine/src/scene/components/camera_component.js");var _scene_components_cmts_component__WEBPACK_IMPORTED_MODULE_62__=__webpack_require__(/*! ./scene/components/cmts_component */"../pioneer/engine/src/scene/components/cmts_component.js");var _scene_components_comet_tail_component__WEBPACK_IMPORTED_MODULE_63__=__webpack_require__(/*! ./scene/components/comet_tail_component */"../pioneer/engine/src/scene/components/comet_tail_component.js");var _scene_components_connected_sprite_component__WEBPACK_IMPORTED_MODULE_64__=__webpack_require__(/*! ./scene/components/connected_sprite_component */"../pioneer/engine/src/scene/components/connected_sprite_component.js");var _scene_components_div_component__WEBPACK_IMPORTED_MODULE_65__=__webpack_require__(/*! ./scene/components/div_component */"../pioneer/engine/src/scene/components/div_component.js");var _scene_components_dynamic_environment_map_component__WEBPACK_IMPORTED_MODULE_66__=__webpack_require__(/*! ./scene/components/dynamic_environment_map_component */"../pioneer/engine/src/scene/components/dynamic_environment_map_component.js");var _scene_components_gizmo_component__WEBPACK_IMPORTED_MODULE_67__=__webpack_require__(/*! ./scene/components/gizmo_component */"../pioneer/engine/src/scene/components/gizmo_component.js");var _scene_components_label_component__WEBPACK_IMPORTED_MODULE_68__=__webpack_require__(/*! ./scene/components/label_component */"../pioneer/engine/src/scene/components/label_component.js");var _scene_components_light_source_component__WEBPACK_IMPORTED_MODULE_69__=__webpack_require__(/*! ./scene/components/light_source_component */"../pioneer/engine/src/scene/components/light_source_component.js");var _scene_components_model_component__WEBPACK_IMPORTED_MODULE_70__=__webpack_require__(/*! ./scene/components/model_component */"../pioneer/engine/src/scene/components/model_component.js");var _scene_components_orbital_particles_component__WEBPACK_IMPORTED_MODULE_71__=__webpack_require__(/*! ./scene/components/orbital_particles_component */"../pioneer/engine/src/scene/components/orbital_particles_component.js");var _scene_components_particle_spray_component__WEBPACK_IMPORTED_MODULE_72__=__webpack_require__(/*! ./scene/components/particle_spray_component */"../pioneer/engine/src/scene/components/particle_spray_component.js");var _scene_components_rings_component__WEBPACK_IMPORTED_MODULE_73__=__webpack_require__(/*! ./scene/components/rings_component */"../pioneer/engine/src/scene/components/rings_component.js");var _scene_components_skybox_component__WEBPACK_IMPORTED_MODULE_74__=__webpack_require__(/*! ./scene/components/skybox_component */"../pioneer/engine/src/scene/components/skybox_component.js");var _scene_components_spheroid_component__WEBPACK_IMPORTED_MODULE_75__=__webpack_require__(/*! ./scene/components/spheroid_component */"../pioneer/engine/src/scene/components/spheroid_component.js");var _scene_components_spheroid_lod_component__WEBPACK_IMPORTED_MODULE_76__=__webpack_require__(/*! ./scene/components/spheroid_lod_component */"../pioneer/engine/src/scene/components/spheroid_lod_component.js");var _scene_components_spout_component__WEBPACK_IMPORTED_MODULE_77__=__webpack_require__(/*! ./scene/components/spout_component */"../pioneer/engine/src/scene/components/spout_component.js");var _scene_components_sprite_component__WEBPACK_IMPORTED_MODULE_78__=__webpack_require__(/*! ./scene/components/sprite_component */"../pioneer/engine/src/scene/components/sprite_component.js");var _scene_components_starfield_component__WEBPACK_IMPORTED_MODULE_79__=__webpack_require__(/*! ./scene/components/starfield_component */"../pioneer/engine/src/scene/components/starfield_component.js");var _scene_components_trail_component__WEBPACK_IMPORTED_MODULE_80__=__webpack_require__(/*! ./scene/components/trail_component */"../pioneer/engine/src/scene/components/trail_component.js");var _scene_controllers_base_controller__WEBPACK_IMPORTED_MODULE_81__=__webpack_require__(/*! ./scene/controllers/base_controller */"../pioneer/engine/src/scene/controllers/base_controller.js");var _scene_controllers_align_controller__WEBPACK_IMPORTED_MODULE_82__=__webpack_require__(/*! ./scene/controllers/align_controller */"../pioneer/engine/src/scene/controllers/align_controller.js");var _scene_controllers_animdata_controller__WEBPACK_IMPORTED_MODULE_83__=__webpack_require__(/*! ./scene/controllers/animdata_controller */"../pioneer/engine/src/scene/controllers/animdata_controller.js");var _scene_controllers_coverage_controller__WEBPACK_IMPORTED_MODULE_84__=__webpack_require__(/*! ./scene/controllers/coverage_controller */"../pioneer/engine/src/scene/controllers/coverage_controller.js");var _scene_controllers_dynamo_controller__WEBPACK_IMPORTED_MODULE_85__=__webpack_require__(/*! ./scene/controllers/dynamo_controller */"../pioneer/engine/src/scene/controllers/dynamo_controller.js");var _scene_controllers_fixed_controller__WEBPACK_IMPORTED_MODULE_86__=__webpack_require__(/*! ./scene/controllers/fixed_controller */"../pioneer/engine/src/scene/controllers/fixed_controller.js");var _scene_controllers_fixed_to_parent_controller__WEBPACK_IMPORTED_MODULE_87__=__webpack_require__(/*! ./scene/controllers/fixed_to_parent_controller */"../pioneer/engine/src/scene/controllers/fixed_to_parent_controller.js");var _scene_controllers_free_fly_controller__WEBPACK_IMPORTED_MODULE_88__=__webpack_require__(/*! ./scene/controllers/free_fly_controller */"../pioneer/engine/src/scene/controllers/free_fly_controller.js");var _scene_controllers_ground_clamp_controller__WEBPACK_IMPORTED_MODULE_89__=__webpack_require__(/*! ./scene/controllers/ground_clamp_controller */"../pioneer/engine/src/scene/controllers/ground_clamp_controller.js");var _scene_controllers_keyframe_controller__WEBPACK_IMPORTED_MODULE_90__=__webpack_require__(/*! ./scene/controllers/keyframe_controller */"../pioneer/engine/src/scene/controllers/keyframe_controller.js");var _scene_controllers_look_controller__WEBPACK_IMPORTED_MODULE_91__=__webpack_require__(/*! ./scene/controllers/look_controller */"../pioneer/engine/src/scene/controllers/look_controller.js");var _scene_controllers_model_animate_controller__WEBPACK_IMPORTED_MODULE_92__=__webpack_require__(/*! ./scene/controllers/model_animate_controller */"../pioneer/engine/src/scene/controllers/model_animate_controller.js");var _scene_controllers_orbit_controller__WEBPACK_IMPORTED_MODULE_93__=__webpack_require__(/*! ./scene/controllers/orbit_controller */"../pioneer/engine/src/scene/controllers/orbit_controller.js");var _scene_controllers_orbit_keyframe_controller__WEBPACK_IMPORTED_MODULE_94__=__webpack_require__(/*! ./scene/controllers/orbit_keyframe_controller */"../pioneer/engine/src/scene/controllers/orbit_keyframe_controller.js");var _scene_controllers_orbital_elements_controller__WEBPACK_IMPORTED_MODULE_95__=__webpack_require__(/*! ./scene/controllers/orbital_elements_controller */"../pioneer/engine/src/scene/controllers/orbital_elements_controller.js");var _scene_controllers_pick_controller__WEBPACK_IMPORTED_MODULE_96__=__webpack_require__(/*! ./scene/controllers/pick_controller */"../pioneer/engine/src/scene/controllers/pick_controller.js");var _scene_controllers_roll_controller__WEBPACK_IMPORTED_MODULE_97__=__webpack_require__(/*! ./scene/controllers/roll_controller */"../pioneer/engine/src/scene/controllers/roll_controller.js");var _scene_controllers_rotate_controller__WEBPACK_IMPORTED_MODULE_98__=__webpack_require__(/*! ./scene/controllers/rotate_controller */"../pioneer/engine/src/scene/controllers/rotate_controller.js");var _scene_controllers_rotate_by_entity_orientation_controller__WEBPACK_IMPORTED_MODULE_99__=__webpack_require__(/*! ./scene/controllers/rotate_by_entity_orientation_controller */"../pioneer/engine/src/scene/controllers/rotate_by_entity_orientation_controller.js");var _scene_controllers_scale_controller__WEBPACK_IMPORTED_MODULE_100__=__webpack_require__(/*! ./scene/controllers/scale_controller */"../pioneer/engine/src/scene/controllers/scale_controller.js");var _scene_controllers_select_controller__WEBPACK_IMPORTED_MODULE_101__=__webpack_require__(/*! ./scene/controllers/select_controller */"../pioneer/engine/src/scene/controllers/select_controller.js");var _scene_controllers_set_parent_controller__WEBPACK_IMPORTED_MODULE_102__=__webpack_require__(/*! ./scene/controllers/set_parent_controller */"../pioneer/engine/src/scene/controllers/set_parent_controller.js");var _scene_controllers_spin_controller__WEBPACK_IMPORTED_MODULE_103__=__webpack_require__(/*! ./scene/controllers/spin_controller */"../pioneer/engine/src/scene/controllers/spin_controller.js");var _scene_controllers_tap_controller__WEBPACK_IMPORTED_MODULE_104__=__webpack_require__(/*! ./scene/controllers/tap_controller */"../pioneer/engine/src/scene/controllers/tap_controller.js");var _scene_controllers_transition_controller__WEBPACK_IMPORTED_MODULE_105__=__webpack_require__(/*! ./scene/controllers/transition_controller */"../pioneer/engine/src/scene/controllers/transition_controller.js");var _scene_controllers_translate_controller__WEBPACK_IMPORTED_MODULE_106__=__webpack_require__(/*! ./scene/controllers/translate_controller */"../pioneer/engine/src/scene/controllers/translate_controller.js");var _scene_controllers_zoom_controller__WEBPACK_IMPORTED_MODULE_107__=__webpack_require__(/*! ./scene/controllers/zoom_controller */"../pioneer/engine/src/scene/controllers/zoom_controller.js");var _scene_types__WEBPACK_IMPORTED_MODULE_108__=__webpack_require__(/*! ./scene/types */"../pioneer/engine/src/scene/types.js")}),"../pioneer/engine/src/material_manager.js": + /*!*************************************************!*\ + !*** ../pioneer/engine/src/material_manager.js ***! + \*************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"MaterialManager":function(){return MaterialManager}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./internal */"../pioneer/engine/src/internal.js");var _shaders_basic__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./shaders/basic */"../pioneer/engine/src/shaders/basic.js");var _shaders_basic_alpha__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./shaders/basic_alpha */"../pioneer/engine/src/shaders/basic_alpha.js");var _shaders_connected_sprite__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ./shaders/connected_sprite */"../pioneer/engine/src/shaders/connected_sprite.js");var _shaders_line__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! ./shaders/line */"../pioneer/engine/src/shaders/line.js");var _shaders_plumes__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(/*! ./shaders/plumes */"../pioneer/engine/src/shaders/plumes.js");var _shaders_sprite__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(/*! ./shaders/sprite */"../pioneer/engine/src/shaders/sprite.js");var _shaders_sprite_particles__WEBPACK_IMPORTED_MODULE_7__=__webpack_require__(/*! ./shaders/sprite_particles */"../pioneer/engine/src/shaders/sprite_particles.js");var _shaders_trail__WEBPACK_IMPORTED_MODULE_8__=__webpack_require__(/*! ./shaders/trail */"../pioneer/engine/src/shaders/trail.js");class Resource{constructor(value){this.value=value;this.useCount=0}} + class MaterialManager{constructor(downloader){this._downloader=downloader;this._cache=new Map();this._clonedMaterials=new Map();this._promises=new Map();this._preload()} + async get(url){let resource=this._cache.get(url);if(resource===undefined){const promise=this._promises.get(url);if(promise!==undefined){resource=await promise}} + if(resource===undefined){const download=await this._downloader.download(url,!1);if(download.status!=='completed'||typeof download.content!=='string'){throw new Error('Failed to download material "'+url+'".')} + const obj=JSON.parse(download.content);resource=new Resource(await this._load(url,obj));this._cache.set(url,resource)} + resource.useCount+=1;return this._clone(resource.value,url)} + getPreloaded(url){const resource=this._cache.get(url);if(resource===undefined){throw new Error('Invalid pre-loaded material "'+url+'".')} + resource.useCount+=1;return this._clone(resource.value,url)} + release(material){const url=this._clonedMaterials.get(material);if(url===undefined){return} + this._clonedMaterials.delete(material);const resource=this._cache.get(url);if(resource){resource.useCount-=1;if(resource.useCount===0){this._unload(resource.value);this._cache.delete(url)}}} + _unload(material){const uniforms=material.uniforms;for(const uniform in uniforms){if(Object.prototype.hasOwnProperty.call(uniforms,uniform)&&uniforms[uniform].value!==null&&uniforms[uniform].value.dispose!==undefined){uniforms[uniform].value.dispose()}} + material.dispose()} + _preload(){const shaders=new Map();shaders.set('basic',_shaders_basic__WEBPACK_IMPORTED_MODULE_1__.BasicShader);shaders.set('basic_alpha',_shaders_basic_alpha__WEBPACK_IMPORTED_MODULE_2__.BasicAlphaShader);shaders.set('connected_sprite',_shaders_connected_sprite__WEBPACK_IMPORTED_MODULE_3__.ConnectedSpriteShader);shaders.set('line',_shaders_line__WEBPACK_IMPORTED_MODULE_4__.LineShader);shaders.set('plumes',_shaders_plumes__WEBPACK_IMPORTED_MODULE_5__.PlumesShader);shaders.set('sprite',_shaders_sprite__WEBPACK_IMPORTED_MODULE_6__.SpriteShader);shaders.set('sprite_particles',_shaders_sprite_particles__WEBPACK_IMPORTED_MODULE_7__.SpriteParticlesShader);shaders.set('trail',_shaders_trail__WEBPACK_IMPORTED_MODULE_8__.TrailShader);for(const[name,json]of shaders){const material=this._load(name,json);const resource=new Resource(material);resource.useCount+=1;this._cache.set(name,resource)}} + _load(url,json){try{const uniforms={};if(json.uniforms){for(const[name,type]of Object.entries(json.uniforms)){if(['modelMatrix','modelViewMatrix','projectionMatrix','viewMatrix','normalMatrix','cameraPosition'].includes(name)){continue} + uniforms[name]=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._getUniformValueFromType(type))}} + let transparent=!1;let depthWrite=!0;let side=(_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.FrontSide);let blending=(_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NoBlending);if(json.properties){if(json.properties.transparent===!0){transparent=!0} + if(json.properties.depthWrite===!1){depthWrite=!1} + switch(json.properties.side){case 'front':side=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.FrontSide;break;case 'back':side=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BackSide;break;case 'double':side=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide;break} + switch(json.properties.blending){case 'normal':blending=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NormalBlending;break;case 'additive':blending=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.AdditiveBlending;break;case 'subtractive':blending=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.SubtractiveBlending;break;case 'multiply':blending=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.MultiplyBlending;break;case 'custom':blending=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CustomBlending;break}} + if(typeof json.vertex!=='object'||typeof json.vertex.code!=='string'){throw new Error('Missing vertex stage code.')} + if(typeof json.fragment!=='object'||typeof json.fragment.code!=='string'){throw new Error('Missing fragment stage code.')} + if(Array.isArray(json.vertex.extensions)){let extensionCode='';for(const extension of json.vertex.extensions){if(_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasGLExtension(extension)){extensionCode+='#extension GL_'+extension+': enable\n'}} + for(const extension of json.vertex.extensions){if(_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasGLExtension(extension)){extensionCode+='#define L_'+extension+' true\n'} + if(_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.isWebGL2()&&extension==='EXT_frag_depth'){extensionCode+='#define L_'+extension+' true\n'}} + json.vertex.code=extensionCode+json.vertex.code} + if(Array.isArray(json.fragment.extensions)){let extensionCode='';for(const extension of json.fragment.extensions){if(_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasGLExtension(extension)){extensionCode+='#extension GL_'+extension+': enable\n'}} + for(const extension of json.fragment.extensions){if(_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasGLExtension(extension)){extensionCode+='#define L_'+extension+' true\n'}} + json.fragment.code=extensionCode+json.fragment.code} + const material=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RawShaderMaterial({uniforms,vertexShader:json.vertex.code,fragmentShader:json.fragment.code,transparent:transparent,depthWrite:depthWrite,side:side,blending:blending,glslVersion:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.GLSL3});_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderFix.fix(material);material.needsUpdate=!0;return material}catch(e){if(e instanceof Error){e.message=`While processing material "${url}": ${e.message}`} + throw e}} + _getUniformValueFromType(type){type=type.replace(/.* /,'');switch(type){case 'int':case 'float':return 0;case 'ivec2':case 'vec2':return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(0,0);case 'ivec3':case 'vec3':return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0,0,0);case 'ivec4':case 'vec4':return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4(0,0,0,0);case 'mat3':return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix3();case 'mat4':return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix4();case 'sampler2D':return null;case 'samplerCube':return null} + if(type.endsWith(']')){const indexOfOpenBracket=type.indexOf('[');const indexOfCloseBracket=type.indexOf(']');const baseType=type.substring(0,indexOfOpenBracket);const numElements=Number.parseInt(type.substring(indexOfOpenBracket+1,indexOfCloseBracket));const array=[];for(let i=0;i 1.0) { + float f = (maxColor - 1.0) / maxColor; + color.r = min(1.0, pow(color.r / maxColor, 1.0 / maxColor)); + color.g = min(1.0, pow(color.g / maxColor, 1.0 / maxColor)); + color.b = min(1.0, pow(color.b / maxColor, 1.0 / maxColor)); + } + return color; + } + + // Calculates a glow around the light direction (the star). + float glow(float spread, float amount, float lightDotCamera) { + return amount * spread / (1.0 + spread - lightDotCamera); + } + + vec4 getEmissiveColor(float totalDensity, vec3 cameraPositionS, vec3 color, float emissivity) { + + // The color that will be added onto gl_FragColor. + vec4 outColor; + + // Apply the total density to the transparency of the atmosphere. + outColor.a = emissivity * clamp(totalDensity, 0.0, 1.0); + + // Multiply it all together with the source light color. + outColor.rgb = emissivity * color * clamp(pow(15.0 * totalDensity / (density * equatorialRadius), 0.2), 0.75, 1.0); + + // Make it more opaque when lower down. + outColor.a = mix(outColor.a, emissivity, getDensity(cameraPositionS, equatorialRadius + scaleHeight, 1.0, 2.0 * scaleHeight)); + + // Clamp it to make it clean for the day/night transition. + outColor.a = clamp(outColor.a, 0.0, 1.0); + + return outColor; + } + + // Gets the color for an atmosphere for a light. + vec4 getColor(float totalDensity, vec3 lightColor, vec3 lightPosition, float spheroidRatio, vec3 positionS, vec3 cameraPositionS, vec3 cameraToPositionUnit) { + + // The color starts out in full brightness (as if emissivity was 1.0). + vec4 outColor = getEmissiveColor(totalDensity, cameraPositionS, lightColor * color, 1.0); + + // Make the alpha dependent on the brightness of the light. + outColor.a *= length(lightColor) / sqrt(3.0); + + // Setup vectors. + highp vec3 lightPositionS = quatRotInv(entityOrientation, lightPosition); + lightPositionS.z *= spheroidRatio; + highp vec3 lightToPosition = positionS - lightPositionS; + highp vec3 lightToPositionUnit = normalize(lightToPosition / 1.0e8); + + // Get the day level, from 0 to 1, and apply it to the alpha. Lots of tricks to get it looking good on earth. + vec3 dayRefUp = normalize(cameraPositionS - min(0.0, dot(cameraPositionS, cameraToPositionUnit)) * cameraToPositionUnit); + float dayLevel = -dot(lightToPositionUnit, dayRefUp); + outColor.rgb *= easeInOut(0.5 + 2.0 * dayLevel, 2.0); + outColor.a *= easeInOut(1.0 + 2.0 * dayLevel, 2.0); + + // Brighten up the atmosphere when looking from space toward the sun. + float lightDotCamera = max(0.0, -dot(lightToPositionUnit, cameraToPositionUnit)); + outColor.a = clamp(outColor.a * (1.0 + glow(0.004, 1.0, lightDotCamera)), 0.0, 1.0); + + // Add narrower sun glare. + outColor.rgb *= lightColor * (1.0 + sunBrightness * outColor.a * glow(0.00004, 1.0, lightDotCamera)); + + // Add broader sun glare. + outColor.rgb *= lightColor * (1.0 + sunBrightness * outColor.a * glow(0.04, 0.125, lightDotCamera)); + + // Apply the sunset. + float lightDotHorizon = pow(clamp(1.0 - dot(lightToPositionUnit, dayRefUp), 0.0, 1.0), 2.0); + float cameraDotHorizon = pow(clamp(1.0 - dot(cameraToPositionUnit, dayRefUp), 0.0, 1.0), 8.0); + float sunsetAmount = sunsetIntensity * lightDotHorizon * cameraDotHorizon * glow(0.04, 0.5, lightDotCamera); + outColor.rgb = mix(outColor.rgb, sunsetColor, clamp(sunsetAmount, 0.0, 1.0)); + + return outColor; + } + + void main(void) { + // Convert everything into a sphere frame. + float spheroidRatio = equatorialRadius / polarRadius; + highp vec3 positionS = localPosition; + highp vec3 cameraPositionS = cameraPosition; + positionS.z *= spheroidRatio; + cameraPositionS.z *= spheroidRatio; + + highp vec3 cameraToPosition = positionS - cameraPositionS; + float cameraToPositionDist = length(cameraToPosition / 1.0e8) * 1.0e8; + highp vec3 cameraToPositionUnit = cameraToPosition / cameraToPositionDist; + + // Get the start and end of the sampling from the camera to the position. + float start; + float end; + getStartEndSamples(start, end, cameraPositionS, cameraToPositionUnit, 1.0e24, equatorialRadius, scaleHeight); + float fracPerStep = 1.0 / float(numIterations - 1); + float stepDist = fracPerStep * (end - start); + + // Do the sampling. + float totalDensity = 0.0; + float segmentStart = start; + for (int j = 0; j < numIterations; j++) { + // Get the distance that this segment covers. + float segDist = stepDist; + if (j == 0 || j == numIterations - 1) { + segDist *= 0.5; + } + + // Get the segment start that we're looking at. + vec3 p = cameraPositionS + segmentStart * cameraToPositionUnit; + + // Get the density at that segment start. It'll be the density for the whole segment. + float densityAtP = getDensity(p, equatorialRadius, density, scaleHeight); + + // Add it to the total density. + totalDensity += densityAtP * segDist; + + // Next step. + segmentStart += stepDist; + } + + // Add emissivity lightness. + gl_FragColor += getEmissiveColor(totalDensity, cameraPositionS, color, emissivity); + + // For each light, + for (int i = 0; i < 5; i++) { + if (i >= numLights) { + break; + } + + // If it's not a camera light, + if (length(lightPositions[i]) > 0.0) { + // Add on the color for the light. + gl_FragColor += getColor(totalDensity, lightColors[i], lightPositions[i], spheroidRatio, positionS, cameraPositionS, cameraToPositionUnit); + } + } + + // Adjust for values that are greater than one. + gl_FragColor.rgb = adjustOverbrightness(gl_FragColor.rgb); + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`}),"../pioneer/engine/src/scene/components/base_component.js": + /*!****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/base_component.js ***! + \****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"BaseComponent":function(){return BaseComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class BaseComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.EntityItem{constructor(type,name,entity){super(type,name,entity);this._radius=0.5;this._pixelSpaceRadiusPerCamera=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._greatestPixelSpaceRadius=0.0;this._loadState='unloaded';this._forceLoaded=!1;this._resourcesLoadedCallback=null;this._resourcesUnloadedCallback=null;this._loadedPromise=Promise.resolve();this._excludedCameras=new Set();this._visible=!0;this._threeJsObjects=[];this._threeJsMaterials=[];this._usesEntityOrientation=!1} + __destroy(){if(this._loadState==='loaded'){this._unloadResources()} + super.__destroy()} + setEnabled(enabled){super.setEnabled(enabled);this.__updateLoadState()} + getRadius(){return this._radius} + __setRadius(radius){this._radius=radius} + getPixelSpaceRadiusInCamera(camera){return this._pixelSpaceRadiusPerCamera.get(camera)} + getGreatestPixelSpaceRadius(){return this._greatestPixelSpaceRadius} + getThreeJsObjects(){return this._threeJsObjects} + getThreeJsMaterials(){return this._threeJsMaterials} + getThreeJsObjectByName(name){for(let i=0;i0.5)))&&this._loadState==='unloaded'){this._loadResources()}else if((!isEnabled||(!this._forceLoaded&&(!isInTime||this._greatestPixelSpaceRadius<0.25)))&&this._loadState==='loaded'){this._unloadResources()}} + resetResources(){if(this._loadState==='loading'){this._loadState='unloaded'}else if(this._loadState==='loaded'){this._unloadResources()}} + setResourcesLoadedCallback(callback){this._resourcesLoadedCallback=callback} + setResourcesUnloadedCallback(callback){this._resourcesUnloadedCallback=callback} + _loadResources(){this._loadState='loading';this._loadedPromise=this.__loadResources().then(()=>{if(this._loadState!=='loading'){this._unloadResources();return} + this._loadState='loaded';if(this._resourcesLoadedCallback!==null){this._resourcesLoadedCallback()}})} + _unloadResources(){this.__unloadResources();this._loadState='unloaded';this._threeJsObjects=[];this._threeJsMaterials=[];if(this._resourcesUnloadedCallback!==null){this._resourcesUnloadedCallback()}} + __loadResources(){return Promise.resolve()} + __unloadResources(){} + getLoadedPromise(){return this._loadedPromise} + __updateCameraVariablesBase(camera){const viewport=camera.getViewport();const normalSpaceRadius=camera.getNormalSpaceRadiusFromRadius(this._radius,this.getEntity().getCameraSpacePosition(camera).magnitude());const pixelSpaceRadius=viewport.getPixelSpaceRadiusFromNormalSpaceRadius(normalSpaceRadius);this._pixelSpaceRadiusPerCamera.set(camera,pixelSpaceRadius);this.__updateCameraVariables(camera)} + __updateBase(){this._greatestPixelSpaceRadius=0.0;for(let i=0,l=this._pixelSpaceRadiusPerCamera.size;i=1){return this._fieldOfView}else{return 2.0*Math.atan(Math.tan(this._fieldOfView/2.0)*this._aspectRatio)}} + getVerticalFieldOfView(){if(this._aspectRatio>1){return 2.0*Math.atan(Math.tan(this._fieldOfView/2.0)/this._aspectRatio)}else{return this._fieldOfView}} + setFieldOfView(fieldOfView){this._fieldOfView=fieldOfView} + getInvertDepth(){return this._invertDepth} + setInvertDepth(invertDepth){this._invertDepth=invertDepth} + getNearDistance(){return this._nearDistance} + setNearDistance(nearDistance){this._nearDistance=nearDistance} + getAutoNearDistance(){return this._autoNearDistance} + getMidDistance(){return this._midDistance} + setMidDistance(midDistance){this._midDistance=midDistance} + getAutoMidDistance(){return this._autoMidDistance} + getNormalSpacePositionFromCameraSpacePosition(outNormalSpacePosition,cameraSpacePosition){const orientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();orientation.copy(this.getEntity().getOrientation());orientation.inverse(orientation);const rotatedCameraSpacePosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();rotatedCameraSpacePosition.rotate(orientation,cameraSpacePosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation);outNormalSpacePosition.x=this._threeJsCamera.projectionMatrix.elements[0]*rotatedCameraSpacePosition.x/rotatedCameraSpacePosition.y;outNormalSpacePosition.y=this._threeJsCamera.projectionMatrix.elements[9]*rotatedCameraSpacePosition.z/rotatedCameraSpacePosition.y;outNormalSpacePosition.z=this._threeJsCamera.projectionMatrix.elements[6]+this._threeJsCamera.projectionMatrix.elements[14]/rotatedCameraSpacePosition.y;_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(rotatedCameraSpacePosition)} + getNormalSpaceRadiusFromRadius(radius,distanceInCameraYDir){return radius/Math.abs(distanceInCameraYDir)/Math.tan(this._fieldOfView/2)} + getCameraSpacePositionFromNormalSpacePosition(outCameraSpacePosition,normalSpacePosition){const rotatedCameraSpacePosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();rotatedCameraSpacePosition.y=this._threeJsCamera.projectionMatrix.elements[14]/(normalSpacePosition.z-this._threeJsCamera.projectionMatrix.elements[6]);rotatedCameraSpacePosition.x=normalSpacePosition.x*rotatedCameraSpacePosition.y/this._threeJsCamera.projectionMatrix.elements[0];rotatedCameraSpacePosition.z=normalSpacePosition.y*rotatedCameraSpacePosition.y/this._threeJsCamera.projectionMatrix.elements[9];outCameraSpacePosition.rotate(this.getEntity().getOrientation(),rotatedCameraSpacePosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(rotatedCameraSpacePosition)} + getRadiusFromNormalSpaceRadius(radius,distanceInCameraYDir){return radius*Math.abs(distanceInCameraYDir)*Math.tan(this._fieldOfView/2)} + isPositionOccluded(cameraSpacePosition){for(let i=0;i=0){const distance=interval.min*entityCameraSpacePosition.magnitude();if(distance0);this._threeJsUnrealBloomPass.strength=strength} + setOutline(color,component,subObjectName){this._outlinePass.enabled=(component!==null);if(component!==null){if(subObjectName!==undefined){const subObject=component.getThreeJsObjectByName(subObjectName);if(subObject===null){throw new Error(`Could not set outline on component ${component} sub-object ${subObjectName}.`)} + this._outlinePass.selectedObjects=[subObject]}else{const objects=component.getThreeJsObjects();this._outlinePass.selectedObjects=[];for(let i=0,l=objects.length;i0&&this._fieldOfView<180&&this._aspectRatio>0){const tanHalfFov=Math.tan(this._fieldOfView/2);let sx=0;let sz=0;if(this._aspectRatio>=1){sx=1/tanHalfFov;sz=this._aspectRatio/tanHalfFov}else{sx=1/(tanHalfFov*this._aspectRatio);sz=1/tanHalfFov} + const f1=Number.EPSILON-1.0;const f2=this._autoNearDistance*(2.0-Number.EPSILON);const projectionMatrix=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix4();projectionMatrix.set(sx,0,0,0,0,0,sz,0,0,f1,0,f2,0,1,0,0);this._threeJsCamera.projectionMatrix=projectionMatrix;const projectionMatrixInverse=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Matrix4();projectionMatrixInverse.set(1/sx,0,0,0,0,0,0,1,0,1/sz,0,0,0,0,1/f2,-f1/f2);this._threeJsCamera.projectionMatrixInverse=projectionMatrixInverse}} + __loadResources(){return Promise.resolve()} + __unloadResources(){}}}),"../pioneer/engine/src/scene/components/cmts_component.js": + /*!****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/cmts_component.js ***! + \****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"CMTSComponent":function(){return CMTSComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class CMTSComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._threeJsScene=this.getEntity().getScene().getThreeJsScene();this._endPoints=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._heightScale=1;this._numEndPointsLoading=0;this._minLevel=Number.NEGATIVE_INFINITY;this._maxLevel=Number.POSITIVE_INFINITY;this._tileOffsets=[];this._splitJoinThresholdFactor=512.0;this._colorTileSize=512;this._shadowEntities=[];this._engine=this.getEntity().getScene().getEngine();this._cameraPositions=[];this._cameraFieldsOfView=[];this._rootTiles=[null,null,null,null,null,null];this._tilesLoadedPromise=null;this._transitionsCompleteCallback=null;this._textureCache=new _internal__WEBPACK_IMPORTED_MODULE_0__.Cache((textureUrl)=>{return this.getEntity().getScene().getEngine().getTextureLoader().loadTexture(textureUrl,!0)},(texturePromise)=>{texturePromise.then((texture)=>{texture.dispose()})});this._numCurrentLoads=0;this._maxCurrentLoads=10;this._atmosphereComponentRef=new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene());this._atmosphereComponentRef.setByType(this.getEntity().getName(),'atmosphere');this._spheroidComponentRef=new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene());this._spheroidComponentRef.setByType(this.getEntity().getName(),'spheroid');this._spheroidComponentRef.setRefChangedCallback(this._spheroidRefChangedCallback.bind(this));this._spheroidChangedCallback=this._spheroidChangedCallback.bind(this);this.__setUsesEntityOrientation(!0)} + setBaseUrl(textureName,endPoint){this.resetResources();this._endPoints.set(textureName,{url:endPoint,configuration:null})} + getHeightScale(){return this._heightScale} + setHeightScale(heightScale){this._heightScale=heightScale;this.resetResources()} + getMinLevel(){return this._minLevel} + setMinLevel(minLevel){this._minLevel=minLevel} + getMaxLevel(){return this._maxLevel} + setMaxLevel(maxLevel){this._maxLevel=maxLevel} + addTileOffset(offset,face,level,minX,minY,maxX,maxY){this._tileOffsets.push({offset,face,level,min:new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(minX,minY),max:new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(maxX,maxY)});this.resetResources()} + removeTileOffset(level,face,minX,minY,maxX,maxY){for(let i=0;i0);for(let i=0,l=this.getThreeJsMaterials().length;i0){const levelFactor=1<<(tile.getLevel()+1);const xTile=Math.floor(uvFace.x*levelFactor-tile.getTileCoord().x*2);const yTile=Math.floor(uvFace.y*levelFactor-tile.getTileCoord().y*2);tile=tile.children[yTile*2+xTile]} + while(tile.getHeightData()===null&&tile.getParent()!==null){tile=tile.getParent()} + const heightData=tile.getHeightData();if(heightData!==null){const levelFactor=1<this._engine.getNumViewports()){this._cameraPositions.pop();this._cameraFieldsOfView.pop()} + while(this._cameraPositions.length{this._transitionsCompleteCallback=resolve})} + if(this._tilesLoadedPromise!==null&&!transitioning){const callback=this._transitionsCompleteCallback;this._tilesLoadedPromise=null;this._transitionsCompleteCallback=null;callback()}} + __prepareForRender(camera){if(this._rootTiles[0]===null){return} + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects(),this.getEntity());for(let face=0;face<6;face++){this._rootTiles[face].prepareForRender(camera)} + const atmosphere=this._atmosphereComponentRef.get();_internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setUniforms(this.getThreeJsMaterials(),camera,this.getEntity(),this._shadowEntities,atmosphere,!0)} + __loadResources(){const promises=[];for(let i=0,l=this._endPoints.size;i{if(download.status==='failed'){throw new Error('Failed to download '+endPoint+'/configuration.json')} + if(download.status==='completed'&&typeof download.content==='string'){const configuration=(JSON.parse(download.content));entry.value.configuration=configuration;if(entry.key==='color'){this._colorTileSize=configuration.tile_size} + this._numEndPointsLoading-=1}});promises.push(promise)} + return Promise.all(promises)} + __unloadResources(){for(let face=0;face<6;face++){if(this._rootTiles[face]!==null){this._rootTiles[face].destroy()}} + this._rootTiles=[null,null,null,null,null,null]} + __getNumCurrentLoads(){return this._numCurrentLoads} + __incNumCurrentLoads(){this._numCurrentLoads+=1} + __decNumCurrentLoads(){this._numCurrentLoads-=1} + __getMaxCurrentLoads(){return this._maxCurrentLoads} + __getEndPoints(){return this._endPoints} + __endPointsAreLoaded(){return this._numEndPointsLoading===0} + __getTileOffsets(){return this._tileOffsets} + __getTextureCache(){return this._textureCache} + __getCameraPositions(){return this._cameraPositions} + __getCameraFieldsOfView(){return this._cameraFieldsOfView} + __getThreeJsScene(){return this._threeJsScene} + __getSplitJoinThresholdFactor(){return this._splitJoinThresholdFactor} + __getColorTileSize(){return this._colorTileSize} + __getSpheroidComponent(){return this._spheroidComponentRef.get()} + _spheroidRefChangedCallback(oldRef,newRef){if(oldRef!==null){oldRef.removeChangedCallback(this._spheroidChangedCallback)} + if(newRef!==null){newRef.addChangedCallback(this._spheroidChangedCallback)} + this._spheroidChangedCallback()} + _spheroidChangedCallback(){const spheroidComponent=this._spheroidComponentRef.get();if(spheroidComponent!==null){this.__setRadius(Math.max(spheroidComponent.getEquatorialRadius(),spheroidComponent.getPolarRadius()))}else{this.__setRadius(0)} + this.resetResources()}} + class CMTSTile extends _internal__WEBPACK_IMPORTED_MODULE_0__.Tile{constructor(component,parent,face,level,tile){super(parent);this._component=component;this._face=face;this._level=level;this._levelPow=Math.pow(2,-Math.max(0,level));this._tile=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2();this._tile.copy(tile);this._isLeaf=!0;this._center=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._radius=0;this._threeJsMaterial=null;this._textureLevels=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._texturePromises=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._nonPositiveTextureLoading=!1;this._threeJsObject=null;this._heightData=null;this._tileOffset=this._getTileOffset();for(let y=0;y<2;y++){for(let x=0;x<2;x++){for(let i=0;i=this._component.getMaxLevel()){return!1} + if(this._component.__getNumCurrentLoads()>=this._component.__getMaxCurrentLoads()){return!1} + if(this._level=this._component.getMaxLevel()){return!0} + if(this._component.__getNumCurrentLoads()>=this._component.__getMaxCurrentLoads()){return!1} + if(this._levelthis._component.__getSplitJoinThresholdFactor()*this._radius/tilePixelSize*4} + async load(){this._component.__incNumCurrentLoads();if(this._threeJsMaterial!==null){this._component.__decNumCurrentLoads();throw new Error('Tile already has material.')} + this._threeJsMaterial=_internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.get();this._component.getThreeJsMaterials().push(this._threeJsMaterial);this._threeJsMaterial.defines.shadowEntities=(this._component.getNumShadowEntities()>0);const endPoints=this._component.__getEndPoints();const loadPromises=[];for(let i=0;i>(this._level-textureLevel);const tileY=this._tile.y>>(this._level-textureLevel);const textureUrl=endPoint.url+'/'+this._face+'/'+textureLevel+'/'+tileX+'/'+tileY+'.'+endPoint.configuration.extension;texturePromise=this._component.__getTextureCache().get(textureUrl);this._texturePromises.set(textureName,texturePromise);loadPromises.push(texturePromise.then((texture)=>{this._setTexture(textureName,texture)}).catch(async()=>{this._component.__getTextureCache().release(texturePromise);texturePromise=this._component.__getTextureCache().get('pink');const texture=await texturePromise;this._setTexture(textureName,texture)}))} + return Promise.all(loadPromises).finally(()=>{this._component.__decNumCurrentLoads()})} + async unload(){if(this._threeJsMaterial===null){throw new Error('Tile has no material to unload.')} + const materials=this._component.getThreeJsMaterials();for(let i=0,l=materials.length;i{this._setTexture(textureName,texture);this._setupMesh();this._nonPositiveTextureLoading=!1}).catch(async()=>{this._component.__getTextureCache().release(texturePromise);texturePromise=this._component.__getTextureCache().get('pink');const texture=await texturePromise;this._setTexture(textureName,texture);this._nonPositiveTextureLoading=!1}).finally(()=>{if(textureName!=='height'){this._component.__getTextureCache().release(prevTexturePromise)}})}}} + transitioning=this._nonPositiveTextureLoading||transitioning;return transitioning} + _setupMesh(){const tilePixelSize=this._component.__getColorTileSize();const meshUVs=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();const uvOffsets=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();const uvScales=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();for(let i=0;idistance){nearestDistance=distance}} + return nearestDistance} + toString(){return this._face+'/'+this._level+'/'+this._tile.x+'/'+this._tile.y} + prepareForRender(camera){const entity=this._component.getEntity();if(this._threeJsObject!==null){const cameraSpacePosition=entity.getCameraSpacePosition(camera);const centerInJ2000=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();centerInJ2000.rotate(entity.getOrientation(),this._center);const angleBetweenCenterAndCamera=Math.acos(centerInJ2000.dot(cameraSpacePosition)/centerInJ2000.magnitude()/cameraSpacePosition.magnitude());_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(centerInJ2000);if(angleBetweenCenterAndCamera>levelDifference)&&(tile.x>>levelDifference)<=boundary.max[0]&&boundary.min[1]<=(tile.y>>levelDifference)&&(tile.y>>levelDifference)<=boundary.max[1]&&greatestLevelthis._level){continue} + const levelMult=1<<(this._level-tileOffset.level);if(tileOffset.min.x*levelMult<=this._tile.x&&this._tile.x<(tileOffset.max.x+1)*levelMult&&tileOffset.min.y*levelMult<=this._tile.y&&this._tile.y<(tileOffset.max.y+1)*levelMult){return tileOffset.offset}} + return _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero} + static getHeightPos(pos,heightDir,x,y,data,uvOffset,numUVerts,numVVerts,uvScale,heightTileSize,heightOffset,heightScale){const u=((uvOffset.x+(x-1)/(numUVerts-3)*uvScale.x))*heightTileSize/(heightTileSize+4)+2.0/(heightTileSize+4);const v=1-(((uvOffset.y+(y-1)/(numVVerts-3)*uvScale.y))*heightTileSize/(heightTileSize+4)+2.0/(heightTileSize+4));const pixelX=u*(heightTileSize+4);const pixelY=v*(heightTileSize+4);const height=this.getLinearInterpolatedHeightPixel(pixelX,pixelY,data,heightTileSize+4);pos.addMult(pos,heightDir,heightOffset+height*heightScale)} + static getLinearInterpolatedHeightPixel(pixelX,pixelY,data,size){const pixelXInt=Math.floor(pixelX);const pixelYInt=Math.floor(pixelY);const pixelXFrac=pixelX-pixelXInt;const pixelYFrac=pixelY-pixelYInt;const u=Math.abs(pixelXFrac-0.5);const v=Math.abs(pixelYFrac-0.5);let height=this.getHeightFromPixel(pixelXInt,pixelYInt,data,size)*((1-u)*(1-v));if(pixelXFrac>=0.5){height+=this.getHeightFromPixel(pixelXInt+1,pixelYInt,data,size)*(u*(1-v));if(pixelYFrac<0.5){height+=this.getHeightFromPixel(pixelXInt+1,pixelYInt-1,data,size)*(u*v)}else if(pixelYFrac>=0.5){height+=this.getHeightFromPixel(pixelXInt+1,pixelYInt+1,data,size)*(u*v)}}else if(pixelXFrac<0.5){height+=this.getHeightFromPixel(pixelXInt-1,pixelYInt,data,size)*(u*(1-v));if(pixelYFrac<0.5){height+=this.getHeightFromPixel(pixelXInt-1,pixelYInt-1,data,size)*(u*v)}else if(pixelYFrac>=0.5){height+=this.getHeightFromPixel(pixelXInt-1,pixelYInt+1,data,size)*(u*v)}} + if(pixelYFrac>=0.5){height+=this.getHeightFromPixel(pixelXInt,pixelYInt+1,data,size)*((1-u)*v)}else if(pixelYFrac<0.5){height+=this.getHeightFromPixel(pixelXInt,pixelYInt-1,data,size)*((1-u)*v)} + return height} + static getHeightFromPixel(pixelX,pixelY,data,size){pixelX=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(pixelX,0,size-1);pixelY=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(pixelY,0,size-1);const pixelIndex=(pixelY*size+pixelX)*4;return data[pixelIndex+0]/256+data[pixelIndex+1]/65536+data[pixelIndex+2]/16777216} + static cmtsCoordToPosition(out,face,levelPow,x,y,spheroid){let u=x*levelPow;let v=y*levelPow;while(u<0||u>1||v<0||v>1){if(0<=face&&face<=3){if(u>1){u-=1;face=(face+1)%4}else if(u<0){u+=1;face=(face+3)%4}else if(face===0){if(v<0){v+=1;face=5}else if(v>1){v-=1;face=4}}else if(face===1){if(v<0){const t=u;u=v+1;v=1-t;face=5}else if(v>1){const t=u;u=2-v;v=t;face=4}}else if(face===2){if(v<0){u=1-u;v=0-v;face=5}else if(v>1){u=1-u;v=2-v;face=4}}else if(face===3){if(v<0){const t=u;u=0-v;v=t;face=5}else if(v>1){const t=u;u=v-1;v=1-t;face=4}}}else if(face===4){if(u<0){const t=u;u=1-v;v=t+1;face=3}else if(u>1){const t=u;u=v;v=2-t;face=1}else if(v<0){v+=1;face=0}else if(v>1){u=1-u;v=2-v;face=2}}else if(face===5){if(u<0){const t=u;u=v;v=0-t;face=3}else if(u>1){const t=u;u=1-v;v=t-1;face=1}else if(v<0){u=1-u;v=0-v;face=2}else if(v>1){v-=1;face=0}}} + const uT=2*u-1;const vT=2*v-1;const basis=this._basis[face];out.set(basis[0].x*uT+basis[1].x*vT+basis[2].x,basis[0].y*uT+basis[1].y*vT+basis[2].y,basis[0].z*uT+basis[1].z*vT+basis[2].z);out.normalize(out);_internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLLAFromXYZOnSphere(this._lla,out,0);this._lla.alt=0;spheroid.xyzFromLLA(out,this._lla)};static cmtsCoordToTangent(out,face,levelPow,x,y,spheroid){this.cmtsCoordToPosition(out,face,levelPow,x,y,spheroid);const basis=this._basis[face];out.setNormalTo(out,basis[0])};static cmtsCoordToBitangent(out,face,levelPow,x,y,spheroid){this.cmtsCoordToPosition(out,face,levelPow,x,y,spheroid);const basis=this._basis[face];out.setNormalTo(out,basis[1])}} + CMTSTile._basis=[[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis],[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis],[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg],[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg],[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis],[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxisNeg]];CMTSTile._lla=new _internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt();CMTSTile._pos=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()}),"../pioneer/engine/src/scene/components/comet_tail_component.js": + /*!**********************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/comet_tail_component.js ***! + \**********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"CometTailComponent":function(){return CometTailComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class CometTailComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._lightSource=new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());this._timeLength=6e5;this._numberOfParticles=200;this._color=new _internal__WEBPACK_IMPORTED_MODULE_0__.Color();this._color.freeze();this._starAccelerationMultiplier=1.0;this._timeOfParticle0=0} + getLightSource(){return this._lightSource.getName()} + setLightSource(lightSource){this._lightSource.setName(lightSource)} + getTimeLength(){return this._timeLength} + setTimeLength(length){this._timeLength=length;this.resetResources()} + getStarAccelerationMultiplier(){return this._starAccelerationMultiplier} + setStarAccelerationMultiplier(starAccelerationMultiplier){this._starAccelerationMultiplier=starAccelerationMultiplier;_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'starAccelerationMultiplier',this._starAccelerationMultiplier)} + getNumberOfParticles(){return this._numberOfParticles} + setNumberOfParticles(numberOfParticles){this._numberOfParticles=numberOfParticles;this.resetResources()} + getColor(){return this._color} + setColor(color){this._color.thaw();this._color.copy(color);this._color.freeze();_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0],'color',this._color)} + __update(){this.__setRadius(Math.max(this.getEntity().getExtentsRadius(),this._timeLength*this.getEntity().getVelocity().magnitude()));if(this.getLoadState()!=='loaded'){return} + const time=this.getEntity().getScene().getEngine().getTime();const originTimeAttribute=(this.getThreeJsObjects()[0]).geometry.attributes.originTime;const originTimeArray=(originTimeAttribute.array);for(let i=0,l=this._numberOfParticles;itime){this._newParticle(i,_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(particleTime,time-this._timeLength,time))}} + if(this._numberOfParticles>1){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'time',time-this._timeOfParticle0)}else{_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'time',0)} + const lightSource=this._lightSource.get();if(lightSource!==null){const lightSourceComponent=(lightSource.getComponentByType('lightSource'));if(lightSourceComponent!==null){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'starAbsoluteMagnitude',lightSourceComponent.getAbsoluteMagnitude())} + const position=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();this.getEntity().getPositionRelativeToEntity(position,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,lightSource);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0],'positionOfEntity',position);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position)}} + __prepareForRender(camera){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects(),this.getEntity(),camera);const cameraSpacePosition=this.getEntity().getCameraSpacePosition(camera);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0],'positionInCamera',cameraSpacePosition);if(cameraSpacePosition.magnitude()<4e4){this.getThreeJsObjects()[0].visible=!1}else{const u=(cameraSpacePosition.magnitude()-4e4)/4e5;this.getThreeJsMaterials()[0].uniforms.color.value.w=this._color.a*_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(u);this.getThreeJsObjects()[0].visible=!0}} + async __loadResources(){const threeJsMaterial=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RawShaderMaterial({uniforms:{time:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0),timeLength:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0),positionInCamera:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()),starAbsoluteMagnitude:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0),starAccelerationMultiplier:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0),positionOfEntity:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()),color:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4()),..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms},vertexShader:CometTailComponent.vertexShader,fragmentShader:CometTailComponent.fragmentShader,transparent:!0,depthWrite:!1,blending:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.AdditiveBlending,side:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide});_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderFix.fix(threeJsMaterial);this.getThreeJsMaterials().push(threeJsMaterial);const positionArray=new Float32Array([-1,-1,0,1,-1,0,1,1,0,-1,1,0]);const indexArray=new Uint16Array([0,1,2,2,3,0]);const originTimeArray=new Float32Array(1*this._numberOfParticles);const originPositionArray=new Float32Array(3*this._numberOfParticles);const accelerationMultiplier=new Float32Array(1*this._numberOfParticles);const threeJsGeometry=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferGeometry();threeJsGeometry.setAttribute('position',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(positionArray,3));threeJsGeometry.setAttribute('originTime',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(originTimeArray,1));threeJsGeometry.setAttribute('originPosition',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(originPositionArray,3));threeJsGeometry.setAttribute('accelerationMultiplier',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InstancedBufferAttribute(accelerationMultiplier,1));threeJsGeometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(indexArray,1));threeJsGeometry.instanceCount=this._numberOfParticles;const threeJsObject=(_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObjectGivenGeometry(this,threeJsMaterial,threeJsGeometry));this.getThreeJsObjects().push(threeJsObject);const time=this.getEntity().getScene().getEngine().getTime();for(let i=0,l=this._numberOfParticles;i0){originTimeArray[i]=originTime-this._timeOfParticle0}else{for(let j=1,l=this._numberOfParticles;j 0.0 ? atan(viewStretch.z, viewStretch.x) : 0.0; + float cosAngle = cos(angle); + float sinAngle = sin(angle); + float stretchedX = (stretch2d.x * cosAngle * cosAngle + stretch2d.y * sinAngle * sinAngle) * 0.5 * (position.x + translate.x) + (stretch2d.x - stretch2d.y) * sinAngle * cosAngle * 0.5 * (position.y + translate.y); + float stretchedY = (stretch2d.x - stretch2d.y) * sinAngle * cosAngle * 0.5 * (position.x + translate.x) + (stretch2d.x * sinAngle * sinAngle + stretch2d.y * cosAngle * cosAngle) * 0.5 * (position.y + translate.y); + + // Get the position in view space and then in normalized space. + vec4 viewPosition = vec4(stretchedX, 0.0, stretchedY, 0.0) + modelViewMatrix * vec4(modelPosition, 1.0); + gl_Position = projectionMatrix * viewPosition; + gl_Position.w = viewPosition.y; + + // Set the varying variables for adjusting te + vPosition = vec2(cosAngle * position.x + sinAngle * position.y, -sinAngle * position.x + cosAngle * position.y); + vAlpha = sqrt(1.0 - sqrt(deltaTime / timeLength)); + + // Make the gas fade far from the star. + vAlpha *= min(1.0, 1.0 - length(originPosition) / 7.0e8); + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`;CometTailComponent.fragmentShader=` + precision highp float; + + uniform vec4 color; + + varying vec2 vPosition; + varying float vAlpha; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main(void) { + // Set the color to be a circle tinted by the color. + gl_FragColor = vec4(color.rgb, 0.5 * color.a) * max(0.0, 1.0 - dot(vPosition, vPosition)) * vAlpha; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`}),"../pioneer/engine/src/scene/components/connected_sprite_component.js": + /*!****************************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/connected_sprite_component.js ***! + \****************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ConnectedSpriteComponent":function(){return ConnectedSpriteComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class ConnectedSpriteComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._entity1=new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());this._entity1Offset=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._entity1Offset.freeze();this._entity2=new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());this._entity2Offset=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._entity2Offset.freeze();this._width1=1.0;this._width2=1.0;this._widthUnits='km';this._textureUrl='';this._textureAspectRatio=1;this._textureRepeat=!0;this._textureStretch=1;this._textureYOffset=0;this._uOffsetStart=0;this._uOffsetEnd=1;this._colorMultiplier=new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1,1,1,1);this._colorMultiplier.freeze();this._blending='normal'} + getEntity1(){return this._entity1.getName()} + setEntity1(entityName){this._entity1.setName(entityName)} + getEntity1Offset(){return this._entity1Offset} + setEntity1Offset(offset){this._entity1Offset.thaw();this._entity1Offset.copy(offset);this._entity1Offset.freeze()} + getEntity2(){return this._entity2.getName()} + setEntity2(entityName){this._entity2.setName(entityName)} + getEntity2Offset(){return this._entity2Offset} + setEntity2Offset(offset){this._entity2Offset.thaw();this._entity2Offset.copy(offset);this._entity2Offset.freeze()} + getWidth1(){return this._width1} + getWidth2(){return this._width2} + setWidths(width1,width2){this._width1=width1;this._width2=width2} + getWidthUnits(){return this._widthUnits} + setWidthUnits(widthUnits){this._widthUnits=widthUnits;if(this.getLoadState()==='loaded'){const material=this.getThreeJsMaterials()[0];material.defines.PIXEL_BASED=(widthUnits==='px');material.needsUpdate=!0}} + getTextureUrl(){return this._textureUrl} + setTextureUrl(url){this._textureUrl=url;this.resetResources()} + getTextureRepeat(){return this._textureRepeat} + setTextureRepeat(repeat){this._textureRepeat=repeat} + getTextureStretch(){return this._textureStretch} + setTextureStretch(stretch){this._textureStretch=stretch} + getTextureYOffset(){return this._textureYOffset} + setTextureYOffset(offset){this._textureYOffset=offset} + getUOffsetStart(){return this._uOffsetStart} + setUOffsetStart(uOffsetStart){this._uOffsetStart=uOffsetStart} + getUOffsetEnd(){return this._uOffsetEnd} + setUOffsetEnd(uOffsetEnd){this._uOffsetEnd=uOffsetEnd} + getColorMultiplier(){return this._colorMultiplier} + setColorMultiplier(colorMultiplier){this._colorMultiplier.thaw();this._colorMultiplier.copy(colorMultiplier);this._colorMultiplier.freeze();_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0],'color',this._colorMultiplier,1.0)} + setBlending(blending){this._blending=blending;_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setBlending(this.getThreeJsMaterials()[0],blending)} + __update(){const entity1=this._entity1.get();const entity2=this._entity2.get();if(entity1===null||entity2===null){return} + const offset=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();entity1.getPositionRelativeToEntity(offset,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,entity2);this.__setRadius(offset.magnitude()+entity1.getExtentsRadius()+entity2.getExtentsRadius());_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(offset)} + __prepareForRender(camera){const entity1=this._entity1.get();const entity2=this._entity2.get();if(entity1===null||entity2===null){this.getThreeJsObjects()[0].visible=!1;return} + const cameraSpacePosition1=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const cameraSpacePosition2=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const cameraSpacePosition1Temp=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();cameraSpacePosition1.rotate(entity1.getOrientation(),this._entity1Offset);cameraSpacePosition1.add(entity1.getCameraSpacePosition(camera),cameraSpacePosition1);cameraSpacePosition2.rotate(entity2.getOrientation(),this._entity2Offset);cameraSpacePosition2.add(entity2.getCameraSpacePosition(camera),cameraSpacePosition2);cameraSpacePosition1Temp.copy(cameraSpacePosition1);cameraSpacePosition1.lerp(cameraSpacePosition1,cameraSpacePosition2,this._uOffsetStart);cameraSpacePosition2.lerp(cameraSpacePosition1Temp,cameraSpacePosition2,this._uOffsetEnd);let entity1DistanceToCamera=cameraSpacePosition1.magnitude();let entity2DistanceToCamera=cameraSpacePosition2.magnitude();let entitiesFlipped=!1;if(entity1DistanceToCamera>entity2DistanceToCamera){cameraSpacePosition1Temp.copy(cameraSpacePosition1);cameraSpacePosition1.copy(cameraSpacePosition2);cameraSpacePosition2.copy(cameraSpacePosition1Temp);entity1DistanceToCamera=cameraSpacePosition1.magnitude();entity2DistanceToCamera=cameraSpacePosition2.magnitude();entitiesFlipped=!0} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraSpacePosition1Temp);const normalSpacePosition1=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const normalSpacePosition2=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();camera.getNormalSpacePositionFromCameraSpacePosition(normalSpacePosition1,cameraSpacePosition1);camera.getNormalSpacePositionFromCameraSpacePosition(normalSpacePosition2,cameraSpacePosition2);const vAxis=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const hAxis=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();vAxis.sub(cameraSpacePosition2,cameraSpacePosition1);hAxis.copy(cameraSpacePosition1);hAxis.cross(vAxis,hAxis);hAxis.normalize(hAxis);vAxis.setMagnitude(vAxis,Math.min(vAxis.magnitude(),entity1DistanceToCamera*10));cameraSpacePosition2.add(cameraSpacePosition1,vAxis);camera.getNormalSpacePositionFromCameraSpacePosition(normalSpacePosition2,cameraSpacePosition2);entity2DistanceToCamera=cameraSpacePosition2.magnitude();let width1=entitiesFlipped?this._width2:this._width1;let width2=entitiesFlipped?this._width1:this._width2;if(this._widthUnits==='px'){const forward=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();camera.getEntity().getOrientation().getAxis(forward,1);width1=camera.getViewport().getNormalSpaceRadiusFromPixelSpaceRadius(width1);width2=camera.getViewport().getNormalSpaceRadiusFromPixelSpaceRadius(width2);width1=camera.getRadiusFromNormalSpaceRadius(width1,cameraSpacePosition1.dot(forward));width2=camera.getRadiusFromNormalSpaceRadius(width2,cameraSpacePosition2.dot(forward));_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(forward)} + let repeatAmount=1/this._textureStretch;if(this._widthUnits==='px'){if(this._textureRepeat){const pixelSpacePosition1=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();const pixelSpacePosition2=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();camera.getViewport().getPixelSpacePositionFromNormalSpacePosition(pixelSpacePosition1,normalSpacePosition1);camera.getViewport().getPixelSpacePositionFromNormalSpacePosition(pixelSpacePosition2,normalSpacePosition2);const pixelDiff=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();pixelDiff.sub(pixelSpacePosition1,pixelSpacePosition2);if(pixelDiff.isNaN()){const bounds=camera.getViewport().getBounds();pixelDiff.x=bounds.size.x*(normalSpacePosition2.x-normalSpacePosition1.x)/2.0;pixelDiff.y=bounds.size.y*(normalSpacePosition2.y-normalSpacePosition1.y)/2.0} + repeatAmount*=pixelDiff.magnitude()/Math.max(this._width1,this._width2)*this._textureAspectRatio;_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelDiff);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelSpacePosition1);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelSpacePosition2)}}else{if(this._textureRepeat){repeatAmount*=vAxis.magnitude()/Math.max(this._width1,this._width2)*this._textureAspectRatio}} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(normalSpacePosition1);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(normalSpacePosition2);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPosition(this.getThreeJsObjects(),cameraSpacePosition1);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0],'vAxis',vAxis);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'width1',width1);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'width2',width2);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'textureYOffset',this._textureYOffset*(entitiesFlipped?-1:1));_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'repeatAmount',repeatAmount);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraSpacePosition1);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraSpacePosition2);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(vAxis);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(hAxis)} + async __loadResources(){const texture=await _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTexture(this,this._textureUrl,!0,!1);texture.wrapT=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RepeatWrapping;this._textureAspectRatio=texture.image.width/texture.image.height;if(this.getLoadState()!=='loading'){texture.dispose();return} + const threeJsMaterial=this.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('connected_sprite');this.getThreeJsMaterials().push(threeJsMaterial);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setBlending(this.getThreeJsMaterials()[0],this._blending);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setDefine(threeJsMaterial,'PIXEL_BASED',(this._widthUnits==='px'));_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(threeJsMaterial,'color',this._colorMultiplier,1.0);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformTexture(threeJsMaterial,'colorTexture',texture);const threeJsObject=_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this,threeJsMaterial,[{name:'position',dimensions:2}],!1);this.getThreeJsObjects().push(threeJsObject);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(threeJsObject.geometry,'position',new Float32Array([-1,0,1,0,-1,1,1,1]));_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(threeJsObject.geometry,new Uint16Array([0,2,3,3,1,0]))} + __unloadResources(){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this)}}}),"../pioneer/engine/src/scene/components/div_component.js": + /*!***************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/div_component.js ***! + \***************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"DivComponent":function(){return DivComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class DivComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._activeCamera=null;this._fadeWhenCloseToCamera=!0;this._fadeWhenCloseToEntity=new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());this._div=document.createElement('div');this._div.style.position='absolute';this._div.style.left='0';this._div.style.top='0';this._div.style.transform='translate(0%, 0%);';this._alignment=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0.0,0.5);this._alignment.freeze();this._sizeInPx=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0,0);this._currentHTML='';this.__setRadius(Number.POSITIVE_INFINITY)} + getDiv(){return this._div} + getActiveCamera(){return this._activeCamera} + setActiveCamera(activeCamera){this._activeCamera=activeCamera;this.resetResources()} + getFadeWhenCloseToCamera(){return this._fadeWhenCloseToCamera} + setFadeWhenCloseToCamera(enable){this._fadeWhenCloseToCamera=enable} + getFadeWhenCloseToEntity(){return this._fadeWhenCloseToEntity.getName()} + setFadeWhenCloseToEntity(entityName){this._fadeWhenCloseToEntity.setName(entityName)} + getAlignment(){return this._alignment} + setAlignment(alignment){this._alignment.thaw();this._alignment.copy(alignment);this._alignment.freeze()} + __loadResources(){return Promise.resolve()} + __unloadResources(){if(this._div.parentNode!==null){this._div.parentNode.removeChild(this._div)}} + __prepareForRender(camera){if(this._activeCamera===null){const firstViewport=this.getEntity().getScene().getEngine().getViewport(0);if(firstViewport!==null){this._activeCamera=firstViewport.getCamera()}} + if(this._activeCamera!==camera||this._activeCamera===null||this._activeCamera.getViewport()===null){return} + if(this._activeCamera.getViewport().getDiv()!==this._div.parentNode){this._activeCamera.getViewport().getDiv().appendChild(this._div)} + let alphaMultiplier=1;if(alphaMultiplier>0&&this._fadeWhenCloseToCamera){const normalizedSizeOfEntity=this.getEntity().getNormalSpaceExtentsRadius(camera);alphaMultiplier*=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((0.02-normalizedSizeOfEntity)/0.02)} + const cameraSpacePosition=this.getEntity().getCameraSpacePosition(camera);if(alphaMultiplier>0){let closeToEntity=(null);if(this._fadeWhenCloseToEntity.getName()===''){closeToEntity=this.getEntity().getParent()}else{closeToEntity=this._fadeWhenCloseToEntity.get()} + if(closeToEntity!==null){const normalSpaceDifferenceFromParent=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();normalSpaceDifferenceFromParent.sub(this.getEntity().getNormalSpacePosition(camera),closeToEntity.getNormalSpacePosition(camera));const normalizedEntityDistanceFromParent=normalSpaceDifferenceFromParent.magnitude();_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(normalSpaceDifferenceFromParent);const normalizedParentRadius=closeToEntity.getNormalSpaceExtentsRadius(camera);if(normalizedParentRadius<0.02){alphaMultiplier*=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((normalizedEntityDistanceFromParent-0.02)/0.02)}}} + if(alphaMultiplier>0){if(this.getEntity().getParent()!==null&&this.getEntity().getParent().isOccludingPosition(camera,cameraSpacePosition)){alphaMultiplier=0}else if(camera.isPositionOccluded(cameraSpacePosition)){alphaMultiplier=0}} + if(alphaMultiplier>0){const cameraForward=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();camera.getEntity().getOrientation().getAxis(cameraForward,1);if(cameraForward.dot(this.getEntity().getCameraSpacePosition(camera))<=0){alphaMultiplier=0} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraForward)} + if(this._div.style.opacity!==''+alphaMultiplier){this._div.style.opacity=''+alphaMultiplier;if(alphaMultiplier===0){this._div.style.pointerEvents='none'}else{this._div.style.pointerEvents=''}} + if(alphaMultiplier>0){if(this._currentHTML!==this._div.innerHTML){this._sizeInPx.set(this._div.offsetWidth,this._div.offsetHeight);this._currentHTML=this._div.innerHTML} + const renderBounds=camera.getViewport().getBounds();const pixelSpacePosition=this.getEntity().getPixelSpacePosition(camera);const left=pixelSpacePosition.x-this._sizeInPx.x*this._alignment.x-renderBounds.origin.x+(renderBounds.size.x%2===0?-0.5:0);const top=pixelSpacePosition.y-this._sizeInPx.y*this._alignment.y-renderBounds.origin.y+(renderBounds.size.y%2===0?-0.5:0);this._div.style.transform=`translate(${left}px, ${top}px)`}}}}),"../pioneer/engine/src/scene/components/dynamic_environment_map_component.js": + /*!***********************************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/dynamic_environment_map_component.js ***! + \***********************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"DynamicEnvironmentMapComponent":function(){return DynamicEnvironmentMapComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class DynamicEnvironmentMapComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._faceSize=64;this._invalidColor=new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0,0,0,1);this._invalidColor.freeze();this._threeJsRenderer=this.getEntity().getScene().getEngine().__getThreeJsRenderer();this._threeJsFaceCameras=[];this._threeJsFaceRenderTargets=[];this._threeJsQuad=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh();this._threeJsScene=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Scene();this._threeJsCubeCamera=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.OrthographicCamera(-1,1,-1,1,-1,1);this._envMapTexture=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLRenderTarget(this._faceSize*4,this._faceSize*4,{minFilter:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter,magFilter:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter,wrapS:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ClampToEdgeWrapping,wrapT:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ClampToEdgeWrapping});this._setupFaceCameras();this._setupQuad()} + getFaceSize(){return this._faceSize} + setFaceSize(faceSize){this._faceSize=faceSize;if(this._envMapTexture.width!==this._faceSize*4){this._envMapTexture.setSize(this._faceSize*4,this._faceSize*4);this._threeJsQuad.material.uniforms.faceSize.value=this._faceSize} + for(let face=0;face<6;face++){this._threeJsFaceRenderTargets[face].setSize(this._faceSize,this._faceSize)}} + getInvalidColor(){return this._invalidColor} + setInvalidColor(invalidColor){this._invalidColor.thaw();this._invalidColor.copy(invalidColor);this._invalidColor.freeze();if(this._threeJsQuad!==null){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGB(this._threeJsQuad.material,'invalidColor',this._invalidColor)}} + getTexture(){return this._envMapTexture.texture} + __destroy(){this._threeJsQuad.geometry.dispose();this._threeJsQuad.material.dispose();this._envMapTexture.dispose();for(let i=0;i pixelSize - 0.6 || xyInPixels.y < 0.6 || xyInPixels.y > pixelSize - 0.6) { + if (0 <= textureIndex && textureIndex <= 3) { // One of the horizontal faces + if (xyInPixels.x > pixelSize - 0.6) { + xyInPixels.x = 1.5; + textureIndex = (textureIndex + 1); + if (textureIndex == 4) { + textureIndex = 0; + } + } + else if (xyInPixels.x < 0.6) { + xyInPixels.x = pixelSize - 1.5; + textureIndex = textureIndex - 1; + if (textureIndex == -1) { + textureIndex = 3; + } + } + } + if (textureIndex == 0) { + if (xyInPixels.y < 0.6) { + xyInPixels.y = pixelSize - 1.5; + textureIndex = 5; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.y = 1.5; + textureIndex = 4; + } + } + if (textureIndex == 1) { + if (xyInPixels.y < 0.6) { + xyInPixels.y = pixelSize - xyInPixels.x; + xyInPixels.x = pixelSize - 1.5; + textureIndex = 5; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.y = xyInPixels.x; + xyInPixels.x = pixelSize - 1.5; + textureIndex = 4; + } + } + if (textureIndex == 2) { + if (xyInPixels.y < 0.6) { + xyInPixels.x = pixelSize - xyInPixels.x; + xyInPixels.y = 1.5; + textureIndex = 5; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.x = pixelSize - xyInPixels.x; + xyInPixels.y = pixelSize - 1.5; + textureIndex = 4; + } + } + if (textureIndex == 3) { + if (xyInPixels.y < 0.6) { + xyInPixels.y = xyInPixels.x; + xyInPixels.x = 1.5; + textureIndex = 5; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.y = pixelSize - xyInPixels.x; + xyInPixels.x = 1.5; + textureIndex = 4; + } + } + if (textureIndex == 4) { + if (xyInPixels.x < 0.6) { + xyInPixels.x = pixelSize - xyInPixels.y; + xyInPixels.y = pixelSize - 1.5; + textureIndex = 3; + } + else if (xyInPixels.x > pixelSize - 0.6) { + xyInPixels.x = xyInPixels.y; + xyInPixels.y = pixelSize - 1.5; + textureIndex = 1; + } + if (xyInPixels.y < 0.6) { + xyInPixels.y = pixelSize - 1.5; + textureIndex = 0; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.x = pixelSize - xyInPixels.x; + xyInPixels.y = pixelSize - 1.5; + textureIndex = 2; + } + } + if (textureIndex == 5) { + if (xyInPixels.x < 0.6) { + xyInPixels.x = xyInPixels.y; + xyInPixels.y = 1.5; + textureIndex = 3; + } + else if (xyInPixels.x > pixelSize - 0.6) { + xyInPixels.x = pixelSize - xyInPixels.y; + xyInPixels.y = 1.5; + textureIndex = 1; + } + if (xyInPixels.y < 0.6) { + xyInPixels.x = pixelSize - xyInPixels.x; + xyInPixels.y = 1.5; + textureIndex = 2; + } + else if (xyInPixels.y > pixelSize - 0.6) { + xyInPixels.y = 1.5; + textureIndex = 0; + } + } + } + + // Shrink all pixels so that they fit within the border. + // The border pixels have already been modified so that they work with this equation. + xyInPixels.x = ((pixelSize - 1.0) * xyInPixels.x - pixelSize) / (pixelSize - 3.0); + xyInPixels.y = ((pixelSize - 1.0) * xyInPixels.y - pixelSize) / (pixelSize - 3.0); + + // Flip the x back. + xyInPixels.x = pixelSize - xyInPixels.x; + + // Go back into unit-space. + xyInTexture = xyInPixels / pixelSize; + } + + void main() { + // Make it pink everywhere else for easy debugging. + vec3 color = invalidColor; + // Get the mip level, size, and offset. + float level = floor(1.0 - log2(1.0 - xy.y)); // 0 is base, then 1, etc. + float mipSizeX = pow(2.0, -level); // 1, .5, .25, .125, etc. + float mipOffsetY = 1.0 - pow(2.0, -level); // 0, .5, .75, .875, etc. + // Get the xy within the mip level. Note the x value is * 3 for less computing further on. + vec2 xyInMip; + xyInMip.x = 0.5 * (xy.x + 1.0) / mipSizeX * 4.0; + xyInMip.y = (xy.y + 1.0 - 2.0 * mipOffsetY) / mipSizeX; + if (xyInMip.x <= 3.0) { + int textureIndex = int(floor(xyInMip.y * 2.0) * 3.0 + floor(xyInMip.x)); + // Get the xy within the face/texture. + vec2 xyInTexture; + xyInTexture.x = 1.0 - xyInMip.x + floor(xyInMip.x); + xyInTexture.y = 2.0 * (xyInMip.y - floor(xyInMip.y * 2.0) / 2.0); + // Adjust the coordinates and face to account for borders. + adjustTextureCoordsForBorders(textureIndex, xyInTexture, faceSize * mipSizeX); + // Set the color based on the face (textureIndex) and the coords. + if (textureIndex == 0) { + color = texture2D(textures[0], xyInTexture).rgb; + } + else if (textureIndex == 1) { + color = texture2D(textures[1], xyInTexture).rgb; + } + else if (textureIndex == 2) { + color = texture2D(textures[2], xyInTexture).rgb; + } + else if (textureIndex == 3) { + color = texture2D(textures[3], xyInTexture).rgb; + } + else if (textureIndex == 4) { + color = texture2D(textures[4], xyInTexture).rgb; + } + else if (textureIndex == 5) { + color = texture2D(textures[5], xyInTexture).rgb; + } + } + gl_FragColor = vec4(color, 1.0); + }`,depthTest:!1,depthWrite:!1});this._threeJsQuad=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh(geometry,material);this._threeJsQuad.frustumCulled=!1;this._threeJsScene.add(this._threeJsQuad)}} + const _tempThreeJsQuaternion=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Quaternion()}),"../pioneer/engine/src/scene/components/gizmo_component.js": + /*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/gizmo_component.js ***! + \*****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"GizmoComponent":function(){return GizmoComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class GizmoComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._size=undefined;this._relativeToEntity=!0;this._joint='';this._jointObject=null;this._model=null;this._lineMesh=null;this.__setRadius(entity.getExtentsRadius()*2.0);this.__setUsesEntityOrientation(this._relativeToEntity)} + getSize(){if(this._size!==undefined){return this._size}else{return Math.max(0.0001,this.getEntity().getExtentsRadius()*2.0)}} + setSize(size){this._size=size;this.__setRadius(this.getSize())} + isRelativeToEntity(){return this._relativeToEntity} + setRelativeToEntity(relativeToEntity){this._relativeToEntity=relativeToEntity;this.__setUsesEntityOrientation(this._relativeToEntity)} + setJoint(joint,model){this._joint=joint;if(!model){const modelFromEntity=(this.getEntity().get('model'));if(modelFromEntity!==null){this._model=modelFromEntity}}else{this._model=model}} + __prepareForRender(camera){if(this._joint!==''&&(this._jointObject===null||this._jointObject.name!==this._joint)&&this._model!==null){this._jointObject=this._model.getThreeJsObjectByName(this._joint)} + if(this._jointObject!==null){const position=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();let jointAncestor=this._jointObject;GizmoComponent._tempThreeJsVector3.copy(jointAncestor.position);GizmoComponent._tempThreeJsQuaternion.copy(jointAncestor.quaternion);while(jointAncestor.parent!==null&&jointAncestor.parent!==this._model.getThreeJsObjects()[0]){jointAncestor=jointAncestor.parent;GizmoComponent._tempThreeJsVector3.add(jointAncestor.position);GizmoComponent._tempThreeJsQuaternion.multiplyQuaternions(jointAncestor.quaternion,GizmoComponent._tempThreeJsQuaternion)} + position.copyFromThreeJs(GizmoComponent._tempThreeJsVector3);position.mult(position,0.001);position.rotate(this._model.getRotation(),position);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0],this.getEntity(),camera,position,!0);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position);const orientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();orientation.copyFromThreeJs(GizmoComponent._tempThreeJsQuaternion);orientation.mult(this._model.getRotation(),orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0],this.getEntity(),orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation)}else{if(this._relativeToEntity){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0],this.getEntity())}else{_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(this.getThreeJsObjects()[0],_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0],this.getEntity(),camera)} + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setScale(this.getThreeJsObjects()[0],this.getSize());this._lineMesh.prepareForRender(camera)} + __loadResources(){this._lineMesh=new _internal__WEBPACK_IMPORTED_MODULE_0__.LineMesh(this);const positions=[];positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,0,0));positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(1,0,0));positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,0,0));positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,1,0));positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,0,0));positions.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,0,1));this._lineMesh.setPositions(positions);const colors=[];colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1,0,0));colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1,0,0));colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0,1,0));colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0,1,0));colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0,0,1));colors.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0,0,1));this._lineMesh.setColors(colors);const widths=[];widths.push(2);widths.push(2);widths.push(2);widths.push(2);widths.push(2);widths.push(2);this._lineMesh.setWidths(widths);return Promise.resolve()} + __unloadResources(){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this);this._lineMesh=null}} + GizmoComponent._tempThreeJsVector3=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()}),"../pioneer/engine/src/scene/components/label_component.js": + /*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/label_component.js ***! + \*****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"LabelComponent":function(){return LabelComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class LabelComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._text='';this._fontFamily='Arial';this._fontSize=16;this._color=new _internal__WEBPACK_IMPORTED_MODULE_0__.Color();this._color.freeze();this._ignoreDistance=!1;this._alignment=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0.0,0.5);this._alignment.freeze();this._pixelOffset=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0,0);this._pixelOffset.freeze();this._pixelSize=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2();this._devicePixelRatio=1;this._canvas=null;this._normalSpaceBounds=new Map();const fontFamily=entity.getScene().getEngine().getConfig().getValue('fontFamily');if(typeof fontFamily==='string'){this._fontFamily=fontFamily} + const fontSize=entity.getScene().getEngine().getConfig().getValue('fontSize');if(typeof fontSize==='number'){this._fontSize=fontSize} + this.__setRadius(Number.POSITIVE_INFINITY)} + getText(){return this._text} + setText(text){this._text=text;this._updateText()} + getFontFamily(){return this._fontFamily} + setFontFamily(fontFamily){this._fontFamily=fontFamily;this._updateText()} + getFontSize(){return this._fontSize} + setFontSize(fontSize){this._fontSize=fontSize;this._updateText()} + getColor(){return this._color} + setColor(color){this._color.thaw();this._color.copy(color);this._color.freeze()} + setIgnoreDistance(enable){this._ignoreDistance=enable} + getAlignment(){return this._alignment} + setAlignment(alignment){this._alignment.thaw();this._alignment.copy(alignment);this._alignment.freeze();this._updateText()} + getPixelOffset(){return this._pixelOffset} + setPixelOffset(pixelOffset){this._pixelOffset.thaw();this._pixelOffset.copy(pixelOffset);this._pixelOffset.freeze()} + getNormalSpaceBounds(camera){return this._normalSpaceBounds.get(camera)} + __prepareForRender(camera){const cameraSpacePosition=this.getEntity().getCameraSpacePosition(camera);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0],this.getEntity(),camera);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(this.getThreeJsObjects()[0],_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity);const renderSize=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();if(camera.getType()==='spout'){const spoutComponent=(camera);renderSize.set(spoutComponent.getForGlobe()?-spoutComponent.getRenderWidth():spoutComponent.getRenderWidth(),spoutComponent.getRenderWidth());renderSize.div(renderSize,4)}else{renderSize.copy(camera.getViewport().getBounds().size)} + const pixelOffset=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();const pixelSize=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();const renderUp=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const renderRight=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();pixelOffset.set((this._pixelOffset.x-this._alignment.x*this._canvas.width),(this._pixelOffset.y-this._alignment.y*this._canvas.height));pixelSize.set(this._canvas.width,this._canvas.height);camera.getEntity().getOrientation().getAxis(renderUp,2);camera.getEntity().getOrientation().getAxis(renderRight,0);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0],'pixelOffset',pixelOffset);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0],'pixelSize',pixelSize);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0],'renderSize',renderSize);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0],'renderUp',renderUp);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector3(this.getThreeJsMaterials()[0],'renderRight',renderRight);if(camera.getType()!=='spout'){if(!this._normalSpaceBounds.has(camera)){this._normalSpaceBounds.set(camera,new _internal__WEBPACK_IMPORTED_MODULE_0__.Rect())} + const normalSpaceBounds=this._normalSpaceBounds.get(camera);normalSpaceBounds.thaw();const normalSpacePosition=this.getEntity().getNormalSpacePosition(camera);normalSpaceBounds.origin.x=normalSpacePosition.x+2.0*(this._pixelOffset.x-this._alignment.x*this._pixelSize.x)/renderSize.x;normalSpaceBounds.origin.y=normalSpacePosition.y+2.0*(this._pixelOffset.y-this._alignment.y*this._pixelSize.y)/renderSize.y;normalSpaceBounds.size.x=2.0*this._pixelSize.x/renderSize.x;normalSpaceBounds.size.y=2.0*this._pixelSize.y/renderSize.y;normalSpaceBounds.freeze()} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelSize);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelOffset);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(renderUp);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(renderRight);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(renderSize);let alphaMultiplier=1.0;const normalizedRadiusOfEntity=this.getEntity().getNormalSpaceExtentsRadius(camera);if(!this._ignoreDistance){alphaMultiplier*=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((0.02-normalizedRadiusOfEntity)/0.02)} + if(this.getEntity().getParent()!==null){const normalizedEntityDistanceFromParent=camera.getNormalSpaceRadiusFromRadius(this.getEntity().getPosition().magnitude(),cameraSpacePosition.magnitude());const normalizedParentRadius=this.getEntity().getParent().getNormalSpaceExtentsRadius(camera);if(!this._ignoreDistance&&normalizedParentRadius<0.02){alphaMultiplier*=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((normalizedEntityDistanceFromParent-0.02)/0.02)}} + if(this.getEntity().getParent()!==null&&this.getEntity().getParent().isOccludingPosition(camera,cameraSpacePosition)){alphaMultiplier=0}else if(camera.isPositionOccluded(cameraSpacePosition)){alphaMultiplier=0} + const color=_internal__WEBPACK_IMPORTED_MODULE_0__.Color.pool.get();color.copy(this._color);color.a*=alphaMultiplier;_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0],'colorMultiplier',color);_internal__WEBPACK_IMPORTED_MODULE_0__.Color.pool.release(color)} + async __loadResources(){if(LabelComponent._useCount===0){LabelComponent._threeJsGeometry=_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createGeometry([{name:'position',dimensions:2},{name:'uv',dimensions:2}],!1);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(LabelComponent._threeJsGeometry,'position',new Float32Array([0,0,1,0,1,1,0,1]));_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(LabelComponent._threeJsGeometry,'uv',new Float32Array([0,1,1,1,1,0,0,0]));_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(LabelComponent._threeJsGeometry,new Uint16Array([0,1,2,2,3,0]));LabelComponent._threeJsMaterial=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ShaderMaterial({uniforms:{colorMultiplier:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4(1.0,1.0,1.0,1.0)),colorTexture:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null),pixelOffset:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(0,0)),pixelSize:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(1,1)),renderSize:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(1,1)),renderUp:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0,1,0)),renderRight:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1,0,0)),..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms},vertexShader:` + uniform vec2 pixelOffset; + uniform vec2 pixelSize; + uniform vec2 renderSize; + uniform vec3 renderUp; + uniform vec3 renderRight; + varying vec2 fUV; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + // Get a frame for the label to be on the x-y axis. + vec3 forward = (modelMatrix * vec4(0, 0, 0, 1.)).xyz; + float distance = length(forward); + forward = normalize(forward); + vec3 up = normalize(renderUp); + vec3 right = normalize(cross(forward, up)); + + // Setup the up and right vectors. + up *= (position.y * pixelSize.y + pixelOffset.y) / renderSize.y * distance; + right *= (position.x * pixelSize.x + pixelOffset.x) / renderSize.x * distance * projectionMatrix[1][3]; + + // Do the transforms. + vec4 viewPosition = modelViewMatrix * vec4(up + right, 1.); + gl_Position = projectionMatrix * viewPosition; + + fUV = uv; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`,fragmentShader:` + precision highp float; + + uniform vec4 colorMultiplier; + uniform sampler2D colorTexture; + varying vec2 fUV; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main(void) { + gl_FragColor = texture2D(colorTexture, fUV); + gl_FragColor *= colorMultiplier; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`,side:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide});_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupLogDepthBuffering(LabelComponent._threeJsMaterial)} + LabelComponent._useCount+=1;const material=LabelComponent._threeJsMaterial.clone();this.getThreeJsMaterials().push(material);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setTransparent(material,!0);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOverlay(material,!0);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(material,'colorMultiplier',this._color);const object=_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObjectGivenGeometry(this,material,LabelComponent._threeJsGeometry);this.getThreeJsObjects().push(object);this._canvas=document.createElement('canvas');this._canvas.width=1;this._canvas.height=1;this._updateText()} + __unloadResources(){LabelComponent._useCount-=1;if(LabelComponent._useCount===0){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyGeometry(LabelComponent._threeJsGeometry);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyMaterial(LabelComponent._threeJsMaterial)} + const object=this.getThreeJsObjects()[0];if(object.parent!==null){object.parent.remove(object)} + this.getThreeJsMaterials()[0].dispose();this._canvas=null} + _updateText(){if(this._canvas===null){return} + const context=this._canvas.getContext('2d');this._devicePixelRatio=window.devicePixelRatio;context.font=this._fontSize+'px '+this._fontFamily;const metrics=context.measureText(this._text);this._pixelSize.set(metrics.width*this._devicePixelRatio,this._fontSize*this._devicePixelRatio);const textureWidth=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.ceilPow2(this._pixelSize.x);const textureHeight=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.ceilPow2(this._pixelSize.y);if(textureWidth!==this._canvas.width||textureHeight!==this._canvas.height){this._canvas.width=textureWidth;this._canvas.height=textureHeight} + context.clearRect(0,0,this._canvas.width,this._canvas.height);this._canvas.style.width=(textureWidth/this._devicePixelRatio)+'px';this._canvas.style.height=(textureHeight/this._devicePixelRatio)+'px';context.font=this._pixelSize.y+'px '+this._fontFamily;context.fillStyle='rgba(255, 255, 255, 255)';context.fillText(this._text,(this._canvas.width-this._pixelSize.x)*_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(this._alignment.x),(this._canvas.height-this._pixelSize.y*0.1875)-(this._canvas.height-this._pixelSize.y)*_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(this._alignment.y));const material=this.getThreeJsMaterials()[0];_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformTexture(material,'colorTexture',_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTextureFromCanvas(this._canvas))}} + LabelComponent._threeJsMaterial=null;LabelComponent._threeJsGeometry=null;LabelComponent._useCount=0}),"../pioneer/engine/src/scene/components/light_source_component.js": + /*!************************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/light_source_component.js ***! + \************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"LightSourceComponent":function(){return LightSourceComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class LightSourceComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._color=new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1,1,1);this._color.freeze();this._absoluteMagnitude=1;this.__setRadius(Number.POSITIVE_INFINITY)} + getColor(){return this._color} + setColor(color){this._color.thaw();this._color.copy(color);this._color.freeze()} + getAbsoluteMagnitude(){return this._absoluteMagnitude} + setAbsoluteMagnitude(absoluteMagnitude){this._absoluteMagnitude=absoluteMagnitude} + __loadResources(){this.getEntity().getScene().__addLightSource(this.getEntity().getName(),this.getTypeIndex());return Promise.resolve()} + __unloadResources(){this.getEntity().getScene().__removeLightSource(this.getEntity().getName(),this.getTypeIndex())} + __setTypeIndex(typeIndex){if(this.getLoadState()==='loaded'){this.getEntity().getScene().__removeLightSource(this.getEntity().getName(),this.getTypeIndex())} + super.__setTypeIndex(typeIndex);if(this.getLoadState()==='loaded'){this.getEntity().getScene().__addLightSource(this.getEntity().getName(),this.getTypeIndex())}}}}),"../pioneer/engine/src/scene/components/model_component.js": + /*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/model_component.js ***! + \*****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ModelComponent":function(){return ModelComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class ModelComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._url='';this._shadowEntities=[];this._translation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._translation.freeze();this._rotation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion();this._rotation.freeze();this._urlReferenceMap=new Map();this._threeJsAnimationClips=new Map();this._hiddenObjects=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._scale=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0.001,0.001,0.001);this._scale.freeze();this._modelRadius=NaN;this._environmentCubemapUrl='';this._environmentCylindricalUrl='';this._environmentCubemap=null;this._environmentIntensity=0.5;this._dynamicEnvironmentMapComponent=null;this._pixelRadiusVisibleInterval=undefined;this._useCompressedTextures=!1;this._onConfigChanged=this._onConfigChanged.bind(this);this.__setRadius(this.getEntity().getExtentsRadius())} + getUrl(){return this._url} + setUrl(url){if(this._url!==''){this.getEntity().getScene().getEngine().getDownloader().cancel(this._url)} + this.resetResources();this._modelRadius=NaN;this._loading=!1;this._url=url} + setHiddenObject(name,hidden){if(hidden&&!this._hiddenObjects.has(name)){this._hiddenObjects.set(name,null)}else if(!hidden&&this._hiddenObjects.has(name)){this._hiddenObjects.delete(name)}} + getTranslation(){return this._translation} + setTranslation(translation){this._translation.thaw();this._translation=translation;this._translation.freeze()} + getScale(){return this._scale} + setScale(scale){this._scale.thaw();if(typeof scale==='number'){this._scale.set(scale,scale,scale)}else{this._scale.copy(scale)} + this._scale.freeze();_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setScale(this.getThreeJsObjects()[0],this._scale);if(!isNaN(this._modelRadius)){this.__setRadius(Math.max(this._scale.x,this._scale.y,this._scale.z)*this._modelRadius)}else{this.__setRadius(this.getEntity().getExtentsRadius())}} + getRotation(){return this._rotation} + setRotation(rotation){this._rotation.thaw();this._rotation.copy(rotation);this._rotation.freeze()} + getEnvironmentCubemapUrl(){return this._environmentCubemapUrl} + setEnvironmentCubemapUrl(url){this._environmentCubemapUrl=url} + getEnvironmentIntensity(){return this._environmentIntensity} + setEnvironmentIntensity(environmentIntensity){this._environmentIntensity=environmentIntensity;for(let i=0,l=this.getThreeJsMaterials().length;i0);for(let i=0,l=this.getThreeJsMaterials().length;i{const urlFileName=url.substring(url.lastIndexOf('/')+1);if(this._urlReferenceMap.has(urlFileName)){return this._urlReferenceMap.get(urlFileName)} + return url});const loader=new _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsGLTFLoader(manager);await new Promise((resolve,reject)=>{loader.parse(download.content,_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LoaderUtils.extractUrlBase(download.actualUrl),async(gltf)=>{const root=gltf.scene;this._populateThreeJsObjectsAndMaterials(gltf.scene);if(this.getLoadState()!=='loading'){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this)} + this._clean();_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupObject(this,root);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setScale(root,this._scale);const boundingBox=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Box3().setFromObject(root);this._modelRadius=Math.max(boundingBox.min.length(),boundingBox.max.length());this.__setRadius(Math.max(this._scale.x,this._scale.y,this._scale.z)*this._modelRadius);for(let i=0;i{this._environmentCubemap=engine.getTextureLoader().generateEnvMap(cubeTexture)})}else if(this._environmentCylindricalUrl!==''){await engine.getTextureLoader().loadTexture(this._environmentCylindricalUrl,!0).then((texture)=>{this._environmentCubemap=engine.getTextureLoader().generateEnvMap(texture)})}} + this._updateMaterials();this.getEntity().getScene().getEngine().getConfig().addEventListener('gammaCorrection',this._onConfigChanged);resolve()},(error)=>{reject(new Error(`Error loading gltf: ${error}`))})})}catch(error){if(error instanceof Error){error.message=`While loading model "${this._url}": ${error.message}`} + throw error}} + __unloadResources(){for(let i=0,l=this._hiddenObjects.size;i0){newMaterial.defines.shadowEntities=!0} + newMaterial.needsUpdate=!0;return newMaterial}}}),"../pioneer/engine/src/scene/components/orbital_particles_component.js": + /*!*****************************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/orbital_particles_component.js ***! + \*****************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"OrbitalParticlesComponent":function(){return OrbitalParticlesComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class OrbitalParticlesComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._scaleOfParticles=1.0;this._loadFunction=null;this._orbitalElementsList=[];this._offsetArray=new Float32Array(0);this._spriteParticles=null;this.__setRadius(this.getEntity().getExtentsRadius()*100)} + getScaleOfParticles(){return this._scaleOfParticles} + setScaleOfParticles(scaleOfParticles){this._scaleOfParticles=scaleOfParticles;this.resetResources()} + setLoadFunction(loadFunction){this._loadFunction=loadFunction;this.resetResources()} + __update(){if(this._spriteParticles===null){return} + const position=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const velocity=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const time=this.getEntity().getScene().getEngine().getTime();for(let i=0,l=this._orbitalElementsList.length;i 0.0 ? u : (1.0 - u); + float sizeAtU = size * max(0.1, uSpread); + vec3 directionPerp2 = cross(direction, directionPerp); + vec3 modelPosition = originOffset + (directionPerp * params.x * sinSpread * uSpread + directionPerp2 * params.y * sinSpread * uSpread + direction * u) * length; + vec4 viewPosition = vec4(position.x * sizeAtU, 0, position.y * sizeAtU, 1) + modelViewMatrix * vec4(modelPosition, 1.0); + gl_Position = projectionMatrix * viewPosition; + gl_Position.w = viewPosition.y; + + // Set the varying variables. + vPosition = position; + vColor = color * (1.0 - u); + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`;ParticleSprayComponent.fragmentShader=` + precision highp float; + + uniform vec4 globalColor; + + varying vec2 vPosition; + varying vec4 vColor; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main(void) { + // Set the color to be a circle tinted by the color and globalColor. + gl_FragColor = globalColor * vColor * max(0.0, 1.0 - dot(vPosition, vPosition)); + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`}),"../pioneer/engine/src/scene/components/rings_component.js": + /*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/rings_component.js ***! + \*****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"RingsComponent":function(){return RingsComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class RingsComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._topTextureUrl='';this._bottomTextureUrl='';this._innerRadius=0;this._outerRadius=0;this._fadeDistance=0;this._shadowEntities=[];this._spheroidComponentRef=new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene());this._spheroidComponentRef.setByType(this.getEntity().getName(),'spheroid');this._spheroidComponentRef.setRefChangedCallback(this._spheroidRefChangedCallback.bind(this));this._spheroidChangedCallback=this._spheroidChangedCallback.bind(this);this.__setUsesEntityOrientation(!0)} + getTopTextureUrl(){return this._topTextureUrl} + setTopTextureUrl(url){this._topTextureUrl=url;_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTextureIntoUniform(this,this.getThreeJsMaterials()[0],'topTexture',this._topTextureUrl,!0,!1)} + getBottomTextureUrl(){return this._bottomTextureUrl} + setBottomTextureUrl(url){this._bottomTextureUrl=url;_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTextureIntoUniform(this,this.getThreeJsMaterials()[0],'bottomTexture',this._bottomTextureUrl,!0,!1)} + getInnerRadius(){return this._innerRadius} + setInnerRadius(radius){this._innerRadius=radius;_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'innerRadius',this._innerRadius)} + getOuterRadius(){return this._outerRadius} + setOuterRadius(radius){this._outerRadius=radius;this.__setRadius(this._outerRadius);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'outerRadius',this._outerRadius)} + getTopTexture(){const material=this.getThreeJsMaterials()[0];if(material!==undefined){return material.uniforms.topTexture.value} + return null} + getFadeDistance(){return this._fadeDistance} + setFadeDistance(fadeDistance){this._fadeDistance=fadeDistance} + getShadowEntity(index){return this._shadowEntities[index]?.getName()} + setShadowEntities(shadowEntities){this._shadowEntities=[];for(const shadowEntity of shadowEntities){this._shadowEntities.push(new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(),shadowEntity))} + const shadowEntitiesEnabled=(shadowEntities.length>0);for(let i=0,l=this.getThreeJsMaterials().length;i0){const posInSpriteFrame=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const orientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();const threeJsOrientation=this.getThreeJsObjects()[0].quaternion;orientation.copyFromThreeJs(threeJsOrientation);posInSpriteFrame.rotateInverse(this.getEntity().getOrientation(),this.getEntity().getCameraSpacePosition(camera));_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'alphaFadeMultiplier',_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(0,1,_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(2*(Math.abs(posInSpriteFrame.z)/this._fadeDistance-1)+1)));_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posInSpriteFrame)} + _internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setLightSourceUniforms(this.getThreeJsMaterials(),this.getEntity(),camera);_internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setUniforms(this.getThreeJsMaterials(),camera,this.getEntity(),this._shadowEntities,null,!1);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0],this.getEntity());_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0],this.getEntity(),camera)} + async __loadResources(){const topPromise=_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTexture(this,this._topTextureUrl,!0,!1);const bottomPromise=_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTexture(this,this._bottomTextureUrl,!0,!1);const[topTexture,bottomTexture]=await Promise.all([topPromise,bottomPromise]);if(this.isDestroyed()){topTexture.dispose();bottomTexture.dispose();return} + const material=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ShaderMaterial({uniforms:{ambientLightColor:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Color()),lightPositions:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1,0,0),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1,0,0),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1,0,0),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1,0,0),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(1,0,0)]),lightColors:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0,0,0),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0,0,0),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0,0,0),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0,0,0),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(0,0,0)]),lightRadii:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0,0,0,0,0]),numLights:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0),entityPos:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()),innerRadius:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._innerRadius),outerRadius:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(this._outerRadius),topTexture:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(topTexture),bottomTexture:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(bottomTexture),alphaFadeMultiplier:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1),spheroidEquatorialRadius:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0),spheroidPolarRadius:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0),numShadowEntities:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(0),shadowEntityPositions:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()]),shadowEntityRadii:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0,0,0,0,0]),shadowEntitySunsetIntensity:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([0,0,0,0,0]),shadowEntitySunsetColors:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform([new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3(),new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector3()]),..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms},vertexShader:RingsComponent.vertexShader,fragmentShader:RingsComponent.fragmentShader,transparent:!0,depthWrite:!1,blending:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.NormalBlending,side:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide});_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupLogDepthBuffering(material);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setDefine(material,'shadowEntities',this._shadowEntities.length>0);this.getThreeJsMaterials().push(material);const object=_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this,material,[{name:'position',dimensions:3},{name:'normal',dimensions:3}],!1);const numSegments=10;const positions=new Float32Array(3*numSegments*numSegments);const normals=new Float32Array(3*numSegments*numSegments);const indices=new Uint16Array(6*(numSegments-1)*(numSegments-1));for(let j=0;j 0.0) { + return 0.0; + } + else { + return 1.0; + } + } + + #ifdef shadowEntities + vec3 applyRayleighScattering(vec3 color, float amount) { + float value = (color.r + color.g + color.b); + if (value > 0.0) { + float rFactor = 1.0; // 6.3^-4 / 6.3^-4 + float gFactor = 1.602; // 5.6^-4 / 6.3^-4 + float bFactor = 3.228; // 4.7^-4 / 6.3^-4 + color.r *= pow(rFactor, -amount); + color.g *= pow(gFactor, -amount); + color.b *= pow(bFactor, -amount); + color = value * color / (color.r + color.g + color.b); + } + return color; + } + + vec3 getLightColorFromShadowEntities(vec3 lightColor, vec3 lightDir, vec3 lightPosition, float lightRadius, vec3 normal) { + vec3 color = lightColor; + for (int i = 0; i < 5; i++) { + if (i >= numShadowEntities) { + break; + } + vec3 origin = cameraSpacePosition - shadowEntityPositions[i]; + vec3 axis = normalize(shadowEntityPositions[i] - lightPosition); + float sd = dot(origin, axis); + if (sd > 0.0) { + float e = length(origin - sd * axis); + float ld = dot(cameraSpacePosition - lightPosition, axis); + float lr = lightRadius; + float sr = shadowEntityRadii[i]; + float e0 = (ld * sr - sd * lr) / (ld - sd); + float e1 = (ld * sr + sd * lr) / (ld - sd); + float lightLevel = 0.0; + if (e1 < 0.0 || sd < 0.0) { // light in front of shadow entity + lightLevel = 1.0; + } + else if (e0 < e1) { + e0 /= max(1.0, shadowEntitySunsetIntensity[i] * 2.0); + lightLevel = (e - e0) / (e1 - e0); + } + else { + lightLevel = e < e0 ? 0.0 : 1.0; // 0 radius light. + } + color = saturate(lightLevel) * applyRayleighScattering(color, saturate(1.5 - lightLevel) * saturate(shadowEntitySunsetIntensity[i])); + } + } + return color; + } + #endif + + void main(void) { + float spheroidScaling = spheroidEquatorialRadius / spheroidPolarRadius; + vec3 positionDir = normalize(cameraSpacePosition); + vec3 ringPos = cameraSpacePosition - entityPos; + vec3 normal = normalize(modelNormal); + float cameraCosAngle = -dot(positionDir, normal); + + // Calculate the UVs. + vec2 uv; + uv.x = (length(localPosition) - innerRadius) / (outerRadius - innerRadius); + if (uv.x < 0.0 || uv.x > 1.0) { + gl_FragColor = vec4(0, 0, 0, 0); + return; + } + uv.y = 0.0; + + // Get the pixels at those uvs. + vec4 topPixel = texture2D(topTexture, uv); + vec4 bottomPixel = texture2D(bottomTexture, uv); + + // Get the initial diffuse light. + vec3 diffuseLight = ambientLightColor; + + // For each light, + for (int i = 0; i < 5; i++) { + if (i >= numLights) { + break; + } + + vec3 lightDir = normalize(cameraSpacePosition - lightPositions[i]); + float lightCosAngle = -dot(lightDir, normal); + + vec3 incomingLight = lightColors[i]; + + #ifdef shadowEntities + incomingLight = getLightColorFromShadowEntities(incomingLight, lightDir, lightPositions[i], lightRadii[i], normal); + #endif + + float cameraDirDotLight = dot(positionDir, lightDir); + float bottomTopRatio = (1.0 + 0.2 * cameraDirDotLight) * sign(cameraCosAngle) * lightCosAngle; + float shadow = spheroidShadow(lightDir, lightCosAngle, spheroidScaling, normal, ringPos); + vec3 bottomColor = saturate(incomingLight * (1.0 - bottomTopRatio) * shadow); + vec3 topColor = 2.0 * saturate(incomingLight * bottomTopRatio * shadow); + + vec3 color = mix(bottomPixel.rgb * bottomColor, topPixel.rgb * topColor, bottomTopRatio); + gl_FragColor.rgb += color; + } + + gl_FragColor.a = topPixel.a; + gl_FragColor.a *= alphaFadeMultiplier; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`}),"../pioneer/engine/src/scene/components/skybox_component.js": + /*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/skybox_component.js ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SkyboxComponent":function(){return SkyboxComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class SkyboxComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._numLatVerts=20;this._textureUrl='';this.__setRadius(1e24);this.__setUsesEntityOrientation(!0)} + getTextureUrl(){return this._textureUrl} + setTextureUrl(url){this._textureUrl=url;this.resetResources()} + __prepareForRender(camera){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0],this.getEntity());_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0],this.getEntity(),camera)} + async __loadResources(){const texture=await _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTexture(this,this._textureUrl,!1,!1);if(this.getLoadState()!=='loading'){texture.dispose();return} + const material=_internal__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.get();this.getThreeJsMaterials().push(material);material.defines.colorMapEmmissive=!0;material.needsUpdate=!0;material.uniforms.colorTexture.value=texture;const object=_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this,material,[{name:'position',dimensions:3},{name:'uv',dimensions:2}],!1);this.getThreeJsObjects().push(object);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.useInDynEnvMap(object,!0);const latStep=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi/(this._numLatVerts-1);const lonStep=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi/this._numLatVerts;const numVerts=(this._numLatVerts*2+1)*this._numLatVerts;const meshPositions=new Float32Array(numVerts*3);const meshUVs=new Float32Array(numVerts*2);const meshIndices=new Uint16Array(this._numLatVerts*(this._numLatVerts-1)*12);const xyz=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const lla=_internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get();for(let latI=0;latI0){const uniform=materials[i].uniforms[name+'Texture'];if(uniform!==undefined){textureLOD.setUniform(uniform)}} + textureLODs.push(textureLOD)} + this._textureLODs.set(name,textureLODs)} + for(let i=0,l=this._numFaces;i0);for(let i=0,l=this.getThreeJsMaterials().length;i{this._updateMeshes()})} + __unloadResources(){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this);for(let i=0;i= xyz.y * xyz.y && xyz.x * xyz.x >= xyz.z * xyz.z) { + if (xyz.x >= 0.0) { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(1, 0, 0); + face = 0.0; + } + else { + basis[0] = vec3(0, -1, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(-1, 0, 0); + face = 2.0; + } + } + else if (xyz.y * xyz.y >= xyz.x * xyz.x && xyz.y * xyz.y >= xyz.z * xyz.z) { + if (xyz.y >= 0.0) { + basis[0] = vec3(-1, 0, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(0, 1, 0); + face = 1.0; + } + else { + basis[0] = vec3(1, 0, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(0, -1, 0); + face = 3.0; + } + } + else { + if (xyz.z >= 0.0) { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(-1, 0, 0); basis[2] = vec3(0, 0, 1); + face = 4.0; + } + else { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(1, 0, 0); basis[2] = vec3(0, 0, -1); + face = 5.0; + } + } + + vec3 uv = vec3( + basis[0].x * xyz.x + basis[0].y * xyz.y + basis[0].z * xyz.z, + basis[1].x * xyz.x + basis[1].y * xyz.y + basis[1].z * xyz.z, + basis[2].x * xyz.x + basis[2].y * xyz.y + basis[2].z * xyz.z); + uv.x /= uv.z; + uv.y /= uv.z; + + return vec3(0.5 * (uv.x + 1.0), 0.5 * (uv.y + 1.0), face); + } + + void main() { + vec3 uvFace = xyToUvFace(xy); + + vec4 pixel; + int face = int(uvFace.z); + + if (face == 0) { + pixel = texture2D(textures[0], vec2(uvFace.x, uvFace.y)); + } + else if (face == 1) { + pixel = texture2D(textures[1], vec2(uvFace.x, uvFace.y)); + } + else if (face == 2) { + pixel = texture2D(textures[2], vec2(uvFace.x, uvFace.y)); + } + else if (face == 3) { + pixel = texture2D(textures[3], vec2(uvFace.x, uvFace.y)); + } + else if (face == 4) { + pixel = texture2D(textures[4], vec2(uvFace.x, uvFace.y)); + } + else if (face == 5) { + pixel = texture2D(textures[5], vec2(uvFace.x, uvFace.y)); + } + + gl_FragColor = pixel; + }`,depthTest:!1,depthWrite:!1,side:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide});this._threeJsQuad=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh(geometry,material);this._threeJsQuad.frustumCulled=!1;this._threeJsSpoutScene.add(this._threeJsQuad)}} + const _tempThreeJsQuaternion=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Quaternion()}),"../pioneer/engine/src/scene/components/sprite_component.js": + /*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/sprite_component.js ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SpriteComponent":function(){return SpriteComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class SpriteComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._textureUrl='';this._size=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(1,Number.NaN);this._size.freeze();this._sizeUnits='km';this._colorMultiplier=new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1,1,1,1);this._colorMultiplier.freeze();this._alignment=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(0.5,0.5);this._alignment.freeze();this._fadeDistance=0;this._transparent=!1;this._blending='normal';this._billboard=!1;this._renderOrder=0} + getTextureUrl(){return this._textureUrl} + setTextureUrl(url){this._textureUrl=url;this.resetResources()} + getSize(){return this._size} + setSize(size){this._size.thaw();this._size.copy(size);this._size.freeze();this._updateSizeUniform()} + getSizeUnits(){return this._sizeUnits} + setSizeUnits(sizeUnits){this._sizeUnits=sizeUnits;this._updateSizeUniform()} + getColorMultiplier(){return this._colorMultiplier} + setColorMultiplier(colorMultiplier){this._colorMultiplier.thaw();this._colorMultiplier.copy(colorMultiplier);this._colorMultiplier.freeze();_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0],'colorMultiplier',colorMultiplier)} + getAlignment(){return this._alignment} + setAlignment(alignment){this._alignment.thaw();this._alignment.copy(alignment);this._alignment.freeze();_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0],'origin',this._alignment)} + getFadeDistance(){return this._fadeDistance} + setFadeDistance(fadeDistance){this._fadeDistance=fadeDistance} + isBillboard(){return this._billboard} + setBillboard(billboard){this._billboard=billboard} + getTransparent(){return this._transparent} + setTransparent(transparent){this._transparent=transparent;_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setTransparent(this.getThreeJsMaterials()[0],this._transparent)} + setBlending(blending){this._blending=blending;_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setBlending(this.getThreeJsMaterials()[0],this._blending)} + getRenderOrder(){return this._renderOrder} + setRenderOrder(renderOrder){this._renderOrder=renderOrder;_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setRenderOrder(this.getThreeJsObjects()[0],this._renderOrder)} + __prepareForRender(camera){if(this._sizeUnits==='pixels'){const size=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();const sizeMultiplier=this.getEntity().getExtentsRadius()/this.getEntity().getPixelSpaceExtentsRadius(camera);size.mult(this._size,sizeMultiplier);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0],'size',size);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(size)} + if(this.getThreeJsObjects().length>0){if(this._billboard){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToBillboard(this.getThreeJsObjects()[0],this.getEntity(),camera)}else{_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects()[0],this.getEntity())}} + if(this._fadeDistance>0){const posInSpriteFrame=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const orientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();const threeJsOrientation=this.getThreeJsObjects()[0].quaternion;orientation.copyFromThreeJs(threeJsOrientation);posInSpriteFrame.rotateInverse(this.getEntity().getOrientation(),this.getEntity().getCameraSpacePosition(camera));_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'alphaFadeMultiplier',_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(0,1,_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(2*(Math.abs(posInSpriteFrame.z)/this._fadeDistance-1)+1)));_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(posInSpriteFrame)} + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0],this.getEntity(),camera)} + async __loadResources(){const texture=await _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTexture(this,this._textureUrl,!1,!1);if(this.getLoadState()!=='loading'){texture.dispose();return} + if(SpriteComponent._useCount===0){SpriteComponent._threeJsGeometry=_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createGeometry([{name:'position',dimensions:3},{name:'uv',dimensions:2}],!1);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(SpriteComponent._threeJsGeometry,'position',new Float32Array([0,0,0,1,0,0,1,1,0,0,1,0]));_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setVertices(SpriteComponent._threeJsGeometry,'uv',new Float32Array([0,1,1,1,1,0,0,0]));_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setIndices(SpriteComponent._threeJsGeometry,new Uint16Array([0,1,2,2,3,0]));SpriteComponent._threeJsMaterial=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ShaderMaterial({uniforms:{colorMultiplier:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector4(1.0,1.0,1.0,1.0)),alphaFadeMultiplier:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1),size:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(1.0,1.0)),colorTexture:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(null),origin:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Vector2(0,0)),..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms},vertexShader:` + uniform vec2 size; + uniform vec2 origin; + varying vec2 fUV; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + vec4 viewPosition = modelViewMatrix * vec4((position.x - origin.x) * size.x, (position.y - origin.y) * size.y, 0.0, 1.0); + gl_Position = projectionMatrix * viewPosition; + fUV = uv; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`,fragmentShader:` + precision highp float; + + uniform vec4 colorMultiplier; + uniform float alphaFadeMultiplier; + uniform sampler2D colorTexture; + varying vec2 fUV; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main(void) { + gl_FragColor = texture2D(colorTexture, fUV); + gl_FragColor *= colorMultiplier; + gl_FragColor.a *= alphaFadeMultiplier; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`,side:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DoubleSide});_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupLogDepthBuffering(SpriteComponent._threeJsMaterial)} + SpriteComponent._useCount+=1;const material=SpriteComponent._threeJsMaterial.clone();this.getThreeJsMaterials().push(material);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setTransparent(material,this._transparent);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setBlending(material,this._blending);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(material,'colorMultiplier',this._colorMultiplier);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material,'alphaFadeMultiplier',1);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(material,'origin',this._alignment);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformTexture(material,'colorTexture',texture);const object=_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObjectGivenGeometry(this,material,SpriteComponent._threeJsGeometry);this.getThreeJsObjects().push(object);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setRenderOrder(object,this._renderOrder);this._updateSizeUniform()} + __unloadResources(){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyMaterial(this.getThreeJsMaterials()[0]);const object=this.getThreeJsObjects()[0];if(object.parent!==undefined){object.parent.remove(object)} + SpriteComponent._useCount-=1;if(SpriteComponent._useCount===0){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyGeometry(SpriteComponent._threeJsGeometry);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyMaterial(SpriteComponent._threeJsMaterial)}} + _updateSizeUniform(){if(this.getThreeJsMaterials().length>0){const texture=this.getThreeJsMaterials()[0].uniforms.colorTexture.value;if(texture!==null){const textureAspectRatio=texture.image.width/texture.image.height;const size=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();if(Number.isNaN(this._size.x)){size.set(this._size.y*textureAspectRatio,this._size.y)}else if(Number.isNaN(this._size.y)){size.set(this._size.x,this._size.x/textureAspectRatio)}else{size.set(this._size.x,this._size.y)} + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(this.getThreeJsMaterials()[0],'size',size);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(size);if(this._sizeUnits==='km'){this.__setRadius(Math.max(size.x,size.y))}else{this.__setRadius(Number.POSITIVE_INFINITY)}}}else{if(this._sizeUnits==='km'){if(Number.isNaN(this._size.x)){this.__setRadius(this._size.y)}else if(Number.isNaN(this._size.y)){this.__setRadius(this._size.y)}else{this.__setRadius(Math.max(this._size.x,this._size.y))}}else{this.__setRadius(Number.POSITIVE_INFINITY)}}}} + SpriteComponent._threeJsMaterial=null;SpriteComponent._threeJsGeometry=null;SpriteComponent._useCount=0}),"../pioneer/engine/src/scene/components/starfield_component.js": + /*!*********************************************************************!*\ + !*** ../pioneer/engine/src/scene/components/starfield_component.js ***! + \*********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"StarfieldComponent":function(){return StarfieldComponent}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");const eclipJ2000ToJ200Rotation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(0.9791532214288992,0.2031230389823101,0,0);class Star{constructor(){this.mag=0;this.absMag=0;this.color=new _internal__WEBPACK_IMPORTED_MODULE_0__.Color();this.position=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this.particle=null}} + class StarfieldComponent extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._url='';this.__setRadius(1e24)} + getUrl(){return this._url} + setUrl(url){this._url=url;this.resetResources()} + __prepareForRender(camera){const renderSize=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();if(camera.getType()==='spout'){const spoutComponent=(camera);renderSize.set(spoutComponent.getRenderWidth(),spoutComponent.getRenderWidth()*0.5)}else{renderSize.copy(camera.getViewport().getBounds().size)} + const resolutionFactor=Math.sqrt(Math.max(renderSize.x,renderSize.y)*window.devicePixelRatio)/60;_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(this.getThreeJsMaterials()[0],'resolutionFactor',resolutionFactor);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(renderSize);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0],this.getEntity(),camera)} + async __loadResources(){const stars=await this._loadStars();if(this.isDestroyed()){return} + const material=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.ShaderMaterial({vertexShader:StarfieldComponent.vertexShader,fragmentShader:StarfieldComponent.fragmentShader,transparent:!0,blending:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.AdditiveBlending,depthWrite:!1,uniforms:{resolutionFactor:new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Uniform(1.0),..._internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.ThreeUniforms}});_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupLogDepthBuffering(material);this.getThreeJsMaterials().push(material);const threeJsGeometry=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferGeometry();threeJsGeometry.setAttribute('position',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Float32Array(0),3));threeJsGeometry.setAttribute('color',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Float32Array(0),4));threeJsGeometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Uint16Array(0),1));const threeJsObject=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Points(threeJsGeometry,material);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setupObject(this,threeJsObject);threeJsObject.renderOrder=-2;this.getThreeJsObjects().push(threeJsObject);const meshPositions=new Float32Array(stars.length*3);const meshColors=new Float32Array(stars.length*4);const meshIndices=new Uint16Array(stars.length);for(let i=0;i{if(download.status==='cancelled'){return Promise.resolve([])}else if(download.status==='failed'){return Promise.reject(new Error('Failed to load starfield component file "'+download.url+'": '+download.errorMessage))} + if(!(download.content instanceof ArrayBuffer)){return Promise.reject(new Error('Failed to load starfield component file "'+download.url+'": Not a binary file.'))} + const reader=new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content);const numStars=reader.readInt32();const stars=[];for(let i=0;i0){const geometry=((this.getThreeJsObjects()[0])).geometry;const newArray=new Float32Array(0);const buffer=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBuffer(newArray,TrailComponent.VERTEX_SIZE);geometry.setAttribute('position',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,3,0,!1));geometry.setAttribute('positionPrev',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,3,3,!1));geometry.setAttribute('positionNext',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,3,6,!1));geometry.setAttribute('side',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,1,9,!1));geometry.setAttribute('index',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,1,10,!1));geometry.setAttribute('dashOffset',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,1,11,!1));geometry.setIndex(new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferAttribute(new Uint16Array(0),1))}} + __loadResources(){const material=this.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('trail');this.getThreeJsMaterials().push(material);material.uniforms.dashLength.value=this._dashLength;material.uniforms.dashGapLength.value=this._dashGapLength;material.uniforms.indexStart.value=0;material.uniforms.indexCount.value=0;material.uniforms.indexLength.value=0;material.uniforms.color.value.set(this._color.r,this._color.g,this._color.b,this._color.a);material.uniforms.widthMin.value=this._widthMin;material.uniforms.widthMax.value=this._widthMax;material.uniforms.glowWidth.value=this._glowWidth;material.uniforms.alphaFade.value=this._alphaFade;const threeJsObject=_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this,material,[{name:'position',dimensions:3},{name:'positionPrev',dimensions:3},{name:'positionNext',dimensions:3},{name:'side',dimensions:1},{name:'index',dimensions:1},{name:'dashOffset',dimensions:1}],!0);this.getThreeJsObjects().push(threeJsObject);return Promise.resolve()} + __unloadResources(){this.getEntity().getScene().getEngine().getMaterialManager().release(this.getThreeJsMaterials()[0]);_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this);this._points=[];this._pointsCount=0;this._pointsStart=0} + __prepareForRender(camera){if(this._relativeToEntity.getName()===''&&this.getEntity().getParent()!==null&&this._currentRelativeToEntity.get()!==this.getEntity().getParent()){this._currentRelativeToEntity.setName(this.getEntity().getParent().getName());this.resetPoints()} + if(this._currentRelativeToEntity===null){return} + this._updatePoints();const material=this.getThreeJsMaterials()[0];material.uniforms.indexStart.value=this._pointsStart;material.uniforms.indexCount.value=this._pointsCount;material.uniforms.indexLength.value=this._points.length;let alphaMultiplier=1.0;if(!this._ignoreDistance){const normalizedSizeOfEntity=this.getEntity().getNormalSpaceExtentsRadius(camera);alphaMultiplier*=(0.02-normalizedSizeOfEntity)/0.02;const camDistOverPosDist=this.getEntity().getCameraSpacePosition(camera).magnitude()/this.getEntity().getPosition().magnitude();alphaMultiplier*=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01(camDistOverPosDist*1000)} + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformNumber(material,'alphaMultiplier',alphaMultiplier);const pixelSize=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();if(camera instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.SpoutComponent){pixelSize.set(camera.getRenderWidth()*0.1,camera.getRenderWidth()*0.5*0.1)}else{pixelSize.copy(camera.getViewport().getBounds().size)} + _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformVector2(material,'pixelSize',pixelSize);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(pixelSize);const currentRelativeToEntity=this._currentRelativeToEntity.get();if(currentRelativeToEntity!==null){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPosition(this.getThreeJsObjects(),currentRelativeToEntity.getCameraSpacePosition(camera));if(this._relativeToEntityOrientation){_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientation(this.getThreeJsObjects(),currentRelativeToEntity.getOrientation())}}} + _updatePoints(){const intervalForUpdate=_internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get();this._getIntervalForUpdate(intervalForUpdate);if(isNaN(intervalForUpdate.min)||isNaN(intervalForUpdate.max)){_internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(intervalForUpdate);return} + const initialTimeStep=this._initialTimeStep??(intervalForUpdate.length()*this._angleCurveThreshold/(2*Math.PI));const updateRange=_internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get();updateRange.set(Number.POSITIVE_INFINITY,0);if(this._relativeStartTime&&this._pointsCount>0&&this._points[this._pointsStart].time!==intervalForUpdate.min){this._popFrontPoint(updateRange)} + while(this._pointsCount>0&&this._points[this._pointsStart].timeintervalForUpdate.min){if(this._pointsCount>=16000&&this._relativeStartTime){break} + this._pushFrontPoint(updateRange);const nextPoint=this._points[this._pointsStart];let minStep=1;let maxStep=Number.POSITIVE_INFINITY;let step=initialTimeStep;if(this._pointsCount>2){step=this._points[(this._pointsStart+2)%this._points.length].time-this._points[(this._pointsStart+1)%this._points.length].time} + let curvatureCheckCount=0;while(curvatureCheckCount<20){let nextTime=intervalForUpdate.max;if(this._pointsCount>1){nextTime=this._points[(this._pointsStart+1)%this._points.length].time-step} + if(nextTime=2){angle=this._points[(this._pointsStart+1)%this._points.length].velocity.angle(nextPoint.velocity)} + if(angle>this._angleCurveThreshold){maxStep=step;step=(minStep+step)/2.0}else if(this._pointsCount>1&&step0&&this._points[(this._pointsStart+this._pointsCount-1)%this._points.length].time!==intervalForUpdate.max){this._popBackPoint(updateRange)} + while(this._pointsCount>0&&this._points[(this._pointsStart+this._pointsCount-1)%this._points.length].time>intervalForUpdate.max){this._popBackPoint(updateRange)} + while(this._pointsCount===0||this._points[(this._pointsStart+this._pointsCount-1)%this._points.length].time=16000&&this._relativeEndTime){break} + this._pushBackPoint(updateRange);const nextPoint=this._points[(this._pointsStart+this._pointsCount-1)%this._points.length];let minStep=1;let maxStep=Number.POSITIVE_INFINITY;let step=initialTimeStep;if(this._pointsCount>2){step=this._points[(this._pointsStart+this._pointsCount-2)%this._points.length].time-this._points[(this._pointsStart+this._pointsCount-3)%this._points.length].time} + let curvatureCheckCount=0;while(curvatureCheckCount<20){let nextTime=intervalForUpdate.min;if(this._pointsCount>1){nextTime=this._points[(this._pointsStart+this._pointsCount-2)%this._points.length].time+step} + if(nextTime>intervalForUpdate.max){nextTime=intervalForUpdate.max} + nextPoint.time=nextTime;this._getPositionAndVelocity(nextPoint.position,nextPoint.velocity,nextPoint.time);if(nextPoint.position.isNaN()||(this._relativeToEntityOrientation&&orientation.isNaN())){break} + let angle=0;if(this._pointsCount>=2){angle=this._points[(this._pointsStart+this._pointsCount-2)%this._points.length].velocity.angle(nextPoint.velocity)} + if(angle>this._angleCurveThreshold){maxStep=step;step=(minStep+step)/2.0}else if(this._pointsCount>1&&step0){this._resize(this._pointsCount-1,updateRange);updateRange.expandTo(this._pointsStart);if(this._pointsCount>1){updateRange.expandTo((this._pointsStart+1)%this._points.length)} + this._points[this._pointsStart].position.x=NaN;this._pointsStart=(this._pointsStart+1)%this._points.length;this._pointsCount-=1}} + _popBackPoint(updateRange){if(this._pointsCount>0){this._resize(this._pointsCount-1,updateRange);this._pointsCount-=1;updateRange.expandTo((this._pointsStart+this._pointsCount)%this._points.length);if(this._pointsCount>0){updateRange.expandTo((this._pointsStart+this._pointsCount-1)%this._points.length)} + this._points[(this._pointsStart+this._pointsCount)%this._points.length].position.x=NaN}} + _pushFrontPoint(updateRange){this._resize(this._pointsCount+1,updateRange);this._pointsStart=(this._pointsStart+this._points.length-1)%this._points.length;updateRange.expandTo(this._pointsStart);if(this._pointsCount>0){updateRange.expandTo((this._pointsStart+1)%this._points.length)} + this._pointsCount+=1} + _pushBackPoint(updateRange){this._resize(this._pointsCount+1,updateRange);this._pointsCount+=1;updateRange.expandTo((this._pointsStart+this._pointsCount-1)%this._points.length);if(this._pointsCount>1){updateRange.expandTo((this._pointsStart+this._pointsCount-2)%this._points.length)}} + _resize(newCount,updateRange){let resizing=!1;let newSize=this._points.length;if(newCount+1>this._points.length||(newCount<=this._points.length/4&&newCount>=8)){resizing=!0} + if(resizing){newSize=Math.max(8,_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.ceilPow2(newCount+1));const points=([]);for(let i=0,l=this._pointsCount;i{this._removeDependentStates(oldRef,this._primaryAlignType);this._addDependentStates(newRef,this._primaryAlignType)});this._primaryTargetAxis=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(1,0,0);this._primaryTargetAxis.freeze();this._secondaryAlignType='none';this._secondaryAxis=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,1,0);this._secondaryAxis.freeze();this._secondaryTargetEntity=new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());this._secondaryTargetEntity.setRefChangedCallback((oldRef,newRef)=>{this._removeDependentStates(oldRef,this._secondaryAlignType);this._addDependentStates(newRef,this._secondaryAlignType)});this._secondaryTargetAxis=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,1,0);this._secondaryTargetAxis.freeze();this._joint='';this._jointObject=null;this._model=null;this._modelRootId=0;this.addModifiedState('orientation')} + getPrimaryAlignType(){return this._primaryAlignType} + setPrimaryAlignType(alignType){if(this._primaryAlignType===alignType){return} + this._removeDependentStates(this._primaryTargetEntity.get(),this._primaryAlignType);this._primaryAlignType=alignType;this._addDependentStates(this._primaryTargetEntity.get(),this._primaryAlignType)} + getPrimaryAxis(){return this._primaryAxis} + setPrimaryAxis(axis){this._primaryAxis.thaw();this._primaryAxis.copy(axis);this._primaryAxis.freeze()} + getPrimaryTargetEntity(){return this._primaryTargetEntity.getName()} + setPrimaryTargetEntity(targetEntityName){this._primaryTargetEntity.setName(targetEntityName)} + getPrimaryTargetAxis(){return this._primaryTargetAxis} + setPrimaryTargetAxis(targetAxis){this._primaryTargetAxis.thaw();this._primaryTargetAxis.copy(targetAxis);this._primaryTargetAxis.freeze()} + getSecondaryAlignType(){return this._secondaryAlignType} + setSecondaryAlignType(alignType){if(this._secondaryAlignType===alignType){return} + this._removeDependentStates(this._secondaryTargetEntity.get(),this._secondaryAlignType);this._secondaryAlignType=alignType;this._addDependentStates(this._secondaryTargetEntity.get(),this._secondaryAlignType)} + getSecondaryAxis(){return this._secondaryAxis} + setSecondaryAxis(axis){this._secondaryAxis.thaw();this._secondaryAxis.copy(axis);this._secondaryAxis.freeze()} + getSecondaryTargetEntity(){return this._secondaryTargetEntity.getName()} + setSecondaryTargetEntity(targetEntityName){this._secondaryTargetEntity.setName(targetEntityName)} + getSecondaryTargetAxis(){return this._secondaryTargetAxis} + setSecondaryTargetAxis(targetAxis){this._secondaryTargetAxis.thaw();this._secondaryTargetAxis.copy(targetAxis);this._secondaryTargetAxis.freeze()} + setJoint(joint,model){this._joint=joint;if(!model){const modelFromEntity=(this.getEntity().get('model'));if(modelFromEntity!==null){this._model=modelFromEntity}}else{this._model=model} + if(this._joint!==''){this.addDependentState(this.getEntity().getName(),'orientation');this.removeModifiedState('orientation')}else{this.removeDependentState(this.getEntity().getName(),'orientation');this.addModifiedState('orientation')}} + __updateOrientationAtTime(orientation,time){if(this._joint!==''){return} + this._getOrientation(orientation,time)} + __update(){const newOrientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();if(this._jointObject!==null){newOrientation.copy(this.getEntity().getOrientation())}else{newOrientation.copy(this.getEntity().getOrientation())} + this._getOrientation(newOrientation);if(this._jointObject!==null){this._jointObject.quaternion.set(newOrientation.x,newOrientation.y,newOrientation.z,newOrientation.w)}else{this.getEntity().setOrientation(newOrientation)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation)} + _getOrientation(orientation,time){if(this._joint!==''&&this._model!==null){const root=this._model.getThreeJsObjects()[0];if(root!==undefined&&(this._jointObject===null||this._jointObject.name!==this._joint||root.id!==this._modelRootId)){const subObject=this._model.getThreeJsObjectByName(this._joint);if(subObject!==null){this._jointObject=subObject;this._modelRootId=root.id}} + if(this._jointObject===null){return}} + const targetAxis=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const primaryAxisGlobal=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const primaryRotation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();const localToWorld=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();if(this._jointObject!==null){let jointAncestor=this._jointObject;AlignController._tempThreeJsQuaternion.set(0,0,0,1);while(jointAncestor.parent!==null&&jointAncestor.parent!==this._model.getThreeJsObjects()[0]){jointAncestor=jointAncestor.parent;AlignController._tempThreeJsQuaternion.multiplyQuaternions(jointAncestor.quaternion,AlignController._tempThreeJsQuaternion)} + localToWorld.copyFromThreeJs(AlignController._tempThreeJsQuaternion);localToWorld.mult(this._model.getRotation(),localToWorld);localToWorld.mult(orientation,localToWorld)}else{localToWorld.copy(orientation)} + if(localToWorld.isNaN()){localToWorld.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + primaryAxisGlobal.rotate(localToWorld,this._primaryAxis);this._getAxis(targetAxis,this._primaryAlignType,this._primaryTargetEntity,this._primaryTargetAxis,primaryAxisGlobal,time);if(targetAxis.isNaN()){targetAxis.set(1,0,0)} + primaryRotation.setFromVectorFromTo(primaryAxisGlobal,targetAxis);orientation.mult(primaryRotation,localToWorld);if(orientation.isNaN()){orientation.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(primaryAxisGlobal);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(primaryRotation);if(this._secondaryAlignType!=='none'&&this._secondaryTargetEntity!==null){this._getAxis(targetAxis,this._secondaryAlignType,this._secondaryTargetEntity,this._secondaryTargetAxis,primaryAxisGlobal,time);if(!targetAxis.isNaN()){const secondaryRotation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();const primaryAxisOriented=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const secondaryAxisOriented=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();primaryAxisOriented.rotate(orientation,this._primaryAxis);secondaryAxisOriented.rotate(orientation,this._secondaryAxis);const angle=secondaryAxisOriented.angleAroundAxis(targetAxis,primaryAxisOriented);secondaryRotation.setFromAxisAngle(primaryAxisOriented,angle);orientation.mult(secondaryRotation,orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(secondaryRotation);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(primaryAxisOriented);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(secondaryAxisOriented)}} + orientation.normalize(orientation);if(this._jointObject!==null){orientation.multInverseL(localToWorld,orientation)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(localToWorld);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(targetAxis)} + _getAxis(outAxis,alignType,targetEntityRef,targetAxis,axisGlobal,time){const targetEntity=targetEntityRef.get();if(alignType==='align'&&targetEntity!==null){const primaryOrientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();targetEntity.getOrientationAtTime(primaryOrientation,time);outAxis.rotate(primaryOrientation,targetAxis);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(primaryOrientation)}else if(alignType==='velocity'&&targetEntity!==null){targetEntity.getVelocityAtTime(outAxis,time);outAxis.normalize(outAxis)}else if(alignType==='point'&&targetEntity!==null){targetEntity.getPositionRelativeToEntity(outAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,this.getEntity(),time);outAxis.normalize(outAxis)}else if(alignType==='position'&&targetEntity!==null){outAxis.normalize(targetEntity.getPosition())}else{outAxis.copy(axisGlobal)}} + _removeDependentStates(entity,alignType){if(entity!==null){if(alignType==='align'){this.removeDependentState(entity.getName(),'orientation')}else if(alignType==='velocity'){this.removeDependentState(entity.getName(),'velocity')}else if(alignType==='point'){this.removeDependentState(this.getEntity().getName(),'position');this.removeDependentState(entity.getName(),'position')}else if(alignType==='position'){this.removeDependentState(entity.getName(),'position')}}} + _addDependentStates(entity,alignType){if(entity!==null){if(alignType==='align'){this.addDependentState(entity.getName(),'orientation')}else if(alignType==='velocity'){this.addDependentState(entity.getName(),'velocity')}else if(alignType==='point'){this.addDependentState(this.getEntity().getName(),'position');this.addDependentState(entity.getName(),'position')}else if(alignType==='position'){this.addDependentState(entity.getName(),'position')}}}} + AlignController._tempThreeJsQuaternion=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Quaternion()}),"../pioneer/engine/src/scene/controllers/animdata_controller.js": + /*!**********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/animdata_controller.js ***! + \**********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"AnimdataController":function(){return AnimdataController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");const eclipJ2000ToJ200Rotation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(0.9791532214288992,0.2031230389823101,0,0);class State{read(_reader){} + interpolate(_state0,_state1,_intervalLength,_u){}} + class PosState extends State{constructor(){super();this.position=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this.velocity=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()} + read(reader){this.position.y=-reader.readFloat64();this.position.z=reader.readFloat64();this.position.x=reader.readFloat64();this.velocity.y=-reader.readFloat64();this.velocity.z=reader.readFloat64();this.velocity.x=reader.readFloat64();this.position.rotate(eclipJ2000ToJ200Rotation,this.position);this.velocity.rotate(eclipJ2000ToJ200Rotation,this.velocity)} + interpolate(state0,state1,intervalLength,u){const oneMinusU=1.0-u;const oneMinusUQuantitySquared=oneMinusU*oneMinusU;const uSquared=u*u;const a=(1.0+2.0*u)*oneMinusUQuantitySquared;const b=u*oneMinusUQuantitySquared;const c=uSquared*(3.0-2.0*u);const d=uSquared*-oneMinusU;this.position.mult(state0.position,a);this.position.addMult(this.position,state0.velocity,intervalLength*b);this.position.addMult(this.position,state1.position,c);this.position.addMult(this.position,state1.velocity,intervalLength*d);const sixUSquaredMinusU=6.0*(uSquared-u);const aV=sixUSquaredMinusU;const bV=3.0*uSquared-4.0*u+1.0;const cV=-sixUSquaredMinusU;const dV=3.0*uSquared-2.0*u;this.velocity.mult(state0.position,aV/intervalLength);this.velocity.addMult(this.velocity,state0.velocity,bV);this.velocity.addMult(this.velocity,state1.position,cV/intervalLength);this.velocity.addMult(this.velocity,state1.velocity,dV)}} + class OriState extends State{constructor(){super();this.orientation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion()} + read(reader){this.orientation.y=reader.readFloat32();this.orientation.z=-reader.readFloat32();this.orientation.x=-reader.readFloat32();this.orientation.w=reader.readFloat32();this.orientation.mult(eclipJ2000ToJ200Rotation,this.orientation)} + interpolate(state0,state1,_intervalLength,u){this.orientation.slerp(state0.orientation,state1.orientation,u)}} + class DataPoint{constructor(controller){this.interval=new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval();this.state=controller.__getNewState()} + read(reader){this.interval.min=reader.readFloat64();this.interval.max=reader.readFloat64();this.state.read(reader)}} + class AnimdataFile{constructor(controller,coverageIndex,animdataIndex){this.interval=new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval();this.dataPoints=[];const url=controller.getUrl()+'/'+controller.getStateType()+'_data/'+('00'+coverageIndex).slice(-3)+'.'+('000'+(animdataIndex+1)).slice(-4)+'.animdata';this.promise=controller.getEntity().getScene().getEngine().getDownloader().download(url,!0).then(async(download)=>{if(download.status==='cancelled'){return Promise.resolve()}else if(download.status==='failed'){return Promise.reject(new Error('Failed to load animdata controller file "'+download.url+'": '+download.errorMessage))} + if(!(download.content instanceof ArrayBuffer)){return Promise.reject(new Error('Failed to load animdata controller file "'+download.url+'": Not a binary file.'))} + const reader=new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content);this.interval.min=reader.readFloat64();this.interval.max=reader.readFloat64();const numDataPoints=reader.readInt32();for(let dataPointIndex=0;dataPointIndex{if(download.status==='cancelled'){return Promise.resolve()}else if(download.status==='failed'){return Promise.reject(new Error('Failed to load animdata controller file "'+download.url+'": '+download.errorMessage))} + if(!(download.content instanceof ArrayBuffer)){return Promise.reject(new Error('Failed to load animdata controller file "'+download.url+'": Not a binary file.'))} + const reader=new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content);const numFileOverlaps=reader.readInt16();for(let fileOverlapIndex=0;fileOverlapIndex{if(download.status==='cancelled'){return Promise.resolve()}else if(download.status==='failed'){return Promise.reject(new Error('Failed to load animdata controller file "'+download.url+'": '+download.errorMessage))} + if(!(download.content instanceof ArrayBuffer)){return Promise.reject(new Error('Failed to load animdata controller file "'+download.url+'": Not a binary file.'))} + const reader=new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content);const numCoverages=reader.readInt16();for(let coverageIndex=0;coverageIndex0){realCoverage.copy(this._animdef.coverages[0].interval);for(let i=1;i{const animinfoPromises=[];for(let coverageIndex=0;coverageIndex{const animdataPromises=[];for(const fileOverlap of animinfo.fileOverlaps.values()){if(fileOverlap.interval.intersects(interval)){const animdataIndex=fileOverlap.fileIndex;if(!coverage.animdatas.has(animdataIndex)){coverage.animdatas.set(animdataIndex,new AnimdataFile(this,coverageIndex,animdataIndex))} + const animdata=coverage.animdatas.get(animdataIndex);animdataPromises.push(animdata.promise)}} + return Promise.all(animdataPromises).then()}))} + return Promise.all(animinfoPromises).then()}}})} + __getNewState(){if(this._stateType==='pos'){return new PosState()}else if(this._stateType==='ori'){return new OriState()}else{return null}} + __update(){if(this._currentDataPoint!==null){if(this._getDataPointAtTime(this._currentDataPoint,this._engine.getTime())){if(this._stateType==='pos'){const state=(this._currentDataPoint.state);this.getEntity().setPosition(state.position);this.getEntity().setVelocity(state.velocity)} + if(this._stateType==='ori'){const state=(this._currentDataPoint.state);this.getEntity().setOrientation(state.orientation)}}}} + _getDataPointAtTime(outDataPoint,time){for(let coverageIndex=0;coverageIndex=this.updateInterval){this.lastUpdateTime=now;this.updateFunction(this.getEntity())}} + this.active=newActive}}}),"../pioneer/engine/src/scene/controllers/dynamo_controller.js": + /*!********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/dynamo_controller.js ***! + \********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"DynamoController":function(){return DynamoController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class Point{load(reader){this.time=reader.readFloat64()} + calculate(_points,_time,_header,_incremental){} + apply(_entity){} + setNaN(_entity){} + static readHeader(_reader){return{}}} + class PosPoint extends Point{constructor(){super();this.position=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this.velocity=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()} + load(reader){super.load(reader);this.position=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(reader.readFloat64(),reader.readFloat64(),reader.readFloat64());this.velocity=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(reader.readFloat64(),reader.readFloat64(),reader.readFloat64())} + calculate(points,time,_header,_incremental){this.time=time;const totalT=points[1].time-points[0].time;const u=(time-points[0].time)/totalT;const oneSubU=1.0-u;const oneSubUSq=oneSubU*oneSubU;const uSq=u*u;const a=(1.0+2.0*u)*oneSubUSq;const b=u*oneSubUSq;const c=uSq*(3.0-2.0*u);const d=uSq*-oneSubU;this.position.mult(points[0].position,a);this.position.addMult(this.position,points[0].velocity,totalT*b);this.position.addMult(this.position,points[1].position,c);this.position.addMult(this.position,points[1].velocity,totalT*d);const sixUSqSubU=6.0*(uSq-u);const aV=sixUSqSubU;const bV=3.0*uSq-4.0*u+1.0;const cV=-sixUSqSubU;const dV=3.0*uSq-2.0*u;this.velocity.mult(points[0].position,aV/totalT);this.velocity.addMult(this.velocity,points[0].velocity,bV);this.velocity.addMult(this.velocity,points[1].position,cV/totalT);this.velocity.addMult(this.velocity,points[1].velocity,dV)} + apply(entity){entity.setPosition(this.position);entity.setVelocity(this.velocity)} + setNaN(entity){entity.setPosition(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);entity.setVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN])} + static readHeader(_reader){return{}}} + class LinPoint extends Point{constructor(){super();this.position=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this.velocity=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()} + load(reader){super.load(reader);this.position.set(reader.readFloat64(),reader.readFloat64(),reader.readFloat64());this.velocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero)} + calculate(points,time,_header,_incremental){this.time=time;if(points[1].time>points[0].time){const u=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time-points[0].time)/(points[1].time-points[0].time));this.position.lerp(points[0].position,points[1].position,u);this.velocity.sub(points[1].position,points[0].position);this.velocity.div(this.velocity,points[1].time-points[0].time)}else{this.position.copy(points[1].position);this.velocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero)}} + apply(entity){entity.setPosition(this.position);entity.setVelocity(this.velocity)} + setNaN(entity){entity.setPosition(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);entity.setVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN])} + static readHeader(_reader){return{}}} + class OriPoint extends Point{constructor(){super();this.orientation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion();this.angularVelocity=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()} + load(reader){super.load(reader);this.orientation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(reader.readFloat64(),reader.readFloat64(),reader.readFloat64(),reader.readFloat64());this.angularVelocity=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(reader.readFloat64(),reader.readFloat64(),reader.readFloat64())} + calculate(points,time,_header,incremental){this.time=time;const orientation0=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();const orientation1=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();const u=(time-points[0].time)/(points[1].time-points[0].time);points[0]._project(orientation0,time,incremental);points[1]._project(orientation1,time,incremental);this.orientation.slerp(orientation0,orientation1,u);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation0);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation1);this.angularVelocity.slerp(points[0].angularVelocity,points[1].angularVelocity,u);this.angularVelocity.neg(this.angularVelocity);this.angularVelocity.rotate(this.orientation,this.angularVelocity)} + apply(entity){entity.setOrientation(this.orientation);entity.setAngularVelocity(this.angularVelocity)} + _project(orientation,time,incremental){const rotationAxis=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const rotation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();rotationAxis.normalize(this.angularVelocity);rotation.setFromAxisAngle(rotationAxis,this.angularVelocity.magnitude()*(time-this.time));_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(rotationAxis);if(incremental){rotation.multInverseR(this.orientation,rotation);orientation.mult(orientation,rotation)}else{orientation.multInverseR(this.orientation,rotation)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation)} + setNaN(entity){entity.setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]);entity.setAngularVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN])} + static readHeader(_reader){return{}}} + class QuatPoint extends Point{constructor(){super();this.orientation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion();this.angularVelocity=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()} + load(reader){super.load(reader);this.orientation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion(reader.readFloat64(),reader.readFloat64(),reader.readFloat64(),reader.readFloat64())} + calculate(points,time,_header,_incremental){this.time=time;const u=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time-points[0].time)/(points[1].time-points[0].time));this.orientation.slerp(points[0].orientation,points[1].orientation,u)} + apply(entity){entity.setOrientation(this.orientation);entity.setAngularVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero)} + setNaN(entity){entity.setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]);entity.setAngularVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN])} + static readHeader(_reader){return{}}} + class OrbPoint extends Point{constructor(){super();this.oe=new _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements();this.oe.orbitOrientation.freeze();this.position=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this.velocity=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()} + load(reader){super.load(reader);this.oe.epoch=this.time;this.oe.semiMajorAxis=reader.readFloat64();this.oe.eccentricity=reader.readFloat64();this.oe.meanAngularMotion=reader.readFloat64();this.oe.meanAnomalyAtEpoch=reader.readFloat64();this.oe.orbitOrientation.thaw();this.oe.orbitOrientation.set(reader.readFloat64(),reader.readFloat64(),reader.readFloat64(),reader.readFloat64());this.oe.orbitOrientation.freeze()} + calculate(points,time,header,incremental){this.time=time;this.oe.epoch=time;const position0=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const position1=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const velocity0=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const velocity1=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const u=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time-points[0].time)/(points[1].time-points[0].time));points[0]._project(position0,velocity0,time,header,incremental);points[1]._project(position1,velocity1,time,header,incremental);this.position.lerp(position0,position1,u);this.velocity.lerp(velocity0,velocity1,u);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position0);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position1);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(velocity0);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(velocity1)} + apply(entity){entity.setPosition(this.position);entity.setVelocity(this.velocity)} + _project(position,velocity,time,header,incremental){const newPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const newVelocity=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();this.oe.project(newPosition,newVelocity,time);let bodyFactor=1;if(header.body===1){bodyFactor=header.gravitationalParameter2/(header.gravitationalParameter1+header.gravitationalParameter2)}else if(header.body===2){bodyFactor=-header.gravitationalParameter1/(header.gravitationalParameter1+header.gravitationalParameter2)} + newPosition.mult(newPosition,bodyFactor);newVelocity.mult(newVelocity,bodyFactor);if(incremental){position.add(newPosition,position)}else{position.copy(newPosition)} + velocity.copy(newVelocity);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newVelocity)} + setNaN(entity){entity.setPosition(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);entity.setVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN])} + static readHeader(reader){return{gravitationalParameter1:reader.readFloat64(),gravitationalParameter2:reader.readFloat64()}}} + class PointSet{constructor(PointClass,version,numberOfDigits,name){this._PointClass=PointClass;this._version=version;this._numberOfDigits=numberOfDigits;this._name=name;this._pointSets=[];this._points=[];this._hintIndex=0;this._interval=new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.POSITIVE_INFINITY,Number.NEGATIVE_INFINITY);this._loadedState=PointSet.State.NOT_LOADED;this._accessedTime=Number.POSITIVE_INFINITY} + getName(){return this._name} + getLoadedState(){return this._loadedState} + getLoadedTime(){return this._accessedTime} + hasPointSets(){return this._pointSets.length!==0} + hasPoints(){return this._points.length!==0} + load(reader){let containsPoints=!0;if(this._version===2||(this._version===1&&this._name==='def')){containsPoints=(reader.readByte()===1)} + if(containsPoints){const numPoints=reader.readInt32();for(let i=0;i0){this._interval.min=this._points[0].time;this._interval.max=this._points[this._points.length-1].time}}else{const numPointSets=reader.readInt32();if(this._version===1){this._numberOfDigits=Math.ceil(Math.log10(numPointSets))} + for(let i=0;i0){this._pointSets[i-1]._interval.max=pointSet._interval.min}} + this._pointSets.push(pointSet)} + if(this._version===2){this._pointSets.splice(this._pointSets.length-1,1)} + if(this._pointSets.length>0){this._interval.min=this._pointSets[0]._interval.min;this._interval.max=this._pointSets[this._pointSets.length-1]._interval.max}} + this._loadedState=PointSet.State.LOADED;this._accessedTime=Date.now()} + loadFromUrl(downloader,baseUrl){this._loadedState=PointSet.State.LOADING;downloader.download(baseUrl+'/'+this._name+'.dyn',!0).then(async(download)=>{if(download.status==='cancelled'){return Promise.resolve()}else if(download.status==='failed'){return Promise.reject(new Error('Failed to load dynamo controller file "'+download.url+'": '+download.errorMessage))} + if(!(download.content instanceof ArrayBuffer)){return Promise.reject(new Error('Failed to load dynamo controller file "'+download.url+'": Not a binary file.'))} + const reader=new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content);this.load(reader)})} + unloadOldPointSet(){for(let i=0,l=this._pointSets.length;i15000){pointSet.unload();return!0}else{if(pointSet.unloadOldPointSet()){return!0}}}} + return!1} + unload(){this._loadedState=PointSet.State.NOT_LOADED;this._accessedTime=Number.POSITIVE_INFINITY;this._pointSets=[];this._points=[]} + getPointSet(time){this._accessedTime=Date.now();if(this._pointSets.length===0){return null} + if(this._pointSets[this._hintIndex]._interval.contains(time)){}else if(this._hintIndex-1>=0&&this._pointSets[this._hintIndex-1]._interval.contains(time)){this._hintIndex-=1}else if(this._hintIndex+1=0&&this._points[this._hintIndex-1].time<=time&&time{const engine=this.getEntity().getScene().getEngine();const callback=()=>{const time=engine.getTime();if(this.isDestroyed()||!this.isEnabled()||!this.getEntity().isEnabled()||this._baseUrl===''||(this._pointSet!==null&&!this.getCoverage().contains(time))||this._dataLoadedAtCurrentTime){engine.removeCallback(callback);resolve()}};engine.addCallback(callback,!0)})} + getTimeOffset(){return this._timeOffset} + setTimeOffset(timeOffset){const oldTimeOffset=this._timeOffset;this._timeOffset=timeOffset;const newCoverage=new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval();newCoverage.copy(this.getCoverage());newCoverage.min+=this._timeOffset-oldTimeOffset;newCoverage.max+=this._timeOffset-oldTimeOffset;super.setCoverage(newCoverage)} + setCoverage(coverage){this._userCoverage.thaw();this._userCoverage.copy(coverage);this._userCoverage.freeze();const finalCoverage=_internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get();if(this._pointSet!==null){finalCoverage.intersection(this._userCoverage,this._pointSet._interval)}else{finalCoverage.copy(new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.POSITIVE_INFINITY,Number.NEGATIVE_INFINITY))} + finalCoverage.min+=this._timeOffset;finalCoverage.max+=this._timeOffset;super.setCoverage(finalCoverage);_internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(finalCoverage)} + getOrbitalElements(orbitalElements,time){if(this._PointClass===OrbPoint&&this._pointSet!==null){this._getPointsAtTime(this._points,time);if(this._points[0]!==null){this._lastPoints[0]=this._points[0];this._lastPoints[1]=this._points[1]} + if(this._lastPoints[0]!==null){const oe0=(this._lastPoints[0]).oe;const oe1=(this._lastPoints[1]).oe;const u=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time-this._lastPoints[0].time)/(this._lastPoints[1].time-this._lastPoints[0].time));orbitalElements.eccentricity=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(oe0.eccentricity,oe1.eccentricity,u);orbitalElements.semiMajorAxis=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(oe0.semiMajorAxis,oe1.semiMajorAxis,u);orbitalElements.epoch=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(oe0.epoch,oe1.epoch,u);orbitalElements.meanAngularMotion=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(oe0.meanAngularMotion,oe1.meanAngularMotion,u);orbitalElements.meanAnomalyAtEpoch=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerpAngle(oe0.meanAnomalyAtEpoch,oe1.meanAnomalyAtEpoch,u);orbitalElements.orbitOrientation.slerp(oe0.orbitOrientation,oe1.orbitOrientation,u)}}} + getEccentricity(time){if(this._PointClass===OrbPoint&&this._pointSet!==null){this._getPointsAtTime(this._points,time);if(this._points[0]!==null){this._lastPoints[0]=this._points[0];this._lastPoints[1]=this._points[1]} + if(this._lastPoints[0]!==null){const u=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time-this._lastPoints[0].time)/(this._lastPoints[1].time-this._lastPoints[0].time));return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp((this._lastPoints[0]).oe.eccentricity,(this._lastPoints[1]).oe.eccentricity,u)}} + return Number.NaN} + getSemiMajorAxis(time){if(this._PointClass===OrbPoint&&this._pointSet!==null){this._getPointsAtTime(this._points,time);if(this._points[0]!==null){this._lastPoints[0]=this._points[0];this._lastPoints[1]=this._points[1]} + if(this._lastPoints[0]!==null){const u=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time-this._lastPoints[0].time)/(this._lastPoints[1].time-this._lastPoints[0].time));return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp((this._lastPoints[0]).oe.semiMajorAxis,(this._lastPoints[1]).oe.semiMajorAxis,u)}} + return Number.NaN} + getOrbitOrientation(outOrbitOrientation,time){if(this._PointClass===OrbPoint&&this._pointSet!==null){this._getPointsAtTime(this._points,time);if(this._points[0]!==null){this._lastPoints[0]=this._points[0];this._lastPoints[1]=this._points[1]} + if(this._lastPoints[0]!==null){const u=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((time-this._lastPoints[0].time)/(this._lastPoints[1].time-this._lastPoints[0].time));outOrbitOrientation.slerp((this._lastPoints[0]).oe.orbitOrientation,(this._lastPoints[1]).oe.orbitOrientation,u)}}} + __destroy(){if(this._baseUrl!==''){this._downloader.cancel(this._baseUrl+'/def.dyn')} + super.__destroy()} + __updatePositionAtTime(position,time){if(this._pointSet===null){position.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);return} + if((this._pCalc).position===undefined||!this.getCoverage().contains(time)){return} + if(this._pCalc.time!==time){this._getPointsAtTime(this._points,time);if(this._points[0]===null){position.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);return} + this._pCalc.calculate(this._points,time-this._timeOffset,this._header,this._incremental)} + position.copy((this._pCalc).position)} + __updateVelocityAtTime(velocity,time){if(this._pointSet===null){velocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);return}else if((this._pCalc).velocity===undefined||!this.getCoverage().contains(time)){return} + if(this._pCalc.time!==time){this._getPointsAtTime(this._points,time);if(this._points[0]===null){velocity.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);return} + this._pCalc.calculate(this._points,time-this._timeOffset,this._header,this._incremental)} + velocity.copy((this._pCalc).velocity)} + __updateOrientationAtTime(orientation,time){if(this._pointSet===null){orientation.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]);return} + if((this._pCalc).orientation===undefined||!this.getCoverage().contains(time)){return} + if(this._pCalc.time!==time){this._getPointsAtTime(this._points,time);if(this._points[0]===null){orientation.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]);return} + this._pCalc.calculate(this._points,time-this._timeOffset,this._header,this._incremental)} + orientation.copy((this._pCalc).orientation)} + __update(){const entity=this.getEntity();const engine=entity.getScene().getEngine();const time=engine.getTime();if(this._pointSet!==null){this._pointSet.unloadOldPointSet();this._getPointsAtTime(this._points,time);if(this._points[0]!==null){this._pCalc.calculate(this._points,time-this._timeOffset,this._header,this._incremental);this._pCalc.apply(entity);this._lastPoints[0]=this._points[0];this._lastPoints[1]=this._points[1];this._dataLoadedAtCurrentTime=!0}else{if(this._lastPoints[0]!==null&&this._lastPoints[1]!==null){this._pCalc.calculate(this._lastPoints,time-this._timeOffset,this._header,this._incremental);this._pCalc.apply(entity)} + this._dataLoadedAtCurrentTime=!1}}else{this.getEntity().setPosition(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);this.getEntity().setVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion[NaN]);this.getEntity().setAngularVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);this._dataLoadedAtCurrentTime=!1} + this._lastTime=time} + async _loadDef(){const url=this._baseUrl;return this._downloader.download(this._baseUrl+'/def.dyn',!0).then(async(download)=>{if(download.status==='cancelled'){return Promise.resolve()}else if(download.status==='failed'){return Promise.reject(new Error('Failed to load dynamo controller file "'+download.url+'": '+download.errorMessage))} + if(!(download.content instanceof ArrayBuffer)){return Promise.reject(new Error('Failed to load dynamo controller file "'+download.url+'": Not a binary file.'))} + const reader=new _internal__WEBPACK_IMPORTED_MODULE_0__.Reader(download.content);this._version=reader.readInt16();if(this._version!==1&&this._version!==2){throw new Error(download.url+' is not Dynamo version 1 or 2')} + this._pointType=reader.readString();if(this._pointType==='pos'){this._PointClass=PosPoint}else if(this._pointType==='lin'){this._PointClass=LinPoint}else if(this._pointType==='ori'){this._PointClass=OriPoint}else if(this._pointType==='quat'){this._PointClass=QuatPoint}else if(this._pointType==='orb'){this._PointClass=OrbPoint} + this._pCalc=new this._PointClass();if(this._PointClass===PosPoint||this._PointClass===LinPoint||this._PointClass===OrbPoint){this.addModifiedState('position');this.addModifiedState('velocity');this.removeModifiedState('orientation');this.removeModifiedState('angularVelocity')}else if(this._PointClass===OriPoint||this._PointClass===QuatPoint){this.addModifiedState('orientation');this.addModifiedState('angularVelocity');this.removeModifiedState('position');this.removeModifiedState('velocity')} + if(this._version===2){this._numberOfDigits=reader.readByte()} + this._header=Object.assign(this._header,this._PointClass.readHeader(reader));this._pointSet=new PointSet(this._PointClass,this._version,this._numberOfDigits,'def');this._pointSet.load(reader);const finalCoverage=_internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get();finalCoverage.intersection(this._userCoverage,this._pointSet._interval);finalCoverage.min+=this._timeOffset;finalCoverage.max+=this._timeOffset;super.setCoverage(finalCoverage);_internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(finalCoverage)}).catch((error)=>{if(error instanceof Error){error.message=`While loading dynamo "${url}/def.dyn": ${error.message}`} + throw error})} + _getPointsAtTime(points,time){let pointSet=this._pointSet;while(!0){if(pointSet.hasPoints()){pointSet.getPoints(points,time-this._timeOffset);return}else if(pointSet.getLoadedState()===PointSet.State.LOADED){pointSet=pointSet.getPointSet(time-this._timeOffset);if(pointSet===null){points[0]=null;points[1]=null;return}}else if(pointSet.getLoadedState()===PointSet.State.NOT_LOADED){pointSet.loadFromUrl(this._downloader,this._baseUrl);points[0]=null;points[1]=null;return}else{points[0]=null;points[1]=null;return}}}} + DynamoController.maxLoadedPointSetsPerController=5}),"../pioneer/engine/src/scene/controllers/fixed_controller.js": + /*!*******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/fixed_controller.js ***! + \*******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"FixedController":function(){return FixedController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class FixedController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._position=null;this._orientation=null} + getPosition(){return this._position} + setPosition(position){if(position!==null){if(this._position===null){this._position=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()} + this._position.thaw();this._position.copy(position);this._position.freeze()}else{this._position=null} + if(position!==null){this.addModifiedState('position');this.addModifiedState('velocity')}else{this.removeModifiedState('position');this.removeModifiedState('velocity')}} + getOrientation(){return this._orientation} + setOrientation(orientation){if(orientation!==null){if(this._orientation===null){this._orientation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion()} + this._orientation.thaw();this._orientation.copy(orientation);this._orientation.freeze()}else{this._orientation=null} + if(orientation!==null){this.addModifiedState('orientation')}else{this.removeModifiedState('orientation')}} + __updatePositionAtTime(position,_time){if(this._position!==null){position.copy(this._position)}} + __updateVelocityAtTime(velocity,_time){if(this._position!==null){velocity.set(0,0,0)}} + __updateOrientationAtTime(orientation,_time){if(this._orientation!==null){orientation.copy(this._orientation)}} + __update(){if(this._position!==null){this.getEntity().setPosition(this._position);this.getEntity().setVelocity(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero)} + if(this._orientation!==null){this.getEntity().setOrientation(this._orientation)}}}}),"../pioneer/engine/src/scene/controllers/fixed_to_parent_controller.js": + /*!*****************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/fixed_to_parent_controller.js ***! + \*****************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"FixedToParentController":function(){return FixedToParentController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class FixedToParentController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._lastParentOrientation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion();const parent=this.getEntity().getParent();if(parent!==null){this._lastParentOrientation.copy(parent.getOrientation())} + this.addModifiedState('position');this.addModifiedState('orientation');this.addDependentState('parent','orientation')} + __update(){const parent=this.getEntity().getParent();if(parent!==null){const rotation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();rotation.inverse(this._lastParentOrientation);rotation.mult(parent.getOrientation(),rotation);const position=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const orientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();position.rotate(rotation,this.getEntity().getPosition());this.getEntity().setPosition(position);orientation.mult(rotation,this.getEntity().getOrientation());this.getEntity().setOrientation(orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation);this._lastParentOrientation.copy(parent.getOrientation())}}}}),"../pioneer/engine/src/scene/controllers/free_fly_controller.js": + /*!**********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/free_fly_controller.js ***! + \**********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"FreeFlyController":function(){return FreeFlyController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class FreeFlyController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._dragSensitivity=0.07;this._dragSmoothness=0.8;this._moveSmoothedValue=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0.0,0.0,0.0);this._changeParentToNearestEntity=!0;this._forcedMoving=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._isMoving=!1;this.addModifiedState('position');this.addDependentState('parent','orientation');this.addDependentState('parent','radius')} + getDragSensitivity(){return this._dragSensitivity} + setDragSensitivity(dragSensitivity){this._dragSensitivity=dragSensitivity} + getDragSmoothness(){return this._dragSmoothness} + setDragSmoothness(dragSmoothness){this._dragSmoothness=dragSmoothness} + getChangeParentToNearestEntity(){return this._changeParentToNearestEntity} + setChangeParentToNearestEntity(changeParentToNearestEntity){this._changeParentToNearestEntity=changeParentToNearestEntity} + getForcedMoving(){return this._forcedMoving} + setForcedMoving(forcedMoving){this._forcedMoving=forcedMoving} + __update(){if(this.getEntity().getParent()===null){return} + if(this._changeParentToNearestEntity&&(this.getEntity().getParent()===null||this._isMoving)){const scene=this.getEntity().getScene();const cameraComponent=(this.getEntity().get('camera'));let nearestEntity=null;let nearestDistance=Number.POSITIVE_INFINITY;for(let i=0,l=scene.getNumEntities();idistance){nearestDistance=distance;nearestEntity=entity}} + if(nearestEntity!==null&&nearestEntity!==this.getEntity().getParent()){this.getEntity().setParent(nearestEntity)}} + if(this.getEntity().getOrientation().isNaN()){this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + if(this.getEntity().getPosition().isNaN()){this.getEntity().setPosition(new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,-1,0))} + const move=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();move.set(0.0,0.0,0.0);const input=this.getEntity().getScene().getEngine().getInput();const viewport=input.getActiveViewport();if(viewport!==null){const camera=viewport.getCamera();if(camera!==null&&camera.getEntity()===this.getEntity()){let moveMultiplier=1;if(input.isKeyPressed('x')){moveMultiplier=0.05} + if(input.isShiftPressed()){moveMultiplier=5} + const zoomOffset=input.getZoomedOffset();if(zoomOffset!==0){move.y+=-zoomOffset*this._dragSensitivity*moveMultiplier} + if(input.isKeyPressed('w')){move.y+=this._dragSensitivity*moveMultiplier} + if(input.isKeyPressed('s')){move.y-=this._dragSensitivity*moveMultiplier} + if(input.isKeyPressed('d')){move.x+=this._dragSensitivity*moveMultiplier} + if(input.isKeyPressed('a')){move.x-=this._dragSensitivity*moveMultiplier} + if(input.isKeyPressed('e')){move.z+=this._dragSensitivity*moveMultiplier} + if(input.isKeyPressed('q')){move.z-=this._dragSensitivity*moveMultiplier} + move.y+=this._dragSensitivity*moveMultiplier*cameraFreeFlyParameters.velocity}} + move.add(move,this._forcedMoving);this._isMoving=(move.magnitudeSqr()>0);this._moveSmoothedValue.lerp(move,this._moveSmoothedValue,this._dragSmoothness);if(!this._isMoving&&this._moveSmoothedValue.magnitudeSqr()<0.0000001){this._moveSmoothedValue.set(0.0,0.0,0.0)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(move);let distance=Number.POSITIVE_INFINITY;const spheroid=(this.getEntity().getParent().getComponentByType('spheroid'));if(spheroid!==null&&!this.getEntity().getParent().getOrientation().isNaN()){const position=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();position.rotateInverse(this.getEntity().getParent().getOrientation(),this.getEntity().getPosition());const lla=_internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get();spheroid.llaFromXYZ(lla,position);distance=Math.min(distance,lla.alt);_internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position)}else{distance=Math.min(distance,this.getEntity().getPosition().magnitude()-this.getEntity().getParent().getOcclusionRadius())} + distance=Math.max(0.1,distance);const oldPosition=this.getEntity().getPosition();const newPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const rotatedMove=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();rotatedMove.rotate(this.getEntity().getOrientation(),this._moveSmoothedValue);newPosition.addMult(oldPosition,rotatedMove,distance);this.getEntity().setPosition(newPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(rotatedMove);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition)}}}),"../pioneer/engine/src/scene/controllers/ground_clamp_controller.js": + /*!**************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/ground_clamp_controller.js ***! + \**************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"GroundClampController":function(){return GroundClampController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class GroundClampController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._groundComponentRef=new _internal__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene());this._distanceFromGround=0;this._up=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,0,1);this.addModifiedState('position')} + setGroundComponentRef(entityName,componentType,componentTypeIndex){this.removeDependentState(this._groundComponentRef.getEntityName(),'orientation');this._groundComponentRef.setByType(entityName,componentType,componentTypeIndex);this.addDependentState(entityName,'orientation')} + getDistanceFromGround(){return this._distanceFromGround} + setDistanceFromGround(distanceFromGround){this._distanceFromGround=distanceFromGround} + setUp(up){this._up.copy(up)} + __updatePositionAtTime(position,time){const entityParentNameAtTime=this.getEntity().getParentAtTime(time);const entityParentAtTime=this.getEntity().getScene().getEntity(entityParentNameAtTime);if(entityParentAtTime===null){return} + let groundComponent=this._groundComponentRef.get();if(groundComponent===null){let parent=this.getEntity().getParent();while(parent!==null){groundComponent=(parent.getComponentByType('spheroid'));if(groundComponent!==null){break} + parent=parent.getParent()} + if(groundComponent===null){return}} + const groundComponentEntity=groundComponent.getEntity();const entityPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const heightDir=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const groundOrientationAtTime=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();groundComponentEntity.getOrientationAtTime(groundOrientationAtTime,time);entityParentAtTime.getPositionRelativeToEntity(entityPosition,position,groundComponentEntity,time);entityPosition.rotateInverse(groundOrientationAtTime,entityPosition);if(groundComponent.getGroundPosition!==undefined){groundComponent.getGroundPosition(entityPosition,heightDir,entityPosition)} + if(!entityPosition.isNaN()){const entityUp=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const entityOrientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();this.getEntity().getOrientationAtTime(entityOrientation,time);entityUp.rotate(entityOrientation,this._up);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(entityOrientation);entityUp.rotateInverse(groundOrientationAtTime,entityUp);const cosUpAndGroundUp=Math.abs(entityUp.dot(heightDir));_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityUp);entityPosition.addMult(entityPosition,heightDir,Math.min(this._distanceFromGround/cosUpAndGroundUp,this._distanceFromGround+this.getEntity().getExtentsRadius()));entityPosition.rotate(groundOrientationAtTime,entityPosition);groundComponentEntity.getPositionRelativeToEntity(position,entityPosition,entityParentAtTime,time)}else{position.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN])} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(heightDir);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(groundOrientationAtTime)} + __update(){if(this.getEntity().getParent()===null){return} + let groundComponent=this._groundComponentRef.get();if(groundComponent===null){let parent=this.getEntity().getParent();while(parent!==null){groundComponent=(parent.getComponentByType('spheroid'));if(groundComponent!==null){break} + parent=parent.getParent()} + if(groundComponent===null){return}} + const groundComponentEntity=groundComponent.getEntity();const entityPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const heightDir=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();this.getEntity().getPositionRelativeToEntity(entityPosition,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,groundComponentEntity);entityPosition.rotateInverse(groundComponentEntity.getOrientation(),entityPosition);if(groundComponent.getGroundPosition!==undefined){groundComponent.getGroundPosition(entityPosition,heightDir,entityPosition)} + if(!entityPosition.isNaN()){const entityUp=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();entityUp.rotate(this.getEntity().getOrientation(),this._up);entityUp.rotateInverse(groundComponentEntity.getOrientation(),entityUp);const cosUpAndGroundUp=Math.abs(entityUp.dot(heightDir));_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityUp);entityPosition.addMult(entityPosition,heightDir,Math.min(this._distanceFromGround/cosUpAndGroundUp,this._distanceFromGround+this.getEntity().getExtentsRadius()));entityPosition.rotate(groundComponentEntity.getOrientation(),entityPosition);groundComponentEntity.getPositionRelativeToEntity(entityPosition,entityPosition,this.getEntity().getParent())}else{entityPosition.copy(this.getEntity().getLastPosition())} + this.getEntity().setPosition(entityPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(heightDir)}}}),"../pioneer/engine/src/scene/controllers/keyframe_controller.js": + /*!**********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/keyframe_controller.js ***! + \**********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"KeyframeController":function(){return KeyframeController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class KeyframeController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._positionKeyframes=[];this._orientationKeyframes=[];this._timesAreRealTime=!1;this._timeOfFirstUpdate=NaN;this.setCoverage(new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.POSITIVE_INFINITY,Number.NEGATIVE_INFINITY));this._position0=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._position1=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._orientation0=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion();this._orientation1=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion();this._newPosition=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._newVelocity=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._newOrientation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion();this._tangent0=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._tangent1=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._tempA=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._tempB=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()} + addPositionKeyframe(time,position,relativeToEntityPosition,relativeToEntityPositionTime,relativeToEntityOrientation,relativeToEntityOrientationTime){const entry=[time,{position,relativeToEntityPosition:relativeToEntityPosition?new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(),relativeToEntityPosition):undefined,relativeToEntityPositionTime,relativeToEntityOrientation:relativeToEntityOrientation?new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(),relativeToEntityOrientation):undefined,relativeToEntityOrientationTime}];_internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(entry,this._positionKeyframes,isLessAdd);if(this._positionKeyframes.length===1){this.addModifiedState('position');this.addModifiedState('velocity')} + this._updateCoverage()} + removePositionKeyframe(time){const found=_internal__WEBPACK_IMPORTED_MODULE_0__.Sort.remove(time,this._positionKeyframes,isLess,isEqual);if(found){if(this._positionKeyframes.length===0){this.removeModifiedState('position');this.removeModifiedState('velocity')} + this._updateCoverage()} + return found} + addOrientationKeyframe(time,orientation,relativeToEntityOrientation,relativeToEntityOrientationTime){const entry=[time,{orientation,relativeToEntityOrientation:relativeToEntityOrientation?new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene(),relativeToEntityOrientation):undefined,relativeToEntityOrientationTime}];_internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(entry,this._orientationKeyframes,isLessAdd);if(this._orientationKeyframes.length===1){this.addModifiedState('orientation')} + this._updateCoverage()} + removeOrientationKeyframe(time){const found=_internal__WEBPACK_IMPORTED_MODULE_0__.Sort.remove(time,this._orientationKeyframes,isLess,isEqual);if(found){if(this._orientationKeyframes.length===0){this.removeModifiedState('orientation')} + this._updateCoverage()} + return found} + areTimesRealTime(){return this._timesAreRealTime} + setTimesAreRealTime(timesAreRealTime){this._timesAreRealTime=timesAreRealTime;this._updateCoverage()} + __updatePositionAtTime(position,time){this._getPositionAtTime(position,time)} + __updateVelocityAtTime(velocity,time){this._getVelocityAtTime(velocity,time)} + __updateOrientationAtTime(orientation,time){this._getOrientationAtTime(orientation,time)} + __update(){const engine=this.getEntity().getScene().getEngine();let time=0;if(this._timesAreRealTime){if(isNaN(this._timeOfFirstUpdate)){this._timeOfFirstUpdate=Date.now()/1000}else{time=Date.now()/1000-this._timeOfFirstUpdate}}else{time=engine.getTime()} + if(this._getPositionAtTime(this._newPosition,time)){this.getEntity().setPosition(this._newPosition)} + if(this._getVelocityAtTime(this._newVelocity,time)){this.getEntity().setVelocity(this._newVelocity)} + if(this._getOrientationAtTime(this._newOrientation,time)){this.getEntity().setOrientation(this._newOrientation)}} + _getPositionAtTime(outPosition,time){const index=_internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time,this._positionKeyframes,isLess);if(index0){const timeA=this._positionKeyframes[index0-1][0];this._getPositionOfKeyframe(this._tempA,this._positionKeyframes[index0-1]);this._tempA.sub(this._position0,this._tempA);this._tempB.sub(this._position1,this._position0);this._tempB.mult(this._tempB,0.5);this._tangent0.addMult(this._tempB,this._tempA,0.5*(time1-time0)/(time0-timeA))}else{this._tangent0.sub(this._position1,this._position0)} + if(index11){const time0=this._positionKeyframes[0][0];const time1=this._positionKeyframes[1][0];this._getPositionOfKeyframe(this._position0,this._positionKeyframes[0]);this._getPositionOfKeyframe(this._position1,this._positionKeyframes[1]);outVelocity.sub(this._position1,this._position0);outVelocity.div(outVelocity,time1-time0)}else{outVelocity.set(0,0,0)} + return!0}}else{const index0=index-1;const index1=index;const time0=this._positionKeyframes[index0][0];const time1=this._positionKeyframes[index1][0];this._getPositionOfKeyframe(this._position0,this._positionKeyframes[index0]);this._getPositionOfKeyframe(this._position1,this._positionKeyframes[index1]);if(index0>0){const timeA=this._positionKeyframes[index0-1][0];this._getPositionOfKeyframe(this._tempA,this._positionKeyframes[index0-1]);this._tempA.sub(this._position0,this._tempA);this._tempB.sub(this._position1,this._position0);this._tempB.mult(this._tempB,0.5);this._tangent0.addMult(this._tempB,this._tempA,0.5*(time1-time0)/(time0-timeA))}else{this._tangent0.sub(this._position1,this._position0)} + if(index10){coverage.min=Math.min(coverage.min,this._positionKeyframes[0][0]);coverage.max=Math.max(coverage.max,this._positionKeyframes[this._positionKeyframes.length-1][0])} + if(this._orientationKeyframes.length>0){coverage.min=Math.min(coverage.min,this._orientationKeyframes[0][0]);coverage.max=Math.max(coverage.max,this._orientationKeyframes[this._orientationKeyframes.length-1][0])} + this.setCoverage(coverage)}} + _cubicHermiteSpline(outP,p0,p1,t0,t1,u){const u2=u*u;const u3=u*u2;const c0=2*u3-3*u2+1;const c1=u3-2*u2+u;const c2=-2*u3+3*u2;const c3=u3-u2;outP.x=c0*p0.x+c1*t0.x+c2*p1.x+c3*t1.x;outP.y=c0*p0.y+c1*t0.y+c2*p1.y+c3*t1.y;outP.z=c0*p0.z+c1*t0.z+c2*p1.z+c3*t1.z} + _cubicHermiteSplineDerivative(outV,p0,p1,t0,t1,u){const u2=u*u;const c0=6*u2-6*u;const c1=3*u2-4*u+1;const c2=-6*u2+6*u;const c3=3*u2-2*u;outV.x=c0*p0.x+c1*t0.x+c2*p1.x+c3*t1.x;outV.y=c0*p0.y+c1*t0.y+c2*p1.y+c3*t1.y;outV.z=c0*p0.z+c1*t0.z+c2*p1.z+c3*t1.z}} + const isLessAdd=(a,b)=>(a[0](a[0](a[0]===b)}),"../pioneer/engine/src/scene/controllers/look_controller.js": + /*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/look_controller.js ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"LookController":function(){return LookController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class LookController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._dragSensitivity=0.03;this._dragSmoothness=0.8;this._yawAngleSmoothedValue=0.0;this._pitchAngleSmoothedValue=0.0;this._yawAxisType='none';this._yawAxisEntity=null;this.addModifiedState('orientation')} + getDragSensitivity(){return this._dragSensitivity} + setDragSensitivity(dragSensitivity){this._dragSensitivity=dragSensitivity} + getDragSmoothness(){return this._dragSmoothness} + setDragSmoothness(dragSmoothness){this._dragSmoothness=dragSmoothness} + getYawAxisType(){return this._yawAxisType} + setYawAxisType(yawAxisType){if(this._yawAxisType===yawAxisType){return} + if(this._yawAxisEntity!==null){if(['x-axis','y-axis','z-axis'].includes(this._yawAxisType)){this.removeDependentState(this._yawAxisEntity.getName(),'orientation')}else if(this._yawAxisType==='position'){this.removeDependentState(this._yawAxisEntity.getName(),'position')}} + this._yawAxisType=yawAxisType;if(this._yawAxisEntity!==null){if(['x-axis','y-axis','z-axis'].includes(this._yawAxisType)){this.addDependentState(this._yawAxisEntity.getName(),'orientation')}else if(this._yawAxisType==='position'){this.addDependentState(this._yawAxisEntity.getName(),'position')}}} + getYawAxisEntity(){return this._yawAxisEntity} + setYawAxisEntity(yawAxisEntity){if(this._yawAxisEntity===yawAxisEntity){return} + if(this._yawAxisEntity!==null){if(['x-axis','y-axis','z-axis'].includes(this._yawAxisType)){this.removeDependentState(this._yawAxisEntity.getName(),'orientation')}else if(this._yawAxisType==='position'){this.removeDependentState(this._yawAxisEntity.getName(),'position')}} + this._yawAxisEntity=yawAxisEntity;if(this._yawAxisEntity!==null){if(['x-axis','y-axis','z-axis'].includes(this._yawAxisType)){this.addDependentState(this._yawAxisEntity.getName(),'orientation')}else if(this._yawAxisType==='position'){this.addDependentState(this._yawAxisEntity.getName(),'position')}}} + __update(){if(this._yawAxisEntity===null){this._yawAxisEntity=this.getEntity().getParent();if(this._yawAxisEntity!==null){if(['x-axis','y-axis','z-axis'].includes(this._yawAxisType)){this.addDependentState(this._yawAxisEntity.getName(),'orientation')}else if(this._yawAxisType==='position'){this.addDependentState(this._yawAxisEntity.getName(),'position')}}} + if(this.getEntity().getOrientation().isNaN()){this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + const input=this.getEntity().getScene().getEngine().getInput();let lookMultiplier=2;if(input.isKeyPressed('x')){lookMultiplier=0.05} + const camera=(this.getEntity().getComponentByType('camera'));if(camera!==null){lookMultiplier*=Math.min(1,camera.getFieldOfView())} + let yawAngle=0;let pitchAngle=0;const viewport=input.getActiveViewport();if(viewport!==null){const camera=viewport.getCamera();if(camera!==null&&camera.getEntity()===this.getEntity()){const draggedOffset=input.getDraggedOffset();yawAngle=-cameraFreeFlyParameters.xAngleDv*this._dragSensitivity;pitchAngle=-cameraFreeFlyParameters.yAngleDv*this._dragSensitivity}} + this._yawAngleSmoothedValue=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(yawAngle,this._yawAngleSmoothedValue,this._dragSmoothness);this._pitchAngleSmoothedValue=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(pitchAngle,this._pitchAngleSmoothedValue,this._dragSmoothness);if(Math.abs(this._yawAngleSmoothedValue)<0.0001*lookMultiplier){this._yawAngleSmoothedValue=0} + if(Math.abs(this._pitchAngleSmoothedValue)<0.0001*lookMultiplier){this._pitchAngleSmoothedValue=0} + const yawAxis=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();if(this._yawAxisType==='x-axis'&&this._yawAxisEntity!==null){this._yawAxisEntity.getOrientation().getAxis(yawAxis,0)}else if(this._yawAxisType==='y-axis'&&this._yawAxisEntity!==null){this._yawAxisEntity.getOrientation().getAxis(yawAxis,1)}else if(this._yawAxisType==='z-axis'&&this._yawAxisEntity!==null){this._yawAxisEntity.getOrientation().getAxis(yawAxis,2)}else if(this._yawAxisType==='position'&&this._yawAxisEntity!==null){yawAxis.normalize(this._yawAxisEntity.getPosition())}else{this.getEntity().getOrientation().getAxis(yawAxis,2)} + if(yawAxis.isNaN()){this.getEntity().getOrientation().getAxis(yawAxis,2)} + const orientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();orientation.copy(this.getEntity().getOrientation());const rotation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();const zAxis=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const yAxis=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();this.getEntity().getOrientation().getAxis(yAxis,1);this.getEntity().getOrientation().getAxis(zAxis,2);const angle=zAxis.angleAroundAxis(yawAxis,yAxis);rotation.setFromAxisAngle(yAxis,angle);rotation.normalize(rotation);orientation.mult(rotation,orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(zAxis);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(yAxis);const pitchAxis=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();orientation.getAxis(pitchAxis,0);rotation.setFromAxisAngle(pitchAxis,this._pitchAngleSmoothedValue);orientation.mult(rotation,orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(pitchAxis);rotation.setFromAxisAngle(yawAxis,this._yawAngleSmoothedValue);orientation.mult(rotation,orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(yawAxis);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation);this.getEntity().setOrientation(orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation)}}}),"../pioneer/engine/src/scene/controllers/model_animate_controller.js": + /*!***************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/model_animate_controller.js ***! + \***************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ModelAnimateController":function(){return ModelAnimateController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class ModelAnimateController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._animations=[]} + setAnimation(model,jointName,animationName,interval){if(model===null){throw new Error('Null model specified.')} + this._animations.push({model,jointName,animationName,interval,animationClip:null,rootObject:null,jointObject:null,animationMixer:null})} + __update(){const time=this.getEntity().getScene().getEngine().getTime();for(let i=0,l=this._animations.length;i_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi-0.0001){lla.lat=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.halfPi-0.0001} + if(lla.latthis._pitchAngleLimits.max){lla.lat=this._pitchAngleLimits.max} + if(lla.lonthis._yawAngleLimits.max){lla.lon=this._yawAngleLimits.max} + _internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getXYZFromLLAOnSphere(position,lla,0);_internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla);position.rotate(axisFrame,position);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(axisFrame);this.getEntity().setPosition(position);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position)}}}),"../pioneer/engine/src/scene/controllers/orbit_keyframe_controller.js": + /*!****************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/orbit_keyframe_controller.js ***! + \****************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"OrbitKeyframeController":function(){return OrbitKeyframeController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class OrbitKeyframeController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._positionKeyframes=[];this._focusKeyframes=[];this._upKeyframes=[];this._timeOfFirstUpdate=NaN;this._directionOfFirstUpdate=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._resolvePromise=null;this._rejectPromise=null;this._endPromise=new Promise((resolve,reject)=>{this._resolvePromise=resolve;this._rejectPromise=reject});this.addModifiedState('position');this.addModifiedState('velocity');this.addModifiedState('orientation');this.addModifiedState('angularVelocity')} + setPositionKeyframe(time,position,relativeToEntity){if(position!==undefined){const keyframe=new PositionKeyframe(this.getEntity().getScene());keyframe.time=time;keyframe.position.copy(position);keyframe.relativeTo.setName(relativeToEntity);_internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add(keyframe,this._positionKeyframes,isLess)}else{const index=_internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time,this._positionKeyframes,isLessThanTime);if(index0&&positionKeyframeIndex=0.5){parentEntity=relativeToEntity1} + if(entity.getParent()!==parentEntity){entity.setParent(parentEntity)} + const position0=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const position1=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();relativeToEntity0.getPositionRelativeToEntity(position0,keyframe0.position,relativeToEntity1);relativeToEntity1.getPositionRelativeToEntity(position1,keyframe1.position,relativeToEntity0);let dist00=Math.max(0,keyframe0.position.magnitude()-relativeToEntity0.getOcclusionRadius());let dist10=Math.max(0,position1.magnitude()-relativeToEntity0.getOcclusionRadius());let dist01=Math.max(0,position0.magnitude()-relativeToEntity1.getOcclusionRadius());let dist11=Math.max(0,keyframe1.position.magnitude()-relativeToEntity1.getOcclusionRadius());dist00=Math.max(dist00,dist10/10000);dist10=Math.max(dist10,dist00/10000);dist01=Math.max(dist01,dist11/10000);dist11=Math.max(dist11,dist10/10000);if(dist00!==dist10&&dist01!==dist11){const u0=(Math.pow(dist10,u)*Math.pow(dist00,1-u)-dist00)/(dist10-dist00);const u1=(Math.pow(dist11,u)*Math.pow(dist01,1-u)-dist01)/(dist11-dist01);u=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(u0,u1,u)} + const sq=u*u;u=sq/(2*(sq-u)+1);relativeToEntity0.getPositionRelativeToEntity(position0,keyframe0.position,parentEntity);relativeToEntity1.getPositionRelativeToEntity(position1,keyframe1.position,parentEntity);const newPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();if(relativeToEntity0===relativeToEntity1){newPosition.slerp(position0,position1,u)}else{newPosition.lerp(position0,position1,u)} + entity.setPosition(newPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position0);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position1)}}else if(positionKeyframeIndex===this._positionKeyframes.length){const keyframe=this._positionKeyframes[this._positionKeyframes.length-1];const relativeToEntity=keyframe.relativeTo.get();if(entity.getParent()!==relativeToEntity){entity.setParent(relativeToEntity)} + entity.setPosition(keyframe.position);doneWithPositionKeyframes=!0} + const forward=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();forward.setMagnitude(entity.getPosition(),-1);const up=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();entity.getOrientation().getAxis(up,2);let doneWithFocusKeyframes=!1;const focusKeyframeIndex=_internal__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time,this._focusKeyframes,isLessThanTime);if(focusKeyframeIndex>0&&focusKeyframeIndex0&&upKeyframeIndex1){coverage.min=Math.min(coverage.min,this._orbitalElementsKeyFrames[0].time);coverage.max=Math.max(coverage.max,this._orbitalElementsKeyFrames[this._orbitalElementsKeyFrames.length-1].time)} + this.setCoverage(coverage)}} + class OrbitalElementsKeyFrame{constructor(){this.time=0;this.oe=new _internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements()}};const isLessAdd=(a,b)=>(a.time(a.time(a.time===b.time);const _tempPosition=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();const _tempVelocity=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3()}),"../pioneer/engine/src/scene/controllers/pick_controller.js": + /*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/pick_controller.js ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"PickController":function(){return PickController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class PickController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._pickedEntity=null;this._callback=null;this._triggerOnHover=!1;this._pickedPosition=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._pickedPosition.freeze()} + getPickedEntity(){return this._pickedEntity} + setPickedEntity(entity){this._pickedEntity=entity} + getCallback(){return this._callback} + setCallback(callback){this._callback=callback} + getTriggerOnHover(){return this._triggerOnHover} + setTriggerOnHover(triggerOnHover){this._triggerOnHover=triggerOnHover} + getPickedPosition(){return this._pickedPosition} + __update(){const input=this.getEntity().getScene().getEngine().getInput();if((input.isSelected()||this._triggerOnHover)&&this._callback!==null&&this._pickedEntity!==null){const viewport=input.getActiveViewport();if(viewport!==null){const camera=viewport.getCamera();if(camera!==null&&camera.getEntity()===this.getEntity()){const pickedPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();viewport.getNormalSpacePositionFromPixelSpacePosition(pickedPosition,input.getCursorPosition());camera.getCameraSpacePositionFromNormalSpacePosition(pickedPosition,pickedPosition);pickedPosition.normalize(pickedPosition);const interval=_internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get();const spheroid=(this.getEntity().getParent().getComponentByType('spheroid'));if(spheroid!==null){const ratio=spheroid.getEquatorialRadius()/spheroid.getPolarRadius();pickedPosition.rotateInverse(this._pickedEntity.getOrientation(),pickedPosition);pickedPosition.z*=ratio;const entityPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();entityPosition.copy(this._pickedEntity.getCameraSpacePosition(camera));entityPosition.rotateInverse(this._pickedEntity.getOrientation(),entityPosition);entityPosition.z*=ratio;_internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLineSphereIntersectionWithLineStartAtOrigin(interval,pickedPosition,entityPosition,spheroid.getEquatorialRadius());pickedPosition.z/=ratio;pickedPosition.rotate(this._pickedEntity.getOrientation(),pickedPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityPosition)}else{const entityPosition=this._pickedEntity.getCameraSpacePosition(camera);_internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLineSphereIntersectionWithLineStartAtOrigin(interval,pickedPosition,entityPosition,this._pickedEntity.getOcclusionRadius())} + if(!Number.isNaN(interval.min)){this._pickedPosition.thaw();this._pickedPosition.mult(pickedPosition,interval.min);camera.getEntity().getPositionRelativeToEntity(this._pickedPosition,this._pickedPosition,this._pickedEntity);this._pickedPosition.freeze();this.getEntity().getScene().getEngine().addCallback(this._callback.bind(undefined,this._pickedPosition),!1)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.release(interval);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(pickedPosition)}}}}}}),"../pioneer/engine/src/scene/controllers/roll_controller.js": + /*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/roll_controller.js ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"RollController":function(){return RollController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class RollController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._rollSensitivity=0.1;this._rollSmoothness=0.8;this._rollAngleSmoothedValue=0.0;this.addModifiedState('orientation')} + getRollSensitivity(){return this._rollSensitivity} + setRollSensitivity(rollSensitivity){this._rollSensitivity=rollSensitivity} + getRollSmoothness(){return this._rollSmoothness} + setRollSmoothness(rollSmoothness){this._rollSmoothness=rollSmoothness} + __update(){if(this.getEntity().getOrientation().isNaN()){this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + let rollAngle=0;const input=this.getEntity().getScene().getEngine().getInput();const viewport=input.getActiveViewport();if(viewport!==null){const camera=viewport.getCamera();if(camera!==null&&camera.getEntity()===this.getEntity()){let rollMultiplier=1;if(input.isKeyPressed('x')){rollMultiplier=0.05} + if(input.isShiftPressed()){rollMultiplier=5} + const rotatedOffset=input.getRotatedOffset();if(rotatedOffset!==0){rollAngle+=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(rotatedOffset*this._rollSensitivity*rollMultiplier,-0.1,+0.1)} + if(input.isKeyPressed('c')){rollAngle+=this._rollSensitivity*rollMultiplier} + if(input.isKeyPressed('z')){rollAngle-=this._rollSensitivity*rollMultiplier} + rollAngle+=rollAngle+this._rollSensitivity*rollMultiplier*cameraOrbitParameters.roll}} + this._rollAngleSmoothedValue=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(rollAngle,this._rollAngleSmoothedValue,this._rollSmoothness);if(Math.abs(this._rollAngleSmoothedValue)<0.0001){this._rollAngleSmoothedValue=0} + if(this._rollAngleSmoothedValue!==0){const newOrientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();const rotation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();rotation.setFromAxisAngle(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis,this._rollAngleSmoothedValue);newOrientation.mult(this.getEntity().getOrientation(),rotation);this.getEntity().setOrientation(newOrientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation)}}}}),"../pioneer/engine/src/scene/controllers/rotate_by_entity_orientation_controller.js": + /*!******************************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/rotate_by_entity_orientation_controller.js ***! + \******************************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"RotateByEntityOrientationController":function(){return RotateByEntityOrientationController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class RotateByEntityOrientationController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._entityRef=new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());this._rotatingPosition=!0;this._rotatingOrientation=!0;this.addModifiedState('position');this.addModifiedState('orientation')} + setEntityForOrientation(name){if(this._entityRef.getName()!==''){this.addDependentState(this._entityRef.getName(),'orientation')} + this._entityRef.setName(name);this.addDependentState(name,'orientation')} + isRotatingPosition(){return this._rotatingPosition} + setRotatingPosition(rotatingPosition){this._rotatingPosition=rotatingPosition;if(rotatingPosition){this.addModifiedState('position')}else{this.removeModifiedState('position')}} + isRotatingOrientation(){return this._rotatingOrientation} + setRotatingOrientation(rotatingOrientation){this._rotatingOrientation=rotatingOrientation;if(rotatingOrientation){this.addModifiedState('orientation')}else{this.removeModifiedState('orientation')}} + __updatePositionAtTime(position,time){if(this._rotatingPosition){const entity=this._entityRef.getName()!==''?this._entityRef.get():this.getEntity().getScene().getEntity(this.getEntity().getParentAtTime(time));if(entity!==null){const entityOrientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();entity.getOrientationAtTime(entityOrientation,time);position.rotate(entityOrientation,position);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(entityOrientation)}}} + __updateVelocityAtTime(velocity,time){if(this._rotatingPosition){const entity=this._entityRef.getName()!==''?this._entityRef.get():this.getEntity().getScene().getEntity(this.getEntity().getParentAtTime(time));if(entity!==null){const entityOrientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();entity.getOrientationAtTime(entityOrientation,time);velocity.rotate(entityOrientation,velocity);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(entityOrientation)}}} + __updateOrientationAtTime(orientation,time){if(this._rotatingOrientation){const entity=this._entityRef.getName()!==''?this._entityRef.get():this.getEntity().getScene().getEntity(this.getEntity().getParentAtTime(time));if(entity!==null){const entityOrientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();entity.getOrientationAtTime(entityOrientation,time);orientation.mult(entityOrientation,orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(entityOrientation)}}} + __update(){const entity=this._entityRef.getName()!==''?this._entityRef.get():this.getEntity().getParent();if(entity!==null){if(this._rotatingPosition){const position=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();position.rotate(entity.getOrientation(),this.getEntity().getPosition());this.getEntity().setPosition(position);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position)} + if(this._rotatingOrientation){const orientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();orientation.mult(entity.getOrientation(),this.getEntity().getOrientation());this.getEntity().setOrientation(orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation)}}}}}),"../pioneer/engine/src/scene/controllers/rotate_controller.js": + /*!********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/rotate_controller.js ***! + \********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"RotateController":function(){return RotateController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class RotateController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._rotation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion();this._rotation.freeze();this._rotatingPosition=!0;this._rotatingOrientation=!0;this.addModifiedState('position');this.addModifiedState('orientation')} + getRotation(){return this._rotation} + setRotation(rotation){this._rotation.thaw();this._rotation.copy(rotation);this._rotation.freeze()} + isRotatingPosition(){return this._rotatingPosition} + setRotatingPosition(rotatingPosition){this._rotatingPosition=rotatingPosition;if(rotatingPosition){this.addModifiedState('position')}else{this.removeModifiedState('position')}} + isRotatingOrientation(){return this._rotatingOrientation} + setRotatingOrientation(rotatingOrientation){this._rotatingOrientation=rotatingOrientation;if(rotatingOrientation){this.addModifiedState('orientation')}else{this.removeModifiedState('orientation')}} + __updatePositionAtTime(position,_time){if(this._rotatingPosition){position.rotate(this._rotation,position)}} + __updateVelocityAtTime(velocity,_time){if(this._rotatingPosition){velocity.rotate(this._rotation,velocity)}} + __updateOrientationAtTime(orientation,_time){if(this._rotatingOrientation){orientation.mult(this._rotation,orientation)}} + __update(){if(this._rotatingPosition){const newPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();newPosition.rotate(this._rotation,this.getEntity().getPosition());this.getEntity().setPosition(newPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition)} + if(this._rotatingOrientation){const newOrientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();newOrientation.mult(this._rotation,this.getEntity().getOrientation());this.getEntity().setOrientation(newOrientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation)}}}}),"../pioneer/engine/src/scene/controllers/scale_controller.js": + /*!*******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/scale_controller.js ***! + \*******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ScaleController":function(){return ScaleController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class ScaleController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._scale=1.0;this.addModifiedState('position')} + getScale(){return this._scale} + setScale(scale){this._scale=scale} + __updatePositionAtTime(position,_time){position.mult(position,this._scale)} + __updateVelocityAtTime(velocity,_time){velocity.mult(velocity,this._scale)} + __update(){const newPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();newPosition.mult(this.getEntity().getPosition(),this._scale);this.getEntity().setPosition(newPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition)}}}),"../pioneer/engine/src/scene/controllers/select_controller.js": + /*!********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/select_controller.js ***! + \********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SelectController":function(){return SelectController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class SelectController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._callback=null} + getCallback(){return this._callback} + setCallback(callback){this._callback=callback} + __update(){const input=this.getEntity().getScene().getEngine().getInput();if(input.isSelected()&&this._callback!==null){const viewport=input.getActiveViewport();if(viewport!==null){const camera=viewport.getCamera();if(camera!==null&&camera.getEntity()===this.getEntity()){const entityPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();viewport.getNormalSpacePositionFromPixelSpacePosition(entityPosition,input.getSelectedPosition());let intersectedEntity=null;let intersectedEntityDistance=0;const entityPosition2D=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.get();entityPosition2D.set(entityPosition.x,entityPosition.y);const numEntities=this.getEntity().getScene().getNumEntities();for(let entityI=0;entityIentityDistance){intersectedEntity=entity;intersectedEntityDistance=entityDistance}}}}} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2.pool.release(entityPosition2D);if(intersectedEntity===null){camera.getCameraSpacePositionFromNormalSpacePosition(entityPosition,entityPosition);entityPosition.mult(entityPosition,1/entityPosition.magnitude());intersectedEntity=camera.getNearestIntersectingEntity(entityPosition)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(entityPosition);this.getEntity().getScene().getEngine().addCallback(this._callback.bind(null,intersectedEntity),!1)}}}}}}),"../pioneer/engine/src/scene/controllers/set_parent_controller.js": + /*!************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/set_parent_controller.js ***! + \************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SetParentController":function(){return SetParentController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class SetParentController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._parent=new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene())} + getParent(){return this._parent.getName()} + setParent(parent){if(this._parent.getName()!==''){this.removeDependentState(this._parent.getName(),'position')} + this._parent.setName(parent);if(this._parent.getName()!==''){this.addDependentState(this._parent.getName(),'position')}} + __update(){const parent=this._parent.get();this.getEntity().setParent(parent)}}}),"../pioneer/engine/src/scene/controllers/spin_controller.js": + /*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/spin_controller.js ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SpinController":function(){return SpinController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class SpinController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._axis=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,0,1);this._axis.freeze();this._axisRelativeToEntity=!0;this._rate=0;this._referenceAngle=0;this._referenceTime=undefined;this._clampedToRealTime=!1;this._usingRealTime=!1;this._rotatingPosition=!1;this._joint='';this._jointObject=null;this._model=null;this._lastTime=entity.getScene().getEngine().getTime();this.addModifiedState('orientation')} + getAxis(){return this._axis} + isAxisRelativeToEntity(){return this._axisRelativeToEntity} + setAxis(axis,relativeToEntity){this._axis.thaw();this._axis.copy(axis);this._axis.freeze();this._axisRelativeToEntity=relativeToEntity} + getRate(){return this._rate} + setRate(rate){this._rate=rate} + getReferenceAngle(){return this._referenceAngle} + setReferenceAngle(referenceAngle){this._referenceAngle=referenceAngle} + getReferenceTime(){return this._referenceTime} + setReferenceTime(referenceTime){this._referenceTime=referenceTime} + isClampedToRealTime(){return this._clampedToRealTime} + setClampedToRealTime(clampedToRealTime){this._clampedToRealTime=clampedToRealTime} + isUsingRealTime(){return this._usingRealTime} + setUsingRealTime(usingRealTime){this._usingRealTime=usingRealTime} + isRotatingPosition(){return this._rotatingPosition} + setRotatingPosition(rotatingPosition){this._rotatingPosition=rotatingPosition;if(rotatingPosition){this.addModifiedState('position')}else{this.removeModifiedState('position')}} + setJoint(joint,model){this._joint=joint;if(!model){const modelFromEntity=(this.getEntity().get('model'));if(modelFromEntity!==null){this._model=modelFromEntity}}else{this._model=model} + if(this._joint!==''){this.removeModifiedState('orientation')}else{this.addModifiedState('orientation')}} + __updatePositionAtTime(position,time){if(this._rotatingPosition){let deltaTime=0;if(!this._usingRealTime){if(this._referenceTime!==undefined){deltaTime=time-this._referenceTime;deltaTime-=this._referenceAngle/this._rate}} + const rotation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();rotation.setFromAxisAngle(this._axis,this._rate*deltaTime);if(this._jointObject===null){if(this._axisRelativeToEntity){const orientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();this.getEntity().getOrientationAtTime(orientation,time);rotation.mult(orientation,rotation);rotation.multInverseR(rotation,orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation)} + position.rotate(rotation,position)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation)}} + __updateOrientationAtTime(orientation,time){if(orientation.isNaN()){orientation.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + let deltaTime=0;if(!this._usingRealTime){if(this._referenceTime!==undefined){deltaTime=time-this._referenceTime;deltaTime-=this._referenceAngle/this._rate}} + const rotation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();rotation.setFromAxisAngle(this._axis,this._rate*deltaTime);if(this._jointObject===null){if(this._axisRelativeToEntity){rotation.mult(orientation,rotation);rotation.multInverseR(rotation,orientation)} + orientation.mult(rotation,orientation);orientation.normalize(orientation)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation)} + __update(){if(this.getEntity().getOrientation().isNaN()){this.getEntity().setOrientation(_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + const engine=this.getEntity().getScene().getEngine();let deltaTime=0;if(this._usingRealTime){deltaTime=engine.getDeltaTime()}else{if(this._referenceTime!==undefined){deltaTime=engine.getTime()-this._referenceTime;deltaTime-=this._referenceAngle/this._rate}else{deltaTime=engine.getTime()-this._lastTime;if(this._clampedToRealTime){const deltaRealTime=engine.getDeltaTime();deltaTime=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(deltaTime,-deltaRealTime,deltaRealTime)}}} + const rotation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();rotation.setFromAxisAngle(this._axis,this._rate*deltaTime);if(this._jointObject!==null&&this._model.getThreeJsObjects()[0]!==null){this._jointObject=null} + if(this._joint!==''&&(this._jointObject===null||this._jointObject.name!==this._joint)&&this._model!==null){const subObject=this._model.getThreeJsObjectByName(this._joint);if(subObject!==null){this._jointObject=subObject}} + const entityOrientation=this.getEntity().getOrientation();if(this._jointObject!==null){if(!this._axisRelativeToEntity){rotation.multInverseL(entityOrientation,rotation);rotation.mult(rotation,entityOrientation)} + _tempThreeJsQuaternion.set(rotation.x,rotation.y,rotation.z,rotation.w);this._jointObject.quaternion.multiplyQuaternions(_tempThreeJsQuaternion,this._jointObject.quaternion);if(this._rotatingPosition){this._jointObject.position.applyQuaternion(_tempThreeJsQuaternion)}}else{const newOrientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();if(this._axisRelativeToEntity){rotation.mult(entityOrientation,rotation);rotation.multInverseR(rotation,entityOrientation)} + newOrientation.mult(rotation,entityOrientation);newOrientation.normalize(newOrientation);const newAngularVelocity=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();newAngularVelocity.mult(this._axis,this._rate);if(this._axisRelativeToEntity){newAngularVelocity.rotate(newOrientation,newAngularVelocity)} + this.getEntity().setOrientation(newOrientation);this.getEntity().setAngularVelocity(newAngularVelocity);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newAngularVelocity);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation);if(this._rotatingPosition){const newPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();newPosition.rotate(rotation,this.getEntity().getPosition());this.getEntity().setPosition(newPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition)}} + _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation);this._lastTime=engine.getTime()}} + const _tempThreeJsQuaternion=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Quaternion()}),"../pioneer/engine/src/scene/controllers/tap_controller.js": + /*!*****************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/tap_controller.js ***! + \*****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TapController":function(){return TapController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class TapController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._tapCallback=null} + getTapCallback(){return this._tapCallback} + setTapCallback(callback){this._tapCallback=callback} + __update(){const input=this.getEntity().getScene().getEngine().getInput();if(input.isSelected()||!input.getDraggedOffset().isZero()){if(this._tapCallback!==null){this._tapCallback()}}}}}),"../pioneer/engine/src/scene/controllers/transition_controller.js": + /*!************************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/transition_controller.js ***! + \************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TransitionController":function(){return TransitionController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class TransitionController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._initialPosition=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._initialPosition.copy(entity.getPosition());this._initialOrientation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion();this._initialOrientation.copy(entity.getOrientation());this._initialParent=new _internal__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());this._transitionStart=Number.NaN;this._transitionTime=1;this._transitionFunction=this._lerpTransitionFunction;this._resolvePromise=null;this._rejectPromise=null;this._endPromise=new Promise((resolve,reject)=>{this._resolvePromise=resolve;this._rejectPromise=reject});const parent=this.getEntity().getParent();if(parent!==null){this._initialParent.setName(parent.getName())} + const existingController=this.getEntity().getControllerByType('transition');if(existingController!==null){this.getEntity().removeController(existingController)} + const setParentController=(this.getEntity().addController('setParent','transitionSetParent',this.getEntity().getController(0)));if(parent!==null){setParentController.setParent(parent.getName())}} + getTransitionTime(){return this._transitionTime} + setTransitionTime(transitionTime){this._transitionTime=transitionTime} + setTransitionFunction(transitionFunction){this._transitionFunction=transitionFunction} + getParent(){const setParentController=(this.getEntity().getController('transitionSetParent'));if(setParentController!==null){return setParentController.getName()}else{const parent=this.getEntity().getParent();if(parent!==null){return parent.getName()} + return null}} + setParent(parent){const setParentController=(this.getEntity().getController('transitionSetParent'));if(setParentController!==null){setParentController.setParent(parent)}} + getEndPromise(){return this._endPromise} + __destroy(){super.__destroy();const setParentController=this.getEntity().getController('transitionSetParent');if(setParentController!==null){this.getEntity().removeController(setParentController)} + if(this._transitionTime!==0){this._rejectPromise('Transition controller was destroyed before completing.')}} + __update(){const initialParent=this._initialParent.get();const finalParent=this.getEntity().getParent();if(finalParent===null){this._transitionTime=0;this.getEntity().removeController(this);this._rejectPromise('The final parent was destroyed or disabled before the transition could complete.')} + if(Number.isNaN(this._transitionStart)){this._transitionStart=Date.now()/1000.0} + const setParentController=(this.getEntity().getController('transitionSetParent'));if(setParentController!==null){if(initialParent===null){this.getEntity().getScene().getEngine().addCallback(()=>{this._transitionTime=0;this.getEntity().removeController(this);if(this._initialParent.getName()!==''){this._rejectPromise(`The initial parent "${this._initialParent.getName()}" was destroyed or disabled before the first half of the transition could complete.`)}else{this._resolvePromise()}},!1);return} + if(Date.now()/1000.0-this._transitionStart>=this._transitionTime/2.0||initialParent===finalParent){this.getEntity().removeController(setParentController);if(initialParent!==finalParent&&initialParent!==null&&finalParent!==null){initialParent.getPositionRelativeToEntity(this._initialPosition,this._initialPosition,finalParent)}}else{this.getEntity().setParent(initialParent)}} + const finalPosition=this.getEntity().getPosition();const finalOrientation=this.getEntity().getOrientation();let u=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp01((Date.now()/1000.0-this._transitionStart)/this._transitionTime);if(Number.isNaN(u)){u=1.0} + this._transitionFunction(this.getEntity(),this._initialPosition,finalPosition,this._initialOrientation,finalOrientation,u);if(Date.now()/1000.0-this._transitionStart>=this._transitionTime){this.getEntity().getScene().getEngine().addCallback(()=>{this._transitionTime=0;this.getEntity().removeController(this);this._resolvePromise()},!1)}} + _lerpTransitionFunction(entity,initialPosition,finalPosition,initialOrientation,finalOrientation,u){const position=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const orientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();position.lerp(initialPosition,finalPosition,u);orientation.slerp(initialOrientation,finalOrientation,u);entity.setPosition(position);entity.setOrientation(orientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation)}}}),"../pioneer/engine/src/scene/controllers/translate_controller.js": + /*!***********************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/translate_controller.js ***! + \***********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TranslateController":function(){return TranslateController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class TranslateController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._translation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3(0,0,0);this._translation.freeze();this._relativeToOrientation=!1;this.addModifiedState('position')} + getTranslation(){return this._translation} + setTranslation(translation){this._translation.thaw();this._translation.copy(translation);this._translation.freeze()} + setRelativeToOrientation(relativeToOrientation){this._relativeToOrientation=relativeToOrientation} + __updatePositionAtTime(position,time){const newPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();if(this._relativeToOrientation){const orientation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();this.getEntity().getOrientationAtTime(orientation,time);newPosition.rotate(orientation,this._translation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation)}else{newPosition.copy(this._translation)} + position.add(newPosition,position);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition)} + __update(){const newPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();if(this._relativeToOrientation){newPosition.rotate(this.getEntity().getOrientation(),this._translation)}else{newPosition.copy(this._translation)} + newPosition.add(newPosition,this.getEntity().getPosition());this.getEntity().setPosition(newPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition)}}}),"../pioneer/engine/src/scene/controllers/zoom_controller.js": + /*!******************************************************************!*\ + !*** ../pioneer/engine/src/scene/controllers/zoom_controller.js ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ZoomController":function(){return ZoomController}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../../internal */"../pioneer/engine/src/internal.js");class ZoomController extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._zoomSensitivity=0.05;this._zoomSmoothness=0.8;this._zoomSmoothedValue=1.0;this._distanceClamp=new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(0.001,Number.POSITIVE_INFINITY);this._distanceClamp.freeze();this._useSpheroidRadiusForDistance=!1;this.addModifiedState('position')} + getZoomSensitivity(){return this._zoomSensitivity} + setZoomSensitivity(zoomSensitivity){this._zoomSensitivity=zoomSensitivity} + getZoomSmoothness(){return this._zoomSmoothness} + setZoomSmoothness(zoomSmoothness){this._zoomSmoothness=zoomSmoothness} + getDistanceClamp(){return this._distanceClamp} + setDistanceClamp(distanceClamp){this._distanceClamp.thaw();this._distanceClamp.copy(distanceClamp);this._distanceClamp.freeze()} + getUseSpheroidRadiusForDistance(){return this._useSpheroidRadiusForDistance} + setUseSpheroidRadiusForDistance(enabled){this._useSpheroidRadiusForDistance=enabled} + __update(){const input=this.getEntity().getScene().getEngine().getInput();let zoomChange=1.0;const viewport=input.getActiveViewport();if(viewport!==null){const camera=viewport.getCamera();if(camera!==null&&camera.getEntity()===this.getEntity()){let zoomMultiplier=1;if(input.isKeyPressed('x')){zoomMultiplier=0.05} + if(input.isShiftPressed()){zoomMultiplier=5} + const zoomOffset=input.getZoomedOffset();if(zoomOffset!==0){zoomChange*=Math.pow(2,zoomOffset*this._zoomSensitivity*zoomMultiplier)} + if(input.isKeyPressed('w')){zoomChange/=Math.pow(2,this._zoomSensitivity*zoomMultiplier)} + if(input.isKeyPressed('s')){zoomChange*=Math.pow(2,this._zoomSensitivity*zoomMultiplier)} + zoomChange*=Math.pow(2,this._zoomSensitivity*zoomMultiplier*cameraOrbitParameters.zoom)}} + this._zoomSmoothedValue=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(zoomChange,this._zoomSmoothedValue,this._zoomSmoothness),0.8,1.25);if(Math.abs(1.0-this._zoomSmoothedValue)<0.0000001){this._zoomSmoothedValue=1.0} + let currentDistance=1;const lla=_internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get();if(this._useSpheroidRadiusForDistance&&this.getEntity().getParent()!==null){const spheroid=(this.getEntity().getParent().getComponentByType('spheroid'));if(spheroid!==null){const positionOriented=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();positionOriented.rotateInverse(this.getEntity().getParent().getOrientation(),this.getEntity().getPosition());spheroid.llaFromXYZ(lla,positionOriented);currentDistance=lla.alt;_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionOriented)}else{currentDistance=this.getEntity().getPosition().magnitude()-this.getEntity().getParent().getOcclusionRadius()}}else{currentDistance=this.getEntity().getPosition().magnitude()} + if(Number.isNaN(currentDistance)){currentDistance=1} + currentDistance*=this._zoomSmoothedValue;if(currentDistancethis._distanceClamp.max){currentDistance=this._distanceClamp.max;this._zoomSmoothedValue=1.0} + const newPosition=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();let newMagnitude=currentDistance;if(this._useSpheroidRadiusForDistance&&this.getEntity().getParent()!==null){const spheroid=(this.getEntity().getParent().getComponentByType('spheroid'));if(spheroid!==null){lla.alt=currentDistance;spheroid.xyzFromLLA(newPosition,lla);newMagnitude=newPosition.magnitude()}else{newMagnitude=currentDistance+this.getEntity().getParent().getOcclusionRadius()}} + newPosition.normalize(this.getEntity().getPosition());newPosition.mult(newPosition,newMagnitude);this.getEntity().setPosition(newPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(newPosition);_internal__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla)}}}),"../pioneer/engine/src/scene/entity.js": + /*!*********************************************!*\ + !*** ../pioneer/engine/src/scene/entity.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Entity":function(){return Entity}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class Entity extends _internal__WEBPACK_IMPORTED_MODULE_0__.CollectionItem{constructor(type,name,scene){super(type,name,scene);this._enabled=!0;this._disabledByAncestor=!1;this._destroyed=!1;this._parent=null;this._lastParent=null;this._children=[];this._parentingTable=[];this._parentChangedCallbacks=[];this._childChangedCallbacks=[];this._state=new EntityState();this._lastState=new EntityState();this._cameraSpacePosition=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._normalSpacePosition=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._pixelSpacePosition=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._normalSpaceExtentsRadius=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._pixelSpaceExtentsRadius=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._greatestPixelSpaceExtentsRadius=0.0;this._components=new _internal__WEBPACK_IMPORTED_MODULE_0__.Collection(this,_internal__WEBPACK_IMPORTED_MODULE_0__.Types.Components);this._controllers=new _internal__WEBPACK_IMPORTED_MODULE_0__.Collection(this,_internal__WEBPACK_IMPORTED_MODULE_0__.Types.Controllers);this._occlusionRadius=0;this._extentsRadius=0;this._canOcclude=!0;this._positionCoverage=new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY);this._positionCoverage.freeze();this._orientationCoverage=new _internal__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY);this._orientationCoverage.freeze();this._isInPositionCoverage=!1;this._isInOrientationCoverage=!1} + getScene(){return this.__getCollectionParent()} + isEnabled(){return this._enabled&&!this._disabledByAncestor} + isDisabledByAncestor(){return this._disabledByAncestor} + setEnabled(enabled){if(this._enabled!==enabled){this._enabled=enabled;this._updateEnabled()}} + _updateEnabled(){for(let i=0;i0){const firstEntry=this._parentingTable[0];const lastEntry=this._parentingTable[this._parentingTable.length-1];this._positionCoverage.min=Math.max(this._positionCoverage.min,firstEntry[1]!==''?firstEntry[0]:Number.POSITIVE_INFINITY);this._positionCoverage.max=Math.min(this._positionCoverage.max,lastEntry[1]!==''?Number.POSITIVE_INFINITY:lastEntry[0])} + this._positionCoverage.freeze();this._orientationCoverage.freeze()} + canOcclude(){return this._canOcclude} + setCanOcclude(canOcclude){this._canOcclude=canOcclude} + isOccludingPosition(camera,cameraSpacePosition){if(!this._canOcclude||!this.isInPositionCoverage()){return!1} + const occludingRadius=Math.min(this._occlusionRadius,this.getCameraSpacePosition(camera).magnitude());const interval=_internal__WEBPACK_IMPORTED_MODULE_0__.Interval.pool.get();_internal__WEBPACK_IMPORTED_MODULE_0__.Geometry.getLineSphereIntersectionWithLineStartAtOrigin(interval,cameraSpacePosition,this.getCameraSpacePosition(camera),occludingRadius);const occluding=interval.min0){return this._parentingTable[index-1][1]}else{if(this._parentingTable.length>0){return''}else{return this._parent!==null?this._parent.getName():''}}} + setParent(parent){if(parent===this._parent){return} + const position=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();this.getPositionRelativeToEntity(position,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,parent);if(!position.isNaN()){this.setPosition(position)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position);if(this._parent!==null){for(let i=0;ilevelOther){levelThis-=1;entityThis=entityThis.getParent()} + while(levelOther>levelThis){levelOther-=1;entityOther=entityOther.getParent()} + while(entityThis!==entityOther&&entityThis!==null){entityThis=entityThis.getParent();entityOther=entityOther.getParent()} + return entityThis} + getLowestCommonAncestorAtTime(entity,time){if(entity===null){return null} + let entityThis=(this);let entityOther=entity;let levelThis=0;let levelOther=0;const scene=this.getScene();while(!0){const parentName=entityThis.getParentAtTime(time);if(parentName===''){break} + const parent=scene.getEntity(parentName);if(parent===null){return null} + levelThis+=1;entityThis=parent} + while(!0){const parentName=entityOther.getParentAtTime(time);if(parentName===''){break} + const parent=scene.getEntity(parentName);if(parent===null){return null} + levelOther+=1;entityOther=parent} + entityThis=this;entityOther=entity;while(levelThis>levelOther){levelThis-=1;const parentName=entityThis.getParentAtTime(time);const parent=scene.getEntity(parentName);if(parent===null){return null} + entityThis=parent} + while(levelOther>levelThis){levelOther-=1;const parentName=entityOther.getParentAtTime(time);const parent=scene.getEntity(parentName);if(parent===null){return null} + entityOther=parent} + while(entityThis!==entityOther&&entityThis!==null){const parentThisName=entityThis.getParentAtTime(time);const parentThis=scene.getEntity(parentThisName);if(parentThis===null){return null} + entityThis=parentThis;const parentOtherName=entityOther.getParentAtTime(time);const parentOther=scene.getEntity(parentOtherName);if(parentOther===null){return null} + entityOther=parentOther} + return entityThis} + getNumParentingTableEntries(){return this._parentingTable.length} + getParentingTableEntry(index){return this._parentingTable[index]} + addParentingTableEntry(startTime,parentName){_internal__WEBPACK_IMPORTED_MODULE_0__.Sort.add([startTime,parentName],this._parentingTable,isStartTimeLess,isStartTimeEqual);this.__updateCoverage()} + removeParentingTableEntry(index){this._parentingTable.splice(index);this.__updateCoverage()} + clearParentingTableEntries(){this._parentingTable=[];this.__updateCoverage()} + addParentChangedCallback(callback){this._parentChangedCallbacks.push(callback)} + removeParentChangedCallback(callback){const index=this._parentChangedCallbacks.indexOf(callback);if(index!==-1){this._parentChangedCallbacks.splice(index,1)}} + addChildChangedCallback(callback){this._childChangedCallbacks.push(callback)} + removeChildChangedCallback(callback){const index=this._childChangedCallbacks.indexOf(callback);if(index!==-1){this._childChangedCallbacks.splice(index,1)}} + getNumComponents(){return this._components.size} + getComponent(nameOrIndex){return this._components.get(nameOrIndex)} + getComponentByType(type,index=0){return this._components.getByType(type,index)} + getComponentByClass(ComponentClass,index=0){return this._components.getByClass(ComponentClass,index)} + addComponent(type,name,beforeComponent){return this._components.add(type,name,beforeComponent)} + addComponentByClass(ClassConstructor,name,beforeComponent){return this._components.addByClass(ClassConstructor,name,beforeComponent)} + removeComponent(componentOrNameOrIndex){this._components.remove(componentOrNameOrIndex)} + clearComponents(){this._components.clear()} + getNumControllers(){return this._controllers.size} + getController(nameOrIndex){return this._controllers.get(nameOrIndex)} + getControllerByType(type,index=0){return this._controllers.getByType(type,index)} + getControllerByClass(ControllerClass,index=0){return this._controllers.getByClass(ControllerClass,index)} + addController(type,name,beforeController){const controller=this._controllers.add(type,name,beforeController);this.__updateCoverage();return controller} + addControllerByClass(ClassConstructor,name,beforeController){return this._controllers.addByClass(ClassConstructor,name,beforeController)} + removeController(controllerOrNameOrIndex){this._controllers.remove(controllerOrNameOrIndex);this.__updateCoverage()} + clearControllers(){this._controllers.clear();this.__updateCoverage()} + getCameraSpacePosition(camera){const pos=this._cameraSpacePosition.get(camera);if(pos!==undefined){return pos} + return _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]} + getNormalSpacePosition(camera){const pos=this._normalSpacePosition.get(camera);if(pos!==undefined){return pos} + return _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]} + getPixelSpacePosition(camera){const pos=this._pixelSpacePosition.get(camera);if(pos!==undefined){return pos} + return _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2[NaN]} + getNormalSpaceOcclusionRadius(camera){if(this._extentsRadius!==0){return this.getNormalSpaceExtentsRadius(camera)*this._occlusionRadius/this._extentsRadius}else{return 0}} + getNormalSpaceExtentsRadius(camera){const radius=this._normalSpaceExtentsRadius.get(camera);if(radius!==undefined){return radius}else{return Number.NaN}} + getPixelSpaceOcclusionRadius(camera){if(this._extentsRadius!==0){return this.getPixelSpaceExtentsRadius(camera)*this._occlusionRadius/this._extentsRadius}else{return 0}} + getPixelSpaceExtentsRadius(camera){const radius=this._pixelSpaceExtentsRadius.get(camera);if(radius!==undefined){return radius}else{return Number.NaN}} + getGreatestPixelSpaceOcclusionRadius(){if(this._extentsRadius!==0){return this.getGreatestPixelSpaceExtentsRadius()*this._occlusionRadius/this._extentsRadius}else{return 0}} + getGreatestPixelSpaceExtentsRadius(){return this._greatestPixelSpaceExtentsRadius} + __setCameraDependentVariables(camera,newCameraSpacePosition){const viewport=camera.getViewport();if(viewport===null){return} + let cameraSpacePosition=this._cameraSpacePosition.get(camera);if(cameraSpacePosition===undefined){cameraSpacePosition=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._cameraSpacePosition.set(camera,cameraSpacePosition)}else{cameraSpacePosition.thaw()} + cameraSpacePosition.copy(newCameraSpacePosition);cameraSpacePosition.freeze();let normalSpacePosition=this._normalSpacePosition.get(camera);if(normalSpacePosition===undefined){normalSpacePosition=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._normalSpacePosition.set(camera,normalSpacePosition)}else{normalSpacePosition.thaw()} + camera.getNormalSpacePositionFromCameraSpacePosition(normalSpacePosition,cameraSpacePosition);normalSpacePosition.freeze();let pixelSpacePosition=this._pixelSpacePosition.get(camera);if(pixelSpacePosition===undefined){pixelSpacePosition=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2();this._pixelSpacePosition.set(camera,pixelSpacePosition)}else{pixelSpacePosition.thaw()} + viewport.getPixelSpacePositionFromNormalSpacePosition(pixelSpacePosition,normalSpacePosition);pixelSpacePosition.freeze();const normalSpaceExtentsRadius=camera.getNormalSpaceRadiusFromRadius(this._extentsRadius,cameraSpacePosition.magnitude());this._normalSpaceExtentsRadius.set(camera,normalSpaceExtentsRadius);const pixelSpaceExtentsRadius=viewport.getPixelSpaceRadiusFromNormalSpaceRadius(normalSpaceExtentsRadius);this._pixelSpaceExtentsRadius.set(camera,pixelSpaceExtentsRadius)} + __removeCameraDependents(camera){this._cameraSpacePosition.delete(camera);this._normalSpacePosition.delete(camera);this._pixelSpacePosition.delete(camera);this._normalSpaceExtentsRadius.delete(camera);this._pixelSpaceExtentsRadius.delete(camera);for(let i=0;i=1){camera.__addToOccludingEntities(this)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(cameraSpacePosition);for(let i=0,l=this._components.size;i{if(controller.getEntity().isEnabled()&&controller.getCoverage().contains(controller.getEntity().getScene().getEngine().getTime())&&controller.isEnabled()){controller.__update()}});this._controllerDependencyGraph.setCompareItemCallback((a,b)=>{if(a===b){return!1} + if(!a.getEntity().isEnabled()||!b.getEntity().isEnabled()||!a.isEnabled()||!b.isEnabled()){return!1} + const time=a.getEntity().getScene().getEngine().getTime();if(!a.getCoverage().contains(time)||!b.getCoverage().contains(time)){return!1} + if(a.getEntity()===b.getEntity()){const entity=a.getEntity();for(let i=0,l=entity.getNumControllers();i=0;i--){const entity=this._entities.get(i);entity.__updateLastState();entity.__updateParent(currentTime);entity.__updateIsInCoverages(currentTime)} + this._controllerDependencyGraph.update()} + __updateVisuals(){for(let i=this._entities.size-1;i>=0;i--){const entity=this._entities.get(i);if(entity.isInPositionCoverage()&&entity.isEnabled()){this._entities.get(i).__updateVisuals()}}} + __removeCameraDependents(camera){for(let i=this._entities.size-1;i>=0;i--){this._entities.get(i).__removeCameraDependents(camera)}}}}),"../pioneer/engine/src/scene/types.js": + /*!********************************************!*\ + !*** ../pioneer/engine/src/scene/types.js ***! + \********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Types":function(){return Types}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class Types{} + Types.Components=new Map();Types.Components.set('atmosphere',_internal__WEBPACK_IMPORTED_MODULE_0__.AtmosphereComponent);Types.Components.set('camera',_internal__WEBPACK_IMPORTED_MODULE_0__.CameraComponent);Types.Components.set('cmts',_internal__WEBPACK_IMPORTED_MODULE_0__.CMTSComponent);Types.Components.set('cometTail',_internal__WEBPACK_IMPORTED_MODULE_0__.CometTailComponent);Types.Components.set('connectedSprite',_internal__WEBPACK_IMPORTED_MODULE_0__.ConnectedSpriteComponent);Types.Components.set('div',_internal__WEBPACK_IMPORTED_MODULE_0__.DivComponent);Types.Components.set('dynEnvMap',_internal__WEBPACK_IMPORTED_MODULE_0__.DynamicEnvironmentMapComponent);Types.Components.set('gizmo',_internal__WEBPACK_IMPORTED_MODULE_0__.GizmoComponent);Types.Components.set('label',_internal__WEBPACK_IMPORTED_MODULE_0__.LabelComponent);Types.Components.set('lightSource',_internal__WEBPACK_IMPORTED_MODULE_0__.LightSourceComponent);Types.Components.set('model',_internal__WEBPACK_IMPORTED_MODULE_0__.ModelComponent);Types.Components.set('orbitalParticles',_internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalParticlesComponent);Types.Components.set('particleSpray',_internal__WEBPACK_IMPORTED_MODULE_0__.ParticleSprayComponent);Types.Components.set('rings',_internal__WEBPACK_IMPORTED_MODULE_0__.RingsComponent);Types.Components.set('skybox',_internal__WEBPACK_IMPORTED_MODULE_0__.SkyboxComponent);Types.Components.set('spheroid',_internal__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent);Types.Components.set('spheroidLOD',_internal__WEBPACK_IMPORTED_MODULE_0__.SpheroidLODComponent);Types.Components.set('spout',_internal__WEBPACK_IMPORTED_MODULE_0__.SpoutComponent);Types.Components.set('sprite',_internal__WEBPACK_IMPORTED_MODULE_0__.SpriteComponent);Types.Components.set('starfield',_internal__WEBPACK_IMPORTED_MODULE_0__.StarfieldComponent);Types.Components.set('trail',_internal__WEBPACK_IMPORTED_MODULE_0__.TrailComponent);Types.Controllers=new Map();Types.Controllers.set('align',_internal__WEBPACK_IMPORTED_MODULE_0__.AlignController);Types.Controllers.set('animdata',_internal__WEBPACK_IMPORTED_MODULE_0__.AnimdataController);Types.Controllers.set('coverage',_internal__WEBPACK_IMPORTED_MODULE_0__.CoverageController);Types.Controllers.set('dynamo',_internal__WEBPACK_IMPORTED_MODULE_0__.DynamoController);Types.Controllers.set('fixed',_internal__WEBPACK_IMPORTED_MODULE_0__.FixedController);Types.Controllers.set('fixedToParent',_internal__WEBPACK_IMPORTED_MODULE_0__.FixedToParentController);Types.Controllers.set('freeFly',_internal__WEBPACK_IMPORTED_MODULE_0__.FreeFlyController);Types.Controllers.set('groundClamp',_internal__WEBPACK_IMPORTED_MODULE_0__.GroundClampController);Types.Controllers.set('keyframe',_internal__WEBPACK_IMPORTED_MODULE_0__.KeyframeController);Types.Controllers.set('look',_internal__WEBPACK_IMPORTED_MODULE_0__.LookController);Types.Controllers.set('modelAnimate',_internal__WEBPACK_IMPORTED_MODULE_0__.ModelAnimateController);Types.Controllers.set('orbit',_internal__WEBPACK_IMPORTED_MODULE_0__.OrbitController);Types.Controllers.set('orbitKeyframe',_internal__WEBPACK_IMPORTED_MODULE_0__.OrbitKeyframeController);Types.Controllers.set('orbitalElements',_internal__WEBPACK_IMPORTED_MODULE_0__.OrbitalElementsController);Types.Controllers.set('pick',_internal__WEBPACK_IMPORTED_MODULE_0__.PickController);Types.Controllers.set('roll',_internal__WEBPACK_IMPORTED_MODULE_0__.RollController);Types.Controllers.set('rotate',_internal__WEBPACK_IMPORTED_MODULE_0__.RotateController);Types.Controllers.set('rotateByEntityOrientation',_internal__WEBPACK_IMPORTED_MODULE_0__.RotateByEntityOrientationController);Types.Controllers.set('scale',_internal__WEBPACK_IMPORTED_MODULE_0__.ScaleController);Types.Controllers.set('select',_internal__WEBPACK_IMPORTED_MODULE_0__.SelectController);Types.Controllers.set('setParent',_internal__WEBPACK_IMPORTED_MODULE_0__.SetParentController);Types.Controllers.set('spin',_internal__WEBPACK_IMPORTED_MODULE_0__.SpinController);Types.Controllers.set('tap',_internal__WEBPACK_IMPORTED_MODULE_0__.TapController);Types.Controllers.set('transition',_internal__WEBPACK_IMPORTED_MODULE_0__.TransitionController);Types.Controllers.set('translate',_internal__WEBPACK_IMPORTED_MODULE_0__.TranslateController);Types.Controllers.set('zoom',_internal__WEBPACK_IMPORTED_MODULE_0__.ZoomController)}),"../pioneer/engine/src/shaders/basic.js": + /*!**********************************************!*\ + !*** ../pioneer/engine/src/shaders/basic.js ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"BasicShader":function(){return BasicShader}});var _log_depth__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./log_depth */"../pioneer/engine/src/shaders/log_depth.js");const BasicShader={uniforms:{modelViewMatrix:'mat4',projectionMatrix:'highp mat4',color:'vec4',..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms},properties:{},vertex:{extensions:['EXT_frag_depth'],code:` + attribute vec3 position; + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + `},fragment:{extensions:['EXT_frag_depth'],code:` + precision highp float; + + uniform vec4 color; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main() { + gl_FragColor = color; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + `}}}),"../pioneer/engine/src/shaders/basic_alpha.js": + /*!****************************************************!*\ + !*** ../pioneer/engine/src/shaders/basic_alpha.js ***! + \****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"BasicAlphaShader":function(){return BasicAlphaShader}});var _log_depth__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./log_depth */"../pioneer/engine/src/shaders/log_depth.js");const BasicAlphaShader={uniforms:{modelViewMatrix:'mat4',projectionMatrix:'highp mat4',color:'vec4',..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms},properties:{transparent:!0,depthWrite:!1,side:'double',blending:'normal'},vertex:{extensions:['EXT_frag_depth'],code:` + attribute vec3 position; + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + `},fragment:{extensions:['EXT_frag_depth'],code:` + precision highp float; + + uniform vec4 color; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main() { + gl_FragColor = color; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + `}}}),"../pioneer/engine/src/shaders/connected_sprite.js": + /*!*********************************************************!*\ + !*** ../pioneer/engine/src/shaders/connected_sprite.js ***! + \*********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ConnectedSpriteShader":function(){return ConnectedSpriteShader}});var _log_depth__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./log_depth */"../pioneer/engine/src/shaders/log_depth.js");const ConnectedSpriteShader={uniforms:{projectionMatrix:'highp mat4',vAxis:'vec3',color:'vec4',colorTexture:'sampler2D',width1:'float',width2:'float',textureYOffset:'float',repeatAmount:'float',..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms},properties:{side:'double',transparent:!0,depthWrite:!1,blending:'normal'},vertex:{extensions:['EXT_frag_depth'],code:` + attribute vec2 position; + + uniform mat4 modelMatrix; + uniform mat4 viewMatrix; + uniform mat4 projectionMatrix; + + uniform vec3 vAxis; + uniform float width1; + uniform float width2; + + varying vec2 vPosition; + varying float vU; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + + // Get the horizontal axis. + float width = mix(width1, width2, position.y); + vec3 viewVAxis = (viewMatrix * vec4(vAxis, 0)).xyz; + vec2 viewHAxisXZ = normalize(cross(vec3(0, 1, 0), viewVAxis)).xz; + vec4 viewHAxis = vec4(viewHAxisXZ.x, 0, viewHAxisXZ.y, 0); + + // Get the view position. + vec4 modelPosition = modelMatrix * vec4(0, 0, 0, 1) + vec4(vAxis, 0) * position.y; + vec4 viewPosition = viewMatrix * modelPosition; + + // Set the final projected position. + gl_Position = projectionMatrix * viewPosition + projectionMatrix * viewHAxis * width * position.x; + + // Setup a vPosition and vU for use in the fragment shader. + vPosition = vec2(0.5 * (position.x + 1.0), position.y); + #ifdef PIXEL_BASED + vPosition.y *= abs(gl_Position.w); + #endif + vU = position.y; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + }`},fragment:{extensions:['EXT_frag_depth'],code:` + precision highp float; + + uniform vec4 color; + uniform sampler2D colorTexture; + uniform float width1; + uniform float width2; + uniform float textureYOffset; + uniform float repeatAmount; + + varying vec2 vPosition; + varying float vU; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main() { + + // If we're using pixel-based, we need to undo the perspective divide that happened. + #ifdef PIXEL_BASED + vec2 uv = vec2(vPosition.x, vPosition.y * gl_FragCoord.w); + #else + vec2 uv = vPosition; + #endif + + // Get a correct use that uses the repeat amount and y offset. + // There's a complicated formula, because the widths may be different and the shape of the sprite may be a trapezoid. + float f = width2 * vU / (width1 * (1.0 - vU) + width2 * vU); + float uFactor = step(vU, uv.x); + uv.x = (1.0 - uFactor) * uv.x * f / vU + uFactor * (1.0 + (uv.x - 1.0) * (1.0 - f) / (1.0 - vU)); + uv.y = uv.y * repeatAmount + textureYOffset; + + // Apply the texture and color. + gl_FragColor = color * texture2D(colorTexture, uv); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`}}}),"../pioneer/engine/src/shaders/line.js": + /*!*********************************************!*\ + !*** ../pioneer/engine/src/shaders/line.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"LineShader":function(){return LineShader}});var _log_depth__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./log_depth */"../pioneer/engine/src/shaders/log_depth.js");const LineShader={uniforms:{modelViewMatrix:'mat4',projectionMatrix:'highp mat4',pixelSize:'vec2',alphaMultiplier:'float',dashLength:'float',dashGapLength:'float',glowWidth:'float',..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms},properties:{transparent:!0,depthWrite:!1,side:'double',blending:'additive'},vertex:{extensions:['EXT_frag_depth'],code:` + attribute vec3 position; + attribute vec3 positionPrev; + attribute vec3 positionNext; + attribute vec4 color; + attribute float width; + attribute float dashOffset; + + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + uniform vec2 pixelSize; + uniform float glowWidth; + + varying vec4 fColor; + varying float fDashOffset; + varying float fWidth; + varying float fOffsetScalar; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + // Get the line vertices into pixel space. + vec4 view_center = modelViewMatrix * vec4(position, 1.0); + vec4 view_prev = modelViewMatrix * vec4(positionPrev, 1.0); + vec4 view_next = modelViewMatrix * vec4(positionNext, 1.0); + vec4 projected_center = projectionMatrix * view_center; + vec4 projected_prev = projectionMatrix * view_prev; + vec4 projected_next = projectionMatrix * view_next; + vec2 ndc_center = projected_center.xy / view_center.y; + vec2 ndc_prev = projected_prev.xy / view_prev.y; + vec2 ndc_next = projected_next.xy / view_next.y; + vec2 pixel_center = (ndc_center.xy + 1.0) / 2.0 * pixelSize; + vec2 pixel_prev = (ndc_prev.xy + 1.0) / 2.0 * pixelSize; + vec2 pixel_next = (ndc_next.xy + 1.0) / 2.0 * pixelSize; + + // Get the offset of the part perpendicular to the lines. + vec2 l0 = normalize(pixel_center - pixel_prev); + vec2 l1 = normalize(pixel_next - pixel_center); + float offsetScalar = sign(width) * (abs(width) / 2.0 + glowWidth); + vec2 offset = vec2(offsetScalar, offsetScalar); + if (pixel_center == pixel_prev) { + if (pixel_center == pixel_next) { + offset = vec2(0.0, 0.0); + } + else { + offset *= vec2(-l1.y, l1.x); + } + } + else if (pixel_center == pixel_next) { + offset *= vec2(-l0.y, l0.x); + } + else { + offset *= normalize(vec2(-l0.y - l1.y, l0.x + l1.x)); + offset /= max(0.25, sqrt((1.0 + dot(l0, l1)) / 2.0)); + } + + // Re-add the perpendicular part to the center as the final vertex. + ndc_center = (pixel_center + offset) / pixelSize * 2.0 - 1.0; + gl_Position = vec4(ndc_center * view_center.y, projected_center.z, projected_center.w); + + // Set the varyings. + fColor = color; + fDashOffset = dashOffset; + fWidth = width; + fOffsetScalar = offsetScalar; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + `},fragment:{extensions:['EXT_frag_depth'],code:` + precision highp float; + + uniform float alphaMultiplier; + uniform float dashLength; + uniform float dashGapLength; + uniform float glowWidth; + + varying vec4 fColor; + varying float fDashOffset; + varying float fWidth; + varying float fOffsetScalar; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + float line_dash_func() { + float u = mod(fDashOffset, dashLength + dashGapLength); + return float(u < dashLength); + } + + float edgeGlow() { + if (glowWidth > 0.0) { + float value = clamp((fWidth / 2.0 + glowWidth - abs(fOffsetScalar)) / glowWidth, 0.0, 1.0); + if (value < 1.0) { + value *= 0.75; + } + return value; + } + return 1.0; + } + + void main() { + gl_FragColor = fColor; + gl_FragColor.a *= alphaMultiplier * edgeGlow() * line_dash_func(); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + `}}}),"../pioneer/engine/src/shaders/log_depth.js": + /*!**************************************************!*\ + !*** ../pioneer/engine/src/shaders/log_depth.js ***! + \**************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ShaderChunkLogDepth":function(){return ShaderChunkLogDepth}});var three__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! three */"../pioneer/engine/node_modules/three/build/three.module.js");class ShaderChunkLogDepth{static Uniforms={invertDepth:'float',nearDistance:'float',midDistance:'float'};static VertexHead=` + #ifdef L_EXT_frag_depth + varying float depth; + #else + uniform float nearDistance; + uniform float midDistance; + #endif + `;static Vertex=` + #ifdef L_EXT_frag_depth + depth = gl_Position.w; + #else + float z = gl_Position.w; + if (z < midDistance) { + gl_Position.z = nearDistance * (z - midDistance) / (midDistance - nearDistance); + } + else { + float logFactor = 0.01254291648; // 1 / log2(1e24 - midDistance + 1.0) + gl_Position.z = log2(z - midDistance + 1.0) * logFactor; + gl_Position.z *= gl_Position.w; + } + #endif + `;static FragmentHead=` + #ifdef L_EXT_frag_depth + uniform float invertDepth; + uniform float nearDistance; + uniform float midDistance; + varying float depth; + #endif + `;static Fragment=` + #ifdef L_EXT_frag_depth + float logFactor = 0.01254291648; // 1 / log2(1 + 1e24) + float nearFactor = 0.5 * (depth - nearDistance) / (midDistance - nearDistance); + float farFactor = 0.5 * (1.0 + log2(1.0 + depth - midDistance) * logFactor); + gl_FragDepthEXT = (1.0 - 2.0 * invertDepth) * (depth >= midDistance ? farFactor : nearFactor) + invertDepth; + #endif + `;static ThreeUniforms={invertDepth:new three__WEBPACK_IMPORTED_MODULE_0__.Uniform(0),nearDistance:new three__WEBPACK_IMPORTED_MODULE_0__.Uniform(0),midDistance:new three__WEBPACK_IMPORTED_MODULE_0__.Uniform(0)}}}),"../pioneer/engine/src/shaders/plumes.js": + /*!***********************************************!*\ + !*** ../pioneer/engine/src/shaders/plumes.js ***! + \***********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"PlumesShader":function(){return PlumesShader}});var _log_depth__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./log_depth */"../pioneer/engine/src/shaders/log_depth.js");const PlumesShader={uniforms:{modelViewMatrix:'mat4',projectionMatrix:'highp mat4',colorTexture:'sampler2D',colorMultiplier:'vec4',speed:'float',time:'float',..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms},properties:{transparent:!0,depthWrite:!1,side:'double',blending:'normal'},vertex:{extensions:['EXT_frag_depth'],code:` + attribute vec3 position; + attribute vec2 uv; + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + varying vec2 vUV; + + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + vUV = uv; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + `},fragment:{extensions:['EXT_frag_depth'],code:` + precision highp float; + + uniform sampler2D colorTexture; + uniform vec4 colorMultiplier; + uniform float speed; + uniform float time; + varying vec2 vUV; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + vec2 v2_construct_func(float x, float y) { + return vec2(x, y); + } + float s_mult_func(float s1, float s2) { + return s1 * s2; + } + float s_mod_func(float s1, float s2) { + return mod(s1, s2); + } + vec2 v2s_mult_func(vec2 v, float s) { + return v * s; + } + vec2 v2_add_func(vec2 v1, vec2 v2) { + return v1 + v2; + } + vec4 texture_func(sampler2D tex, vec2 uv) { + return texture2D(tex, uv); + } + vec4 v4v4_mult_func(vec4 v1, vec4 v2) { + return v1 * v2; + } + float s_sub_func(float s1, float s2) { + return s1 - s2; + } + vec4 alpha_mult_func(vec4 color, float alpha) { + return vec4(color.rgb, color.a * alpha); + } + void main() { + vec2 yAxis = v2_construct_func(0.0, 1.0); + float yMultiplier = s_mult_func(time, speed); + float yMultiplierMod = s_mod_func(yMultiplier, 1.0); + vec2 uvOffset = v2s_mult_func(yAxis, yMultiplierMod); + vec2 finalUV = v2_add_func(vUV, uvOffset); + vec4 textureOffset = texture_func(colorTexture, finalUV); + vec4 color = v4v4_mult_func(textureOffset, colorMultiplier); + float fade = s_sub_func(1.0, vUV.y); + vec4 color_with_fade = alpha_mult_func(color, fade); + gl_FragColor = color_with_fade; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + `}}}),"../pioneer/engine/src/shaders/sprite.js": + /*!***********************************************!*\ + !*** ../pioneer/engine/src/shaders/sprite.js ***! + \***********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SpriteShader":function(){return SpriteShader}});var _log_depth__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./log_depth */"../pioneer/engine/src/shaders/log_depth.js");const SpriteShader={uniforms:{modelViewMatrix:'mat4',projectionMatrix:'highp mat4',pixelBased:'float',color:'vec4',colorTexture:'sampler2D',..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms},properties:{transparent:!0,depthWrite:!1,side:'double',blending:'normal'},vertex:{extensions:['EXT_frag_depth'],code:` + attribute vec3 position; + attribute vec2 uv; + + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + uniform float pixelBased; + + varying vec2 vUV; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + if (pixelBased != 0.0) { + gl_Position /= abs(gl_Position.w); + } + vUV = uv; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + `},fragment:{extensions:['EXT_frag_depth'],code:` + precision highp float; + + uniform vec4 color; + uniform sampler2D colorTexture; + + varying vec2 vUV; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main() { + gl_FragColor = texture2D(colorTexture, vUV) * color; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + `}}}),"../pioneer/engine/src/shaders/sprite_particles.js": + /*!*********************************************************!*\ + !*** ../pioneer/engine/src/shaders/sprite_particles.js ***! + \*********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"SpriteParticlesShader":function(){return SpriteParticlesShader}});var _log_depth__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./log_depth */"../pioneer/engine/src/shaders/log_depth.js");const SpriteParticlesShader={uniforms:{modelViewMatrix:'mat4',projectionMatrix:'highp mat4',..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms},properties:{transparent:!0,depthWrite:!1,side:'double',blending:'additive'},vertex:{extensions:['EXT_frag_depth'],code:` + attribute vec3 position; + attribute vec4 color; + attribute vec3 offset; + attribute float scale; + + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + varying vec4 fColor; + varying vec2 fPosition; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + vec4 viewPosition = modelViewMatrix * vec4(offset, 1.0) + vec4(position, 0.0) * scale; + gl_Position = projectionMatrix * viewPosition; + fColor = color; + fPosition = position.xz; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + `},fragment:{extensions:['EXT_frag_depth'],code:` + precision highp float; + + varying vec4 fColor; + varying vec2 fPosition; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + void main() { + gl_FragColor = fColor * (1.0 - length(fPosition)); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + `}}}),"../pioneer/engine/src/shaders/trail.js": + /*!**********************************************!*\ + !*** ../pioneer/engine/src/shaders/trail.js ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TrailShader":function(){return TrailShader}});var _log_depth__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./log_depth */"../pioneer/engine/src/shaders/log_depth.js");const TrailShader={uniforms:{modelViewMatrix:'mat4',projectionMatrix:'highp mat4',pixelSize:'vec2',alphaMultiplier:'float',dashLength:'float',dashGapLength:'float',glowWidth:'float',indexStart:'float',indexCount:'float',indexLength:'float',color:'vec4',alphaFade:'float',widthMin:'float',widthMax:'float',..._log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Uniforms},properties:{transparent:!0,depthWrite:!1,side:'double',blending:'additive'},vertex:{extensions:['EXT_frag_depth'],code:` + attribute vec3 positionCurr; + attribute vec3 positionPrev; + attribute vec3 positionNext; + attribute float side; + attribute float index; + attribute float dashOffset; + + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + + uniform vec2 pixelSize; + uniform float glowWidth; + uniform float indexStart; + uniform float indexCount; + uniform float indexLength; + uniform float widthMin; + uniform float widthMax; + + varying vec4 fColor; + varying float fDashOffset; + varying float fWidth; + varying float fOffsetScalar; + varying float fIndexU; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.VertexHead} + + void main() { + // Get the width depending on the length. + float indexU = mod(index - indexStart + indexLength, indexLength) / (indexCount - 1.0); + float width = mix(widthMin, widthMax, indexU); + + // Get the line vertices into pixel space. + vec4 viewCenter = modelViewMatrix * vec4(positionCurr, 1.0); + vec4 viewPrev = modelViewMatrix * vec4(positionPrev, 1.0); + vec4 viewNext = modelViewMatrix * vec4(positionNext, 1.0); + vec4 projectedCenter = projectionMatrix * viewCenter; + vec4 projected_prev = projectionMatrix * viewPrev; + vec4 projected_next = projectionMatrix * viewNext; + vec2 ndcCenter = projectedCenter.xy / viewCenter.y; + vec2 ndcPrev = projected_prev.xy / viewPrev.y; + vec2 ndcNext = projected_next.xy / viewNext.y; + vec2 pixelCenter = (ndcCenter.xy + 1.0) / 2.0 * pixelSize; + vec2 pixelPrev = (ndcPrev.xy + 1.0) / 2.0 * pixelSize; + vec2 pixelNext = (ndcNext.xy + 1.0) / 2.0 * pixelSize; + + // Get the offset of the part perpendicular to the lines. + vec2 l0 = normalize(pixelCenter - pixelPrev); + vec2 l1 = normalize(pixelNext - pixelCenter); + float offsetScalar = side * (width / 2.0 + glowWidth); + vec2 offset = vec2(offsetScalar, offsetScalar); + if (pixelCenter == pixelPrev) { + if (pixelCenter == pixelNext) { + offset = vec2(0.0, 0.0); + } + else { + offset *= vec2(-l1.y, l1.x); + } + } + else if (pixelCenter == pixelNext) { + offset *= vec2(-l0.y, l0.x); + } + else { + offset *= normalize(vec2(-l0.y - l1.y, l0.x + l1.x)); + offset /= sqrt((1.0 + max(0.0, dot(l0, l1))) / 2.0); + } + + // Re-add the perpendicular part to the center as the final vertex. + ndcCenter = (pixelCenter + offset) / pixelSize * 2.0 - 1.0; + gl_Position = vec4(ndcCenter * viewCenter.y, projectedCenter.z, projectedCenter.w); + + // Set the varyings. + fIndexU = indexU; + fDashOffset = dashOffset; + fWidth = width; + fOffsetScalar = offsetScalar; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Vertex} + } + `},fragment:{extensions:['EXT_frag_depth'],code:` + precision highp float; + + uniform vec4 color; + uniform float alphaMultiplier; + uniform float alphaFade; + uniform float dashLength; + uniform float dashGapLength; + uniform float glowWidth; + + varying float fIndexU; + varying float fDashOffset; + varying float fWidth; + varying float fOffsetScalar; + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.FragmentHead} + + float lineDash() { + float u = mod(fDashOffset, dashLength + dashGapLength); + return float(u < dashLength); + } + + float edgeGlow() { + if (glowWidth > 0.0) { + float value = clamp((fWidth / 2.0 + glowWidth - abs(fOffsetScalar)) / glowWidth, 0.0, 1.0); + if (value < 1.0) { + value *= 0.75; + } + return value; + } + return 1.0; + } + + void main() { + gl_FragColor = color; + gl_FragColor.a *= alphaMultiplier * edgeGlow() * lineDash() * mix(alphaFade, 1.0, fIndexU); + + ${_log_depth__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + } + `}}}),"../pioneer/engine/src/texture_loader.js": + /*!***********************************************!*\ + !*** ../pioneer/engine/src/texture_loader.js ***! + \***********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TextureLoader":function(){return TextureLoader}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./internal */"../pioneer/engine/src/internal.js");class TextureLoader extends _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Loader{constructor(downloader,renderer){super();this._downloader=downloader;this._renderer=renderer;this._crossOrigin='anonymous';this._path=undefined;this._white=null;this._black=null;this._clear=null;this._pink=null;this._gray=null;this._threeJsTextureLoader=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.TextureLoader();this._threeJsTextureLoader.setCrossOrigin(this._crossOrigin);this._threeJsTextureLoader.setPath(this._path);this._white=TextureLoader._newTexture(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1,1,1,1));this._black=TextureLoader._newTexture(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0,0,0,1));this._clear=TextureLoader._newTexture(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0,0,0,0));this._pink=TextureLoader._newTexture(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(1,105/255,180/255,1));this._gray=TextureLoader._newTexture(new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0.4,0.4,0.4,1));_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.DefaultLoadingManager.addHandler(/.$/i,this)} + async loadIntoUniform(uniform,url,useMipMaps){return this.loadTexture(url,useMipMaps).then((texture)=>{if(uniform.value!==null){uniform.value.dispose()} + uniform.value=texture})} + async loadCubeTexture(url,useMipMaps){const cubeTexture=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CubeTexture();const promises=[];for(let i=0;i<6;i++){const newUrl=url.replace('$FACE',_cubeFaceNames[i]);promises.push(new Promise((resolve)=>{this.loadTexture(newUrl,useMipMaps).then((texture)=>{cubeTexture.images[i]=texture.image;resolve()})}))} + return Promise.all(promises).then(()=>{cubeTexture.needsUpdate=!0;return cubeTexture})} + async loadTexture(url,useMipMaps){return new Promise((resolve,reject)=>{this.load(url,(texture)=>{resolve(texture)},undefined,(message)=>{reject(new Error(`Failed to load ${url}: ${message}`))},useMipMaps)})} + generateEnvMap(texture){let cubemap=texture;if(!(texture instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CubeTexture)){const options={depthBuffer:!1,stencilBuffer:!1,generateMipmaps:!0,minFilter:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearMipMapLinearFilter,magFilter:_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter};cubemap=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.WebGLCubeRenderTarget(512,options).fromEquirectangularTexture(this._renderer,texture).texture} + const pmremGenerator=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.PMREMGenerator(this._renderer);pmremGenerator.compileEquirectangularShader();const envMap=pmremGenerator.fromEquirectangular(cubemap).texture;return envMap} + load(url,onLoad,_onProgress,onError,useMipMaps){url=this._downloader.processUrl(url);let texture=(null);if(url==='white'){texture=this._white}else if(url==='black'){texture=this._black}else if(url==='clear'){texture=this._clear}else if(url==='pink'){texture=this._pink}else if(url==='gray'){texture=this._gray} + if(texture!==null){onLoad(texture)}else{if(url.includes('.mp4')){const videoElement=document.createElement('video');videoElement.src=url;videoElement.muted=!0;videoElement.playsInline=!0;videoElement.loop=!1;videoElement.crossOrigin='anonymous';texture=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.VideoTexture(videoElement);texture.format=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.RGBAFormat;texture.flipY=!1;texture.needsUpdate=!0;this._downloader.download(url,!0).then((download)=>{videoElement.src=URL.createObjectURL(new Blob([download.content],{type:'video/mp4'}));videoElement.onerror=(event)=>{onError(event.toString())};videoElement.oncanplaythrough=()=>{onLoad(texture)};videoElement.load()})}else{this._threeJsTextureLoader.load(url,(texture)=>{texture.flipY=!1;if(useMipMaps===!1){texture.minFilter=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter;texture.generateMipmaps=!1} + texture.needsUpdate=!0;onLoad(texture)},undefined,(event)=>{onError(event.message)})}} + return texture} + get crossOrigin(){return this._crossOrigin} + set crossOrigin(crossOrigin){this._crossOrigin=crossOrigin;if(this._threeJsTextureLoader){this._threeJsTextureLoader.setCrossOrigin(this._crossOrigin)}} + setCrossOrigin(crossOrigin){this.crossOrigin=crossOrigin;return this} + get path(){return this._path} + set path(path){this._path=path;if(this._threeJsTextureLoader){this._threeJsTextureLoader.setPath(this._path)}} + setPath(path){this.path=path;return this} + static _newTexture(color){const canvas=document.createElement('canvas');canvas.width=1;canvas.height=1;const context=canvas.getContext('2d');context.fillStyle='rgba('+(color.r*255)+','+(color.g*255)+','+(color.b*255)+','+(color.a*255)+')';context.fillRect(0,0,1,1);return new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.CanvasTexture(canvas)}} + const _cubeFaceNames=['posx','negx','posy','negy','posz','negz']}),"../pioneer/engine/src/texture_loader_compressed.js": + /*!**********************************************************!*\ + !*** ../pioneer/engine/src/texture_loader_compressed.js ***! + \**********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"TextureLoaderCompressed":function(){return TextureLoaderCompressed}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./internal */"../pioneer/engine/src/internal.js");class TextureLoaderCompressed extends _internal__WEBPACK_IMPORTED_MODULE_0__.TextureLoader{constructor(downloader,config,renderer){super(downloader,renderer);this._config=config;this._threeJsKTXLoader=new _internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsKTXLoader();this._threeJsKTXLoader.setCrossOrigin(this._crossOrigin);this._threeJsKTXLoader.setPath(this._path)} + load(url,onLoad,onProgress,onError,useMipMaps){if(url.match(/_n\.[^.]+$/)!==null){return super.load(url,onLoad,onProgress,onError,useMipMaps)} + url=this._downloader.processUrl(url);let texture=null;if(url==='white'){texture=this._white}else if(url==='black'){texture=this._black}else if(url==='clear'){texture=this._clear}else if(url==='pink'){texture=this._pink} + if(texture!==null){onLoad(texture)}else{url=url.replace(/\.(\w+)$/,'-'+_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.__getCompressedTextureExtension()+'.ktx');this._threeJsKTXLoader.load(url,(texture)=>{texture.flipY=!1;texture.needsUpdate=!0;if(useMipMaps===!1){texture.minFilter=_internal__WEBPACK_IMPORTED_MODULE_0__.THREE.LinearFilter;texture.generateMipmaps=!1} + texture.ktxFormat=texture.format;onLoad(texture)},undefined,(event)=>{onError(event.message)})} + return texture}}}),"../pioneer/engine/src/utils/aer.js": + /*!******************************************!*\ + !*** ../pioneer/engine/src/utils/aer.js ***! + \******************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"AER":function(){return AER}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class AER extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable{static get pool(){return _pool} + constructor(azimuth=0,elevation=0,range=0){super();this._azimuth=azimuth;this._elevation=elevation;this._range=range} + get azimuth(){return this._azimuth} + set azimuth(azimuth){this.throwIfFrozen();this._azimuth=azimuth} + get elevation(){return this._elevation} + set elevation(elevation){this.throwIfFrozen();this._elevation=elevation} + get range(){return this._range} + set range(range){this.throwIfFrozen();this._range=range} + toString(deg=!1){if(deg){return'['+_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.radToDeg(this._azimuth)+', '+_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.radToDeg(this._elevation)+', '+this._range+']'}else{return'['+this._azimuth+', '+this._elevation+', '+this._range+']'}} + copy(a){this.throwIfFrozen();this._azimuth=a._azimuth;this._elevation=a._elevation;this._range=a._range} + set(azimuth,elevation,range){this.throwIfFrozen();this._azimuth=azimuth;this._elevation=elevation;this._range=range} + setFromVector(xyz){this.throwIfFrozen();this._range=xyz.magnitude();this._elevation=Math.asin(xyz.z/this._range);this._azimuth=Math.atan2(xyz.y,xyz.x)}} + const _pool=new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(AER)}),"../pioneer/engine/src/utils/base_ref.js": + /*!***********************************************!*\ + !*** ../pioneer/engine/src/utils/base_ref.js ***! + \***********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"BaseRef":function(){return BaseRef}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class BaseRef{constructor(scene){this._scene=scene;this._ref=null;this._refChangedCallback=null} + get(){this.update();return this._ref} + setRefChangedCallback(refChangedCallback){this._refChangedCallback=refChangedCallback} + update(){} + _setRef(newRef){if(newRef!==null&&!newRef.isEnabled()){newRef=null} + if(this._ref!==newRef){const oldRef=this._ref;this._ref=newRef;if(this._refChangedCallback!==null){this._refChangedCallback(oldRef,this._ref)}}}}}),"../pioneer/engine/src/utils/cache.js": + /*!********************************************!*\ + !*** ../pioneer/engine/src/utils/cache.js ***! + \********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Cache":function(){return Cache}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class Cache extends _internal__WEBPACK_IMPORTED_MODULE_0__.FastIterable{constructor(itemConstructor=null,itemDestructor=null){super();this._keysToEntries=new _internal__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._itemToKeys=new Map();this._itemConstructor=itemConstructor;this._itemDestructor=itemDestructor} + get(key){const entry=this._keysToEntries.get(key);if(entry===undefined){const newEntry={item:this._itemConstructor(key),count:1};this._keysToEntries.set(key,newEntry);this._itemToKeys.set(newEntry.item,key);return newEntry.item}else{entry.count+=1;return entry.item}} + release(item){const key=this._itemToKeys.get(item);if(key!==undefined){const entry=this._keysToEntries.get(key);entry.count-=1;if(entry.count===0){this._itemDestructor(entry.item);this._keysToEntries.delete(key);this._itemToKeys.delete(item)}}} + getAt(index){return this._keysToEntries.getAt(index).value.item} + get size(){return this._keysToEntries.size}}}),"../pioneer/engine/src/utils/collection.js": + /*!*************************************************!*\ + !*** ../pioneer/engine/src/utils/collection.js ***! + \*************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"CollectionItem":function(){return CollectionItem},"Collection":function(){return Collection}});class CollectionItem{constructor(type,name,collectionParent){this._type=type;this._index=0;this._typeIndex=0;this._name=name;this._collectionParent=collectionParent} + getType(){return this._type} + getIndex(){return this._index} + __setIndex(index){this._index=index} + getTypeIndex(){return this._typeIndex} + __setTypeIndex(typeIndex){this._typeIndex=typeIndex} + getName(){return this._name} + __getCollectionParent(){return this._collectionParent} + __setCollectionParent(collectionParent){this._collectionParent=collectionParent} + __destroy(){}} + class Collection{constructor(parent,types){this._parent=parent;this._types=types;this._items=[];this._itemsByName=new Map();this._itemsByType=new Map()} + get(itemOrNameOrIndex){const index=this._getByItemOrNameOrIndex(itemOrNameOrIndex);return index!==undefined?this._items[index]:null} + getByType(typeName,index=0){const type=this._types.get(typeName);if(type===undefined){return null} + const itemsOfType=this._itemsByType.get(type);if(itemsOfType===undefined){return null} + if(index<0||index>=itemsOfType.length){return null} + return itemsOfType[index]} + getByClass(ClassConstructor,index=0){const typesList=this._itemsByType.get(ClassConstructor);if(typesList!==undefined&&index>=0&&index=0;i--){this._items[i].__destroy()} + this._items=[];this._itemsByName.clear();this._itemsByType.clear()} + get size(){return this._items.length} + _addToLists(name,item,beforeItem){const index=beforeItem!==undefined?beforeItem.getIndex():this._items.length;this._items.splice(index,0,item);if(name!==''){this._itemsByName.set(name,item)} + this._updateIndices(index,item)} + _removeFromLists(index,name,item){this._items.splice(index,1);if(name!==''){this._itemsByName.delete(name)} + this._updateIndices(index,item)} + _updateIndices(startingIndex,item){for(let i=startingIndex;i=0;i--){this._items[i].__destroy()}} + _getByItemOrNameOrIndex(itemOrNameOrIndex){if(typeof itemOrNameOrIndex==='number'){if(itemOrNameOrIndex>=0&&itemOrNameOrIndex=0;i--){if(this._items[i]===item){return i}}} + return undefined}}}),"../pioneer/engine/src/utils/color.js": + /*!********************************************!*\ + !*** ../pioneer/engine/src/utils/color.js ***! + \********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Color":function(){return Color}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class Color extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable{static get pool(){return _pool} + static get Black(){return _black} + static get Clear(){return _clear} + constructor(r=1,g=1,b=1,a=1){super();this._r=r;this._g=g;this._b=b;this._a=a} + get r(){return this._r} + set r(r){this.throwIfFrozen();this._r=r} + get g(){return this._g} + set g(g){this.throwIfFrozen();this._g=g} + get b(){return this._b} + set b(b){this.throwIfFrozen();this._b=b} + get a(){return this._a} + set a(a){this.throwIfFrozen();this._a=a} + toString(){return'['+this._r+', '+this._g+', '+this._b+', '+this._a+']'} + copy(a){this.throwIfFrozen();this._r=a._r;this._g=a._g;this._b=a._b;this._a=a._a} + set(r,g,b,a=1){this.throwIfFrozen();this._r=r;this._g=g;this._b=b;this._a=a} + add(a,b){this.throwIfFrozen();this._r=a._r+b._r;this._g=a._g+b._g;this._b=a._b+b._b;this._a=a._a+b._a} + sub(a,b){this.throwIfFrozen();this._r=a._r-b._r;this._g=a._g-b._g;this._b=a._b-b._b;this._a=a._a-b._a} + mult(a,b){this.throwIfFrozen();this._r=a._r*b;this._g=a._g*b;this._b=a._b*b;this._a=a._a*b} + addMult(a,b,c){this.throwIfFrozen();this._r=a._r+b._r*c;this._g=a._g+b._g*c;this._b=a._b+b._b*c;this._a=a._a+b._a*c} + div(a,b){this.throwIfFrozen();this._r=a._r/b;this._g=a._g/b;this._b=a._b/b;this._a=a._a/b} + scale(a,b){this.throwIfFrozen();this._r=a._r*b._r;this._g=a._g*b._g;this._b=a._b*b._b;this._a=a._a*b._a} + value(){return(this._r+this._g+this._b)/3.0} + min(){return Math.min(this._r,this._g,this._b)} + max(){return Math.max(this._r,this._g,this._b)} + lerp(a,b,u){this.throwIfFrozen();this._r=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._r,b._r,u);this._g=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._g,b._g,u);this._b=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._b,b._b,u);this._a=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._a,b._a,u)}} + const _pool=new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Color);const _black=new Color(0,0,0,1);_black.freeze();const _clear=new Color(0,0,0,1);_clear.freeze()}),"../pioneer/engine/src/utils/component_ref.js": + /*!****************************************************!*\ + !*** ../pioneer/engine/src/utils/component_ref.js ***! + \****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ComponentRef":function(){return ComponentRef}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class ComponentRef extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseRef{constructor(scene){super(scene);this._entityName='';this._componentName='';this._componentType='';this._componentTypeIndex=0} + getEntityName(){return this._entityName} + getComponentName(){return this._componentName} + getComponentType(){return this._componentType} + getComponentTypeIndex(){return this._componentTypeIndex} + setByName(entityName,componentName){this._entityName=entityName;this._componentName=componentName;this._componentType=''} + setByType(entityName,componentType,componentTypeIndex=0){this._entityName=entityName;this._componentType=componentType;this._componentTypeIndex=componentTypeIndex;this._componentName=''} + update(){if(this._entityName===''||(this._componentName===''&&this._componentType==='')){this._setRef(null)}else if(this._componentName!==''){const entity=this._scene.getEntity(this._entityName);if(entity!==null&&entity.isEnabled()){const ref=(entity.getComponent(this._componentName));this._setRef(ref)}else{this._setRef(null)}}else{const entity=this._scene.getEntity(this._entityName);if(entity!==null&&entity.isEnabled()){const ref=(entity.getComponentByType(this._componentType,this._componentTypeIndex));this._setRef(ref)}else{this._setRef(null)}}}}}),"../pioneer/engine/src/utils/controller_ref.js": + /*!*****************************************************!*\ + !*** ../pioneer/engine/src/utils/controller_ref.js ***! + \*****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ControllerRef":function(){return ControllerRef}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class ControllerRef extends _internal__WEBPACK_IMPORTED_MODULE_0__.BaseRef{constructor(scene){super(scene);this._entityName='';this._controllerName='';this._controllerType='';this._controllerTypeIndex=0} + getEntityName(){return this._entityName} + getControllerName(){return this._controllerName} + getControllerType(){return this._controllerType} + getControllerTypeIndex(){return this._controllerTypeIndex} + setByName(entityName,controllerName){this._entityName=entityName;this._controllerName=controllerName;this._controllerType=''} + setByType(entityName,controllerType,controllerTypeIndex=0){this._entityName=entityName;this._controllerType=controllerType;this._controllerTypeIndex=controllerTypeIndex;this._controllerName=''} + update(){if(this._entityName===''||(this._controllerName===''&&this._controllerType==='')){this._setRef(null)}else if(this._controllerName!==''){const entity=this._scene.getEntity(this._entityName);if(entity!==null&&entity.isEnabled()){const ref=(entity.getController(this._controllerName));this._setRef(ref)}else{this._setRef(null)}}else{const entity=this._scene.getEntity(this._entityName);if(entity!==null&&entity.isEnabled()){const ref=(entity.getControllerByType(this._controllerType,this._controllerTypeIndex));this._setRef(ref)}else{this._setRef(null)}}}}}),"../pioneer/engine/src/utils/cube_map.js": + /*!***********************************************!*\ + !*** ../pioneer/engine/src/utils/cube_map.js ***! + \***********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"CubeMap":function(){return CubeMap}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class CubeMap{static xyzToUVFace(outUVFace,xyz,cubeMapFaceFrames=this._defaultCubeMapFaceFrames){let basis;for(let i=0;i<6;i++){const cubeMapFaceFrame=cubeMapFaceFrames[i];const outVector=cubeMapFaceFrame[2];let value0=0;let value1=0;let value2=0;let neg=!1;if(outVector===_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis||outVector===_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg){value0=xyz.x;value1=xyz.y;value2=xyz.z;neg=(outVector===_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg)}else if(outVector===_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis||outVector===_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg){value0=xyz.y;value1=xyz.z;value2=xyz.x;neg=(outVector===_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg)}else{value0=xyz.z;value1=xyz.x;value2=xyz.y;neg=(outVector===_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxisNeg)} + if(Math.abs(value0)>=Math.abs(value1)&&Math.abs(value0)>=Math.abs(value2)){if((value0>=0.0&&!neg)||(value0<0.0&&neg)){basis=cubeMapFaceFrame;outUVFace.z=i}}} + if(basis===undefined){outUVFace.set(NaN,NaN,NaN);return} + let z=basis[2].x*xyz.x+basis[2].y*xyz.y+basis[2].z*xyz.z;if(z<0.0){z=1.0} + outUVFace.x=(basis[0].x*xyz.x+basis[0].y*xyz.y+basis[0].z*xyz.z)/z;outUVFace.y=(basis[1].x*xyz.x+basis[1].y*xyz.y+basis[1].z*xyz.z)/z;outUVFace.x=0.5*(outUVFace.x+1.0);outUVFace.y=0.5*(outUVFace.y+1.0)}} + CubeMap._defaultCubeMapFaceFrames=[[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis],[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis],[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg],[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg],[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxisNeg,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis],[_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxisNeg]]}),"../pioneer/engine/src/utils/dependency_graph.js": + /*!*******************************************************!*\ + !*** ../pioneer/engine/src/utils/dependency_graph.js ***! + \*******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"DependencyGraph":function(){return DependencyGraph}});class DependencyGraph{constructor(){this._updateItemCallback=null;this._compareItemCallback=null;this._nodes=new Map();this._sortedNodes=[];this._needsSorting=!1} + setUpdateItemCallback(updateItemCallback){this._updateItemCallback=updateItemCallback} + setCompareItemCallback(compareItemCallback){this._compareItemCallback=compareItemCallback} + addItem(item){const node=new Node(item);this._nodes.set(item,node);this._needsSorting=!0} + removeItem(item){if(this._nodes.delete(item)){this._needsSorting=!0}} + needsSorting(){this._needsSorting=!0} + update(){if(this._needsSorting){for(const node of this._nodes.values()){node.permanentMark=!1;node.temporaryMark=!1} + this._sortedNodes=[];const iterator=this._nodes.values();do{const result=iterator.next();if(result.done){break} + const keepGoing=this._visit(result.value);if(!keepGoing){break}}while(!0);this._needsSorting=!1} + for(let i=0,l=this._sortedNodes.length;iindex){this._keyMap.set(pair[0],pair[1]-1)}} + return!0}else{return!1}} + clear(){this._entries=[];this._keyMap.clear()} + getAt(index){return this._entries[index]} + get size(){return this._entries.length}}}),"../pioneer/engine/src/utils/fast_set.js": + /*!***********************************************!*\ + !*** ../pioneer/engine/src/utils/fast_set.js ***! + \***********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"FastSet":function(){return FastSet}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class FastSet extends _internal__WEBPACK_IMPORTED_MODULE_0__.FastIterable{constructor(iterable){super();this._values=[];this._valueMap=new Map();if(iterable!==undefined){for(const key of iterable){this._values.push(key);this._valueMap.set(key,this._values.length-1)}}} + has(value){return this._valueMap.has(value)} + add(value){const index=this._valueMap.get(value);if(index===undefined){this._values.push(value);this._valueMap.set(value,this._values.length-1)} + return this} + delete(value){const index=this._valueMap.get(value);if(index!==undefined){this._values.splice(index,1);this._valueMap.delete(value);for(const pair of this._valueMap){if(pair[1]>index){this._valueMap.set(pair[0],pair[1]-1)}} + return!0}else{return!1}} + clear(){this._values=[];this._valueMap.clear()} + getAt(index){return this._values[index]} + get size(){return this._values.length}}}),"../pioneer/engine/src/utils/fps.js": + /*!******************************************!*\ + !*** ../pioneer/engine/src/utils/fps.js ***! + \******************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"FPS":function(){return FPS}});class FPS{constructor(){this._numberOfSamples=100;this._samples=new Array(this._numberOfSamples);this._index=0} + getNumberOfSamples(){return this._numberOfSamples} + setNumberOfSamples(numberOfSamples){this._numberOfSamples=numberOfSamples;this._samples=new Array(this._numberOfSamples)} + getFPS(){let samplesTotal=0;for(let i=0;inumThreeJsObjects){const objectToRemove=this._threeJsObjects[this._threeJsObjects.length-1];_internal__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyObject(objectToRemove);this._threeJsObjects.splice(this._threeJsObjects.length-1,1);for(let i=0,l=this._component.getThreeJsObjects().length;i0){this._setupThreeJsGeometry(this._threeJsObjects[this._threeJsObjects.length-1].geometry,LineMesh._verticesPerGeometry)} + for(let i=this._threeJsObjects.length;i0){const geometry=this._threeJsObjects[numThreeJsObjects-1].geometry;const numVerticesInLastGeometry=numVertices-(numThreeJsObjects-1)*LineMesh._verticesPerGeometry;if(geometry.getAttribute('position').array.length!==numVerticesInLastGeometry*LineMesh._floatsPerVertex){this._setupThreeJsGeometry(geometry,numVerticesInLastGeometry)}}} + _setupThreeJsGeometry(geometry,numVertices){const vertices=new Float32Array(numVertices*LineMesh._floatsPerVertex);const buffer=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBuffer(vertices,LineMesh._floatsPerVertex);geometry.setAttribute('position',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,3,0,!1));geometry.setAttribute('positionPrev',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,3,3,!1));geometry.setAttribute('positionNext',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,3,6,!1));geometry.setAttribute('color',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,4,9,!1));geometry.setAttribute('width',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,1,13,!1));geometry.setAttribute('dashOffset',new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.InterleavedBufferAttribute(buffer,1,14,!1));const meshIndices=new Uint16Array(numVertices*6/4);for(let j=0;j0){let validShadowEntities=0;for(let j=0;j 0.0) { + float rFactor = 1.0; // 6.3^-4 / 6.3^-4 + float gFactor = 1.602; // 5.6^-4 / 6.3^-4 + float bFactor = 3.228; // 4.7^-4 / 6.3^-4 + color.r *= pow(rFactor, -amount); + color.g *= pow(gFactor, -amount); + color.b *= pow(bFactor, -amount); + } + return color; + } + + vec3 getLightColorFromShadowEntities(vec3 lightColor, vec3 lightDir, vec3 lightPosition, float lightRadius, vec3 normal) { + vec3 color = lightColor; + for (int i = 0; i < 5; i++) { + if (i >= numShadowEntities || lightRadius < 0.0) { + break; + } + vec3 origin = cameraSpacePosition - shadowEntityPositions[i]; + vec3 axis = normalize(shadowEntityPositions[i] - lightPosition); + float sd = dot(origin, axis); + if (sd > 0.0) { + float e = length(origin - sd * axis); + float ld = dot(cameraSpacePosition - lightPosition, axis); + float lr = lightRadius; + float sr = shadowEntityRadii[i]; + float e0 = (ld * sr - sd * lr) / (ld - sd); + float e1 = (ld * sr + sd * lr) / (ld - sd); + float lightLevel = 0.0; + if (e1 < 0.0 || sd < 0.0) { // light in front of shadow entity + lightLevel = 1.0; + } + else if (e0 < e1) { + e0 /= max(1.0, shadowEntitySunsetIntensity[i] * 2.0); + lightLevel = (e - e0) / (e1 - e0); + } + else { + lightLevel = e < e0 ? 0.0 : 1.0; // 0 radius light. + } + color = saturate(lightLevel) * applyRayleighScattering(color, saturate(1.5 - lightLevel) * saturate(shadowEntitySunsetIntensity[i])); + } + } + return color; + } + #endif + + #ifdef shadowRings + vec3 getLightColorFromShadowRings(vec3 lightColor, vec3 lightDir) { + vec3 position = cameraSpacePosition - entityPos; + float d = dot(position, shadowRingsNormal) / dot(lightDir, shadowRingsNormal); + highp vec3 pointOnDisc = -d * lightDir + position; + float lengthOnDisc = length(pointOnDisc - dot(pointOnDisc, shadowRingsNormal) * shadowRingsNormal); + float u = (lengthOnDisc - shadowRingsInnerRadius) / (shadowRingsOuterRadius - shadowRingsInnerRadius); + float shadow = 1.0 - texture2D(shadowRingsTexture, vec2(u, 0.0), 0.0).a; + if (shadowRingsInnerRadius <= lengthOnDisc && lengthOnDisc <= shadowRingsOuterRadius && d > 0.0) { + return lightColor * saturate(shadow); + } + else { + return lightColor; + } + } + #endif + + // ATMOSPHERE + + #ifdef atmosphere + uniform vec3 atmospherePosition; + uniform vec4 atmosphereOrientation; + uniform float atmosphereEquatorialRadius; + uniform float atmospherePolarRadius; + uniform float atmosphereDensity; + uniform float atmosphereScaleHeight; + uniform vec3 atmosphereColor; + uniform float atmosphereEmissivity; + uniform float atmosphereSunBrightness; + uniform vec3 atmosphereSunsetColor; + uniform float atmosphereSunsetIntensity; + uniform float atmosphereGroundIsSpheroid; + + const int atmosphereNumIterations = 5; + + // Inverse rotate a vector by a quaternion. + vec3 quatRotInv(vec4 q, vec3 v) { + float tx = q.w * v.x - q.y * v.z + q.z * v.y; + float ty = q.w * v.y - q.z * v.x + q.x * v.z; + float tz = q.w * v.z - q.x * v.y + q.y * v.x; + float tw = q.x * v.x + q.y * v.y + q.z * v.z; + float x = tx * q.w + tw * q.x + ty * q.z - tz * q.y; + float y = ty * q.w + tw * q.y + tz * q.x - tx * q.z; + float z = tz * q.w + tw * q.z + tx * q.y - ty * q.x; + return vec3(x, y, z); + } + + // Given an origin and direction, computes the sampling start and end as distance from the origin in the direction. + void getStartEndSamples(out float start, out float end, vec3 origin, vec3 direction, float maxDistance, float groundRadius, float atmosphereScaleHeight) { + // Get the along the ray perpendicular to the sphere. + float perpD = -dot(origin, direction); + vec3 perp = origin + direction * perpD; + + // Figure out the sample distance. + float atmosphereRadius = groundRadius + atmosphereScaleHeight * 6.0; + float chordHalfLength = sqrt(max(0.0, atmosphereRadius * atmosphereRadius - dot(perp, perp))); + + // Figure out starting and ending sample points. + start = max(0.0, perpD - chordHalfLength); + end = min(maxDistance, perpD + chordHalfLength); + } + + // Gets the density of the atmosphere at a given position. + float getDensity(vec3 position, float radius, float density, float atmosphereScaleHeight) { + return density * exp((radius - length(position)) / atmosphereScaleHeight); + } + + // Returns 0 if the ray does not intersect and 1.0 if the ray very intersects (with a gradient inbetween). + float getDayLevel(vec3 origin, vec3 direction, float radius, float scaleHeight) { + float blendHeight = scaleHeight * radius / 200.0; + float perpD = -dot(origin, direction); + float depth = radius - sqrt(dot(origin, origin) - sign(perpD) * perpD * perpD); + if (depth < 0.0) { // day + return 1.0 - max(0.0, 0.25 * depth / blendHeight + 0.25); + } + else { // night + return 1.0 - min(1.0, 0.75 * depth / blendHeight + 0.25); + } + } + + // Adjusts the color if one of the RGB values is greater than 1.0. + vec3 adjustOverbrightness(vec3 color) { + float maxColor = max(color.r, max(color.g, color.b)); + if (maxColor > 1.0) { + float f = (maxColor - 1.0) / maxColor; + color.r = min(1.0, pow(color.r / maxColor, 1.0 / maxColor)); + color.g = min(1.0, pow(color.g / maxColor, 1.0 / maxColor)); + color.b = min(1.0, pow(color.b / maxColor, 1.0 / maxColor)); + } + return color; + } + + float easeInOut(float x, float sharpness) { + float b = sharpness; + if (x < 0.5) { + return max(0.0, (pow(b, 2.0 * x) - 1.0) / (2.0 * (b - 1.0))); + } + else { + return min(1.0, 1.0 - (pow(b, 2.0 * (1.0 - x)) - 1.0) / (2.0 * (b - 1.0))); + } + } + + // Calculates a glow around the light direction. + float glow(float spread, float amount, float lightDotCamera) { + return amount * spread / (1.0 + spread - lightDotCamera); + } + + struct AtmosphereInfo { + float spheroidRatio; + highp vec3 position; + highp vec3 cameraPosition; + highp vec3 cameraToPosition; + float cameraToPositionDist; + highp vec3 cameraToPositionUnit; + float start; + float end; + float totalDensity; + }; + + // Get atmosphere info that is independent of any light. + AtmosphereInfo getAtmosphereInfo() { + + AtmosphereInfo atmosphereInfo; + + // Get position and camera in the atmosphere frame. + atmosphereInfo.position = quatRotInv(atmosphereOrientation, cameraSpacePosition - atmospherePosition); + atmosphereInfo.cameraPosition = quatRotInv(atmosphereOrientation, -atmospherePosition); + + // Convert everything into a sphere frame. + atmosphereInfo.spheroidRatio = atmosphereEquatorialRadius / atmospherePolarRadius; + atmosphereInfo.position.z *= atmosphereInfo.spheroidRatio; + atmosphereInfo.cameraPosition.z *= atmosphereInfo.spheroidRatio; + + // Make sure the position is right on the ground. + atmosphereInfo.position = normalize(atmosphereInfo.position / 1.0e8) * atmosphereEquatorialRadius; + + // Get some shortcut vectors. + atmosphereInfo.cameraToPosition = atmosphereInfo.position - atmosphereInfo.cameraPosition; + atmosphereInfo.cameraToPositionDist = length(atmosphereInfo.cameraToPosition / 1.0e8) * 1.0e8; + atmosphereInfo.cameraToPositionUnit = atmosphereInfo.cameraToPosition / atmosphereInfo.cameraToPositionDist; + + // Get the start and end of the sampling from the camera to the position. + getStartEndSamples(atmosphereInfo.start, atmosphereInfo.end, atmosphereInfo.cameraPosition, atmosphereInfo.cameraToPositionUnit, atmosphereInfo.cameraToPositionDist, atmosphereEquatorialRadius, atmosphereScaleHeight); + float step = 1.0 / float(atmosphereNumIterations - 1); + float stepDist = step * (atmosphereInfo.end - atmosphereInfo.start); + + // Do the sampling. + atmosphereInfo.totalDensity = 0.0; + float segmentStart = atmosphereInfo.start; + for (int j = 0; j < atmosphereNumIterations; j++) { + // Get the distance that this segment covers. + float segDist = stepDist; + if (j == 0 || j == atmosphereNumIterations - 1) { + segDist *= 0.5; + } + + // Get the segment start that we're looking at. + vec3 p = atmosphereInfo.cameraPosition + segmentStart * atmosphereInfo.cameraToPositionUnit; + + // Get the density at that segment start. It'll be the density for the whole segment. + float densityAtP = getDensity(p, atmosphereEquatorialRadius, atmosphereDensity, atmosphereScaleHeight); + + // Add it to the total density. + atmosphereInfo.totalDensity += densityAtP * segDist; + + // Next step. + segmentStart += stepDist; + } + + return atmosphereInfo; + } + + vec4 getAtmosphereEmissiveColor(AtmosphereInfo atmosphereInfo, vec3 color, float emissivity) { + + // Scale the total density with the emissivity. + atmosphereInfo.totalDensity *= emissivity; + + // Apply the total density to the transparency of the atmosphere. + vec4 outColor = vec4(0.0); + outColor.a = clamp(pow(3.0 * atmosphereInfo.totalDensity, 0.3), 0.0, 1.0); + + // Multiply it all together with the source light color. + outColor.rgb = emissivity * color * clamp(pow(15.0 * atmosphereInfo.totalDensity / (atmosphereDensity * atmosphereEquatorialRadius), 0.2), 0.75, 1.0); + + // Make it more opaque when lower down. + outColor.a *= 1.0 + 0.5 * getDensity(atmosphereInfo.cameraPosition, atmosphereEquatorialRadius, 1.0, atmosphereScaleHeight); + + // Clamp it to make it clean. + outColor.a = clamp(outColor.a, 0.0, 1.0); + + // Return the color. + return outColor; + } + + // Adjust the incoming light for the atmosphere. + vec4 getAtmosphereColor(AtmosphereInfo atmosphereInfo, vec3 incomingLight, vec3 lightPosition) { + + // The color starts out in full brightness (as if emissivity was 1.0). + vec4 outColor = getAtmosphereEmissiveColor(atmosphereInfo, incomingLight * atmosphereColor, 1.0); + + // Get the light position in the sphere entity-space. + lightPosition = quatRotInv(atmosphereOrientation, lightPosition); + lightPosition.z *= atmosphereInfo.spheroidRatio; + highp vec3 lightToPosition = atmosphereInfo.position - lightPosition; + highp vec3 lightToPositionUnit = normalize(lightToPosition / 1.0e8); + + // Get the day level, from 0 to 1, and apply it to the alpha. + float ambientLightIntensity = min(1.0, length(ambientLightColor)); + vec3 dayRefUp = normalize(atmosphereInfo.cameraPosition + atmosphereInfo.end * atmosphereInfo.cameraToPositionUnit); + float dayLevel = -dot(lightToPositionUnit, dayRefUp); + float lightIntensity = mix(dayLevel, 0.0, ambientLightIntensity); + outColor.a *= easeInOut(0.25 * 700.0 * atmosphereDensity + 1.0 * lightIntensity, 2.0); + + // Add broader sun glare. + float lightDotCamera = max(0.0, -dot(lightToPositionUnit, atmosphereInfo.cameraToPositionUnit)); + outColor.rgb *= incomingLight * (1.0 + atmosphereSunBrightness * outColor.a * glow(0.04, 0.125, lightDotCamera)); + + // Apply the sunset. + float sunsetAmount = mix(atmosphereSunsetIntensity * easeInOut(0.5 * (1.0 - abs(dayLevel)), 4.0), 0.0, ambientLightIntensity); + outColor.rgb *= mix(vec3(1.0), atmosphereSunsetColor, clamp(sunsetAmount, 0.0, 1.0)); + + // Adjust for values that are greater than one. + outColor.rgb = adjustOverbrightness(outColor.rgb); + + return outColor; + } + #endif + + void main(void) { + // Get the camera direction to the position. + vec3 positionDir = normalize(cameraSpacePosition); + + // Calculate the normal. + #ifdef normalMap + vec3 normal = getNormalFromMap(); + #else + vec3 normal = normalize(cameraSpaceNormal); + #endif + + // The diffuse light. + vec3 diffuseLight = ambientLightColor; + vec3 specularLight = vec3(0, 0, 0); + + // Atmosphere emissive shading. + #ifdef atmosphere + AtmosphereInfo atmosphereInfo = getAtmosphereInfo(); + vec4 atmosphereColor = getAtmosphereEmissiveColor(atmosphereInfo, atmosphereColor, atmosphereEmissivity); + #endif + + // For each light, + for (int i = 0; i < 5; i++) { + if (i >= numLights) { + break; + } + + // Get lighting angles. + vec3 lightDir = normalize(cameraSpacePosition - lightPositions[i]); + float lightCosAngle = -dot(lightDir, normal); + + // Make the shadows a bit sharper, depending on atmospheres. + float sharpness = 3.0; + #ifdef atmosphere + sharpness /= 1.0 + 700.0 * atmosphereDensity; + #endif + lightCosAngle = 2.0 * (1.0 + exp(-sharpness)) / (1.0 + exp(-sharpness * lightCosAngle)) - 1.0; + + // Get the incoming light after shadows. + vec3 incomingLight = lightColors[i]; + #if !defined(colorMapEmmissive) | !defined(nightMapEmmissive) | !defined(decalMapEmmissive) + #ifdef shadowEntities + incomingLight = getLightColorFromShadowEntities(incomingLight, lightDir, lightPositions[i], lightRadii[i], normal); + #endif + #ifdef shadowRings + incomingLight = getLightColorFromShadowRings(incomingLight, lightDir); + #endif + #endif + + // Diffuse shading. + diffuseLight += incomingLight * saturate(lightCosAngle); + + // Specular shading. + vec3 reflectedLightDir = reflect(lightDir, normal); + vec3 halfVector = normalize(-lightDir - positionDir); + float phongHighlight = 0.25 * pow(saturate(-dot(reflectedLightDir, positionDir)), specularHardness / 2.0); + float blinnHighlight = 4.0 * pow(saturate(dot(halfVector, normal)), specularHardness); + float specularAngle = phongHighlight + pow(1.0 - saturate(-dot(positionDir, normal)), specularHardness / 12.0) * blinnHighlight; + specularLight += saturate(lightCosAngle * 20.0) * specularAngle * incomingLight; + + // Atmosphere shading. + #ifdef atmosphere + if (length(lightPositions[i]) > 0.0) { // don't use a camera light + atmosphereColor += getAtmosphereColor(atmosphereInfo, incomingLight, lightPositions[i]); + } + #endif + } + diffuseLight = saturate(diffuseLight); + + // If there's ambience, remove the direct light components. + specularLight *= vec3(1, 1, 1) - ambientLightColor; + + // Main Color map. + vec4 colorPixel = vec4(1, 0, 1, 1); + #ifdef colorTextureEnvironment + colorPixel = getColorFromEnvironmentMap(colorTexture, positionDir, normal); + #else + colorPixel = texture2D(colorTexture, vColorUV) * vec4(color, 1); + #endif + #ifdef baseColor + colorPixel = vec4(color, 1); + #endif + + // Apply diffuse shading. + #ifndef colorMapEmmissive + colorPixel *= vec4(diffuseLight, 1.0); + #endif + gl_FragColor = colorPixel; + + // Specular Map + vec3 specularPixel = specularColor * specularIntensity; + #ifdef specularMap + #ifdef specularUVs + vec2 specularUV = vSpecularUV; + #else + vec2 specularUV = vColorUV; + #endif + specularPixel = specularColor * texture2D(specularTexture, specularUV).r; + #endif + + // Apply specular Shading + gl_FragColor.rgb += specularLight * specularPixel; + + // Night-Side Map + #ifdef nightMap + float ambientLightIntensity = min(1.0, length(ambientLightColor)); + #ifdef nightUVs + vec2 nightUV = vNightUV; + #else + vec2 nightUV = vColorUV; + #endif + vec4 nightPixel = texture2D(nightTexture, nightUV); + #ifndef nightMapEmmissive + nightPixel *= vec4(diffuseLight, 1.0); + #endif + gl_FragColor = mix(gl_FragColor, nightPixel, 1.0 - min(1.0, length(ambientLightColor + diffuseLight)));//(1.0 - ambientLightIntensity) * saturate(0.5 - length(diffuseLight))); + #endif + + // Decal Map + #ifdef decalMap + #ifdef decalUVs + vec2 decalUV = vDecalUV; + #else + vec2 decalUV = vColorUV; + #endif + vec4 decalPixel = texture2D(decalTexture, decalUV); + #ifndef decalMapEmmissive + decalPixel *= vec4(diffuseLight, 1.0); + #endif + gl_FragColor.rgb = mix(gl_FragColor.rgb, decalPixel.rgb, decalPixel.a); + #endif + + // Atmosphere + #ifdef atmosphere + gl_FragColor.rgb = mix(gl_FragColor.rgb, atmosphereColor.rgb, clamp(atmosphereColor.a, 0.0, 1.0)); + #endif + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`})} + const newMaterial=MaterialUtilsPhong._material.clone();for(let i=0;i 0.0) { + float rFactor = 1.0; // 6.3^-4 / 6.3^-4 + float gFactor = 1.602; // 5.6^-4 / 6.3^-4 + float bFactor = 3.228; // 4.7^-4 / 6.3^-4 + color.r *= pow(rFactor, -amount); + color.g *= pow(gFactor, -amount); + color.b *= pow(bFactor, -amount); + color = value * color / (color.r + color.g + color.b); + } + return color; + } + + vec3 getLightColorFromShadowEntities(vec3 lightColor, vec3 lightDir, vec3 lightPosition, float lightRadius, vec3 normal) { + vec3 color = lightColor; + for (int i = 0; i < 5; i++) { + if (i >= numShadowEntities || lightRadius < 0.0) { + break; + } + vec3 origin = cameraSpacePosition - shadowEntityPositions[i]; + vec3 axis = normalize(shadowEntityPositions[i] - lightPosition); + float sd = dot(origin, axis); + if (sd > 0.0) { + float e = length(origin - sd * axis); + float ld = dot(cameraSpacePosition - lightPosition, axis); + float lr = lightRadius; + float sr = shadowEntityRadii[i]; + float e0 = (ld * sr - sd * lr) / (ld - sd); + float e1 = (ld * sr + sd * lr) / (ld - sd); + float lightLevel = 0.0; + if (e1 < 0.0 || sd < 0.0) { // light in front of shadow entity + lightLevel = 1.0; + } + else if (e0 < e1) { + e0 -= (e1 - e0) * saturate(shadowEntitySunsetIntensity[i] / 3.0); + lightLevel = pow(saturate((e - e0) / (e1 - e0)), 0.5); // soft light + } + else { + lightLevel = e < e0 ? 0.0 : 1.0; // 0 radius light. + } + color = lightLevel * mix(color, shadowEntitySunsetColors[i], (1.0 - lightLevel) * saturate(shadowEntitySunsetIntensity[i])); + } + } + return color; + } + #endif + + vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) { + return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); + } + + // These use optimizations found in https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf. + + // The Smith-method geometry function. Calculates the ratio of incident light that is blocked by the microfacets to never reach the viewer. + // alpha is the roughness^2 + // dotNL is the normal · the light vector. + // dotNV is the normal · the view vector. + float G_GGX_SmithCorrelated( float alpha, float dotNL, float dotNV ) { + float a2 = pow2( alpha ); + // Get the light direction part of the geometry function. + float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); + // Get the view direction part of the geometry function. + float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); + // It would normally be be gv * gl, but this is using an optimization by Heitz (2014), + // including the BRDF denominator, simplifying the results. + return 0.5 / max( gv + gl, EPSILON ); + } + + // The Trowbridge-Reitz normal distribution function. Calculates the relative surface area microfacets exactly aligned to the halfway vector, how "smooth" the surface is. + // alpha is the roughness^2. + // dotNH is the normal · the halfway vector. + float D_GGX( float alpha, float dotNH ) { + float a2 = pow2( alpha ); + float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; + return RECIPROCAL_PI * a2 / pow2( denom ); + } + + // The Schlick approximation for the Fresnel equation. + // Since metallic and non-metallic surfaces have different equations, this function combines the two by approximation. + // specularColor is the specular color at normal incidence. + // dotLH is the light direction · the halfway vector. + vec3 F_Schlick( vec3 specularColor, float dotLH ) { + float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH ); + return ( 1.0 - specularColor ) * fresnel + specularColor; + } + + // The specular part of the main BRDF function that describes the weighting function for the sum of every incoming light. + // It uses the Cook-Torrance model. + vec3 BRDF_Specular_GGX( IncidentLight incidentLight, GeometricContext geometry, vec3 specularColor, float roughness ) { + float alpha = pow2( roughness ); + vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); + float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); + float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); + float dotNH = saturate( dot( geometry.normal, halfDir ) ); + float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); + vec3 F = F_Schlick( specularColor, dotLH ); + float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV ); + float D = D_GGX( alpha, dotNH ); + return F * ( G * D ); + } + + // The diffuse part of the main BRDF function. + vec3 BRDF_Diffuse_Lambert( vec3 diffuseColor ) { + return RECIPROCAL_PI * diffuseColor; + } + + float BlinnExponentToGGXRoughness( float blinnExponent ) { + return sqrt( 2.0 / ( blinnExponent + 2.0 ) ); + } + + float GGXRoughnessToBlinnExponent( float ggxRoughness ) { + return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 ); + } + + vec2 integrateSpecularBRDF( float dotNV, float roughness ) { + const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); + const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); + vec4 r = roughness * c0 + c1; + float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; + return vec2( -1.04, 1.04 ) * a004 + r.zw; + } + + vec3 BRDF_Specular_GGX_Environment( GeometricContext geometry, vec3 specularColor, float roughness ) { + float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); + vec2 brdf = integrateSpecularBRDF( dotNV, roughness ); + return specularColor * brdf.x + brdf.y; + } + + void BRDF_Specular_Multiscattering_Environment( GeometricContext geometry, vec3 specularColor, float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) { + float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); + vec3 F = F_Schlick( specularColor, dotNV ); + vec2 brdf = integrateSpecularBRDF( dotNV, roughness ); + vec3 FssEss = F * brdf.x + brdf.y; + float Ess = brdf.x + brdf.y; + float Ems = 1.0 - Ess; + vec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg ); + singleScatter += FssEss; + multiScatter += Fms * Ems; + } + + float opacity = 1.0; + + uniform float reflectivity; + uniform int maxMipLevel; + + // Returns the radiance: the incoming light * the cos(light angle to the normal) + vec3 getIncomingLight( IncidentLight directLight, GeometricContext geometry) { + float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); + return (dotNL * directLight.color); + } + + float getSpecularMIPLevel( float blinnShininessExponent, int maxMIPLevel ) { + float maxMIPLevelScalar = float( maxMIPLevel ); + float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 ); + return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar ); + } + + #ifdef envIsCubeUV + // These defines must match with PMREMGenerator + #define cubeUV_maxMipLevel 8.0 + #define cubeUV_minMipLevel 4.0 + #define cubeUV_maxTileSize 256.0 + #define cubeUV_minTileSize 16.0 + // These shader functions convert between the UV coordinates of a single face of + // a cubemap, the 0-5 integer index of a cube face, and the direction vector for + // sampling a textureCube (not generally normalized ). + float getFace( vec3 direction ) { + vec3 absDirection = abs( direction ); + float face = - 1.0; + if ( absDirection.x > absDirection.z ) { + if ( absDirection.x > absDirection.y ) + face = direction.x > 0.0 ? 0.0 : 3.0; + else + face = direction.y > 0.0 ? 1.0 : 4.0; + } else { + if ( absDirection.z > absDirection.y ) + face = direction.z > 0.0 ? 2.0 : 5.0; + else + face = direction.y > 0.0 ? 1.0 : 4.0; + } + return face; + } + // RH coordinate system; PMREM face-indexing convention + vec2 getUV( vec3 direction, float face ) { + vec2 uv; + if ( face == 0.0 ) { + uv = vec2( direction.z, direction.y ) / abs( direction.x ); // pos x + } else if ( face == 1.0 ) { + uv = vec2( - direction.x, - direction.z ) / abs( direction.y ); // pos y + } else if ( face == 2.0 ) { + uv = vec2( - direction.x, direction.y ) / abs( direction.z ); // pos z + } else if ( face == 3.0 ) { + uv = vec2( - direction.z, direction.y ) / abs( direction.x ); // neg x + } else if ( face == 4.0 ) { + uv = vec2( - direction.x, direction.z ) / abs( direction.y ); // neg y + } else { + uv = vec2( direction.x, direction.y ) / abs( direction.z ); // neg z + } + return 0.5 * ( uv + 1.0 ); + } + vec3 bilinearCubeUV( sampler2D environmentMap, vec3 direction, float mipInt ) { + float face = getFace( direction ); + float filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 ); + mipInt = max( mipInt, cubeUV_minMipLevel ); + float faceSize = exp2( mipInt ); + float texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize ); + vec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ); + vec2 f = fract( uv ); + uv += 0.5 - f; + if ( face > 2.0 ) { + uv.y += faceSize; + face -= 3.0; + } + uv.x += face * faceSize; + if ( mipInt < cubeUV_maxMipLevel ) { + uv.y += 2.0 * cubeUV_maxTileSize; + } + uv.y += filterInt * 2.0 * cubeUV_minTileSize; + uv.x += 3.0 * max( 0.0, cubeUV_maxTileSize - 2.0 * faceSize ); + uv *= texelSize; + vec3 tl = texture2D( environmentMap, uv ).rgb; + uv.x += texelSize; + vec3 tr = texture2D( environmentMap, uv ).rgb; + uv.y += texelSize; + vec3 br = texture2D( environmentMap, uv ).rgb; + uv.x -= texelSize; + vec3 bl = texture2D( environmentMap, uv ).rgb; + vec3 tm = mix( tl, tr, f.x ); + vec3 bm = mix( bl, br, f.x ); + return mix( tm, bm, f.y ); + } + #define r0 1.0 + #define v0 0.339 + #define m0 - 2.0 + #define r1 0.8 + #define v1 0.276 + #define m1 - 1.0 + #define r4 0.4 + #define v4 0.046 + #define m4 2.0 + #define r5 0.305 + #define v5 0.016 + #define m5 3.0 + #define r6 0.21 + #define v6 0.0038 + #define m6 4.0 + float roughnessToMip( float roughness ) { + float mip = 0.0; + if ( roughness >= r1 ) { + mip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0; + } else if ( roughness >= r4 ) { + mip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1; + } else if ( roughness >= r5 ) { + mip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4; + } else if ( roughness >= r6 ) { + mip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5; + } else { + mip = - 2.0 * log2( 1.16 * roughness ); // 1.16 = 1.79^0.25 + } + return mip; + } + vec4 textureCubeUV( sampler2D environmentMap, vec3 sampleDir, float roughness ) { + float mip = clamp( roughnessToMip( roughness ), m0, cubeUV_maxMipLevel ); + float mipF = fract( mip ); + float mipInt = floor( mip ); + vec3 color0 = bilinearCubeUV( environmentMap, sampleDir, mipInt ); + if ( mipF == 0.0 ) { + return vec4( color0, 1.0 ); + } else { + vec3 color1 = bilinearCubeUV( environmentMap, sampleDir, mipInt + 1.0 ); + return vec4( mix( color0, color1, mipF ), 1.0 ); + } + } + #endif + + #ifdef dynEnvMap + // Converts an XY in cylindrical space to a face (z) with coordinates within that face (xy). + vec3 xyzToUvFace(vec3 xyz, float pixelSize) { + // Figure out which basis we're using. + vec3 basis[3]; + float face; + if (xyz.x * xyz.x >= xyz.y * xyz.y && xyz.x * xyz.x >= xyz.z * xyz.z) { + if (xyz.x >= 0.0) { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(1, 0, 0); + face = 0.0; + } + else { + basis[0] = vec3(0, -1, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(-1, 0, 0); + face = 2.0; + } + } + else if (xyz.y * xyz.y >= xyz.x * xyz.x && xyz.y * xyz.y >= xyz.z * xyz.z) { + if (xyz.y >= 0.0) { + basis[0] = vec3(-1, 0, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(0, 1, 0); + face = 1.0; + } + else { + basis[0] = vec3(1, 0, 0); basis[1] = vec3(0, 0, 1); basis[2] = vec3(0, -1, 0); + face = 3.0; + } + } + else { + if (xyz.z >= 0.0) { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(-1, 0, 0); basis[2] = vec3(0, 0, 1); + face = 4.0; + } + else { + basis[0] = vec3(0, 1, 0); basis[1] = vec3(1, 0, 0); basis[2] = vec3(0, 0, -1); + face = 5.0; + } + } + + // Convert into the uv basis from the xyz basis. + float z = basis[2].x * xyz.x + basis[2].y * xyz.y + basis[2].z * xyz.z; + if (z < 0.0) { + z = 1.0; + } + vec2 uv = vec2( + (basis[0].x * xyz.x + basis[0].y * xyz.y + basis[0].z * xyz.z) / z, + (basis[1].x * xyz.x + basis[1].y * xyz.y + basis[1].z * xyz.z) / z); + + // Convert from -1 to +1, to 0 to 1. + uv = 0.5 * (uv + vec2(1.0)); + + // Convert to pixel-space. + uv *= pixelSize; + + // Shrink to ignore 1 pixel borders. + uv.x = (pixelSize - 2.0) / pixelSize * uv.x + 1.0; + uv.y = (pixelSize - 2.0) / pixelSize * uv.y + 1.0; + + // Convert back to unit-space. + uv /= pixelSize; + + return vec3(uv, face); + } + + // Gets the dynamic environmental lighting given the outward direction. + vec3 getEnvLight(vec3 direction, float roughness) { + // Get the mip levels. + float mipLevel = pow(roughness, 0.25) * (log2(dynEnvFaceSize) - 2.0); + float mipLevel0 = floor(mipLevel); + float mipLevel1 = floor(mipLevel) + 1.0; + float mipLevelU = mipLevel - mipLevel0; + float mipSizeX0 = pow(2.0, -mipLevel0); + float mipOffsetY0 = 1.0 - pow(2.0, -mipLevel0); + float mipSizeX1 = pow(2.0, -mipLevel1); + float mipOffsetY1 = 1.0 - pow(2.0, -mipLevel1); + // Get UV within a mip of cube faces. + vec3 uvFace0 = xyzToUvFace(direction, dynEnvFaceSize * mipSizeX0); + vec3 uvFace1 = xyzToUvFace(direction, dynEnvFaceSize * mipSizeX1); + vec2 faceOffset = vec2(mod(uvFace0.z, 3.0) / 3.0, floor(uvFace0.z / 3.0) / 2.0); + vec2 uvInMip0 = vec2(faceOffset.x + uvFace0.x / 3.0, faceOffset.y + uvFace0.y / 2.0); + vec2 uvInMip1 = vec2(faceOffset.x + uvFace1.x / 3.0, faceOffset.y + uvFace1.y / 2.0); + // Get the UVs within the textures. + vec2 uv0 = vec2(uvInMip0.x * mipSizeX0 * 0.75, 0.5 * uvInMip0.y * mipSizeX0 + mipOffsetY0); + vec2 uv1 = vec2(uvInMip1.x * mipSizeX1 * 0.75, 0.5 * uvInMip1.y * mipSizeX1 + mipOffsetY1); + vec3 color0 = texture2D(dynEnvTexture, uv0).rgb; + vec3 color1 = texture2D(dynEnvTexture, uv1).rgb; + return mix(color0, color1, mipLevelU) * environmentIntensity * ((PI - 1.0) * roughness + 1.0); + } + #endif + + vec3 getLightProbeIndirectRadiance( GeometricContext geometry, float blinnShininessExponent, int maxMIPLevel ) { + vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal ); + #if defined( envMap ) + reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); + float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel ); + vec3 queryReflectVec = vec3( reflectVec.x, reflectVec.yz ); + #ifdef envIsCube + #ifdef TEXTURE_LOD_EXT + vec4 envMapColor = textureCubeLodEXT( envTexture, queryReflectVec, specularMIPLevel ); + #else + vec4 envMapColor = textureCube( envTexture, queryReflectVec, specularMIPLevel ); + #endif + #elif defined( envIsCubeUV ) + vec4 envMapColor = textureCubeUV( envTexture, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent )); + #else + vec2 sampleUV; + sampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; + sampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5; + #ifdef TEXTURE_LOD_EXT + vec4 envMapColor = texture2DLodEXT( envTexture, sampleUV, specularMIPLevel ); + #else + vec4 envMapColor = texture2D( envTexture, sampleUV, specularMIPLevel ); + #endif + #endif + return envMapColor.rgb * environmentIntensity; + #else + return vec3(0, 0, 0); + #endif + } + + // Given the directLight, accumulates onto the reflectedLight the irradiance as the BRDF function. + void RE_Direct_Physical( IncidentLight directLight, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight ) { + vec3 irradiance = getIncomingLight( directLight, geometry ); + irradiance *= PI; + float clearCoatDHR = 0.0; + reflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness ); + reflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); + } + + void RE_IndirectDiffuse_Physical( vec3 irradiance, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight ) { + reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); + } + + void RE_IndirectSpecular_Physical( vec3 radiance, vec3 irradiance, vec3 clearCoatRadiance, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight) { + float clearCoatDHR = 0.0; + float clearCoatInv = 1.0 - clearCoatDHR; + reflectedLight.indirectSpecular += clearCoatInv * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness ); + } + + #define RE_Direct RE_Direct_Physical + #define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness ) + #define RE_IndirectDiffuse RE_IndirectDiffuse_Physical + #define RE_IndirectSpecular RE_IndirectSpecular_Physical + + void main(void) { + vec4 diffuseColor = vec4( color, 1.0 ); + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + + #ifdef colorMap + vec4 texelColor = texture2D(colorTexture, localUV); + diffuseColor *= texelColor; + opacity = texelColor.a; + #endif + + // PBR variables + float roughnessFactor; + float metalnessFactor; + + roughnessFactor = roughness; + #ifdef roughnessMap + roughnessFactor *= texture2D( roughnessTexture, localUV ).g; + #endif + + metalnessFactor = metalness; + #ifdef metalnessMap + metalnessFactor *= texture2D( metalnessTexture, localUV ).b; + #endif + + PhysicalMaterial material; + material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); + material.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 ); + material.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor ); + + GeometricContext geometry; + geometry.viewDir = -normalize(cameraSpacePosition); + #ifdef normalMap + geometry.normal = normalize((modelMatrix * vec4(getNormalFromMap(), 0.)).xyz); + #else + geometry.normal = modelNormal; + #endif + + // Env Light + vec3 irradiance = ambientLightColor; + #ifdef dynEnvMap + irradiance += getEnvLight(geometry.normal, 1.0); + #endif + vec3 radiance = ambientLightColor / 2.0; + #ifdef dynEnvMap + radiance += getEnvLight(reflect(-geometry.viewDir, geometry.normal), material.specularRoughness); + #endif + + // Add emissivity. + vec3 totalEmissiveRadiance = emissiveColor; + #ifdef emissiveMap + totalEmissiveRadiance *= texture2D(emissiveTexture, localUV).rgb; + #endif + + // Add direct radiance. + vec3 totalDirectIrradiance = ambientLightColor / 2.0; + #ifdef dynEnvMap + totalDirectIrradiance += getEnvLight(reflect(-geometry.viewDir, geometry.normal), material.specularRoughness); + #endif + + // For each light, + for (int i = 0; i < 5; i++) { + if (i >= numLights) { + break; + } + + IncidentLight directLight; + directLight.color = lightColors[i]; + directLight.direction = -normalize(cameraSpacePosition - lightPositions[i]); + #ifdef shadowEntities + directLight.color = getLightColorFromShadowEntities(directLight.color, directLight.direction, lightPositions[i], lightRadii[i], geometry.normal); + #endif + + RE_Direct(directLight, geometry, material, reflectedLight); + + radiance += getLightProbeIndirectRadiance(geometry, Material_BlinnShininessExponent(material), maxMipLevel); + RE_IndirectDiffuse(irradiance, geometry, material, reflectedLight); + RE_IndirectSpecular(radiance, irradiance, vec3(0.0), geometry, material, reflectedLight); + + // Modify env light by total incoming light. + totalDirectIrradiance += getIncomingLight(directLight, geometry); + } + + // Multiply in the direct irradiance. + reflectedLight.indirectSpecular *= totalDirectIrradiance; + + // If there's ambience, remove the direct light components. + reflectedLight.directDiffuse *= vec3(1, 1, 1) - ambientLightColor; + reflectedLight.directSpecular *= vec3(1, 1, 1) - ambientLightColor; + + // Add the reflected light to the outgoing light. + vec3 outgoingLight = totalEmissiveRadiance + reflectedLight.directDiffuse + reflectedLight.directSpecular + reflectedLight.indirectDiffuse + reflectedLight.indirectSpecular; + + // Set the frag color based on the total outgoing light. + gl_FragColor = vec4( outgoingLight, opacity ); + + // Gamma correction + gl_FragColor = vec4( pow( abs(gl_FragColor.rgb), vec3( 1.0 / gammaCorrectionFactor ) ), gl_FragColor.a ); + + // Convert to sRGB. + gl_FragColor = LinearTosRGB(gl_FragColor); + + // Multiply the alphaMultiplier. + gl_FragColor.a *= alphaMultiplier; + + ${_internal__WEBPACK_IMPORTED_MODULE_0__.ShaderChunkLogDepth.Fragment} + }`})} + const newMaterial=MaterialUtilsStandard._material.clone();for(let i=0;iMath.PI){return a0-a1+2*Math.PI} + if(a0-a1>Math.PI){return a1-a0+2*Math.PI} + return Math.abs(a1-a0)} + static clamp(a,a0,a1){return Math.min(Math.max(a0,a),a1)} + static clamp01(a){return Math.min(Math.max(0,a),1)} + static wrap(a,a0,a1){let phase=(a-a0)%(a1-a0)+a0;if(phaseMath.PI){a0+=2*Math.PI} + if(a0-a1>Math.PI){a1+=2*Math.PI} + return this.wrap(this.lerp(a0,a1,u),-Math.PI,+Math.PI)} + static radToDeg(a){return a*57.29577951308232} + static degToRad(a){return a*0.01745329251994329} + static ceilPow2(a){return Math.pow(2,Math.ceil(Math.log(a)/Math.log(2)))}}}),"../pioneer/engine/src/utils/orbital_elements.js": + /*!*******************************************************!*\ + !*** ../pioneer/engine/src/utils/orbital_elements.js ***! + \*******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"OrbitalElements":function(){return OrbitalElements}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class OrbitalElements{constructor(){this.epoch=0;this.eccentricity=0;this.semiMajorAxis=0;this.meanAngularMotion=0;this.meanAnomalyAtEpoch=0;this.orbitOrientation=new _internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion()} + copy(other){this.epoch=other.epoch;this.eccentricity=other.eccentricity;this.semiMajorAxis=other.semiMajorAxis;this.meanAnomalyAtEpoch=other.meanAnomalyAtEpoch;this.meanAngularMotion=other.meanAngularMotion;this.orbitOrientation.copy(other.orbitOrientation)} + projectFromMeanAnomaly(outPosition,outVelocity,meanAnomaly){if(this.eccentricity<1.0){const eccentricAnomaly=this.getEccentricAnomalyFromMeanAnomaly(meanAnomaly);const radius=this.semiMajorAxis*(1.0-this.eccentricity*Math.cos(eccentricAnomaly));const velocityFactor=this.meanAngularMotion*this.semiMajorAxis*this.semiMajorAxis/radius;outPosition.x=this.semiMajorAxis*(Math.cos(eccentricAnomaly)-this.eccentricity);outPosition.y=this.semiMajorAxis*Math.sqrt(1.0-this.eccentricity*this.eccentricity)*Math.sin(eccentricAnomaly);outVelocity.x=-velocityFactor*Math.sin(eccentricAnomaly);outVelocity.y=velocityFactor*Math.sqrt(1.0-this.eccentricity*this.eccentricity)*Math.cos(eccentricAnomaly)}else{const hyperbolicAnomaly=this.getEccentricAnomalyFromMeanAnomaly(meanAnomaly);const radius=-this.semiMajorAxis*(1.0-this.eccentricity*Math.cosh(hyperbolicAnomaly));const velocityFactor=this.meanAngularMotion*this.semiMajorAxis*this.semiMajorAxis/radius;outPosition.x=this.semiMajorAxis*(this.eccentricity-Math.cosh(hyperbolicAnomaly));outPosition.y=this.semiMajorAxis*Math.sqrt(this.eccentricity*this.eccentricity-1.0)*Math.sinh(hyperbolicAnomaly);outVelocity.x=-velocityFactor*Math.sinh(hyperbolicAnomaly);outVelocity.y=velocityFactor*Math.sqrt(this.eccentricity*this.eccentricity-1.0)*Math.cosh(hyperbolicAnomaly)} + outPosition.z=0.0;outVelocity.z=0.0;outPosition.rotate(this.orbitOrientation,outPosition);outVelocity.rotate(this.orbitOrientation,outVelocity)} + project(outPosition,outVelocity,time){let meanAnomaly=this.meanAnomalyAtEpoch+this.meanAngularMotion*(time-this.epoch);if(this.eccentricity<1.0){meanAnomaly=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(meanAnomaly,-_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi,+_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi)} + this.projectFromMeanAnomaly(outPosition,outVelocity,meanAnomaly)} + getTrueAnomalyFromPosition(position){const positionInPlane=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();positionInPlane.rotateInverse(this.orbitOrientation,position);const trueAnomaly=Math.atan2(positionInPlane.y,positionInPlane.x);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionInPlane);return trueAnomaly} + getMeanAnomalyFromTrueAnomaly(trueAnomaly){let eccentricAnomaly=0.0;let meanAnomaly=0.0;if(this.eccentricity<1.0){eccentricAnomaly=2.0*Math.atan(Math.tan(trueAnomaly/2.0)*Math.sqrt((1-this.eccentricity)/(1+this.eccentricity)));meanAnomaly=eccentricAnomaly-this.eccentricity*Math.sin(eccentricAnomaly)}else{eccentricAnomaly=2.0*Math.atanh(Math.tan(trueAnomaly/2.0)*Math.sqrt((this.eccentricity-1)/(1+this.eccentricity)));meanAnomaly=this.eccentricity*Math.sinh(eccentricAnomaly)-eccentricAnomaly} + return meanAnomaly} + getEccentricAnomalyFromMeanAnomaly(meanAnomaly){if(this.eccentricity<1.0){let eccentricAnomaly=meanAnomaly;if(this.eccentricity>=0.8){eccentricAnomaly=Math.sign(meanAnomaly)*_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.pi} + for(let i=0;i<20;i++){const difference=(eccentricAnomaly-this.eccentricity*Math.sin(eccentricAnomaly)-meanAnomaly)/(this.eccentricity*Math.cos(eccentricAnomaly)-1.0);eccentricAnomaly+=difference;if(Math.abs(difference)<0.00174532925){break}} + return eccentricAnomaly}else{let hyperbolicAnomaly=Math.log(2.0*Math.abs(meanAnomaly)/Math.E+1.8);if(this.eccentricity<=1.2){hyperbolicAnomaly=Math.log(2.0*Math.abs(meanAnomaly)/Math.E+1.8)} + if(meanAnomaly<0.0){hyperbolicAnomaly*=-1} + for(let i=0;i<20;i++){const difference=(hyperbolicAnomaly-this.eccentricity*Math.sinh(hyperbolicAnomaly)+meanAnomaly)/(this.eccentricity*Math.cosh(hyperbolicAnomaly)-1.0);hyperbolicAnomaly+=difference;if(Math.abs(difference)<0.00174532925){break}} + return hyperbolicAnomaly}} + getMeanAnomalyFromEccentricAnomaly(eccentricAnomaly){if(this.eccentricity<1.0){const meanAnomaly=eccentricAnomaly-this.eccentricity*Math.sin(eccentricAnomaly);return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(meanAnomaly,-Math.PI,+Math.PI)}else{return this.eccentricity*Math.sinh(eccentricAnomaly)-eccentricAnomaly}} + getTrueAnomalyFromEccentricAnomaly(eccentricAnomaly){if(this.eccentricity<1.0){return 2.0*Math.atan(Math.sqrt((1+this.eccentricity)/(1-this.eccentricity))*Math.tan(eccentricAnomaly/2.0))}else{return 2.0*Math.atan(Math.sqrt((1+this.eccentricity)/(this.eccentricity-1))*Math.tanh(eccentricAnomaly/2.0))}} + getEccentricAnomalyFromTrueAnomaly(trueAnomaly){if(this.eccentricity<1.0){const eccentricAnomaly=2.0*Math.atan2(Math.tan(trueAnomaly/2.0),Math.sqrt((1+this.eccentricity)/(1-this.eccentricity)));return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(eccentricAnomaly,-Math.PI,+Math.PI)}else{return 2.0*Math.atanh(Math.sqrt((this.eccentricity-1.0)/(this.eccentricity+1.0))*Math.tan(trueAnomaly/2.0))}} + getInclination(){const h=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();this.orbitOrientation.getAxis(h,2);const inclination=h.angle(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.ZAxis);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(h);return inclination} + getLongitudeOfAscendingNode(){const h=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();this.orbitOrientation.getAxis(h,2);const longitudeOfAscendingNode=Math.atan2(h.x,-h.y);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(h);return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(longitudeOfAscendingNode,0,_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi)} + getArgumentOfPeriapsis(){const h=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const e=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();this.orbitOrientation.getAxis(h,2);h.set(-h.y,h.x,0);this.orbitOrientation.getAxis(e,0);const argumentOfPeriapsis=h.angle(e);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(e);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(h);return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(argumentOfPeriapsis,0,_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi)} + getPeriod(){return _internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi/this.meanAngularMotion} + getPeriapsis(){return this.semiMajorAxis*(1-this.eccentricity)} + getApoapsis(){return this.semiMajorAxis*(1+this.eccentricity)} + setOrbitOrientationFromElements(inclination,longitudeOfAscendingNode,argumentOfPeriapsis){const n=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const h=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const periapsisRotation=_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();n.set(Math.cos(longitudeOfAscendingNode),Math.sin(longitudeOfAscendingNode),0);h.set(Math.sin(longitudeOfAscendingNode)*Math.sin(inclination),-Math.cos(longitudeOfAscendingNode)*Math.sin(inclination),Math.cos(inclination));this.orbitOrientation.setFromAxes(n,undefined,h);periapsisRotation.setFromAxisAngle(h,argumentOfPeriapsis);this.orbitOrientation.mult(periapsisRotation,this.orbitOrientation);_internal__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(periapsisRotation);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(h);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(n)} + setFromPositionAndVelocity(position,velocity,time,gm){const gmInv=1/gm;this.epoch=time;const specificAngularMomentum=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();specificAngularMomentum.cross(position,velocity);const eccentricityVec=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const positionNormalized=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();positionNormalized.normalize(position);eccentricityVec.cross(velocity,specificAngularMomentum);eccentricityVec.mult(eccentricityVec,gmInv);eccentricityVec.sub(eccentricityVec,positionNormalized);this.eccentricity=eccentricityVec.magnitude();const semiLatusRectum=specificAngularMomentum.dot(specificAngularMomentum)*gmInv;this.semiMajorAxis=semiLatusRectum/(1-this.eccentricity*this.eccentricity);if(this.eccentricity>1){this.semiMajorAxis*=-1} + let trueAnomaly=Math.acos(_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(eccentricityVec.dot(positionNormalized)/this.eccentricity,-1,1));if(position.dot(velocity)<0){trueAnomaly*=-1} + if(trueAnomaly<-Math.PI){trueAnomaly+=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi} + if(trueAnomaly>=Math.PI){trueAnomaly-=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.twoPi} + eccentricityVec.normalize(eccentricityVec);specificAngularMomentum.normalize(specificAngularMomentum);this.orbitOrientation.setFromAxes(eccentricityVec,undefined,specificAngularMomentum);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionNormalized);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(specificAngularMomentum);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(eccentricityVec);const eccentricAnomaly=this.getEccentricAnomalyFromTrueAnomaly(trueAnomaly);this.meanAnomalyAtEpoch=this.getMeanAnomalyFromEccentricAnomaly(eccentricAnomaly);this.meanAngularMotion=Math.sqrt(gm/(this.semiMajorAxis*this.semiMajorAxis*this.semiMajorAxis))}}}),"../pioneer/engine/src/utils/pool.js": + /*!*******************************************!*\ + !*** ../pioneer/engine/src/utils/pool.js ***! + \*******************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Pool":function(){return Pool}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class Pool extends _internal__WEBPACK_IMPORTED_MODULE_0__.FastIterable{constructor(type){super();this._type=type;this._objects=[];this._free=[];this._freeLength=0;this._constructorFunction=()=>{return new this._type()};this._destructorFunction=()=>{}} + setConstructorFunction(constructorFunction){this._constructorFunction=constructorFunction} + setDestructorFunction(destructorFunction){this._destructorFunction=destructorFunction} + get(){let objectToGet=null;if(this._freeLength>0){objectToGet=this._objects[this._free[this._freeLength-1]];this._freeLength-=1}else{const poolIndex=this._objects.push(this._constructorFunction())-1;this._objects[poolIndex]._poolIndex=poolIndex;objectToGet=this._objects[poolIndex]} + objectToGet._poolUsed=!0;return objectToGet} + release(o){const poolItem=o;if(poolItem._poolIndex!==undefined){if(this._freeLength>=this._free.length){this._free.push(poolItem._poolIndex)}else{this._free[this._freeLength]=poolItem._poolIndex} + this._freeLength+=1;poolItem._poolUsed=!1}} + clean(threshold){if(threshold===undefined||threshold>=(this._objects.length-this._freeLength)/this._objects.length){for(let freeI=0;freeIindexToRemove){this._free[i]-=1}}} + this._free=[];this._freeLength=0}} + getAsArray(){return this._objects} + isUsed(o){return o._poolUsed} + areAnyUsed(){return this._freeLength0){const S=Math.sqrt(tr+1.0)*2;this._w=0.25*S;this._x=(yAxis.z-zAxis.y)/S;this._y=(zAxis.x-xAxis.z)/S;this._z=(xAxis.y-yAxis.x)/S}else if((xAxis.x>yAxis.y)&&(xAxis.x>zAxis.z)){const S=Math.sqrt(1.0+xAxis.x-yAxis.y-zAxis.z)*2;this._w=(yAxis.z-zAxis.y)/S;this._x=0.25*S;this._y=(yAxis.x+xAxis.y)/S;this._z=(zAxis.x+xAxis.z)/S}else if(yAxis.y>zAxis.z){const S=Math.sqrt(1.0+yAxis.y-zAxis.z-xAxis.x)*2;this._w=(zAxis.x-xAxis.z)/S;this._x=(yAxis.x+xAxis.y)/S;this._y=0.25*S;this._z=(zAxis.y+yAxis.z)/S}else{const S=Math.sqrt(1.0+zAxis.z-xAxis.x-yAxis.y)*2;this._w=(xAxis.y-yAxis.x)/S;this._x=(zAxis.x+xAxis.z)/S;this._y=(zAxis.y+yAxis.z)/S;this._z=0.25*S} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(missingAxis)} + setFromEuler(pitch,roll,yaw){this.throwIfFrozen();const halfX=pitch*0.5;const halfY=roll*0.5;const halfZ=yaw*0.5;const cosHalfX=Math.cos(halfX);const sinHalfX=Math.sin(halfX);const cosHalfY=Math.cos(halfY);const sinHalfY=Math.sin(halfY);const cosHalfZ=Math.cos(halfZ);const sinHalfZ=Math.sin(halfZ);this._w=cosHalfX*cosHalfY*cosHalfZ+sinHalfX*sinHalfY*sinHalfZ;this._x=sinHalfX*cosHalfY*cosHalfZ-cosHalfX*sinHalfY*sinHalfZ;this._y=cosHalfX*sinHalfY*cosHalfZ+sinHalfX*cosHalfY*sinHalfZ;this._z=cosHalfX*cosHalfY*sinHalfZ-sinHalfX*sinHalfY*cosHalfZ} + setFromVectorFromTo(fromVector,toVector){const axis=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const dot=fromVector.dot(toVector);if(dot>=1.0){this.set(1,0,0,0)}else if(dot<=-1.0){this.set(0,1,0,0)}else{axis.cross(fromVector,toVector);axis.normalize(axis);const angle=Math.acos(dot);this.setFromAxisAngle(axis,angle)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(axis)} + setFromAxis(axis,which){const axis0=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const axis1=_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();axis0.normalize(axis);axis1.cross(axis0,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.XAxis);if(axis1.isZero()){axis1.cross(axis0,_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxis)} + axis1.normalize(axis1);if(which===0){this.setFromAxes(axis0,axis1,undefined)}else if(which===1){this.setFromAxes(undefined,axis0,axis1)}else if(which===2){this.setFromAxes(axis1,undefined,axis0)} + _internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(axis0);_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(axis1)} + toString(){return'['+this._w+', '+this._x+', '+this._y+', '+this._z+']'} + isNaN(){return(!(this._w<=0)&&!(this._w>0))} + magnitude(){return Math.sqrt(this._w*this._w+this._x*this._x+this._y*this._y+this._z*this._z)} + normalize(a){this.throwIfFrozen();const magnitude=a.magnitude();if(magnitude>0){this._w=a._w/magnitude;this._x=a._x/magnitude;this._y=a._y/magnitude;this._z=a._z/magnitude}} + inverse(a){this.throwIfFrozen();this._w=a._w;this._x=-a._x;this._y=-a._y;this._z=-a._z} + mult(a,b){this.throwIfFrozen();const r=Quaternion.pool.get();r._w=a._w*b._w-a._x*b._x-a._y*b._y-a._z*b._z;r._x=a._w*b._x+a._x*b._w+a._y*b._z-a._z*b._y;r._y=a._w*b._y-a._x*b._z+a._y*b._w+a._z*b._x;r._z=a._w*b._z+a._x*b._y-a._y*b._x+a._z*b._w;this.copy(r);Quaternion.pool.release(r)} + multInverseL(a,b){this.throwIfFrozen();const r=Quaternion.pool.get();r._w=a._w*b._w+a._x*b._x+a._y*b._y+a._z*b._z;r._x=a._w*b._x-a._x*b._w-a._y*b._z+a._z*b._y;r._y=a._w*b._y+a._x*b._z-a._y*b._w-a._z*b._x;r._z=a._w*b._z-a._x*b._y+a._y*b._x-a._z*b._w;this.copy(r);Quaternion.pool.release(r)} + multInverseR(a,b){this.throwIfFrozen();const r=Quaternion.pool.get();r._w=+a._w*b._w+a._x*b._x+a._y*b._y+a._z*b._z;r._x=-a._w*b._x+a._x*b._w-a._y*b._z+a._z*b._y;r._y=-a._w*b._y+a._x*b._z+a._y*b._w-a._z*b._x;r._z=-a._w*b._z-a._x*b._y+a._y*b._x+a._z*b._w;this.copy(r);Quaternion.pool.release(r)} + scaleAngle(a,b){this.throwIfFrozen();const halfAngle=Math.acos(a._w);const sinHalfAngle=Math.sin(halfAngle);if(sinHalfAngle===0){this.copy(a);return} + const sinHalfAngleB=Math.sin(halfAngle*b);this._w=Math.cos(halfAngle*b);this._x=a._x/sinHalfAngle*sinHalfAngleB;this._y=a._y/sinHalfAngle*sinHalfAngleB;this._z=a._z/sinHalfAngle*sinHalfAngleB} + angle(a){return Math.acos(this._w*a._w+this._x*a._x+this._y*a._y+this._z*a._z)*2.0} + slerp(a,b,u){this.throwIfFrozen();let dot=a._w*b._w+a._x*b._x+a._y*b._y+a._z*b._z;let f=1;if(dot<0.0){f=-1;dot=-dot} + if(dot<=0.9995){const angle=Math.acos(dot);const A=f*Math.sin((1.0-u)*angle)/Math.sin(angle);const B=Math.sin(u*angle)/Math.sin(angle);this._w=A*a._w+B*b._w;this._x=A*a._x+B*b._x;this._y=A*a._y+B*b._y;this._z=A*a._z+B*b._z}else{const A=f*(1.0-u);const B=u;this._w=A*a._w+B*b._w;this._x=A*a._x+B*b._x;this._y=A*a._y+B*b._y;this._z=A*a._z+B*b._z;this.normalize(this)}} + getAxis(outAxis,axis){if(axis===undefined){outAxis.set(this._x,this._y,this._z);outAxis.normalize(outAxis)}else if(axis===0){outAxis.x=this._w*this._w+this._x*this._x-this._y*this._y-this._z*this._z;outAxis.y=2.0*this._w*this._z+2.0*this._x*this._y;outAxis.z=2.0*this._x*this._z-2.0*this._w*this._y}else if(axis===1){outAxis.x=2.0*this._y*this._x-2.0*this._w*this._z;outAxis.y=this._w*this._w-this._x*this._x+this._y*this._y-this._z*this._z;outAxis.z=2.0*this._x*this._w+2.0*this._y*this._z}else if(axis===2){outAxis.x=2.0*this._y*this._w+2.0*this._z*this._x;outAxis.y=2.0*this._z*this._y-2.0*this._w*this._x;outAxis.z=this._w*this._w-this._x*this._x-this._y*this._y+this._z*this._z}}} + const _pool=new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Quaternion);const _identity=new Quaternion();_identity.freeze();const _nan=new Quaternion(Number.NaN,Number.NaN,Number.NaN,Number.NaN);_nan.freeze()}),"../pioneer/engine/src/utils/reader.js": + /*!*********************************************!*\ + !*** ../pioneer/engine/src/utils/reader.js ***! + \*********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Reader":function(){return Reader}});class Reader{constructor(data){this._dataView=new DataView(data);this._offset=0} + isAtEnd(){return this._offset>=this._dataView.byteLength} + readByte(){const result=this._dataView.getUint8(this._offset);this._offset+=1;return result} + readFloat32(){const result=this._dataView.getFloat32(this._offset,!0);this._offset+=4;return result} + readFloat64(){const result=this._dataView.getFloat64(this._offset,!0);this._offset+=8;return result} + readUInt8(){const result=this._dataView.getUint8(this._offset);this._offset+=1;return result} + readUInt16(){const result=this._dataView.getUint16(this._offset,!0);this._offset+=2;return result} + readUInt32(){const result=this._dataView.getUint32(this._offset,!0);this._offset+=4;return result} + readUInt64(){const result=Number(this._dataView.getBigUint64(this._offset,!0));this._offset+=8;return Number.isSafeInteger(result)?result:NaN} + readInt8(){const result=this._dataView.getInt8(this._offset);this._offset+=1;return result} + readInt16(){const result=this._dataView.getInt16(this._offset,!0);this._offset+=2;return result} + readInt32(){const result=this._dataView.getInt32(this._offset,!0);this._offset+=4;return result} + readInt64(){const result=Number(this._dataView.getBigInt64(this._offset,!0));this._offset+=8;return Number.isSafeInteger(result)?result:NaN} + readLine(){const byteArray=[];while(!0){const byte=this.readByte();const byteAsString=String.fromCharCode(byte);if(byteAsString==='\r'){continue} + if(byteAsString==='\n'){break} + byteArray.push(byte)} + if(typeof TextEncoder!=='undefined'){const utf8Decoder=new TextDecoder();const array=new Uint8Array(byteArray);return utf8Decoder.decode(array)}else{return this._utf8ArrayToStr(byteArray)}} + readString(numBytes){const byteArray=[];while(!0){const byte=this.readByte();if(numBytes===undefined&&byte===0){break} + byteArray.push(byte);if(numBytes!==undefined&&byteArray.length===numBytes){break}} + if(typeof TextEncoder!=='undefined'){const utf8Decoder=new TextDecoder();const array=new Uint8Array(byteArray);return utf8Decoder.decode(array)}else{return this._utf8ArrayToStr(byteArray)}} + _utf8ArrayToStr(byteArray){let c0=0;let c1=0;let c2=0;let c3=0;let out='';let i=0;const len=byteArray.length;while(i>4){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:out+=String.fromCharCode(c0);break;case 12:case 13:c1=byteArray[i]|0;i+=1;out+=String.fromCharCode(((c0&0x1F)<<6)|(c1&0x3F));break;case 14:c1=byteArray[i]|0;i+=1;c2=byteArray[i]|0;i+=1;out+=String.fromCharCode(((c0&0x0F)<<12)|((c1&0x3F)<<6)|((c2&0x3F)<<0));break;case 15:c1=byteArray[i]|0;i+=1;c2=byteArray[i]|0;i+=1;c3=byteArray[i]|0;i+=1;out+=String.fromCharCode(((c0&0x07)<<18)|((c1&0x3F)<<12)|((c2&0x3F)<<6)|((c3&0x3F)<<0));break}} + return out}}}),"../pioneer/engine/src/utils/rect.js": + /*!*******************************************!*\ + !*** ../pioneer/engine/src/utils/rect.js ***! + \*******************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Rect":function(){return Rect}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class Rect extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable{static get pool(){return _pool} + constructor(x=0,y=0,w=0,h=0){super();this._origin=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(x,y);this._size=new _internal__WEBPACK_IMPORTED_MODULE_0__.Vector2(w,h)} + freeze(){this._origin.freeze();this._size.freeze()} + thaw(){this._origin.thaw();this._size.thaw()} + get origin(){return this._origin} + get size(){return this._size} + toString(){return'[Origin: ('+this._origin.x+', '+this._origin.y+'), Size: ('+this._size.x+', '+this._size.y+')]'} + copy(a){this._origin.copy(a._origin);this._size.copy(a._size)} + set(x,y,w,h){this._origin.set(x,y);this._size.set(w,h)} + contains(position){return this._origin.x<=position.x&&position.xrect._origin.x&&rect._origin.x+rect._size.x>this._origin.x&&this._origin.y+this._size.y>rect._origin.y&&rect._origin.y+rect._size.y>this._origin.y}} + const _pool=new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Rect)}),"../pioneer/engine/src/utils/shader_fix.js": + /*!*************************************************!*\ + !*** ../pioneer/engine/src/utils/shader_fix.js ***! + \*************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ShaderFix":function(){return ShaderFix}});var three__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! three */"../pioneer/engine/node_modules/three/build/three.module.js");var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class ShaderFix{static fix(rawShaderMaterial){const webGL2=_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.isWebGL2();const fragDepth=_internal__WEBPACK_IMPORTED_MODULE_0__.Capabilities.hasFragDepth();let prependVertex='';let prependFragment='';if(webGL2){prependVertex+=` + #define attribute in + #define varying out + #define texture2D texture + precision highp float; + precision highp int; + #define L_EXT_frag_depth true + `;prependFragment+=` + #define varying in + out highp vec4 pc_fragColor; + #define gl_FragColor pc_fragColor + #define gl_FragDepthEXT gl_FragDepth + #define texture2D texture + #define textureCube texture + #define texture2DProj textureProj + #define texture2DLodEXT textureLod + #define texture2DProjLodEXT textureProjLod + #define textureCubeLodEXT textureLod + #define texture2DGradEXT textureGrad + #define texture2DProjGradEXT textureProjGrad + #define textureCubeGradEXT textureGrad + #define L_EXT_frag_depth true + precision highp float; + precision highp int; + `;rawShaderMaterial.glslVersion=three__WEBPACK_IMPORTED_MODULE_1__.GLSL3}else{if(fragDepth){prependVertex+=` + #extension GL_EXT_frag_depth : enable + #define L_EXT_frag_depth true + `;prependFragment+=` + #extension GL_EXT_frag_depth : enable + #define L_EXT_frag_depth true + `} + prependVertex+=` + precision highp float; + precision highp int; + `;prependFragment+=` + precision highp float; + precision highp int; + `;rawShaderMaterial.glslVersion=three__WEBPACK_IMPORTED_MODULE_1__.GLSL1} + rawShaderMaterial.vertexShader=prependVertex+rawShaderMaterial.vertexShader;rawShaderMaterial.fragmentShader=prependFragment+rawShaderMaterial.fragmentShader}}}),"../pioneer/engine/src/utils/sort.js": + /*!*******************************************!*\ + !*** ../pioneer/engine/src/utils/sort.js ***! + \*******************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Sort":function(){return Sort}});class Sort{static getIndex(value,array,isLess){let low=0;let high=array.length;if(isLess===undefined){while(low>>1;if(array[mid]>>1;if(isLess(array[mid],value)){low=mid+1}else{high=mid}}} + return low} + static add(value,array,isLess,isEqual){let index=this.getIndex(value,array,isLess);if(isEqual===undefined){while(index=targetSize||(typeof maxTextureSize==='number'&&size>=maxTextureSize&&this._forcedSize===undefined)){sizeIndex=i;break}} + if(this._currentSize!==this._sizes[sizeIndex]){this._currentSize=this._sizes[sizeIndex];this._loadTexture(this._currentSize)}} + _loadTexture(size){const url=this._url.replace('$SIZE',size.toString());this._loading=!0;const textureLoader=this._useCompression?this._engine.getTextureLoaderCompressed():this._engine.getTextureLoader();this._loadedPromise=textureLoader.loadIntoUniform(this._uniform,url,!0).then(()=>{this._loading=!1}).catch((error)=>{throw Error(error)})}}}),"../pioneer/engine/src/utils/three_js_helper.js": + /*!******************************************************!*\ + !*** ../pioneer/engine/src/utils/three_js_helper.js ***! + \******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ThreeJsHelper":function(){return ThreeJsHelper}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class ThreeJsHelper{static createGeometry(attributes,interleavedAttributes){const geometry=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.BufferGeometry();if(interleavedAttributes){let stride=0;for(let i=0;i0){this.destroyObject(object.children[object.children.length-1])} + if(object.parent!==null){object.parent.remove(object)} + if(object instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Mesh){this.destroyGeometry(object.geometry)}} + static destroyMaterial(material){const uniforms=material.uniforms;for(const uniform in uniforms){if(Object.prototype.hasOwnProperty.call(uniforms,uniform)&&uniforms[uniform].value!==null&&uniforms[uniform].value.dispose!==undefined){uniforms[uniform].value.dispose()}} + material.dispose()} + static destroyAllObjectsAndMaterials(component){const objects=component.getThreeJsObjects();const materials=component.getThreeJsMaterials();for(let i=0;i0&&this.checkJoin()){this._join()}} + return this._transitioning} + get children(){return this._children} + createNewTile(_parent,_row,_col){return null} + checkSplit(){return!1} + checkJoin(){return!1} + async load(){} + async unload(){} + async activate(){} + async deactivate(){} + destroy(){this._destroyed=!0;for(let i=0;i{this.unload()}).catch((error)=>{throw error})}else if(this._loaded){this.unload()}}} + _split(){const loadedPromises=[];const newTiles=[];this._splitAndLoad(loadedPromises,newTiles);Promise.all(loadedPromises).then(()=>{const activatedPromises=[];for(let i=0;i{if(this._destroyed){return this.deactivate().then(()=>{this.unload()}).catch((error)=>{throw error})} + newTiles[i]._active=!0;newTiles[i]._transitioning=!1}).catch((error)=>{throw error}))}else{newTiles[i]._transitioning=!1}} + if(this._active){activatedPromises.push(this.deactivate().then(()=>{this._active=!1}).catch((error)=>{throw error}))} + return activatedPromises}).then(()=>{if(this._loaded){this.unload().then(()=>{this._loaded=!1;this._transitioning=!1}).catch((error)=>{throw error})}else{this._transitioning=!1}}).catch((error)=>{throw error})} + _join(){if(this._checkIfDescendantsAreTransitioning()){return} + const tilesToUnload=[];this._transitioning=!0;this._markDescendantsAsTransitioning(tilesToUnload);this.load().then(async()=>{if(this._destroyed){return this.unload()} + this._loaded=!0}).then(()=>{const promises=[];for(let i=0;i{tilesToUnload[i]._active=!1}).catch((error)=>{throw error}))} + if(!this._destroyed){promises.push(this.activate().then(async()=>{if(this._destroyed){return this.deactivate().then(()=>{this.unload()}).catch((error)=>{throw error})} + this._active=!0}).catch((error)=>{throw error}))} + return Promise.all(promises)}).then(()=>{const promises=[];for(let i=0;i{tilesToUnload[i]._loaded=!1}).catch((error)=>{throw error}))} + return Promise.all(promises)}).then(()=>{this._children=[];this._transitioning=!1}).catch((error)=>{throw error})} + _splitAndLoad(loadedPromises,newTiles){this._transitioning=!0;for(let row=0;row<2;row++){for(let col=0;col<2;col++){const tile=this.createNewTile(this,row,col);if(tile!==null){this._children.push(tile);if(tile.checkSplit()){tile._splitAndLoad(loadedPromises,newTiles)}else{tile._transitioning=!0;loadedPromises.push(tile.load().then(async()=>{if(tile._destroyed){return tile.unload()} + tile._loaded=!0}).catch((error)=>{throw error}))} + newTiles.push(tile)}}}} + _checkIfDescendantsAreTransitioning(){for(let i=0;i=_leapSeconds[i]+1){leapSecondsOffset-=1}} + return et+946727957.816+leapSecondsOffset} + static unixToEt(unix){let leapSecondsOffset=0;for(let i=0;i<_leapSeconds.length;i++){if(unix>=_leapSeconds[i]+1){leapSecondsOffset+=1}} + return unix-946727957.816+leapSecondsOffset} + static get leapSeconds(){return _leapSeconds}} + const _leapSeconds=[Date.UTC(1972,6-1,30,23,59,59)/1000.0,Date.UTC(1972,12-1,31,23,59,59)/1000.0,Date.UTC(1973,12-1,31,23,59,59)/1000.0,Date.UTC(1974,12-1,31,23,59,59)/1000.0,Date.UTC(1975,12-1,31,23,59,59)/1000.0,Date.UTC(1976,12-1,31,23,59,59)/1000.0,Date.UTC(1977,12-1,31,23,59,59)/1000.0,Date.UTC(1978,12-1,31,23,59,59)/1000.0,Date.UTC(1979,12-1,31,23,59,59)/1000.0,Date.UTC(1981,6-1,30,23,59,59)/1000.0,Date.UTC(1982,6-1,30,23,59,59)/1000.0,Date.UTC(1983,6-1,30,23,59,59)/1000.0,Date.UTC(1985,6-1,30,23,59,59)/1000.0,Date.UTC(1987,12-1,31,23,59,59)/1000.0,Date.UTC(1989,12-1,31,23,59,59)/1000.0,Date.UTC(1990,12-1,31,23,59,59)/1000.0,Date.UTC(1992,6-1,30,23,59,59)/1000.0,Date.UTC(1993,6-1,30,23,59,59)/1000.0,Date.UTC(1994,6-1,30,23,59,59)/1000.0,Date.UTC(1995,12-1,31,23,59,59)/1000.0,Date.UTC(1997,6-1,30,23,59,59)/1000.0,Date.UTC(1998,12-1,31,23,59,59)/1000.0,Date.UTC(2005,12-1,31,23,59,59)/1000.0,Date.UTC(2008,12-1,31,23,59,59)/1000.0,Date.UTC(2012,6-1,30,23,59,59)/1000.0,Date.UTC(2015,6-1,30,23,59,59)/1000.0,Date.UTC(2016,12-1,31,23,59,59)/1000.0]}),"../pioneer/engine/src/utils/vector2.js": + /*!**********************************************!*\ + !*** ../pioneer/engine/src/utils/vector2.js ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Vector2":function(){return Vector2}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class Vector2 extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable{static get pool(){return _pool} + static get NaN(){return _nan} + static get Zero(){return _zero} + static get XAxis(){return _xAxis} + static get YAxis(){return _yAxis} + constructor(x=0,y=0){super();this._x=x;this._y=y} + get x(){return this._x} + set x(x){this.throwIfFrozen();this._x=x} + get y(){return this._y} + set y(y){this.throwIfFrozen();this._y=y} + toString(){return'['+this._x+', '+this._y+']'} + equals(a){return this._x===a._x&&this._y===a._y} + isZero(){return this._x===0&&this._y===0} + isNaN(){return(!(this._x<=0)&&!(this._x>0))||(!(this._y<=0)&&!(this._y>0))} + copy(a){this.throwIfFrozen();this._x=a._x;this._y=a._y} + copyFromThreeJs(a){this.throwIfFrozen();this._x=a.x;this._y=a.y} + set(x,y){this.throwIfFrozen();this._x=x;this._y=y} + neg(a){this.throwIfFrozen();this._x=-a._x;this._y=-a._y} + add(a,b){this.throwIfFrozen();this._x=a._x+b._x;this._y=a._y+b._y} + sub(a,b){this.throwIfFrozen();this._x=a._x-b._x;this._y=a._y-b._y} + mult(a,b){this.throwIfFrozen();this._x=a._x*b;this._y=a._y*b} + addMult(a,b,c){this.throwIfFrozen();this._x=a._x+b._x*c;this._y=a._y+b._y*c} + div(a,b){this.throwIfFrozen();this._x=a._x/b;this._y=a._y/b} + scale(a,b){this.throwIfFrozen();this._x=a._x*b._x;this._y=a._y*b._y} + scaleInv(a,b){this.throwIfFrozen();this._x=a._x/b._x;this._y=a._y/b._y} + dot(a){return this._x*a._x+this._y*a._y} + cross(a){return this._x*a._y-this._y*a._x} + magnitudeSqr(){return this._x*this._x+this._y*this._y} + magnitude(){return Math.sqrt(this.magnitudeSqr())} + normalize(a){this.throwIfFrozen();const magnitude=a.magnitude();if(magnitude>0){this._x=a._x/magnitude;this._y=a._y/magnitude}} + setMagnitude(a,magnitude){this.throwIfFrozen();this.normalize(a);this._x*=magnitude;this._y*=magnitude} + distance(a){const x=this._x-a._x;const y=this._y-a._y;return Math.sqrt(x*x+y*y)} + angle(a){const magnitudes=this.magnitude()*a.magnitude();if(magnitudes>0){return Math.acos(_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(this.dot(a)/magnitudes,-1.0,1.0))}else{return Number.NaN}} + clamp(a,min,max){this.throwIfFrozen();this._x=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a._x,min._x,max._x);this._y=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a._y,min._y,max._y)} + lerp(a,b,u){this.throwIfFrozen();this._x=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._x,b._x,u);this._y=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._y,b._y,u)}} + const _pool=new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Vector2);const _zero=new Vector2();_zero.freeze();const _xAxis=new Vector2(1,0);_xAxis.freeze();const _yAxis=new Vector2(0,1);_yAxis.freeze();const _nan=new Vector2(Number.NaN,Number.NaN);_nan.freeze()}),"../pioneer/engine/src/utils/vector3.js": + /*!**********************************************!*\ + !*** ../pioneer/engine/src/utils/vector3.js ***! + \**********************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Vector3":function(){return Vector3}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../internal */"../pioneer/engine/src/internal.js");class Vector3 extends _internal__WEBPACK_IMPORTED_MODULE_0__.Freezable{static get pool(){return _pool} + static get NaN(){return _nan} + static get Zero(){return _zero} + static get XAxis(){return _xAxis} + static get YAxis(){return _yAxis} + static get ZAxis(){return _zAxis} + static get XAxisNeg(){return _xAxisNeg} + static get YAxisNeg(){return _yAxisNeg} + static get ZAxisNeg(){return _zAxisNeg} + static fromAER(aer){const v=new Vector3();v.setFromAER(aer);return v} + constructor(x=0,y=0,z=0){super();this._x=x;this._y=y;this._z=z} + get x(){return this._x} + set x(x){this.throwIfFrozen();this._x=x} + get y(){return this._y} + set y(y){this.throwIfFrozen();this._y=y} + get z(){return this._z} + set z(z){this.throwIfFrozen();this._z=z} + toString(){return'['+this._x+', '+this._y+', '+this._z+']'} + equals(a){return this._x===a._x&&this._y===a._y&&this._z===a._z} + isZero(){return this._x===0&&this._y===0&&this._z===0} + isNaN(){return(!(this._x<=0)&&!(this._x>0))||(!(this._y<=0)&&!(this._y>0))||(!(this._z<=0)&&!(this._z>0))} + copy(a){this.throwIfFrozen();this._x=a._x;this._y=a._y;this._z=a._z} + copyFromThreeJs(a){this.throwIfFrozen();this._x=a.x;this._y=a.y;this._z=a.z} + set(x,y,z){this.throwIfFrozen();this._x=x;this._y=y;this._z=z} + setFromAER(aer){this.throwIfFrozen();const cosElevation=Math.cos(aer.elevation);this._x=aer.range*cosElevation*Math.cos(aer.azimuth);this._y=aer.range*cosElevation*Math.sin(aer.azimuth);this._z=aer.range*Math.sin(aer.elevation)} + neg(a){this.throwIfFrozen();this._x=-a._x;this._y=-a._y;this._z=-a._z} + add(a,b){this.throwIfFrozen();this._x=a._x+b._x;this._y=a._y+b._y;this._z=a._z+b._z} + sub(a,b){this.throwIfFrozen();this._x=a._x-b._x;this._y=a._y-b._y;this._z=a._z-b._z} + mult(a,b){this.throwIfFrozen();this._x=a._x*b;this._y=a._y*b;this._z=a._z*b} + addMult(a,b,c){this.throwIfFrozen();this._x=a._x+b._x*c;this._y=a._y+b._y*c;this._z=a._z+b._z*c} + div(a,b){this.throwIfFrozen();this._x=a._x/b;this._y=a._y/b;this._z=a._z/b} + scale(a,b){this.throwIfFrozen();this._x=a._x*b._x;this._y=a._y*b._y;this._z=a._z*b._z} + scaleInv(a,b){this.throwIfFrozen();this._x=a._x/b._x;this._y=a._y/b._y;this._z=a._z/b._z} + dot(a){return this._x*a._x+this._y*a._y+this._z*a._z} + cross(a,b){this.throwIfFrozen();const x=a._y*b._z-a._z*b._y;const y=a._z*b._x-a._x*b._z;const z=a._x*b._y-a._y*b._x;this._x=x;this._y=y;this._z=z} + magnitudeSqr(){return this._x*this._x+this._y*this._y+this._z*this._z} + magnitude(){return Math.sqrt(this.magnitudeSqr())} + magnitudeXY(){return Math.sqrt(this._x*this._x+this._y*this._y)} + normalize(a){this.throwIfFrozen();const magnitude=a.magnitude();if(magnitude>0){this._x=a._x/magnitude;this._y=a._y/magnitude;this._z=a._z/magnitude}else{this.copy(a)}} + setMagnitude(a,magnitude){this.throwIfFrozen();this.normalize(a);this._x*=magnitude;this._y*=magnitude;this._z*=magnitude} + distance(a){const x=this._x-a._x;const y=this._y-a._y;const z=this._z-a._z;return Math.sqrt(x*x+y*y+z*z)} + angle(a){const magnitudes=this.magnitude()*a.magnitude();if(magnitudes>0){return Math.acos(_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(this.dot(a)/magnitudes,-1.0,1.0))}else{return Number.NaN}} + angleAroundAxis(a,axis){const thisP=Vector3.pool.get();const aP=Vector3.pool.get();thisP.addMult(this,axis,-this.dot(axis));aP.addMult(a,axis,-a.dot(axis));let angle=thisP.angle(aP);thisP.cross(thisP,aP);if(thisP.dot(axis)<0){angle*=-1} + Vector3.pool.release(thisP);Vector3.pool.release(aP);return angle} + clamp(a,min,max){this.throwIfFrozen();this._x=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a._x,min._x,max._x);this._y=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a._y,min._y,max._y);this._z=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a._z,min._z,max._z)} + lerp(a,b,u){this.throwIfFrozen();this._x=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._x,b._x,u);this._y=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._y,b._y,u);this._z=_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.lerp(a._z,b._z,u)} + slerp(a,b,u){this.throwIfFrozen();const aMag=a.magnitude();const bMag=b.magnitude();if(aMag>0.0&&bMag>0.0){const angle=Math.acos(_internal__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(a.dot(b)/(aMag*bMag),-1,+1));if(Math.abs(angle)>0.01745327777){const sinAngleInv=1/Math.sin(angle);const aFactor=Math.sin((1-u)*angle)*sinAngleInv;const bFactor=Math.sin(u*angle)*sinAngleInv;this.set(a.x*aFactor/aMag+b.x*bFactor/bMag,a.y*aFactor/aMag+b.y*bFactor/bMag,a.z*aFactor/aMag+b.z*bFactor/bMag);this.mult(this,(1-u)*aMag+u*bMag)}else{this.lerp(a,b,u)}}else{this.lerp(a,b,u)}} + rotate(a,b){this.throwIfFrozen();const tx=a.w*b._x+a.y*b._z-a.z*b._y;const ty=a.w*b._y+a.z*b._x-a.x*b._z;const tz=a.w*b._z+a.x*b._y-a.y*b._x;const tw=-a.x*b._x-a.y*b._y-a.z*b._z;this._x=tx*a.w-tw*a.x-ty*a.z+tz*a.y;this._y=ty*a.w-tw*a.y-tz*a.x+tx*a.z;this._z=tz*a.w-tw*a.z-tx*a.y+ty*a.x} + rotateInverse(a,b){this.throwIfFrozen();const tx=a.w*b._x-a.y*b._z+a.z*b._y;const ty=a.w*b._y-a.z*b._x+a.x*b._z;const tz=a.w*b._z-a.x*b._y+a.y*b._x;const tw=a.x*b._x+a.y*b._y+a.z*b._z;this._x=tx*a.w+tw*a.x+ty*a.z-tz*a.y;this._y=ty*a.w+tw*a.y+tz*a.x-tx*a.z;this._z=tz*a.w+tw*a.z+tx*a.y-ty*a.x} + setNormalTo(a,b){const x=b._x*(a._y*a._y+a._z*a._z)-a._x*(a._y*b._y+a._z*b._z);const y=b._y*(a._z*a._z+a._x*a._x)-a._y*(a._z*b._z+a._x*b._x);const z=b._z*(a._x*a._x+a._y*a._y)-a._z*(a._x*b._x+a._y*b._y);this._x=x;this._y=y;this._z=z;this.normalize(this)}} + const _pool=new _internal__WEBPACK_IMPORTED_MODULE_0__.Pool(Vector3);const _zero=new Vector3();_zero.freeze();const _xAxis=new Vector3(1,0,0);_xAxis.freeze();const _yAxis=new Vector3(0,1,0);_yAxis.freeze();const _zAxis=new Vector3(0,0,1);_zAxis.freeze();const _xAxisNeg=new Vector3(-1,0,0);_xAxis.freeze();const _yAxisNeg=new Vector3(0,-1,0);_yAxis.freeze();const _zAxisNeg=new Vector3(0,0,-1);_zAxis.freeze();const _nan=new Vector3(Number.NaN,Number.NaN,Number.NaN);_nan.freeze()}),"../pioneer/engine/src/utils/wait_until.js": + /*!*************************************************!*\ + !*** ../pioneer/engine/src/utils/wait_until.js ***! + \*************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"waitUntil":function(){return waitUntil}});async function waitUntil(testFunc,testInterval,timeout){return new Promise((resolve,reject)=>{let timeSoFar=0;const intervalCheck=setInterval(()=>{if(testFunc()){clearInterval(intervalCheck);resolve()} + timeSoFar+=testInterval;if(timeSoFar>=timeout){clearInterval(intervalCheck);reject(new Error())}},testInterval*1000.0)})}}),"../pioneer/engine/src/version.js": + /*!****************************************!*\ + !*** ../pioneer/engine/src/version.js ***! + \****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Version":function(){return Version}});const Version='51.0.1'}),"../pioneer/engine/src/viewport.js": + /*!*****************************************!*\ + !*** ../pioneer/engine/src/viewport.js ***! + \*****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Viewport":function(){return Viewport}});var _internal__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./internal */"../pioneer/engine/src/internal.js");class Viewport extends _internal__WEBPACK_IMPORTED_MODULE_0__.CollectionItem{constructor(type,name,engine){super(type,name,engine);this._enabled=!0;this._camera=null;this._div=document.createElement('div');this._bounds=new _internal__WEBPACK_IMPORTED_MODULE_0__.Rect(0,0,0,0);this._bounds.freeze();this._backgroundColor=new _internal__WEBPACK_IMPORTED_MODULE_0__.Color(0,0,0,1);this._backgroundColor.freeze();this._threeJsBackgroundColor=new _internal__WEBPACK_IMPORTED_MODULE_0__.THREE.Color();this._div.style.position='absolute';this._div.style.overflow='hidden';this._div.id=name??'';this._div.classList.add('viewport');if(!this._enabled){this._div.style.display='none'} + this.getEngine().getViewportDiv().appendChild(this._div);const rootDiv=this.getEngine().getRootDiv();this._bounds.thaw();this._bounds.set(this._div.offsetLeft-rootDiv.offsetLeft,this._div.offsetTop-rootDiv.offsetTop,this._div.offsetWidth,this._div.offsetHeight);this._bounds.freeze();const input=this.getEngine().getInput();if(input.getActiveViewport()===null){input.__setActiveViewport(this)}} + getEngine(){return this.__getCollectionParent()} + getDiv(){return this._div} + getBounds(){return this._bounds} + getBackgroundColor(){return this._backgroundColor} + setBackgroundColor(backgroundColor){this._backgroundColor.thaw();this._backgroundColor=backgroundColor;this._backgroundColor.freeze();this._threeJsBackgroundColor.setRGB(this._backgroundColor.r,this._backgroundColor.g,this._backgroundColor.b)} + getCamera(){return this._camera} + setCamera(camera){this._camera=camera;if(this._camera!==null){this._camera.__setViewport(this)}} + isEnabled(){return this._enabled} + setEnabled(enabled){this._enabled=enabled;if(!this._enabled){this._div.style.display='none'}else{this._div.style.display='block'}} + getNormalSpacePositionFromPixelSpacePosition(outNormalSpacePosition,pixelSpacePosition){outNormalSpacePosition.x=2.0*(pixelSpacePosition.x-this._bounds.origin.x)/this._bounds.size.x-1.0;outNormalSpacePosition.y=1.0-2.0*(pixelSpacePosition.y-this._bounds.origin.y)/this._bounds.size.y;outNormalSpacePosition.z=+1} + getPixelSpacePositionFromNormalSpacePosition(outPixelSpacePosition,normalSpacePosition){if(-1.0+1||outDirection.y<-1||outDirection.y>+1||outDirection.z<-1||outDirection.z>+1){outDirection.copy(_internal__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN]);return} + camera.getCameraSpacePositionFromNormalSpacePosition(outDirection,outDirection);outDirection.normalize(outDirection)} + __destroy(){super.__destroy();this._div.parentNode.removeChild(this._div)} + __updateViewportVariables(){if(this._enabled){this._bounds.thaw();this._bounds.set(this._div.offsetLeft,this._div.offsetTop,this._div.offsetWidth,this._div.offsetHeight);this._bounds.freeze();if(this._camera!==null){this._camera.__updateCameraVariablesForConnectedScene()}}} + __render(){if(!this._enabled){return} + const renderer=this.getEngine().__getThreeJsRenderer();const positionFromBottomLeft=this.getEngine().getRootDiv().offsetHeight-this._div.offsetTop-this._div.offsetHeight;renderer.setViewport(this._bounds.origin.x,positionFromBottomLeft,this._bounds.size.x,this._bounds.size.y);renderer.setScissor(this._bounds.origin.x,positionFromBottomLeft,this._bounds.size.x,this._bounds.size.y);this._threeJsBackgroundColor.setRGB(this._backgroundColor.r,this._backgroundColor.g,this._backgroundColor.b);renderer.setClearColor(this._threeJsBackgroundColor,this._backgroundColor.a);if(this._camera!==null){this._camera.__prepareForRender();this._camera.__render()}else{this.getEngine().__getThreeJsRenderer().clear()}}}}),"../pioneer/scripts/src/animation.js": + /*!*******************************************!*\ + !*** ../pioneer/scripts/src/animation.js ***! + \*******************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Animation":function(){return Animation}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class Animation{static makeSubobjectVisibleAnimation(model,subobject,visibilityAtNegInf,keyframes){keyframes.sort((a,b)=>a[0]-b[0]);const entity=model.getEntity();const coverageController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CoverageController);coverageController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY));coverageController.setUpdateFunction((entity)=>{const time=entity.getScene().getEngine().getTime();const index=pioneer__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time,keyframes,(a,time)=>a[0]a[0]-b[0]);const entity=model.getEntity();const coverageController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CoverageController);coverageController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY));coverageController.setUpdateFunction((entity)=>{const obj=model.getThreeJsObjectByName(joint);if(obj!==null){const time=entity.getScene().getEngine().getTime();const index=pioneer__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time,keyframes,(a,time)=>a[0]{const spheroidComponent=pickedEntity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent);if(spheroidComponent!==null){const positionInSpheroidFrame=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();positionInSpheroidFrame.rotateInverse(pickedEntity.getOrientation(),position);const lla=pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get();spheroidComponent.llaFromXYZ(lla,positionInSpheroidFrame);callback(positionInSpheroidFrame,lla);pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(positionInSpheroidFrame)}})} + static getDistanceToFitEntities(cameraEntity,cameraOrientation,focusEntity,entities){const cameraComponent=cameraEntity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CameraComponent);if(cameraComponent===null){return NaN} + let distance=0;const positionOfEntity=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const sinHalfHorizontalFov=Math.sin(cameraComponent.getHorizontalFieldOfView()/2.0);const sinHalfVerticalFov=Math.sin(cameraComponent.getVerticalFieldOfView()/2.0);const tanHalfHorizontalFov=Math.tan(cameraComponent.getHorizontalFieldOfView()/2.0);const tanHalfVerticalFov=Math.tan(cameraComponent.getVerticalFieldOfView()/2.0);for(let i=0;i0&&this._highlightedIndex!==undefined){const colors=[];for(let i=0,l=this._numVertices[this._highlightedIndex];i0&&this._highlightedIndex!==undefined){const colors=[];for(let i=0,l=this._numVertices[this._highlightedIndex];iposition.x){minBounds.x=position.x} + if(maxBounds.xposition.y){minBounds.y=position.y} + if(maxBounds.yposition.z){minBounds.z=position.z} + if(maxBounds.z=0;i--){const controller=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.DynamoController,i);if(controller!==null&&controller.getCoverage().contains(currentTime)){if(controller.getPointType()==='orb'){gm=controller.getHeaderValue('gravitationalParameter1')+controller.getHeaderValue('gravitationalParameter2');break}}} + orbitalElements.setFromPositionAndVelocity(entity.getPosition(),entity.getVelocity(),currentTime,gm);const entityPosition=entity.getPosition();const trueAnomalyAtCurrentTime=orbitalElements.getTrueAnomalyFromPosition(entityPosition);const eccentricAnomalyAtCurrentTime=orbitalElements.getEccentricAnomalyFromTrueAnomaly(trueAnomalyAtCurrentTime);let lastMeanAnomalyNaN=!1;for(let angle=0;angle<360;angle+=1){const index0=angle*2;const index1=(angle*2-1+this._positions.length)%this._positions.length;let eccentricAnomaly=orbitalElements.getEccentricAnomalyFromTrueAnomaly(pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(angle-180));const eccentricAnomalyNext=orbitalElements.getEccentricAnomalyFromTrueAnomaly(pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(angle+1-180));if((eccentricAnomaly=1){this._positions[this._positions.length-2].copy(this._positions[this._positions.length-3]);this._positions[this._positions.length-1].copy(this._positions[this._positions.length-3]);this._colors[this._colors.length-2].a=0;this._colors[this._colors.length-1].a=0} + this._lineMesh.setPositions(this._positions);this._lineMesh.setColors(this._colors)}} + const orbitalElements=new pioneer__WEBPACK_IMPORTED_MODULE_0__.OrbitalElements();const velocity=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3()}),"../pioneer/scripts/src/components/shadow_cone_component.js": + /*!******************************************************************!*\ + !*** ../pioneer/scripts/src/components/shadow_cone_component.js ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ShadowConeComponent":function(){return ShadowConeComponent}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class ShadowConeComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._color=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1,1,1,1);this._color.freeze();this._sourceEntity=new pioneer__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());this._shadowType='umbra';this._targetEntity=new pioneer__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());this._visibleDistanceInterval=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(0,Number.POSITIVE_INFINITY);this._visibleDistanceInterval.freeze();this._alphaMultiplier=1.0;this._numberOfCirclePoints=20;this.__setRadius(Number.POSITIVE_INFINITY)} + getColor(){return this._color} + setColor(color){this._color.thaw();this._color.copy(color);this._color.freeze();pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0],'color',this._color,this._alphaMultiplier)} + getSourceEntity(){return this._sourceEntity.getName()} + setSourceEntity(name){this._sourceEntity.setName(name)} + getTargetEntity(){return this._targetEntity.getName()} + setTargetEntity(name){this._targetEntity.setName(name)} + getShadowType(){return this._shadowType} + setShadowType(shadowType){this._shadowType=shadowType;this.resetResources()} + getVisibleDistanceInterval(){return this._visibleDistanceInterval} + setVisibleDistanceInterval(distanceInterval){this._visibleDistanceInterval.thaw();this._visibleDistanceInterval.copy(distanceInterval);this._visibleDistanceInterval.freeze()} + __prepareForRender(camera){this._updateMesh();pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects()[0],this.getEntity(),camera);const cameraSpacePosition=this.getEntity().getCameraSpacePosition(camera);const distanceToObject=cameraSpacePosition.magnitude();const diffFadeDistance=(this._visibleDistanceInterval.max-this._visibleDistanceInterval.min)*0.5;const minFadeDistance=Math.min(this._visibleDistanceInterval.min*0.5,diffFadeDistance);const maxFadeDistance=Math.min(this._visibleDistanceInterval.max*0.5,diffFadeDistance);if(distanceToObjectthis._visibleDistanceInterval.max-maxFadeDistance){this._alphaMultiplier=Math.max(0,(this._visibleDistanceInterval.max-distanceToObject)/maxFadeDistance)}else{this._alphaMultiplier=1.0} + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0],'color',this._color,this._alphaMultiplier)} + __loadResources(){const material=this.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('basic_alpha');this.getThreeJsMaterials().push(material);pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(material,'color',this._color,this._alphaMultiplier);const object=pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this,material,[{name:'position',dimensions:3}],!1);this.getThreeJsObjects().push(object);this._createMesh();return Promise.resolve()} + __unloadResources(){pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this)} + _createMesh(){const positions=new Float32Array(this._numberOfCirclePoints*2*3);const indices=new Uint16Array(this._numberOfCirclePoints*6);for(let i=0;ithis._visibleDistanceInterval.max-maxFadeDistance){this._alphaMultiplier=Math.max(0,(this._visibleDistanceInterval.max-distanceToObject)/maxFadeDistance)}else{this._alphaMultiplier=1.0} + pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(this.getThreeJsMaterials()[0],'color',this._color,this._alphaMultiplier)} + __loadResources(){const material=this.getEntity().getScene().getEngine().getMaterialManager().getPreloaded('basic_alpha');this.getThreeJsMaterials().push(material);pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setUniformColorRGBA(material,'color',this._color,this._alphaMultiplier);const object=pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.createMeshObject(this,material,[{name:'position',dimensions:3}],!1);this.getThreeJsObjects().push(object);this._createMesh();return Promise.resolve()} + __unloadResources(){pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.destroyAllObjectsAndMaterials(this)} + _createMesh(){const numberOfCirclePoints=100;const numberOfTorusPoints=20;const positions=new Float32Array(numberOfCirclePoints*numberOfTorusPoints*3);const indices=new Uint16Array(numberOfCirclePoints*numberOfTorusPoints*6);const middleRadius=(this._outerRadius+this._innerRadius)/2;const diffRadius=(this._outerRadius-this._innerRadius)/2;for(let i=0;i{if(typeof download.content==='string'){this._capabilitiesXML=new DOMParser().parseFromString(download.content,'application/xml')} + if(this._capabilitiesXML!==null){const layerElems=this._capabilitiesXML.querySelectorAll('Contents > Layer');for(const layerElem of layerElems){const title=layerElem.querySelector('*|Title').textContent;const identifier=layerElem.querySelector('*|Identifier').textContent;this._layers.set(title,identifier)}}})} + get readyPromise(){return this._readyPromise} + get endPoint(){return this._endPoint} + get layers(){return this._layers} + getLayer(identifier){let layer=null;if(this._capabilitiesXML!==null){const layerElems=this._capabilitiesXML.querySelectorAll('Contents > Layer');for(const layerElem of layerElems){const layerIdentifier=layerElem.querySelector('*|Identifier').textContent;if(identifier===layerIdentifier){layer=new Layer(layerElem,this._endPoint+'/1.0.0')}}} + return layer} + getTileMatrixSet(identifier){let tileMatrixSet=null;if(this._capabilitiesXML!==null){const tileMatrixSetElems=this._capabilitiesXML.querySelectorAll('Contents > TileMatrixSet');for(const tileMatrixSetElem of tileMatrixSetElems){const tileMatrixSetIdentifier=tileMatrixSetElem.querySelector('*|Identifier').textContent;if(identifier===tileMatrixSetIdentifier){tileMatrixSet=new TileMatrixSet(tileMatrixSetElem)}}} + return tileMatrixSet}} + class Layer{constructor(elem,baseUrl){this._baseUrl=baseUrl;this._title=elem.querySelector('*|Title').textContent;this._identifier=elem.querySelector('*|Identifier').textContent;this._styles=new Map();this._defaultStyle='';this._boundingBox=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Rect();this._dimensions=new Map();this._tileMatrixSets=new Set();this._url='';const styleElems=elem.querySelectorAll('Style');for(const styleElem of styleElems){const title=styleElem.querySelector('*|Title').textContent;const identifier=styleElem.querySelector('*|Identifier').textContent;this._styles.set(title,identifier);if(styleElem.getAttribute('isDefault')==='true'){this._defaultStyle=identifier}} + let boundingBoxElem=elem.querySelector('*|BoundingBox');if(boundingBoxElem===null){boundingBoxElem=elem.querySelector('*|WGS84BoundingBox')} + if(boundingBoxElem===null){throw new Error('Layer "'+this._identifier+'" missing a BoundingBox or a WGS84BoundingBox tag.')} + const lowerCornerArray=boundingBoxElem.querySelector('*|LowerCorner').textContent.split(' ');const upperCornerArray=boundingBoxElem.querySelector('*|UpperCorner').textContent.split(' ');this._boundingBox.origin.set(Number.parseFloat(lowerCornerArray[0]),Number.parseFloat(lowerCornerArray[1]));this._boundingBox.size.set(Number.parseFloat(upperCornerArray[0])-this._boundingBox.origin.x,Number.parseFloat(upperCornerArray[1])-this._boundingBox.origin.y);const dimensionElems=elem.querySelectorAll('Dimension');for(const dimensionElem of dimensionElems){const identifier=dimensionElem.querySelector('*|Identifier').textContent;const defaultValue=dimensionElem.querySelector('Default').textContent;this._dimensions.set(identifier,defaultValue)} + const tileMatrixSetLinkElems=elem.querySelectorAll('TileMatrixSetLink');for(const tileMatrixSetLinkElem of tileMatrixSetLinkElems){const tileMatrixSet=tileMatrixSetLinkElem.querySelector('TileMatrixSet').textContent;this._tileMatrixSets.add(tileMatrixSet)} + const resourceURLElem=elem.querySelector('ResourceURL');this._url=resourceURLElem.getAttribute('template');if(!/^(?:[a-z]+:)?\/\//i.test(this._url)){this._url=this._baseUrl+this._url}} + get title(){return this._title} + get identifier(){return this._identifier} + get styles(){return this._styles} + get defaultStyle(){return this._defaultStyle} + get boundingBox(){return this._boundingBox} + get dimensions(){return this._dimensions} + get tileMatrixSets(){return this._tileMatrixSets} + get url(){return this._url}} + class TileMatrixSet{constructor(elem){this._identifier=elem.querySelector('*|Identifier').textContent;this._crs=elem.querySelector('*|SupportedCRS').textContent;this._boundingBox=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Rect();this._numTiles=[];this._readyPromise=null;let scalePrev;let level=0;for(const node of elem.querySelectorAll('TileMatrix')){const scaleElem=node.querySelector('ScaleDenominator');if(!scaleElem){throw new Error('ScaleDenominator tag not found for TileMatrix '+level+'.')} + const scale=parseFloat(scaleElem.innerHTML);if(scalePrev!==undefined&&Math.abs(scale*2-scalePrev)/scale>0.01){throw new Error('ScaleDenominator for TileMatrix '+level+' must be half of the next higher level, but is not.')} + scalePrev=scale;this._numTiles[level]=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(parseFloat(node.querySelector('MatrixWidth').innerHTML),parseFloat(node.querySelector('MatrixHeight').innerHTML));level+=1} + this._numLevels=level;const tileMatrix0Elem=elem.querySelector('TileMatrix');const scaleDenominator=Number.parseFloat(tileMatrix0Elem.querySelector('ScaleDenominator').textContent);const pixelsPerTile=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(Number.parseFloat(tileMatrix0Elem.querySelector('TileWidth').textContent),Number.parseFloat(tileMatrix0Elem.querySelector('TileHeight').textContent));const kmPerPixel=scaleDenominator*0.28e-6;const kmPerTile=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(kmPerPixel*pixelsPerTile.x,kmPerPixel*pixelsPerTile.y);const kmPerMatrix=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2(kmPerTile.x*this._numTiles[0].x,kmPerTile.y*this._numTiles[0].y);const topLeftCornerArray=tileMatrix0Elem.querySelector('TopLeftCorner').textContent.split(' ');this._boundingBox.origin.set(Number.parseFloat(topLeftCornerArray[0]),Number.parseFloat(topLeftCornerArray[1]));this._readyPromise=TileMatrixSet.setCRS(this._crs).then((crs)=>{this._crs=crs;let unitsPerKm=1e3;const proj=proj4__WEBPACK_IMPORTED_MODULE_1__["default"].defs(this._crs);if(proj.to_meter){unitsPerKm=1000/proj.to_meter}else if(proj.units==='degrees'){unitsPerKm=0.00898315284}else if(proj.units==='feet'||proj.units==='us feet'){unitsPerKm=3280.83333335} + this._boundingBox.size.x=Math.round(kmPerMatrix.x*unitsPerKm*1e6)/1e6;this._boundingBox.size.y=Math.round(kmPerMatrix.y*unitsPerKm*1e6)/1e6;this._boundingBox.origin.y=this._boundingBox.origin.y-this._boundingBox.size.y})} + get readyPromise(){return this._readyPromise} + get identifier(){return this._identifier} + get boundingBox(){return this._boundingBox} + get numLevels(){return this._numLevels} + getNumTiles(level){return this._numTiles[level]} + crsUnitsToXYZ(outXYZ,crsUnits,spheroid){const lla=pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.get();const x=pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(crsUnits.x,this._boundingBox.origin.x,this._boundingBox.origin.x+this._boundingBox.size.x);const y=pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.clamp(crsUnits.y,this._boundingBox.origin.y,this._boundingBox.origin.y+this._boundingBox.size.y);const ll=(0,proj4__WEBPACK_IMPORTED_MODULE_1__["default"])(this._crs,'WGS84',[x,y]);lla.set(pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(ll[1]),pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.degToRad(ll[0]),0);spheroid.xyzFromLLA(outXYZ,lla);pioneer__WEBPACK_IMPORTED_MODULE_0__.LatLonAlt.pool.release(lla)} + static async setCRS(crs){if(crs.startsWith('urn:ogc:def:crs:')){crs=crs.substring('urn:ogc:def:crs:'.length)} + let proj4Text=crsToWKT.get(crs);if(proj4Text===undefined&&crs.startsWith('EPSG::')){const url='https://epsg.io/'+crs.substring('EPSG::'.length)+'.proj4';const result=await fetch(url);proj4Text=await result.text()} + proj4__WEBPACK_IMPORTED_MODULE_1__["default"].defs(crs,proj4Text);return crs}} + const crsToWKT=(new Map());crsToWKT.set('EPSG::104903','GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]');crsToWKT.set('EPSG::104905','GEOGCS["GCS_Mars_2000",DATUM["D_Mars_2000",SPHEROID["Mars_2000_IAU_IAG",3396190.0,169.8944472236118]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]');crsToWKT.set('EPSG::4326','+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs');crsToWKT.set('EPSG::3857','+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs');crsToWKT.set('OGC:1.3:84',proj4__WEBPACK_IMPORTED_MODULE_1__["default"].defs('WGS84'));crsToWKT.set('OGC:1.3:CRS84',proj4__WEBPACK_IMPORTED_MODULE_1__["default"].defs('WGS84'));crsToWKT.set('OGC:2:84',proj4__WEBPACK_IMPORTED_MODULE_1__["default"].defs('WGS84'))}),"../pioneer/scripts/src/components/wmts_component.js": + /*!***********************************************************!*\ + !*** ../pioneer/scripts/src/components/wmts_component.js ***! + \***********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"WMTSComponent":function(){return WMTSComponent}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var _wmts__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./wmts */"../pioneer/scripts/src/components/wmts.js");class WMTSComponent extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseComponent{constructor(type,name,entity){super(type,name,entity);this._capabilities=null;this._endPoint='';this._layerIdentifier='';this._tileMatrixSetIdentifier='';this._style='';this._dimensionValues=new Map();this._minLevel=Number.NEGATIVE_INFINITY;this._maxLevel=Number.POSITIVE_INFINITY;this._splitJoinThresholdFactor=512;this._layer=null;this._tileMatrixSet=null;this._tileUrl='';this._shadowEntities=[];this._engine=this.getEntity().getScene().getEngine();this._cameraPositions=[];this._rootTile=null;this._tilePixelSize=undefined;this._tilesLoadedPromise=null;this._transitionsCompleteCallback=null;this._loadsThisFrame=0;this._atmosphereComponentRef=new pioneer__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene());this._atmosphereComponentRef.setByType(this.getEntity().getName(),'atmosphere');this._spheroidComponentRef=new pioneer__WEBPACK_IMPORTED_MODULE_0__.ComponentRef(this.getEntity().getScene());this._spheroidComponentRef.setByType(this.getEntity().getName(),'spheroid');this._spheroidComponentRef.setRefChangedCallback(this._spheroidRefChangedCallback.bind(this));this._spheroidChangedCallback=this._spheroidChangedCallback.bind(this);this.__setUsesEntityOrientation(!0)} + async setEndPoint(endPoint){this._endPoint=endPoint;this.resetResources()} + setLayer(identifier){this._layerIdentifier=identifier;this.resetResources()} + setTileMatrixSet(identifier){this._tileMatrixSetIdentifier=identifier;this.resetResources()} + setStyle(identifier){this._style=identifier;this.resetResources()} + setDimensionValue(dimension,value){this._dimensionValues.set(dimension,value);this.resetResources()} + getLayers(){if(this._capabilities!==null){return this._capabilities.layers}else{return new Map()}} + getMinLevel(){return this._minLevel} + setMinLevel(minLevel){this._minLevel=minLevel} + getMaxLevel(){return this._maxLevel} + setMaxLevel(maxLevel){this._maxLevel=maxLevel} + getTilesLoadedPromise(){return this._tilesLoadedPromise||Promise.resolve()} + setSpheroidReference(nameOrTypeIndex){if(typeof nameOrTypeIndex==='string'){this._spheroidComponentRef.setByName(this.getEntity().getName(),nameOrTypeIndex)}else{this._spheroidComponentRef.setByType(this.getEntity().getName(),'spheroid',nameOrTypeIndex)}} + __getLayer(){return this._layer} + __getTileMatrixSet(){return this._tileMatrixSet} + __getTileUrl(){return this._tileUrl} + __getLayerBounds(){if(this._layer!==null){return this._layer.boundingBox}else{return null}} + __getMaxLevel(){return this._maxLevel} + __getMinLevel(){return this._minLevel} + __getSplitJoinFactor(){return this._splitJoinThresholdFactor} + __getTilePixelSize(){return this._tilePixelSize} + __setTilePixelSize(tilePixelSize){this._tilePixelSize=tilePixelSize} + __getLoadsThisFrame(){return this._loadsThisFrame} + __incLoadsThisFrame(){this._loadsThisFrame+=1} + __getCameraPositions(){return this._cameraPositions} + __getSpheroidComponent(){return this._spheroidComponentRef.get()} + __destroy(){const spheroidComponent=this._spheroidComponentRef.get();if(spheroidComponent!==null){spheroidComponent.removeChangedCallback(this._spheroidChangedCallback)} + super.__destroy()} + __update(){this._spheroidComponentRef.update();if(this._rootTile===null){return} + while(this._cameraPositions.length>this._engine.getNumViewports()){this._cameraPositions.pop()} + while(this._cameraPositions.length{this._transitionsCompleteCallback=resolve})} + if(this._tilesLoadedPromise!==null&&!transitioning){const callback=this._transitionsCompleteCallback;this._tilesLoadedPromise=null;this._transitionsCompleteCallback=null;callback()}} + __prepareForRender(camera){pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setOrientationToEntity(this.getThreeJsObjects(),this.getEntity());pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.setPositionToEntity(this.getThreeJsObjects(),this.getEntity(),camera);const atmosphere=this._atmosphereComponentRef.get();pioneer__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.setUniforms(this.getThreeJsMaterials(),camera,this.getEntity(),this._shadowEntities,atmosphere,!0)} + async __loadResources(){if(this._endPoint!==''){this._capabilities=new _wmts__WEBPACK_IMPORTED_MODULE_1__.Capabilities(this._endPoint,this._engine);await this._capabilities.readyPromise;let layerIdentifier=this._layerIdentifier;if(layerIdentifier===''){const layers=this._capabilities.layers;if(layers.size===1){for(const[,identifier]of layers){layerIdentifier=identifier}}} + if(layerIdentifier===''){return} + this._layer=this._capabilities.getLayer(layerIdentifier);if(this._layer===null){throw new Error('Invalid layer: "'+layerIdentifier+'".')} + let tileMatrixSetIdentifier=this._tileMatrixSetIdentifier;if(tileMatrixSetIdentifier===''){const tileMatrixSets=this._layer.tileMatrixSets;if(tileMatrixSets.size===1){for(const identifier of tileMatrixSets){tileMatrixSetIdentifier=identifier}}} + this._tileMatrixSet=this._capabilities.getTileMatrixSet(tileMatrixSetIdentifier);if(this._tileMatrixSet===null){throw new Error('Invalid tile matrix set: "'+tileMatrixSetIdentifier+'".')} + await this._tileMatrixSet.readyPromise;const rootTileBounds=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Rect();rootTileBounds.copy(this._tileMatrixSet.boundingBox);if(this._tileMatrixSet.getNumTiles(0).x===1){rootTileBounds.size.x*=2.0} + if(this._tileMatrixSet.getNumTiles(0).y===1){rootTileBounds.origin.y-=rootTileBounds.size.y;rootTileBounds.size.y*=2.0} + let style=this._style;if(style===''){style=this._layer.defaultStyle} + for(const[identifier,defaultValue]of this._layer.dimensions){if(!this._dimensionValues.has(identifier)){this._dimensionValues.set(identifier,defaultValue)}} + this._tileUrl=this._layer.url;this._tileUrl=this._tileUrl.replace('{TileMatrixSet}',this._tileMatrixSet.identifier);this._tileUrl=this._tileUrl.replace('{Style}',style);this._dimensionValues.forEach((value,dimension)=>{this._tileUrl=this._tileUrl.replace('{'+dimension+'}',value)});this._rootTile=new WMTSTile(this,null,-1,0,0,rootTileBounds)}} + __unloadResources(){this._capabilities=null;this._layer=null;this._tileMatrixSet=null;this._tileUrl='';this._rootTile.destroy();this._rootTile=null} + _spheroidRefChangedCallback(oldRef,newRef){if(oldRef!==null){oldRef.removeChangedCallback(this._spheroidChangedCallback)} + if(newRef!==null){newRef.addChangedCallback(this._spheroidChangedCallback)} + this._spheroidChangedCallback()} + _spheroidChangedCallback(){const spheroidComponent=this._spheroidComponentRef.get();if(spheroidComponent!==null){this.__setRadius(Math.max(spheroidComponent.getEquatorialRadius(),spheroidComponent.getPolarRadius()))}else{this.__setRadius(0)} + this.resetResources()}} + class WMTSTile extends pioneer__WEBPACK_IMPORTED_MODULE_0__.Tile{constructor(component,parent,level,row,col,tileBounds){super(parent);this._component=component;this._level=level;this._row=row;this._col=col;this._tileBounds=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Rect();this._tileBounds.copy(tileBounds);this._center=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();this._radius=0;this._threeJsMaterial=null;this._threeJsObject=null;const spheroid=component.__getSpheroidComponent();const tileMatrixSet=this._component.__getTileMatrixSet();const originXYZ=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();tileMatrixSet.crsUnitsToXYZ(originXYZ,this._tileBounds.origin,spheroid);const end=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2();end.add(this._tileBounds.origin,this._tileBounds.size);const endXYZ=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();tileMatrixSet.crsUnitsToXYZ(endXYZ,end,spheroid);const tileBoundsCenter=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector2();tileBoundsCenter.addMult(this._tileBounds.origin,this._tileBounds.size,0.5);tileMatrixSet.crsUnitsToXYZ(this._center,tileBoundsCenter,spheroid);const min=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();const max=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();min.x=Math.min(originXYZ.x,endXYZ.x,this._center.x);min.y=Math.min(originXYZ.y,endXYZ.y,this._center.y);min.z=Math.min(originXYZ.z,endXYZ.z,this._center.z);max.x=Math.max(originXYZ.x,endXYZ.x,this._center.x);max.y=Math.max(originXYZ.y,endXYZ.y,this._center.y);max.z=Math.max(originXYZ.z,endXYZ.z,this._center.z);this._center.add(min,max);this._center.mult(this._center,0.5);const diagonal=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3();diagonal.sub(this._center,min);this._radius=diagonal.magnitude()} + createNewTile(parent,row,col){const newLevel=parent._level+1;const newRow=parent._row*2+row;const newCol=parent._col*2+col;const numTiles=parent._component.__getTileMatrixSet().getNumTiles(parent._level+1);if(newRow>=numTiles.y||newCol>=numTiles.x){return null} + const tileBounds=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Rect();tileBounds.origin.set(parent._tileBounds.origin.x+col*0.5*parent._tileBounds.size.x,parent._tileBounds.origin.y+(1-row)*0.5*parent._tileBounds.size.y);tileBounds.size.set(0.5*parent._tileBounds.size.x,0.5*parent._tileBounds.size.y);return new WMTSTile(parent._component,parent,newLevel,newRow,newCol,tileBounds)} + checkSplit(){if(this._level>=this._component.__getTileMatrixSet().numLevels-1){return!1} + if(!this._tileBounds.intersects(this._component.__getLayerBounds())){return!1} + if(this._level>=this._component.__getMaxLevel()){return!1} + if(this._component.__getLoadsThisFrame()>=1){return!1} + if(this._level=1){return!1} + if(this._level>this._component.__getMaxLevel()){return!0} + if(this._level<=this._component.__getMinLevel()){return!1} + let tilePixelSize=this._component.__getTilePixelSize();if(tilePixelSize===undefined&&this._threeJsMaterial!==null){tilePixelSize=this._threeJsMaterial.uniforms.colorTexture.value.image.width;this._component.__setTilePixelSize(tilePixelSize)} + return this._getNearestDistance()>this._component.__getSplitJoinFactor()*this._radius*4/tilePixelSize} + async load(){if(this._level===-1){return Promise.resolve()} + this._component.__incLoadsThisFrame();if(this._threeJsMaterial!==null){throw new Error('Tile already has material.')} + if(this._tileBounds.intersects(this._component.__getLayerBounds())){this._threeJsMaterial=pioneer__WEBPACK_IMPORTED_MODULE_0__.MaterialUtils.get();this._component.getThreeJsMaterials().push(this._threeJsMaterial);let url=this._component.__getTileUrl();url=url.replace('{TileMatrix}',''+this._level);url=url.replace('{TileRow}',''+this._row);url=url.replace('{TileCol}',''+this._col);try{await pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTextureIntoUniform(this._component,this._threeJsMaterial,'colorTexture',url,!1,!1)}catch(e){await pioneer__WEBPACK_IMPORTED_MODULE_0__.ThreeJsHelper.loadTextureIntoUniform(this._component,this._threeJsMaterial,'colorTexture','gray',!1,!1)}}} + async unload(){if(this._level===-1){return} + if(this._threeJsMaterial!==null){const materials=this._component.getThreeJsMaterials();for(let i=0,l=materials.length;idistance){nearestDistance=distance}} + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(diff);return nearestDistance} + toString(){return this._level+'-'+this._row+'-'+this._col}}}),"../pioneer/scripts/src/controllers/keyframe_pointing_controller.js": + /*!**************************************************************************!*\ + !*** ../pioneer/scripts/src/controllers/keyframe_pointing_controller.js ***! + \**************************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"KeyframePointingController":function(){return KeyframePointingController}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class KeyframePointingController extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._keyframes=[];this._direction=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(1,0,0);this.addModifiedState('orientation')} + setKeyframes(keyframes){for(let i=0,l=this._keyframes.length;ia[0]-b[0])} + setDirection(direction){this._direction.copy(direction)} + __updateOrientationAtTime(orientation,time){if(orientation.isNaN()){orientation.copy(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + this._getNewOrientation(orientation,time,orientation)} + __update(){if(this._keyframes.length===0){return} + const entity=this.getEntity();const time=entity.getScene().getEngine().getTime();if(entity.getOrientation().isNaN()){entity.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + const newOrientation=pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();this._getNewOrientation(newOrientation,time,entity.getOrientation());entity.setOrientation(newOrientation);pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation)} + _getNewOrientation(newOrientation,time,oldOrientation){const index=pioneer__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time,this._keyframes,(a,time)=>a[0]0){prevIndex=index-1;nextIndex=index} + const prevKeyframe=this._keyframes[prevIndex];const nextKeyframe=this._keyframes[nextIndex];const u=(nextKeyframe[0]>prevKeyframe[0])?(time-prevKeyframe[0])/(nextKeyframe[0]-prevKeyframe[0]):0;const prevDirection=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const nextDirection=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();this._getDirection(prevDirection,time,prevKeyframe[1]);this._getDirection(nextDirection,time,nextKeyframe[1]);nextDirection.slerp(prevDirection,nextDirection,u);nextDirection.normalize(nextDirection);prevDirection.rotate(oldOrientation,this._direction);const rotation=pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();rotation.setFromVectorFromTo(prevDirection,nextDirection);newOrientation.mult(rotation,oldOrientation);pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(nextDirection);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(prevDirection)} + _getDirection(outDirection,time,type){const entity=this.getEntity();const isNeg=type.startsWith('-');if(isNeg){type=type.substring(1)} + if(type.startsWith('velocity')){type=type.substring(8);if(type.startsWith(' rel ')){type=type.substring(5);const relEntity=entity.getScene().getEntity(type);if(relEntity!==null){entity.getVelocityRelativeToEntity(outDirection,pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,relEntity,time)}}else{entity.getVelocityAtTime(outDirection,time)}}else{const otherEntity=entity.getScene().getEntity(type);if(otherEntity!==null){otherEntity.getPositionRelativeToEntity(outDirection,pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero,entity,time)}else{outDirection.copy(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3[NaN])}} + outDirection.normalize(outDirection);if(isNeg){outDirection.mult(outDirection,-1)}}}}),"../pioneer/scripts/src/controllers/keyframe_spin_controller.js": + /*!**********************************************************************!*\ + !*** ../pioneer/scripts/src/controllers/keyframe_spin_controller.js ***! + \**********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"KeyframeSpinController":function(){return KeyframeSpinController}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class KeyframeSpinController extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._keyframes=[];this._axis=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(1,0,0);this._startingAngle=0;this.addModifiedState('orientation')} + setKeyframes(keyframes){this._keyframes=[];let lastAngle=0;for(let i=0,l=keyframes.length;i0){lastAngle=pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(lastAngle+(keyframes[i][0]-keyframes[i-1][0])*(keyframes[i-1][1]+keyframes[i][1])*0.5,0,2*Math.PI)} + this._keyframes.push([keyframes[i][0],keyframes[i][1],lastAngle])} + this._keyframes.sort((a,b)=>a[0]-b[0])} + setAxis(axis){this._axis.copy(axis)} + setStartingAngle(angle){this._startingAngle=angle} + __updateOrientationAtTime(orientation,time){if(orientation.isNaN()){orientation.copy(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + this._getNewOrientation(orientation,time,orientation)} + __update(){if(this._keyframes.length===0){return} + const entity=this.getEntity();const time=entity.getScene().getEngine().getTime();if(entity.getOrientation().isNaN()){entity.setOrientation(pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity)} + const newOrientation=pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();this._getNewOrientation(newOrientation,time,entity.getOrientation());entity.setOrientation(newOrientation);pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(newOrientation)} + _getNewOrientation(newOrientation,time,oldOrientation){const index=pioneer__WEBPACK_IMPORTED_MODULE_0__.Sort.getIndex(time,this._keyframes,(a,time)=>a[0]0){prevIndex=index-1;nextIndex=index} + const prevKeyframe=this._keyframes[prevIndex];const nextKeyframe=this._keyframes[nextIndex];const u=(nextKeyframe[0]>prevKeyframe[0])?(time-prevKeyframe[0])/(nextKeyframe[0]-prevKeyframe[0]):0;const angle=pioneer__WEBPACK_IMPORTED_MODULE_0__.MathUtils.wrap(this._startingAngle+prevKeyframe[2]+(time-prevKeyframe[0])*(prevKeyframe[1]+u*nextKeyframe[1])/(1+u),0,2*Math.PI);const axis=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();axis.rotate(oldOrientation,this._axis);const rotation=pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();rotation.setFromAxisAngle(axis,angle);newOrientation.mult(rotation,oldOrientation);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(axis);pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(rotation)}}}),"../pioneer/scripts/src/controllers/position_sum_controller.js": + /*!*********************************************************************!*\ + !*** ../pioneer/scripts/src/controllers/position_sum_controller.js ***! + \*********************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"PositionSumController":function(){return PositionSumController}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class PositionSumController extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._entities=new pioneer__WEBPACK_IMPORTED_MODULE_0__.FastMap();this.addModifiedState('position')} + addEntity(entityName,mult,add){const ref=new pioneer__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());ref.setName(entityName);this._entities.set(entityName,{ref,mult,add});this.addDependentState(entityName,'position')} + removeEntity(entityName){this._entities.delete(entityName);this.removeDependentState(entityName,'position')} + setEntityParams(entityName,mult,add){if(!this._entities.has(entityName)){throw new Error(`The entity ${entityName} has not been previously added to the controller.`)} + const params=this._entities.get(entityName);if(mult!==undefined){params.mult=mult} + if(add!==undefined){params.add=add}} + __update(){const accumulatedPosition=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const position=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();accumulatedPosition.set(0,0,0);for(let i=0,l=this._entities.size;i0?entry.add/magnitude:0))} + this.getEntity().setPosition(accumulatedPosition);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(accumulatedPosition);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position)}}}),"../pioneer/scripts/src/controllers/zoom_fit_controller.js": + /*!*****************************************************************!*\ + !*** ../pioneer/scripts/src/controllers/zoom_fit_controller.js ***! + \*****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"ZoomFitController":function(){return ZoomFitController}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class ZoomFitController extends pioneer__WEBPACK_IMPORTED_MODULE_0__.BaseController{constructor(type,name,entity){super(type,name,entity);this._entities=new pioneer__WEBPACK_IMPORTED_MODULE_0__.FastMap();this._tightFit=!1;this._zoomOutOnly=!1;this._edgeSize=0;this.addModifiedState('position')} + addEntity(entityName){const ref=new pioneer__WEBPACK_IMPORTED_MODULE_0__.EntityRef(this.getEntity().getScene());ref.setName(entityName);this._entities.set(entityName,{ref});this.addDependentState(entityName,'position')} + removeEntity(entityName){this._entities.delete(entityName);this.removeDependentState(entityName,'position')} + setTightFit(tightFit){this._tightFit=tightFit} + setZoomOutOnly(zoomOutOnly){this._zoomOutOnly=zoomOutOnly} + setEdgeSize(edgeSize){this._edgeSize=edgeSize} + __update(){let tanHalfFov=1;const camera=this.getEntity().getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CameraComponent);if(camera!==null){const fieldOfView=Math.min(camera.getHorizontalFieldOfView(),camera.getVerticalFieldOfView());if(this._tightFit){tanHalfFov=Math.tan(fieldOfView/2.0)} + tanHalfFov=Math.tan(fieldOfView/2.0)} + const direction=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();direction.normalize(this.getEntity().getPosition());if(direction.magnitudeSqr()===0){this.getEntity().getOrientation().getAxis(direction,1);direction.neg(direction)} + if(direction.isNaN()){direction.copy(pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.YAxisNeg)} + const factor=(1+this._edgeSize/(0.5-this._edgeSize))/tanHalfFov;let maxDistance=0;const position=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();for(let i=0,l=this._entities.size;ithis.getEntity().getPosition().magnitude()){direction.mult(direction,maxDistance);this.getEntity().setPosition(direction)} + pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(direction)}}}),"../pioneer/scripts/src/date_time.js": + /*!*******************************************!*\ + !*** ../pioneer/scripts/src/date_time.js ***! + \*******************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"DateTime":function(){return DateTime}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class DateTime{constructor(year=1,month=1,day=1,hour=0,minute=0,second=0,millisecond=0){this.year=year;this.month=month;this.day=day;this.hour=hour;this.minute=minute;this.second=second;this.millisecond=millisecond} + copy(dateTime){this.year=dateTime.year;this.month=dateTime.month;this.day=dateTime.day;this.hour=dateTime.hour;this.minute=dateTime.minute;this.second=dateTime.second;this.millisecond=dateTime.millisecond} + fromET(et){const unixTime=pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.etToUnix(et);_date.setTime(unixTime*1000.0);this.year=_date.getUTCFullYear();this.month=_date.getUTCMonth()+1;this.day=_date.getUTCDate();this.hour=_date.getUTCHours();this.minute=_date.getUTCMinutes();this.second=_date.getUTCSeconds();this.millisecond=_date.getUTCMilliseconds();for(let i=0,l=pioneer__WEBPACK_IMPORTED_MODULE_0__.TimeUtils.leapSeconds.length;ipassedDays+daysInMonth&&this.month<12){passedDays+=daysInMonth;this.month+=1;daysInMonth=this.getDaysInMonth()} + this.day=doy-passedDays} + toDOY(){const originalMonth=this.month;let doy=0;for(this.month=1;this.month5){this.month=parseInt(text.substring(5,7))}else{this.month=1} + if(text.length>8){this.day=parseInt(text.substring(8,10))}else{this.day=1} + if(text.length>11){this.hour=parseInt(text.substring(11,13));this.minute=parseInt(text.substring(14,16))}else{this.hour=0;this.minute=0} + if(text.length>17){this.second=parseInt(text.substring(17,19))}else{this.second=0} + if(text.length>20){this.millisecond=parseInt(text.substring(20))*Math.pow(10,23-text.length)}else{this.millisecond=0}} + parseDOY(text){const year=parseInt(text.substring(0,4));let doy=1;if(text.length>5){doy=parseInt(text.substring(5,8))} + this.fromDOY(year,doy);if(text.length>9){this.hour=parseInt(text.substring(9,11));this.minute=parseInt(text.substring(12,14))}else{this.hour=0;this.minute=0} + if(text.length>15){this.second=parseInt(text.substring(15,17))}else{this.second=0} + if(text.length>18){this.millisecond=parseInt(text.substring(18))*Math.pow(10,21-text.length)}else{this.millisecond=0}} + toString(){return `${this.year.toString().padStart(4, '0')}-${this.month.toString().padStart(2, '0')}-${this.day.toString().padStart(2, '0')} ${this.hour.toString().padStart(2, '0')}:${this.minute.toString().padStart(2, '0')}:${this.second.toString().padStart(2, '0')}.${Math.floor(this.millisecond * 1e3).toString().padStart(6, '0')}`} + toStringDOY(){return `${this.year.toString().padStart(4, '0')}-${this.toDOY().toString().padStart(3, '0')}`}};const _daysInMonth=[31,28,31,30,31,30,31,31,30,31,30,31];const _date=new Date()}),"../pioneer/scripts/src/entities/comets.js": + /*!*************************************************!*\ + !*** ../pioneer/scripts/src/entities/comets.js ***! + \*************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var _entity_utils__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./entity_utils */"../pioneer/scripts/src/entities/entity_utils.js");var pioneer__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({'1i_oumuamua':{groups:['comets'],occlusionRadius:0.030,extentsRadius:0.225,label:'ʻOumuamua',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/1i_oumuamua/oumuamua.gltf'},comet:{},controllers:[{type:'dynamo',url:'1i_oumuamua/sun/orb'},{type:'spin',axis:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.57735026919,0.57735026919,0.57735026919),periodInHours:8.10}]},'1p_halley':{groups:['comets'],radius:6.0,label:'Halley (1P/Halley)',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[6,6,6]},comet:{},controllers:[{type:'dynamo',url:'1p_halley/sun/orb'},{type:'spin',periodInHours:52,axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,axisInFrameSpace:!1}]},'103p_hartley_2':{groups:['comets'],radius:2.0,label:'Hartley 2 (103P/Hartley)',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/103p_hartley_2/hartley_2.gltf'},comet:{},controllers:[{type:'dynamo',url:'103p_hartley_2/sun/orb'},{type:'dynamo',url:'103p_hartley_2/ori'}]},'9p_tempel_1':{groups:['comets'],radius:5.0,label:'Tempel 1 (9P/Tempel)',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/9p_tempel_1/9p_tempel.gltf',rotate:[{y:90}]},comet:{},controllers:[{type:'dynamo',url:'9p_tempel_1/sun/orb'},{type:'dynamo',url:'9p_tempel_1/ori'}]},'81p_wild_2':{groups:['comets'],radius:2.5,label:'Wild 2 (81P/Wild)',parents:[[Number.NEGATIVE_INFINITY,'sun'],[-800047271,'jupiter'],[-797029475,'sun']],trail:{length:undefined,lengthCoverages:[[1356976800,Number.NEGATIVE_INFINITY,-611927948.817],[189345600,-611927948.817,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.5,2.5,2.5]},comet:{},controllers:[{type:'dynamo',url:'81p_wild_2/sun/1/orb'},{type:'dynamo',url:'81p_wild_2/jupiter/orb'},{type:'dynamo',url:'81p_wild_2/sun/2/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}]},'67p_churyumov_gerasimenko':{groups:['comets'],radius:4.1,label:'Churyumov–Gerasimenko (67P/C-G)',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/67p_churyumov_gerasimenko/67p_churyumov_gerasimenko.gltf',rotate:[{x:90}],scale:0.00124},comet:{},controllers:[{type:'dynamo',url:'67p_churyumov_gerasimenko/sun/orb'},{type:'spin',axis:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.15191127889562422,0.404099951782066,0.9020123016422935),axisInFrameSpace:!1,periodInHours:12.0550932412},{type:'dynamo',url:'67p_churyumov_gerasimenko/ori'}],postCreateFunction:(entity)=>{entity.setOrientation(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.26732846830704055,0.017948528101847026,0.22012096235022358,0.9379552773483394));_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,1,1,100,1,1,[1,-0.25,1.2],[0,0,1]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,2,0.5,100,1,1,[-1.2,-0.25,0.6],[0.2,-0.5,1]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,1,0.07,100,1,10,[-1.2,0.1,0.6],[0.2,-0.5,1]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,1,1,100,1,1,[-0.8,0.75,1.0],[0.2,0.5,1]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,1,0.5,100,1,1,[-0.8,0.35,-1.0],[0.2,0.25,-1])}},'19p_borrelly':{groups:['comets'],radius:2.4,label:'Borrelly (19P/Borrelly)',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/19p_borrelly/borrelly.gltf'},comet:{},controllers:[{type:'dynamo',url:'19p_borrelly/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}]},c_1995_o1:{groups:['comets'],radius:5.0,label:'Hale-Bopp (C/1995 O1)',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[5,5,5]},comet:{},controllers:[{type:'dynamo',url:'c_1995_o1/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,axisInFrameSpace:!1,periodInHours:11.766666666}]},c_2010_x1:{groups:['comets'],radius:5.0,label:'Elenin (C/2010 X1)',parents:[[Number.NEGATIVE_INFINITY,'sun'],[370699266.182,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[5,5,5]},comet:{},controllers:[{type:'dynamo',url:'c_2010_x1/sun/pos'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}]},c_2012_s1:{groups:['comets'],radius:3.0,label:'ISON (C/2012 S1)',parents:[[Number.NEGATIVE_INFINITY,'sun'],[440596867.184,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[3,3,3]},comet:{},controllers:[{type:'dynamo',url:'c_2012_s1/sun/pos'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}]},c_2013_a1:{groups:['comets'],radius:5.0,label:'Siding Spring (C/2013 A1)',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[5,5,5]},comet:{},controllers:[{type:'dynamo',url:'c_2013_a1/sun/pos'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,axisInFrameSpace:!1,periodInHours:8}]},c_2019_y4:{groups:['comets'],radius:3.0,label:'ATLAS (C/2019 Y4)',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[3,3,3]},comet:{},controllers:[{type:'dynamo',url:'c_2019_y4/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}]},c_2020_f3:{groups:['comets'],radius:6.0,label:'NEOWISE (C/2020 F3)',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[6,6,6]},comet:{},controllers:[{type:'dynamo',url:'c_2020_f3/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,axisInFrameSpace:!1,periodInHours:7.58}]}})}),"../pioneer/scripts/src/entities/comparison.js": + /*!*****************************************************!*\ + !*** ../pioneer/scripts/src/entities/comparison.js ***! + \*****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({rose_bowl:{groups:['comparison'],radius:0.15,label:'Rose Bowl',parents:[],model:{url:'$STATIC_ASSETS_URL/models/comparison/rose_bowl/rose_bowl.gltf',rotate:[{x:90},{z:-90}]},controllers:[{type:'fixed',position:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero,orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},school_bus:{groups:['comparison'],radius:0.0065,label:'School bus',parents:[],model:{url:'$STATIC_ASSETS_URL/models/comparison/school_bus/school_bus.gltf',rotate:[{x:90},{z:-90}]},controllers:[{type:'fixed',position:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero,orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},scientist:{groups:['comparison'],radius:0.000835,label:'Scientist',parents:[],model:{url:'$STATIC_ASSETS_URL/models/comparison/scientist/scientist.gltf',rotate:[{x:90}]},controllers:[{type:'fixed',position:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero,orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]}})}),"../pioneer/scripts/src/entities/earth_moon.js": + /*!*****************************************************!*\ + !*** ../pioneer/scripts/src/entities/earth_moon.js ***! + \*****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({moon:{groups:['earth','moons'],radius:1737.4,label:'Moon',parents:[[Number.NEGATIVE_INFINITY,'earth']],trail:{length:undefined,color:[0.0,0.6,0.8,0.7]},spheroid:{equatorialRadius:1737.4,polarRadius:1737.4,planetographic:!0},spheroidLOD:{features:['normalMap','shadowEntities'],textures:{color:{url:'moon/color_$SIZE_$FACE.png',sizes:[16,512,4096]},normal:{url:'moon/normal_$SIZE_$FACE.png',sizes:[16,512,2048]}},shadowEntities:['earth']},controllers:[{type:'dynamo',url:'moon/earth/orb'},{type:'dynamo',url:'moon/ori'}]}})}),"../pioneer/scripts/src/entities/earth_spacecraft.js": + /*!***********************************************************!*\ + !*** ../pioneer/scripts/src/entities/earth_spacecraft.js ***! + \***********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var _entity_utils__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./entity_utils */"../pioneer/scripts/src/entities/entity_utils.js");var pioneer__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({sc_3d_winds:{groups:['earth','spacecraft'],occlusionRadius:0.00200,extentsRadius:0.00250,label:'3D-Winds',parents:[[347025366.1839032,'earth']],trail:{length:5573.0},controllers:[{type:'dynamo',url:'sc_3d_winds'}]},sc_ace:{groups:['earth','spacecraft'],occlusionRadius:0.0008,extentsRadius:0.0023,label:'ACE',parents:[[265550465.18489534,'earth'],[694267269.1839212,'']],trail:{length:31715490.0},model:{url:'$STATIC_ASSETS_URL/models/sc_ace/ace.gltf',shadowEntities:['earth','moon']},controllers:[{type:'animdata',url:'sc_ace',dataType:'pos'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg,periodInHours:0.0033}]},sc_acrimsat:{groups:['earth','spacecraft'],radius:0.0015,label:'ACRIMSAT',parents:[[-963797,'earth'],[459950467,'']],trail:{length:5933.5},model:{url:'$STATIC_ASSETS_URL/models/sc_acrimsat/acrimsat.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_acrimsat'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg,periodInHours:0.00238}]},sc_aim:{groups:['earth','spacecraft'],occlusionRadius:0.00070,extentsRadius:0.0014,label:'AIM',parents:[[344589947.18311954,'earth']],trail:{length:5788.83},controllers:[{type:'dynamo',url:'sc_aim'}]},sc_aqua:{groups:['earth','spacecraft'],occlusionRadius:0.00400,extentsRadius:0.015,label:'Aqua',parents:[[73781738,'earth']],trail:{length:5933.5},model:{url:'$STATIC_ASSETS_URL/models/sc_aqua/Aqua.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_aqua'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_aqua',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_ascends:{groups:['earth','spacecraft'],radius:0.004,label:'ASCENDS',parents:[[347025366.1839032,'earth']],trail:{length:5573.0},controllers:[{type:'dynamo',url:'sc_ascends'}]},sc_aura:{groups:['earth','spacecraft'],occlusionRadius:0.003450,extentsRadius:0.017,label:'Aura',parents:[[143161358,'earth']],trail:{length:5933.5},model:{url:'$STATIC_ASSETS_URL/models/sc_aura/Aura.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_aura'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_aura',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_c_nofs:{groups:['earth','spacecraft'],radius:0.004,label:'C/NOFS',parents:[[352800006.1854904,'earth'],[502051928.18300515,'']],trail:{length:5573.0},controllers:[{type:'dynamo',url:'sc_c_nofs'}]},sc_calipso:{groups:['earth','spacecraft'],occlusionRadius:0.001650,extentsRadius:0.005,label:'CALIPSO',parents:[[199506047,'earth']],trail:{length:5933.0},model:{url:'$STATIC_ASSETS_URL/models/sc_calipso/calipso.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_calipso'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_calipso',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}}]},sc_chandra:{groups:['earth','spacecraft'],occlusionRadius:0.0059,extentsRadius:0.010,label:'Chandra',parents:[[339465600,'earth'],[709344000,'']],trail:{length:228505.5},model:{url:'$STATIC_ASSETS_URL/models/sc_chandra/chandra.gltf',shadowEntities:['earth','moon']},controllers:[{type:'animdata',url:'sc_chandra/earth/all',dataType:'pos'},{type:'align',primary:{type:'point',target:'sun',axis:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.70710678118,-0.70710678118,0)}}]},sc_clarreo:{groups:['earth','spacecraft'],radius:0.004,label:'CLARREO',parents:[[347025366.1839032,'earth']],trail:{length:5573.0},controllers:[{type:'dynamo',url:'sc_clarreo'}]},sc_cloudsat:{groups:['earth','spacecraft'],occlusionRadius:0.0025,extentsRadius:0.0025,label:'CloudSat',parents:[[199491286,'earth']],trail:{length:5933.5},model:{url:'$STATIC_ASSETS_URL/models/sc_cloudsat/CloudSat.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cloudsat'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_cloudsat',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_cluster_ii_fm5:{groups:['earth','spacecraft'],occlusionRadius:0.001450,extentsRadius:0.00435,label:'Rumba',parents:[[19105314,'earth']],trail:{length:195541.5},model:{url:'$STATIC_ASSETS_URL/models/sc_cluster_ii/cluster_ii.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cluster_ii_fm5'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_cluster_ii_fm5',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_cluster_ii_fm6:{groups:['earth','spacecraft'],occlusionRadius:0.001450,extentsRadius:0.00435,label:'Salsa',parents:[[17028089,'earth']],trail:{length:195351.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cluster_ii/cluster_ii.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cluster_ii_fm6'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_cluster_ii_fm6',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_cluster_ii_fm7:{groups:['earth','spacecraft'],occlusionRadius:0.001450,extentsRadius:0.00435,label:'Samba',parents:[[17028093,'earth']],trail:{length:195316.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cluster_ii/cluster_ii.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cluster_ii_fm7'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_cluster_ii_fm7',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_cluster_ii_fm8:{groups:['earth','spacecraft'],occlusionRadius:0.001450,extentsRadius:0.00435,label:'Tango',parents:[[19105052,'earth']],trail:{length:195388.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cluster_ii/cluster_ii.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cluster_ii_fm8'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_cluster_ii_fm8',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_cygnss_1:{groups:['earth','spacecraft'],radius:0.0008,label:'CYGNSS 1',parents:[[548415404.1851876,'earth']],trail:{length:5573.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cygnss_1'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_cygnss_1',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg}}]},sc_cygnss_2:{groups:['earth','spacecraft'],radius:0.0008,label:'CYGNSS 2',parents:[[548415404.1851876,'earth']],trail:{length:5573.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cygnss_2'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_cygnss_2',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg}}]},sc_cygnss_3:{groups:['earth','spacecraft'],radius:0.0008,label:'CYGNSS 3',parents:[[548415404.1851876,'earth']],trail:{length:5573.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cygnss_3'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_cygnss_3',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg}}]},sc_cygnss_4:{groups:['earth','spacecraft'],radius:0.0008,label:'CYGNSS 4',parents:[[548415404.1851876,'earth']],trail:{length:5573.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cygnss_4'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_cygnss_4',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg}}]},sc_cygnss_5:{groups:['earth','spacecraft'],radius:0.0008,label:'CYGNSS 5',parents:[[548415404.1851876,'earth']],trail:{length:5573.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cygnss_5'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_cygnss_5',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg}}]},sc_cygnss_6:{groups:['earth','spacecraft'],radius:0.0008,label:'CYGNSS 6',parents:[[548415404.1851876,'earth'],[722736069,'']],trail:{length:5573.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cygnss_6'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_cygnss_6',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg}}]},sc_cygnss_7:{groups:['earth','spacecraft'],radius:0.0008,label:'CYGNSS 7',parents:[[548415404.1851876,'earth']],trail:{length:5573.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cygnss_7'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_cygnss_7',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg}}]},sc_cygnss_8:{groups:['earth','spacecraft'],radius:0.0008,label:'CYGNSS 8',parents:[[548415404.1851876,'earth']],trail:{length:5573.0},model:{url:'$STATIC_ASSETS_URL/models/sc_cygnss/CYGNSS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_cygnss_8'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_cygnss_8',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg}}]},sc_dscovr:{groups:['earth','spacecraft'],occlusionRadius:0.00090,extentsRadius:0.0020,label:'DSCOVR',parents:[[476711467.18497694,'earth']],trail:{length:60*60*24*365},model:{url:'$STATIC_ASSETS_URL/models/sc_dscovr/dscovr.gltf',shadowEntities:['earth','moon']},controllers:[{type:'animdata',url:'sc_dscovr/earth/all',dataType:'pos'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg},secondary:{type:'velocity',target:'sc_dscovr',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg}}]},sc_eo_1:{groups:['earth','spacecraft'],occlusionRadius:0.0030,extentsRadius:0.0010,label:'EO-1',parents:[[344589947.18311954,'earth'],[544104069.186,'']],trail:{length:5933.33},model:{url:'$STATIC_ASSETS_URL/models/sc_eo_1/eo-1.gltf',rotate:[{y:45}],shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_eo_1'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'velocity',target:'sc_eo_1',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg}}]},sc_explorer_1:{groups:['earth','spacecraft'],occlusionRadius:0.0010,extentsRadius:0.0010,label:'Explorer 1',parents:[[-1322726967,'earth'],[-939025103,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_explorer_1_v2/explorer_1.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_explorer_1/earth'},{type:'align',primary:{type:'velocity',target:'sc_explorer_1',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg,periodInHours:0.000022}]},sc_face:{groups:['earth','spacecraft'],radius:0.004,label:'FACE',parents:[[347025366.1839032,'earth'],[631022168.1838934,'']],trail:{length:5933.33},controllers:[{type:'dynamo',url:'sc_face'}]},sc_fgrst:{groups:['earth','spacecraft'],occlusionRadius:0.00140,extentsRadius:0.0040,label:'FGRST',parents:[[344589947.18311954,'earth'],[661006268.1833516,'']],trail:{length:5733.0},controllers:[{type:'dynamo',url:'sc_fgrst'}]},sc_gacm:{groups:['earth','spacecraft'],radius:0.004,label:'GACM',parents:[[347025366.1839032,'earth']],trail:{length:5733.0},controllers:[{type:'dynamo',url:'sc_gacm'}]},sc_galex:{groups:['earth','spacecraft'],occlusionRadius:0.0010,extentsRadius:0.00140,label:'GALEX',parents:[[352800006.1854904,'earth'],[425718607.184,'']],trail:{length:5733.0},controllers:[{type:'dynamo',url:'sc_galex'}]},sc_geo_cape:{groups:['earth','spacecraft'],radius:0.004,label:'GEO-CAPE',parents:[[347025366.1839032,'earth']],trail:{length:5733.0},controllers:[{type:'dynamo',url:'sc_geo_cape'}]},sc_geotail:{groups:['earth','spacecraft'],occlusionRadius:0.0018,extentsRadius:0.003,label:'Geotail',parents:[[-234758765,'earth'],[722891591,'']],trail:{length:450372.0},model:{url:'$STATIC_ASSETS_URL/models/sc_geotail/geotail.gltf',shadowEntities:['earth']},controllers:[{type:'dynamo',url:'sc_geotail/earth/orb'},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.662,0.749,0,0)},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis,periodInHours:0.00083333333,relativeToTime:0}]},sc_goes_12:{groups:['earth','spacecraft'],radius:0.003,label:'GOES 12',parents:[[344589947.18311954,'earth'],[661006268.1833516,'']],trail:{length:5733.0},controllers:[{type:'dynamo',url:'sc_goes_12'}]},sc_goes_13:{groups:['earth','spacecraft'],radius:0.003,label:'GOES 13',parents:[[344589947.18311954,'earth']],trail:{length:5733.0},controllers:[{type:'dynamo',url:'sc_goes_13'}]},sc_goes_14:{groups:['earth','spacecraft'],radius:0.003,label:'GOES 14',parents:[[344589947.18311954,'earth']],trail:{length:5733.0},controllers:[{type:'dynamo',url:'sc_goes_14'}]},sc_goes_15:{groups:['earth','spacecraft'],radius:0.003,label:'GOES 15',parents:[[344589947.18311954,'earth']],trail:{length:5733.0},controllers:[{type:'dynamo',url:'sc_goes_15'}]},sc_gpm:{groups:['earth','spacecraft'],occlusionRadius:0.0020,extentsRadius:0.007,label:'GPM',parents:[[629484755.7856493,'earth']],trail:{length:5549.5},model:{url:'$STATIC_ASSETS_URL/models/sc_gpm/GPM.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_gpm'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_gpm',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}],postCreateFunction:(entity)=>{const spin=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpinController);spin.setJoint('GPM_antenna');spin.setRate(pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.degToRad(192));spin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg,!0);spin.setClampedToRealTime(!0)}},sc_grace_1:{groups:['earth','spacecraft'],occlusionRadius:0.0015,extentsRadius:0.0019,label:'GRACE-1',parents:[[69656411.096817,'earth'],[562382552.2587994,'']],trail:{length:5575.0},model:{url:'$STATIC_ASSETS_URL/models/sc_grace/grace.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_grace_1/earth/orb'},{type:'align',primary:{type:'point',target:'sc_grace_2',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}},{type:'coverage',coverage:[Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY],update:(entity)=>{const microwave=(entity.getComponent('microwave'));const engine=entity.getScene().getEngine();const newOffset=pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.wrap(microwave.getTextureYOffset()-pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.clamp(engine.getTimeRate(),-1,+1)*engine.getDeltaTime(),0,1);microwave.setTextureYOffset(newOffset);const other=entity.getScene().getEntity('sc_grace_2');const shouldBeEnabled=other!==null&&other.getPosition().distance(entity.getPosition())<=3929;if(shouldBeEnabled!==microwave.isEnabled()){microwave.setEnabled(shouldBeEnabled)}}}],postCreateFunction:entity=>{const microwave=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ConnectedSpriteComponent,'microwave');microwave.setTextureUrl('$STATIC_ASSETS_URL/sprites/sine_wave.png');microwave.setEntity1('sc_grace_1');microwave.setEntity1Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0,-0.00165,0));microwave.setEntity2('sc_grace_2');microwave.setEntity2Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0,-0.00165,0));microwave.setWidths(0.0005,0.0005);microwave.setColorMultiplier(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(0.5,1.0,1.0));microwave.setTextureRepeat(!0);microwave.setTextureStretch(4)}},sc_grace_2:{groups:['earth','spacecraft'],occlusionRadius:0.0015,extentsRadius:0.0019,label:'GRACE-2',parents:[[69656411.096817,'earth'],[562382552.2588,'']],trail:{length:5575.0},model:{url:'$STATIC_ASSETS_URL/models/sc_grace/grace.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_grace_2/earth/orb'},{type:'align',primary:{type:'point',target:'sc_grace_1',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_grace_fo1:{groups:['earth','spacecraft'],occlusionRadius:0.0015,extentsRadius:0.0019,label:'GRACE-FO 1',parents:[[580290547.185,'earth']],trail:{length:5575.0},model:{url:'$STATIC_ASSETS_URL/models/sc_grace_fo/graceFO.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_grace_fo1'},{type:'align',primary:{type:'point',target:'sc_grace_fo2',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg},secondary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg}},{type:'coverage',coverage:[Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY],update:(entity)=>{const microwave=(entity.getComponent('microwave'));const engine=entity.getScene().getEngine();const newOffset=pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.wrap(microwave.getTextureYOffset()-pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.clamp(engine.getTimeRate(),-1,+1)*engine.getDeltaTime(),0,1);microwave.setTextureYOffset(newOffset);const other=entity.getScene().getEntity('sc_grace_fo2');const shouldBeEnabled=other!==null&&other.getPosition().distance(entity.getPosition())<=3929;if(shouldBeEnabled!==microwave.isEnabled()){const laser1=(entity.getComponent('laser1'));const laser2=(entity.getComponent('laser2'));microwave.setEnabled(shouldBeEnabled);laser1.setEnabled(shouldBeEnabled);laser2.setEnabled(shouldBeEnabled)}}}],postCreateFunction:entity=>{const microwave=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ConnectedSpriteComponent,'microwave');microwave.setTextureUrl('$STATIC_ASSETS_URL/sprites/sine_wave.png');microwave.setEntity1('sc_grace_fo1');microwave.setEntity1Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0,0,-0.00165));microwave.setEntity2('sc_grace_fo2');microwave.setEntity2Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0,0,-0.00165));microwave.setWidths(0.0005,0.0005);microwave.setColorMultiplier(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(0.5,1.0,1.0));microwave.setTextureRepeat(!0);microwave.setTextureStretch(4);const laser1=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ConnectedSpriteComponent,'laser1');laser1.setTextureUrl('$STATIC_ASSETS_URL/sprites/line.png');laser1.setEntity1('sc_grace_fo1');laser1.setEntity1Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(+0.0003,0.00015,-0.00165));laser1.setEntity2('sc_grace_fo2');laser1.setEntity2Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.0003,0.00015,-0.00165));laser1.setWidths(0.00002,0.00002);laser1.setColorMultiplier(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(1,0.24,0.64));laser1.setTextureRepeat(!1);const laser2=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ConnectedSpriteComponent,'laser2');laser2.setTextureUrl('$STATIC_ASSETS_URL/sprites/line.png');laser2.setEntity1('sc_grace_fo1');laser2.setEntity1Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.0003,0.00015,-0.00165));laser2.setEntity2('sc_grace_fo2');laser2.setEntity2Offset(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(+0.0003,0.00015,-0.00165));laser2.setWidths(0.00002,0.00002);laser2.setColorMultiplier(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(1,0.24,0.64));laser2.setTextureRepeat(!1)}},sc_grace_fo2:{groups:['earth','spacecraft'],occlusionRadius:0.0015,extentsRadius:0.0019,label:'GRACE-FO 2',parents:[[580290547.185,'earth']],trail:{length:5575.0},model:{url:'$STATIC_ASSETS_URL/models/sc_grace_fo/graceFO.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_grace_fo2'},{type:'align',primary:{type:'point',target:'sc_grace_fo1',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg},secondary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg}}]},sc_grifex:{groups:['earth','spacecraft'],occlusionRadius:0.000150,extentsRadius:0.00034,label:'GRIFEX',parents:[[476542806.1849232,'earth']],trail:{length:5706.25},model:{url:'$STATIC_ASSETS_URL/models/sc_grifex/grifex.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_grifex'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_grifex',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg}}]},sc_hubble_space_telescope:{groups:['earth','spacecraft','telescope'],occlusionRadius:0.0066,extentsRadius:0.0066,label:'Hubble',parents:[[-305719099.92837775,'earth']],trail:{length:5748.5},model:{url:'$STATIC_ASSETS_URL/models/sc_hubble/Hubble.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_hubble_space_telescope/earth/orb'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_hubble_space_telescope',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}}]},sc_hyspiri:{groups:['earth','spacecraft'],occlusionRadius:0.004,extentsRadius:0.012,label:'HyspIRI',parents:[[347025366.1839032,'earth']],trail:{length:5733.0},model:{url:'$STATIC_ASSETS_URL/models/sc_hyspiri/HyspIRI.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_hyspiri'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_hyspiri',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_ibex:{groups:['earth','spacecraft'],occlusionRadius:0.0005,extentsRadius:0.001,label:'IBEX',parents:[[277718464.1823969,'earth']],trail:{length:797489.16},model:{url:'$STATIC_ASSETS_URL/models/sc_ibex/iBEX.gltf',shadowEntities:['earth','moon']},controllers:[{type:'animdata',url:'sc_ibex',dataType:'pos'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis,periodInHours:0.00416}]},sc_icesat_2:{groups:['earth','spacecraft'],occlusionRadius:0.00198,extentsRadius:0.0065,label:'ICESat-2',parents:[[590288589.182,'earth']],trail:{length:5653.2},model:{url:'$STATIC_ASSETS_URL/models/sc_icesatii/ICESat2.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_icesat_2'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'velocity',target:'sc_icesat_2',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_image:{groups:['earth','spacecraft'],occlusionRadius:0.00113,extentsRadius:0.006,label:'IMAGE',parents:[[7288547.186,'earth'],[188163587.1835355,'']],trail:{length:55541},model:{url:'$STATIC_ASSETS_URL/models/sc_image/image.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_image'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_image',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_integral:{groups:['earth','spacecraft'],occlusionRadius:0.0025,extentsRadius:0.005,label:'INTEGRAL',parents:[[367498866.18276465,'earth']],trail:{length:229689.0},controllers:[{type:'dynamo',url:'sc_integral'}]},sc_ipex:{groups:['earth','spacecraft'],occlusionRadius:0.0001,extentsRadius:0.00015,label:'IPEX',parents:[[439586087.183,'earth']],trail:{length:5862.0},model:{url:'$STATIC_ASSETS_URL/models/sc_ipex/IPEX.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_ipex'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_ipex',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_isas:{groups:['earth','spacecraft'],occlusionRadius:0.001,extentsRadius:0.0015,label:'ISAS',parents:[[-186102945.06492478,'earth'],[-183424845.06434903,'']],trail:{length:92680.5},model:{url:'$STATIC_ASSETS_URL/models/sc_isas/isas.gltf',shadowEntities:['earth','moon']},controllers:[{type:'animdata',url:'sc_isas',dataType:'pos'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_isas',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_iss:{groups:['earth','spacecraft'],occlusionRadius:0.008,extentsRadius:0.072,label:'ISS',parents:[[344589947.18311954,'earth']],trail:{length:5573.0},model:{url:'$STATIC_ASSETS_URL/models/sc_iss/ISS_stationary.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_iss'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_iss',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}],postCreateFunction:(entity)=>{const vectorForAlphaGimbal=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0,0.5,0.5*Math.sqrt(3.0));const vectorForBetaGimbalAxis=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0,0.5*Math.sqrt(3.0),-0.5);const vectorForBetaGimbalPoint=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0,0.5,0.5*Math.sqrt(3.0));let align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);align.setJoint('20_P4_Truss');align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis);align.setSecondaryAxis(vectorForAlphaGimbal);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);align.setJoint('23_S4_Truss');align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis);align.setSecondaryAxis(vectorForAlphaGimbal);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);align.setJoint('20_P4_Truss_01');align.setPrimaryAxis(vectorForBetaGimbalAxis);align.setSecondaryAxis(vectorForBetaGimbalPoint);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);align.setJoint('20_P4_Truss_02');align.setPrimaryAxis(vectorForBetaGimbalAxis);align.setSecondaryAxis(vectorForBetaGimbalPoint);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);align.setJoint('23_S4_Truss_01');align.setPrimaryAxis(vectorForBetaGimbalAxis);align.setSecondaryAxis(vectorForBetaGimbalPoint);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);align.setJoint('23_S4_Truss_02');align.setPrimaryAxis(vectorForBetaGimbalAxis);align.setSecondaryAxis(vectorForBetaGimbalPoint);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);align.setJoint('32_S6_Truss_01');align.setPrimaryAxis(vectorForBetaGimbalAxis);align.setSecondaryAxis(vectorForBetaGimbalPoint);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);align.setJoint('32_S6_Truss_02');align.setPrimaryAxis(vectorForBetaGimbalAxis);align.setSecondaryAxis(vectorForBetaGimbalPoint);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);align.setJoint('08_P6_Truss_01');align.setPrimaryAxis(vectorForBetaGimbalAxis);align.setSecondaryAxis(vectorForBetaGimbalPoint);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);align.setJoint('08_P6_Truss_02');align.setPrimaryAxis(vectorForBetaGimbalAxis);align.setSecondaryAxis(vectorForBetaGimbalPoint);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');const rapidScatSpin=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpinController);rapidScatSpin.setJoint('RapidScat_dish');rapidScatSpin.setRate(pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.degToRad(108));rapidScatSpin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,!0);rapidScatSpin.setClampedToRealTime(!0);rapidScatSpin.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(465418867.184,524890952.183));_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.showSubObjectDuringInterval(entity,'Ecostress',584127348,Number.POSITIVE_INFINITY);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.showSubObjectDuringInterval(entity,'EMIT',711345507,Number.POSITIVE_INFINITY);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.showSubObjectDuringInterval(entity,'OCO3',610718469,Number.POSITIVE_INFINITY);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.showSubObjectDuringInterval(entity,'45_RapidScat',465418867.184,575406069.184)}},sc_iss_ecostress:{groups:['instrument','sc_iss'],occlusionRadius:0.001,extentsRadius:0.0012,label:'ECOSTRESS',parents:[[584127348,'sc_iss']],controllers:[{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity,position:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.0200195,-0.00202631,0.0161099),coverage:[584127348,Number.POSITIVE_INFINITY]}],postCreateFunction:(entity)=>{const rotateByEntityOrientation=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RotateByEntityOrientationController);rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(584127348,Number.POSITIVE_INFINITY))}},sc_iss_emit:{groups:['instrument','sc_iss'],occlusionRadius:0.0008,extentsRadius:0.0013,label:'EMIT',parents:[[711345507,'sc_iss']],controllers:[{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity,position:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.024,-0.00225,0.00325),coverage:[711345507,Number.POSITIVE_INFINITY]}],postCreateFunction:(entity)=>{const rotateByEntityOrientation=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RotateByEntityOrientationController);rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(711345507,Number.POSITIVE_INFINITY))}},sc_iss_oco_3:{groups:['instrument','sc_iss'],occlusionRadius:0.0008,extentsRadius:0.0012,label:'OCO-3',parents:[[610718469,'sc_iss']],controllers:[{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity,position:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.0156458,-0.00195982,0.0200232),coverage:[610718469,Number.POSITIVE_INFINITY]}],postCreateFunction:(entity)=>{const rotateByEntityOrientation=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RotateByEntityOrientationController);rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(610718469,Number.POSITIVE_INFINITY))}},sc_iss_rapidscat:{groups:['instrument','sc_iss'],occlusionRadius:0.0008,extentsRadius:0.0002,label:'RapidScat',parents:[[465418867.184,'sc_iss'],[575406069.184,'']],controllers:[{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity,position:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.0100725,-0.00133401,0.0162145),coverage:[465418867.184,575406069.184]}],postCreateFunction:(entity)=>{const rotateByEntityOrientation=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RotateByEntityOrientationController);rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(465418867.184,575406069.184))}},sc_ixpe:{groups:['earth','spacecraft','telescope'],occlusionRadius:0.0055,extentsRadius:0.0026,label:'IXPE',parents:[[692324766.6007013,'earth']],trail:{length:5400},model:{url:'$STATIC_ASSETS_URL/models/sc_ixpe/ixpe.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_ixpe'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}]},sc_jason_1:{groups:['earth','spacecraft'],occlusionRadius:0.0014,extentsRadius:0.004,label:'Jason-1',parents:[[352800006.1854904,'earth'],[458074266.1839004,'']],trail:{length:6744.5},model:{url:'$STATIC_ASSETS_URL/models/sc_ostm/ostm.gltf',shadowEntities:['earth','moon']},controllers:[{type:'animdata',url:'sc_jason_1',dataType:'pos'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_jason_1',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg}}]},sc_jason_2:{groups:['earth','spacecraft'],occlusionRadius:0.0014,extentsRadius:0.004,label:'OSTM/Jason-2',parents:[[344589947.18311954,'earth'],[623851269.182,'']],trail:{length:6744.25},model:{url:'$STATIC_ASSETS_URL/models/sc_ostm/ostm.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_jason_2'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_jason_2',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg}}]},sc_jason_3:{groups:['earth','spacecraft'],occlusionRadius:0.0014,extentsRadius:0.004,label:'Jason-3',parents:[[506497796.18443054,'earth']],trail:{length:6721.0},model:{url:'$STATIC_ASSETS_URL/models/sc_ostm/ostm.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_jason_3'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_jason_3',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg}}]},sc_jwst:{groups:['earth','spacecraft'],radius:0.010,label:'James Webb Space Telescope',parents:[[693708549.184,'earth']],trail:{length:5900033.33},model:{url:'$STATIC_ASSETS_URL/models/sc_jwst/webb_deployed.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_jwst/earth/orb'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'align',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}},{type:'coverage',coverage:[Number.NEGATIVE_INFINITY,694937889.184],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);model.setUrl('$STATIC_ASSETS_URL/models/sc_jwst/webb_stowed.gltf')},exit:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);model.setUrl('$STATIC_ASSETS_URL/models/sc_jwst/webb_deployed.gltf')}}]},sc_landsat_5:{groups:['earth','spacecraft'],radius:0.004,label:'Landsat 5',parents:[[352800006.1854904,'earth'],[473889066.18410677,'']],trail:{length:5933.33},controllers:[{type:'dynamo',url:'sc_landsat_5'}]},sc_landsat_7:{groups:['earth','spacecraft'],occlusionRadius:0.004,extentsRadius:0.012,label:'Landsat 7',parents:[[344589947.18311954,'earth']],trail:{length:5933.33},model:{url:'$STATIC_ASSETS_URL/models/sc_landsat_7/LandSat7.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_landsat_7'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'velocity',target:'sc_landsat_7',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg}}]},sc_landsat_8:{groups:['earth','spacecraft'],occlusionRadius:0.004,extentsRadius:0.0095,label:'Landsat 8',parents:[[413877787.185,'earth']],trail:{length:5933.33},model:{url:'$STATIC_ASSETS_URL/models/sc_landsat_8/LandSat8.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_landsat_8'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg},secondary:{type:'velocity',target:'sc_landsat_8',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}}]},sc_landsat_9:{groups:['earth','spacecraft'],occlusionRadius:0.004,extentsRadius:0.015,label:'Landsat 9',parents:[[686043940.723348,'earth']],trail:{length:5933.33},model:{url:'$STATIC_ASSETS_URL/models/sc_landsat_9/Landsat9.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_landsat_9'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'velocity',target:'sc_landsat_9',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_list:{groups:['earth','spacecraft'],radius:0.004,label:'LIST',parents:[[347025366.1839032,'earth']],trail:{length:5933.33},controllers:[{type:'dynamo',url:'sc_list'}]},sc_m_cubed:{groups:['earth','spacecraft'],radius:0.0001,label:'M-Cubed',parents:[[373032066.182,'earth']],trail:{length:5768.333333333333},model:{url:'$STATIC_ASSETS_URL/models/sc_m_cubed/mCubed.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_m_cubed'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_m_cubed',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg}}]},sc_mcubed_2:{groups:['earth','spacecraft'],occlusionRadius:0.0001,extentsRadius:0.0002,label:'MCubed-2',parents:[[439560067.183,'earth']],trail:{length:5861.0},model:{url:'$STATIC_ASSETS_URL/models/sc_mcubed_2/M-Cubed2.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_mcubed_2'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg},secondary:{type:'velocity',target:'sc_mcubed_2',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_mms_1:{groups:['earth','spacecraft'],occlusionRadius:0.0017,extentsRadius:0.013,label:'MMS 1',parents:[[479519767.1855569,'earth']],trail:{length:85994.0},model:{url:'$STATIC_ASSETS_URL/models/sc_mms/MMS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_mms_1'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg,periodInHours:0.00556}]},sc_mms_2:{groups:['earth','spacecraft'],occlusionRadius:0.0017,extentsRadius:0.013,label:'MMS 2',parents:[[479519767.1855569,'earth']],trail:{length:85962.0},model:{url:'$STATIC_ASSETS_URL/models/sc_mms/MMS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_mms_2'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg,periodInHours:0.00556}]},sc_mms_3:{groups:['earth','spacecraft'],occlusionRadius:0.0017,extentsRadius:0.013,label:'MMS 3',parents:[[479519767.1855569,'earth']],trail:{length:86347.0},model:{url:'$STATIC_ASSETS_URL/models/sc_mms/MMS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_mms_3'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg,periodInHours:0.00556}]},sc_mms_4:{groups:['earth','spacecraft'],occlusionRadius:0.0017,extentsRadius:0.013,label:'MMS 4',parents:[[479519767.1855569,'earth']],trail:{length:86024.0},model:{url:'$STATIC_ASSETS_URL/models/sc_mms/MMS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_mms_4'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg,periodInHours:0.00556}]},sc_nisar:{groups:['earth','spacecraft'],occlusionRadius:0.006,extentsRadius:0.017,label:'NISAR',parents:[[757339269,'earth']],trail:{length:5573.0},model:{url:'$STATIC_ASSETS_URL/models/sc_nisar/Nisar.gltf',shadowEntities:['earth','moon']},controllers:[{type:'orbitalElements',eccentricity:0,semiMajorAxis:7118,meanAngularMotion:0.0011382582,meanAnomalyAtEpoch:0,inclination:Math.PI/180*98.5,longitudeOfAscendingNode:0,argumentOfPeriapsis:0,coverage:[757339269,Number.POSITIVE_INFINITY]},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_nisar',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_noaa_14:{groups:['earth','spacecraft'],radius:0.004,label:'NOAA 14',parents:[[344589947.18311954,'earth'],[661006268.1833516,'']],trail:{length:5933.0},controllers:[{type:'dynamo',url:'sc_noaa_14'}]},sc_noaa_15:{groups:['earth','spacecraft'],radius:0.004,label:'NOAA 15',parents:[[344589947.18311954,'earth']],trail:{length:5933.0},controllers:[{type:'dynamo',url:'sc_noaa_15'}]},sc_noaa_16:{groups:['earth','spacecraft'],radius:0.004,label:'NOAA 16',parents:[[344589947.18311954,'earth'],[661006268.1833516,'']],trail:{length:5933.0},controllers:[{type:'dynamo',url:'sc_noaa_16'}]},sc_noaa_17:{groups:['earth','spacecraft'],radius:0.004,label:'NOAA 17',parents:[[344589947.18311954,'earth'],[661006268.1833516,'']],trail:{length:5933.0},controllers:[{type:'dynamo',url:'sc_noaa_17'}]},sc_noaa_18:{groups:['earth','spacecraft'],radius:0.004,label:'NOAA 18',parents:[[344589947.18311954,'earth']],trail:{length:5933.0},controllers:[{type:'dynamo',url:'sc_noaa_18'}]},sc_noaa_19:{groups:['earth','spacecraft'],radius:0.004,label:'NOAA 19',parents:[[344589947.18311954,'earth']],trail:{length:5933.0},controllers:[{type:'dynamo',url:'sc_noaa_19'}]},sc_nustar:{groups:['earth','spacecraft'],occlusionRadius:0.006,extentsRadius:0.006,label:'NuSTAR',parents:[[392875303.185,'earth']],trail:{length:5798.66},model:{url:'$STATIC_ASSETS_URL/models/sc_nustar/nustar.gltf',shadowEntities:['earth']},controllers:[{type:'dynamo',url:'sc_nustar'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis,target:'sun',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_oco_2:{groups:['earth','spacecraft'],occlusionRadius:0.0021,extentsRadius:0.004,label:'OCO-2',parents:[[457567050.184,'earth']],trail:{length:5933.333333333333},model:{url:'$STATIC_ASSETS_URL/models/sc_oco_2/oco2.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_oco_2'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg},secondary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}}]},sc_path:{groups:['earth','spacecraft'],radius:0.004,label:'PATH',parents:[[347025366.1839032,'earth']],trail:{length:5933.0},controllers:[{type:'dynamo',url:'sc_path'}]},sc_polar:{groups:['earth','spacecraft'],occlusionRadius:0.0012,extentsRadius:0.005,label:'Polar',parents:[[-121608237.81469652,'earth'],[262612565.1855274,'']],trail:{length:66571.0},model:{url:'$STATIC_ASSETS_URL/models/sc_polar/polar.gltf',shadowEntities:['earth','moon']},controllers:[{type:'animdata',url:'sc_polar',dataType:'pos'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_polar',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_quikscat:{groups:['earth','spacecraft'],occlusionRadius:0.0016,extentsRadius:0.0018,label:'QuikSCAT',parents:[[344589947.18311954,'earth'],[591710469.182,'']],trail:{length:6061.33},model:{url:'$STATIC_ASSETS_URL/models/sc_quikscat/QuikSCAT.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_quikscat'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_quikscat',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg}}]},sc_race:{groups:['earth','spacecraft'],radius:0.00015,label:'RACE',parents:[[467726467.182,'earth'],[467812867.182,'']],trail:{length:5933.0},controllers:[{type:'dynamo',url:'sc_race'}]},sc_raincube:{groups:['earth','spacecraft'],occlusionRadius:0.00035,extentsRadius:0.0005,label:'RainCube',parents:[[608189026.1856545,'earth'],[662040069.184,'']],trail:{length:5743.0},model:{url:'$STATIC_ASSETS_URL/models/sc_raincube/Raincube.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_raincube'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_raincube',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_rax_2:{groups:['earth','spacecraft'],radius:0.0002,label:'RAX-2',parents:[[373067348.182,'earth'],[418824067.186,'']],trail:{length:5743.0},controllers:[{type:'dynamo',url:'sc_rax_2'}]},sc_rbsp_a:{groups:['earth','spacecraft'],radius:0.004,label:'Van Allen Probe A',parents:[[399585967.183,'earth'],[624628869.182,'']],trail:{length:32214.0},model:{url:'$STATIC_ASSETS_URL/models/sc_rbsp/rbsp.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_rbsp_a'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_rbsp_a',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_rbsp_b:{groups:['earth','spacecraft'],radius:0.004,label:'Van Allen Probe B',parents:[[399585967.183,'earth'],[616766469.184,'']],trail:{length:32574.0},model:{url:'$STATIC_ASSETS_URL/models/sc_rbsp/rbsp.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_rbsp_b'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_rbsp_b',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_sac_d:{groups:['earth','spacecraft'],occlusionRadius:0.003,extentsRadius:0.0045,label:'Aquarius',parents:[[360987666.185,'earth'],[486907267.185,'']],trail:{length:5884.25},model:{url:'$STATIC_ASSETS_URL/models/sc_sac_d/aquarius.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_sac_d'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis},secondary:{type:'velocity',target:'sc_sac_d',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}}]},sc_sclp:{groups:['earth','spacecraft'],radius:0.004,label:'SCLP',parents:[[347025366.1839032,'earth']],trail:{length:5933},controllers:[{type:'dynamo',url:'sc_sclp'}]},sc_sdo:{groups:['earth','spacecraft'],occlusionRadius:0.0022,extentsRadius:0.00315,label:'SDO',parents:[[505918808.18474686,'earth']],trail:{length:86137.66},model:{url:'$STATIC_ASSETS_URL/models/sc_sdo/sdo.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_sdo'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_sdo',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_sentinel_6:{groups:['earth','spacecraft'],occlusionRadius:0.0026,extentsRadius:0.0031,label:'Sentinel-6 Michael Freilich',parents:[[659322339.7879795,'earth']],trail:{length:5933.5},model:{url:'$STATIC_ASSETS_URL/models/sc_sentinel_6/Sentinel6.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_sentinel_6'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_sentinel_6',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_smap:{groups:['earth','spacecraft'],occlusionRadius:0.003,extentsRadius:0.009,label:'SMAP',parents:[[476542806.1849232,'earth']],trail:{length:5906.8},model:{url:'$STATIC_ASSETS_URL/models/sc_smap/SMAP.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_smap'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_smap',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}],postCreateFunction:(entity)=>{const spin=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpinController);spin.setJoint('arm_etc');spin.setRate(pioneer__WEBPACK_IMPORTED_MODULE_2__.MathUtils.degToRad(87.6));spin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis,!0);spin.setClampedToRealTime(!0)}},sc_soho:{groups:['earth','spacecraft'],occlusionRadius:0.00215,extentsRadius:0.00425,label:'SOHO',parents:[[265550465.18489534,'earth']],trail:{length:60*60*24*365},model:{url:'$STATIC_ASSETS_URL/models/sc_soho/soho.gltf',shadowEntities:['earth','moon']},controllers:[{type:'animdata',url:'sc_soho',dataType:'pos'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_soho',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_sorce:{groups:['earth','spacecraft'],occlusionRadius:0.001,extentsRadius:0.0022,label:'SORCE',parents:[[344589947.18311954,'earth'],[635860869.185,'']],trail:{length:5812.5},model:{url:'$STATIC_ASSETS_URL/models/sc_sorce/sorce.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_sorce'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_sorce',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg}}]},sc_starling_1:{groups:['earth','spacecraft'],occlusionRadius:0.00023,extentsRadius:0.00076,label:'Starling-1',parents:[[Number.NEGATIVE_INFINITY,'earth']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_starling/starling.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_starling_1'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_starling_1',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_starling_2:{groups:['earth','spacecraft'],occlusionRadius:0.00023,extentsRadius:0.00076,label:'Starling-2',parents:[[Number.NEGATIVE_INFINITY,'earth']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_starling/starling.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_starling_2'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_starling_2',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_starling_3:{groups:['earth','spacecraft'],occlusionRadius:0.00023,extentsRadius:0.00076,label:'Starling-3',parents:[[Number.NEGATIVE_INFINITY,'earth']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_starling/starling.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_starling_3'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_starling_3',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_starling_4:{groups:['earth','spacecraft'],occlusionRadius:0.00023,extentsRadius:0.00076,label:'Starling-4',parents:[[Number.NEGATIVE_INFINITY,'earth']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_starling/starling.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_starling_4'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_starling_4',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis}}]},sc_suomi_npp:{groups:['earth','spacecraft'],occlusionRadius:0.0022,extentsRadius:0.008,label:'Suomi NPP',parents:[[373067348.01,'earth']],trail:{length:5798.66},model:{url:'$STATIC_ASSETS_URL/models/sc_npp/NPP.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_suomi_npp'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg},secondary:{type:'velocity',target:'sc_suomi_npp',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}}]},sc_swift:{groups:['earth','spacecraft'],occlusionRadius:0.0028,extentsRadius:0.0028,label:'Swift',parents:[[344589947.18311954,'earth']],trail:{length:5933},controllers:[{type:'dynamo',url:'sc_swift'}]},sc_swot:{groups:['earth','spacecraft'],occlusionRadius:0.005,extentsRadius:0.009,label:'SWOT',parents:[[347025366.1839032,'earth']],trail:{length:5933},model:{url:'$STATIC_ASSETS_URL/models/sc_swot_v2/swot.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_swot'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_swot',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg}}]},sc_tdrs_3:{groups:['earth','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.0085,label:'TDRS 3',parents:[[344589947.18311954,'earth']],trail:{length:86137.33},model:{url:'$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf'},controllers:[{type:'dynamo',url:'sc_tdrs_3'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_tdrs_5:{groups:['earth','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.0085,label:'TDRS 5',parents:[[344589947.18311954,'earth']],trail:{length:86137.66},model:{url:'$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf'},controllers:[{type:'dynamo',url:'sc_tdrs_5'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_tdrs_6:{groups:['earth','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.0085,label:'TDRS 6',parents:[[344589947.18311954,'earth']],trail:{length:86137.66},model:{url:'$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf'},controllers:[{type:'dynamo',url:'sc_tdrs_6'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_tdrs_7:{groups:['earth','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.0085,label:'TDRS 7',parents:[[344589947.18311954,'earth']],trail:{length:86151.0},model:{url:'$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf'},controllers:[{type:'dynamo',url:'sc_tdrs_7'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_tdrs_8:{groups:['earth','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.0085,label:'TDRS 8',parents:[[344589947.18311954,'earth']],trail:{length:86151.2},model:{url:'$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf'},controllers:[{type:'dynamo',url:'sc_tdrs_8'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_tdrs_9:{groups:['earth','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.0085,label:'TDRS 9',parents:[[344589947.18311954,'earth']],trail:{length:86151.0},model:{url:'$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf'},controllers:[{type:'dynamo',url:'sc_tdrs_9'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_tdrs_10:{groups:['earth','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.0085,label:'TDRS 10',parents:[[344589947.18311954,'earth']],trail:{length:86151.2},model:{url:'$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf'},controllers:[{type:'dynamo',url:'sc_tdrs_10'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_tdrs_11:{groups:['earth','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.0085,label:'TDRS 11',parents:[[412868947.185,'earth']],trail:{length:86151.0},model:{url:'$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf'},controllers:[{type:'dynamo',url:'sc_tdrs_11'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_tdrs_12:{groups:['earth','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.0085,label:'TDRS 12',parents:[[443808067.185,'earth']],trail:{length:86151.0},model:{url:'$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf'},controllers:[{type:'dynamo',url:'sc_tdrs_12'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_tdrs_13:{groups:['earth','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.0085,label:'TDRS 13',parents:[[556338669.183,'earth']],trail:{length:86151.0},model:{url:'$STATIC_ASSETS_URL/models/sc_tdrs/tdrs.gltf'},controllers:[{type:'dynamo',url:'sc_tdrs_13'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}}]},sc_terra:{groups:['earth','spacecraft'],occlusionRadius:0.0034,extentsRadius:0.012,label:'Terra',parents:[[344589947.18311954,'earth']],trail:{length:5933.33},model:{url:'$STATIC_ASSETS_URL/models/sc_terra/Terra.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_terra'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_terra',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg}}]},sc_tess:{groups:['earth','spacecraft','telescope'],occlusionRadius:0.002,extentsRadius:0.003,label:'TESS',parents:[[577366932.3626,'earth']],trail:{length:591840},model:{url:'$STATIC_ASSETS_URL/models/sc_tess/TESS.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_tess/earth/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}]},sc_themis_a:{groups:['earth','spacecraft'],occlusionRadius:0.000400,extentsRadius:0.00170,label:'THEMIS A',parents:[[344589947.18311954,'earth']],trail:{length:98428.0},model:{url:'$STATIC_ASSETS_URL/models/sc_themis/themis.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_themis_a'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis,periodInHours:0.0008333}]},sc_themis_d:{groups:['earth','spacecraft'],occlusionRadius:0.000400,extentsRadius:0.00170,label:'THEMIS D',parents:[[344589947.18311954,'earth']],trail:{length:114807.0},model:{url:'$STATIC_ASSETS_URL/models/sc_themis/themis.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_themis_d'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis,periodInHours:0.0008333}]},sc_themis_e:{groups:['earth','spacecraft'],occlusionRadius:0.000400,extentsRadius:0.00170,label:'THEMIS E',parents:[[344589947.18311954,'earth']],trail:{length:105907.5},model:{url:'$STATIC_ASSETS_URL/models/sc_themis/themis.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_themis_e'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis,periodInHours:0.0008333}]},sc_timed:{groups:['earth','spacecraft'],occlusionRadius:0.0015,extentsRadius:0.005,label:'TIMED',parents:[[344589947.18311954,'earth']],trail:{length:5933},controllers:[{type:'dynamo',url:'sc_timed'}]},sc_trmm:{groups:['earth','spacecraft'],occlusionRadius:0.002550,extentsRadius:0.0073,label:'TRMM',parents:[[-66052736.817,'earth'],[482328067.186,'']],trail:{length:5545.6},model:{url:'$STATIC_ASSETS_URL/models/sc_trmm/TRMM.gltf',shadowEntities:['earth','moon']},controllers:[{type:'orbitalElements',eccentricity:0.00111201719,semiMajorAxis:6744.5,meanAngularMotion:0.0011382582,meanAnomalyAtEpoch:0,inclination:Math.PI/180*30,longitudeOfAscendingNode:0,argumentOfPeriapsis:0,coverage:[-66052736.817,482328067.186]},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_trmm',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg}}]},sc_uars:{groups:['earth','spacecraft'],occlusionRadius:0.00535,extentsRadius:0.00535,label:'UARS',parents:[[352800006.1854904,'earth'],[370106644.184,'']],trail:{length:5490.0},controllers:[{type:'animdata',url:'sc_uars',dataType:'pos'}]},sc_wind:{groups:['earth','spacecraft'],occlusionRadius:0.00120,extentsRadius:0.00750,label:'WIND',parents:[[543931270,'earth']],trail:{length:16485927.0},model:{url:'$STATIC_ASSETS_URL/models/sc_wind/wind.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_wind/earth/orb'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxisNeg},secondary:{type:'velocity',target:'sc_wind',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg}}]},sc_wise:{groups:['earth','spacecraft'],occlusionRadius:0.0014200,extentsRadius:0.001420,label:'WISE',parents:[[344589947.18311954,'earth']],trail:{length:5715.4},controllers:[{type:'dynamo',url:'sc_wise'}]}})}),"../pioneer/scripts/src/entities/entity_utils.js": + /*!*******************************************************!*\ + !*** ../pioneer/scripts/src/entities/entity_utils.js ***! + \*******************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"EntityUtils":function(){return EntityUtils}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class EntityUtils{static addGeyser(entity,size,alpha,particleNumber,speed,spread,position,direction){const particleSpray=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ParticleSprayComponent);particleSpray.setNumberOfParticles(particleNumber);particleSpray.setSizeOfParticles(0.25*size*spread);particleSpray.setSpeedOfParticles(speed*size);particleSpray.setColorOfParticles(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1,1,1,0.5*alpha));particleSpray.setSpread(1*spread);particleSpray.setParticleSpacingRandom(!1);particleSpray.setLength(2.5*size);particleSpray.setOriginOffset(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(position[0],position[1],position[2]));particleSpray.setDirection(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(direction[0],direction[1],direction[2]))} + static showSubObjectDuringInterval(entity,subObjectName,startTime,endTime){const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent);model.setHiddenObject(subObjectName,!0);const coverageController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CoverageController);coverageController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(startTime,endTime));coverageController.setEnterFunction((entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent);model.setHiddenObject(subObjectName,!1)});coverageController.setExitFunction((entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent);model.setHiddenObject(subObjectName,!0)})}}}),"../pioneer/scripts/src/entities/jupiter_irregular_moons.js": + /*!******************************************************************!*\ + !*** ../pioneer/scripts/src/entities/jupiter_irregular_moons.js ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({aitne:{groups:['jupiter','moons','irregular','carme'],radius:1.5,label:'Aitne',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.5,1.5,1.5],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'aitne/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},ananke:{groups:['jupiter','moons','irregular','ananke'],radius:14.0,label:'Ananke',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[14,14,14],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'ananke/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},aoede:{groups:['jupiter','moons','irregular','pasiphae'],radius:2.0,label:'Aoede',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2,2,2],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'aoede/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},arche:{groups:['jupiter','moons','irregular','carme'],radius:1.5,label:'Arche',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.5,1.5,1.5],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'arche/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},autonoe:{groups:['jupiter','moons','irregular','pasiphae'],radius:2.0,label:'Autonoe',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2,2,2],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'autonoe/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},callirrhoe:{groups:['jupiter','moons','irregular','pasiphae'],radius:4.3,label:'Callirrhoe',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[4.3,4.3,4.3],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'callirrhoe/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},carme:{groups:['jupiter','moons','irregular','carme'],radius:23.0,label:'Carme',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[23,23,23],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'carme/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},carpo:{groups:['jupiter','moons','irregular'],radius:1.5,label:'Carpo',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'carpo/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},chaldene:{groups:['jupiter','moons','irregular','carme'],radius:1.9,label:'Chaldene',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.9,1.9,1.9],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'chaldene/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},cyllene:{groups:['jupiter','moons','irregular','pasiphae'],radius:1.0,label:'Cyllene',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'cyllene/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},dia:{groups:['jupiter','moons','irregular','himalia'],radius:2,label:'Dia',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:2,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'dia/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},eirene:{groups:['jupiter','moons','irregular','carme'],radius:2,label:'Eirene',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:2,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'eirene/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},elara:{groups:['jupiter','moons','irregular','himalia'],radius:43.0,label:'Elara',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[43,43,43],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'elara/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},erinome:{groups:['jupiter','moons','irregular','carme'],radius:1.6,label:'Erinome',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.6,1.6,1.6],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'erinome/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},ersa:{groups:['jupiter','moons','irregular','himalia'],radius:1.5,label:'Ersa',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:1.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'ersa/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},euanthe:{groups:['jupiter','moons','irregular','ananke'],radius:1.5,label:'Euanthe',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.5,1.5,1.5],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'euanthe/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},eukelade:{groups:['jupiter','moons','irregular','carme'],radius:2.0,label:'Eukelade',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2,2,2],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'eukelade/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},eupheme:{groups:['jupiter','moons','irregular','ananke'],radius:1,label:'Eupheme',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'eupheme/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},euporie:{groups:['jupiter','moons','irregular','ananke'],radius:1.0,label:'Euporie',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'euporie/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},eurydome:{groups:['jupiter','moons','irregular','pasiphae'],radius:1.5,label:'Eurydome',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.5,1.5,1.5],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'eurydome/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},harpalyke:{groups:['jupiter','moons','irregular','ananke'],radius:2.2,label:'Harpalyke',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.2,2.2,2.2],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'harpalyke/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},hegemone:{groups:['jupiter','moons','irregular','pasiphae'],radius:1.5,label:'Hegemone',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'hegemone/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},helike:{groups:['jupiter','moons','irregular','ananke'],radius:2.0,label:'Helike',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2,2,2],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'helike/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},hermippe:{groups:['jupiter','moons','irregular','ananke'],radius:2.0,label:'Hermippe',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2,2,2],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'hermippe/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},herse:{groups:['jupiter','moons','irregular','carme'],radius:1.0,label:'Herse',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'herse/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},himalia:{groups:['jupiter','moons','irregular','himalia'],radius:85.0,label:'Himalia',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[85,85,85],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'himalia/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},iocaste:{groups:['jupiter','moons','irregular','ananke'],radius:2.6,label:'Iocaste',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.6,2.6,2.6],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'iocaste/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},isonoe:{groups:['jupiter','moons','irregular','carme'],radius:1.9,label:'Isonoe',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.9,1.9,1.9],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'isonoe/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_li:{groups:['jupiter','moons','irregular','carme'],radius:1,label:'Jupiter LI',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_li/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lii:{groups:['jupiter','moons','irregular','ananke'],radius:0.5,label:'Jupiter LII',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lii/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_liv:{groups:['jupiter','moons','irregular','ananke'],radius:0.5,label:'Jupiter LIV',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_liv/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lv:{groups:['jupiter','moons','irregular','ananke'],radius:1,label:'Jupiter LV',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lv/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lvi:{groups:['jupiter','moons','irregular','pasiphae'],radius:0.5,label:'Jupiter LVI',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lvi/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lix:{groups:['jupiter','moons','irregular','pasiphae'],radius:1,label:'Jupiter LIX',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lix/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lxi:{groups:['jupiter','moons','irregular','carme'],radius:1,label:'Jupiter LXI',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lxi/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lxiii:{groups:['jupiter','moons','irregular','carme'],radius:1,label:'Jupiter LXIII',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lxiii/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lxiv:{groups:['jupiter','moons','irregular','ananke'],radius:1,label:'Jupiter LXIV',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lxiv/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lxvi:{groups:['jupiter','moons','irregular','carme'],radius:1,label:'Jupiter LXVI',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lxvi/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lxvii:{groups:['jupiter','moons','irregular','pasiphae'],radius:1,label:'Jupiter LXVII',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lxvii/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lxviii:{groups:['jupiter','moons','irregular','ananke'],radius:1,label:'Jupiter LXVIII',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lxviii/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lxix:{groups:['jupiter','moons','irregular','carme'],radius:0.5,label:'Jupiter LXIX',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lxix/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lxx:{groups:['jupiter','moons','irregular','ananke'],radius:1.5,label:'Jupiter LXX',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lxx/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},jupiter_lxxii:{groups:['jupiter','moons','irregular','ananke'],radius:1,label:'Jupiter LXXII',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'jupiter_lxxii/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},kale:{groups:['jupiter','moons','irregular','carme'],radius:1.0,label:'Kale',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'kale/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},kallichore:{groups:['jupiter','moons','irregular','carme'],radius:1.0,label:'Kallichore',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'kallichore/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},kalyke:{groups:['jupiter','moons','irregular','carme'],radius:2.6,label:'Kalyke',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.6,2.6,2.6],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'kalyke/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},kore:{groups:['jupiter','moons','irregular','pasiphae'],radius:1.0,label:'Kore',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'kore/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},leda:{groups:['jupiter','moons','irregular','himalia'],radius:10.0,label:'Leda',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[10,10,10],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'leda/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},lysithea:{groups:['jupiter','moons','irregular','himalia'],radius:18.0,label:'Lysithea',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[18,18,18],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'lysithea/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},megaclite:{groups:['jupiter','moons','irregular','pasiphae'],radius:2.7,label:'Megaclite',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.7,2.7,2.7],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'megaclite/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},mneme:{groups:['jupiter','moons','irregular','ananke'],radius:1.0,label:'Mneme',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'mneme/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},orthosie:{groups:['jupiter','moons','irregular','ananke'],radius:1.0,label:'Orthosie',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'orthosie/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},pandia:{groups:['jupiter','moons','irregular','himalia'],radius:1.5,label:'Pandia',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:1.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'pandia/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},pasiphae:{groups:['jupiter','moons','irregular','pasiphae'],radius:30.0,label:'Pasiphae',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[30,30,30],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'pasiphae/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},pasithee:{groups:['jupiter','moons','irregular','carme'],radius:1.0,label:'Pasithee',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'pasithee/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},philophrosyne:{groups:['jupiter','moons','irregular','pasiphae'],radius:1,label:'Philophrosyne',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'philophrosyne/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},praxidike:{groups:['jupiter','moons','irregular','ananke'],radius:3.4,label:'Praxidike',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[3.4,3.4,3.4],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'praxidike/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2003_j_2:{groups:['jupiter','moons','irregular','ananke'],radius:1,label:'S/2003 J 2',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2003_j_2/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2003_j_4:{groups:['jupiter','moons','irregular','pasiphae'],radius:1,label:'S/2003 J 4',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2003_j_4/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2003_j_9:{groups:['jupiter','moons','irregular','carme'],radius:0.5,label:'S/2003 J 9',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2003_j_9/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2003_j_10:{groups:['jupiter','moons','irregular','carme'],radius:1,label:'S/2003 J 10',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2003_j_10/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2003_j_12:{groups:['jupiter','moons','irregular','ananke'],radius:0.5,label:'S/2003 J 12',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2003_j_12/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2003_j_16:{groups:['jupiter','moons','irregular','ananke'],radius:1,label:'S/2003 J 16',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2003_j_16/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2003_j_23:{groups:['jupiter','moons','irregular','pasiphae'],radius:1,label:'S/2003 J 23',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2003_j_23/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2003_j_24:{groups:['jupiter','moons','irregular','carme'],radius:1,label:'S/2003 J 24',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2003_j_24/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2011_j_3:{groups:['jupiter','moons','irregular','himalia'],radius:1.5,label:'S/2011 J 3',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2011_j_3/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2016_j_3:{groups:['jupiter','moons','irregular','carme'],radius:1,label:'S/2016 J 3',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2016_j_3/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2016_j_4:{groups:['jupiter','moons','irregular','pasiphae'],radius:0.5,label:'S/2016 J 4',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2016_j_4/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2018_j_2:{groups:['jupiter','moons','irregular','himalia'],radius:1.5,label:'S/2018 J 2',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2018_j_2/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2018_j_3:{groups:['jupiter','moons','irregular','carme'],radius:0.5,label:'S/2018 J 3',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2018_j_3/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2018_j_4:{groups:['jupiter','moons','irregular','carpo'],radius:1,label:'S/2018 J 4',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2018_j_4/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2021_j_1:{groups:['jupiter','moons','irregular','ananke'],radius:0.5,label:'S/2021 J 1',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2021_j_1/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2021_j_2:{groups:['jupiter','moons','irregular','ananke'],radius:1,label:'S/2021 J 2',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2021_j_2/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2021_j_3:{groups:['jupiter','moons','irregular','ananke'],radius:1,label:'S/2021 J 3',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2021_j_3/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2021_j_4:{groups:['jupiter','moons','irregular','carme'],radius:0.5,label:'S/2021 J 4',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2021_j_4/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2021_j_5:{groups:['jupiter','moons','irregular','carme'],radius:1,label:'S/2021 J 5',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2021_j_5/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2021_j_6:{groups:['jupiter','moons','irregular','carme'],radius:0.5,label:'S/2021 J 6',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2021_j_6/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2022_j_1:{groups:['jupiter','moons','irregular','carme'],radius:0.5,label:'S/2022 J 1',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2022_j_1/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2022_j_2:{groups:['jupiter','moons','irregular','carme'],radius:0.5,label:'S/2022 J 2',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2022_j_2/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2022_j_3:{groups:['jupiter','moons','irregular','ananke'],radius:0.5,label:'S/2022 J 3',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'s_2022_j_3/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},sinope:{groups:['jupiter','moons','irregular','pasiphae'],radius:19.0,label:'Sinope',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[19,19,19],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'sinope/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},sponde:{groups:['jupiter','moons','irregular','pasiphae'],radius:1.0,label:'Sponde',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'sponde/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},taygete:{groups:['jupiter','moons','irregular','carme'],radius:2.5,label:'Taygete',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.5,2.5,2.5],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'taygete/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},thelxinoe:{groups:['jupiter','moons','irregular','ananke'],radius:1.0,label:'Thelxinoe',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1,1,1],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'thelxinoe/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},themisto:{groups:['jupiter','moons','irregular'],radius:4.0,label:'Themisto',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[4,4,4],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'themisto/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},thyone:{groups:['jupiter','moons','irregular','ananke'],radius:2.0,label:'Thyone',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2,2,2],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'thyone/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},valetudo:{groups:['jupiter','moons','irregular'],radius:0.5,label:'Valetudo',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.5,shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'valetudo/jupiter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]}})}),"../pioneer/scripts/src/entities/jupiter_regular_moons.js": + /*!****************************************************************!*\ + !*** ../pioneer/scripts/src/entities/jupiter_regular_moons.js ***! + \****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({adrastea:{groups:['jupiter','moons','amalthea','inner','regular'],radius:8.2,label:'Adrastea',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[8.2,8.2,8.2],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'adrastea/jupiter/orb'},{type:'dynamo',url:'adrastea/ori'}]},amalthea:{groups:['jupiter','moons','amalthea','inner','regular'],radius:83.5,label:'Amalthea',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[83.5,83.5,83.5],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'amalthea/jupiter/orb'},{type:'dynamo',url:'amalthea/ori'}]},callisto:{groups:['jupiter','moons','main','galilean','regular'],radius:2410.3,label:'Callisto',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},spheroid:{equatorialRadius:2410.3,polarRadius:2410.3,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'callisto/color_$SIZE_$FACE.png',sizes:[4,512]}},shadowEntities:['jupiter','io','europa','ganymede']},controllers:[{type:'dynamo',url:'callisto/jupiter/orb'},{type:'dynamo',url:'callisto/ori'}]},europa:{groups:['jupiter','moons','main','galilean','regular'],radius:1569.0,label:'Europa',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},spheroid:{equatorialRadius:1569.0,polarRadius:1569.0,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'europa/color_$SIZE_$FACE.png',sizes:[4,512,1024]}},shadowEntities:['jupiter','io','callisto','ganymede']},controllers:[{type:'dynamo',url:'europa/jupiter/orb'},{type:'dynamo',url:'europa/ori'}]},ganymede:{groups:['jupiter','moons','main','galilean','regular'],radius:2634.1,label:'Ganymede',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},spheroid:{equatorialRadius:2634.1,polarRadius:2634.1,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'ganymede/color_$SIZE_$FACE.png',sizes:[4,512]}},shadowEntities:['jupiter','io','europa','callisto']},controllers:[{type:'dynamo',url:'ganymede/jupiter/orb'},{type:'dynamo',url:'ganymede/ori'}]},io:{groups:['jupiter','moons','main','galilean','regular'],radius:1821.3,label:'Io',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},spheroid:{equatorialRadius:1821.3,polarRadius:1821.3,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'io/color_$SIZE_$FACE.png',sizes:[4,512,1024]}},shadowEntities:['jupiter','europa','ganymede','callisto']},controllers:[{type:'dynamo',url:'io/jupiter/orb'},{type:'dynamo',url:'io/ori'}]},metis:{groups:['jupiter','moons','amalthea','inner','regular'],radius:21.5,label:'Metis',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[21.5,21.5,21.5],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'metis/jupiter/orb'},{type:'dynamo',url:'metis/ori'}]},thebe:{groups:['jupiter','moons','amalthea','inner','regular'],radius:49.0,label:'Thebe',parents:[[Number.NEGATIVE_INFINITY,'jupiter']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[49,49,49],shadowEntities:['jupiter']},controllers:[{type:'dynamo',url:'thebe/jupiter/orb'},{type:'dynamo',url:'thebe/ori'}]}})}),"../pioneer/scripts/src/entities/lunar_spacecraft.js": + /*!***********************************************************!*\ + !*** ../pioneer/scripts/src/entities/lunar_spacecraft.js ***! + \***********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({sc_apollo_15:{groups:['moon','spacecraft'],radius:0.004,label:'Apollo 15',parents:[[-897044358.3260887,'moon'],[-896822958.3195117,'']],trail:{length:6855.0},controllers:[{type:'animdata',url:'sc_apollo_15',dataType:'pos'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},sc_artemis_1:{groups:['moon','spacecraft'],radius:0.005,label:'Artemis I',parents:[[721860361,'earth'],[724052473,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_artemis_1/artemis_cmsm.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_artemis_1/earth/pos'},{type:'align',primary:{type:'velocity',target:'sc_artemis_1',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis},secondary:{type:'align',target:'moon',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}}]},sc_capstone:{groups:['moon','spacecraft'],radius:0.0005,label:'CAPSTONE',parents:[[710192447.9999855,'earth'],[721583059,'moon']],trail:{length:undefined,lengthCoverages:[[4000000,Number.NEGATIVE_INFINITY,721583059],[1210909,721583059,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_capstone/capstone.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_capstone/earth/orb'},{type:'dynamo',url:'sc_capstone/moon/orb'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg},secondary:{type:'align',target:'moon',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}}]},sc_clementine:{groups:['moon','spacecraft'],radius:0.002,label:'Clementine',parents:[[-187185539.81536362,'moon'],[-178496939.81459716,'']],trail:{length:5408.5},model:{url:'$STATIC_ASSETS_URL/models/sc_clementine/clementine.gltf',shadowEntities:['moon']},controllers:[{type:'animdata',url:'sc_clementine/moon/all',dataType:'pos'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg},secondary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg}}]},sc_grail_a:{groups:['moon','spacecraft'],radius:0.001,label:'Ebb',parents:[[368763000,'moon'],[414201667.18513304,'']],trail:{length:41115.75},model:{url:'$STATIC_ASSETS_URL/models/sc_grail/grail_b.gltf',shadowEntities:['moon']},controllers:[{type:'animdata',url:'sc_grail_a/moon/all',dataType:'pos'},{type:'align',primary:{type:'velocity',target:'sc_grail_a',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg},secondary:{type:'point',target:'moon',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}}]},sc_grail_b:{groups:['moon','spacecraft'],radius:0.001,label:'Flow',parents:[[368763000,'moon'],[414201667.18513304,'']],trail:{length:41239.8},model:{url:'$STATIC_ASSETS_URL/models/sc_grail/grail_b.gltf',shadowEntities:['moon']},controllers:[{type:'animdata',url:'sc_grail_b/moon/all',dataType:'pos'},{type:'align',primary:{type:'velocity',target:'sc_grail_b',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg},secondary:{type:'point',target:'moon',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}}]},sc_ladee:{groups:['moon','spacecraft'],radius:0.0012,label:'LADEE',parents:[[431798467.18253195,'moon'],[451355187.44558257,'']],trail:{length:7889.57},model:{url:'$STATIC_ASSETS_URL/models/sc_ladee/ladee.gltf',shadowEntities:['moon']},controllers:[{type:'animdata',url:'sc_ladee/moon/all',dataType:'pos'},{type:'align',primary:{type:'velocity',target:'sc_ladee',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg},secondary:{type:'point',target:'moon',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}}]},sc_lcross:{groups:['moon','spacecraft'],occlusionRadius:0.00130,extentsRadius:0.0022,label:'LCROSS',parents:[[298635466.0304444,'moon'],[308360200.75,'']],trail:{length:3598022.0},model:{url:'$STATIC_ASSETS_URL/models/sc_lcross/lcross.gltf',rotate:[{z:-90}],shadowEntities:['moon']},controllers:[{type:'animdata',url:'sc_lcross/moon/all',dataType:'pos',coverage:[Number.NEGATIVE_INFINITY,308360200.750]},{type:'align',primary:{type:'velocity',target:'sc_lcross',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg},secondary:{type:'point',target:'moon',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}}]},sc_lcross_impact_site:{groups:['moon','sc_lcross','sites'],radius:0.001,systemRadius:200,label:'LCROSS Impact Site',parents:[[298635466.0304444,'moon']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(-1.4782008103461848,-0.8648271467797672,0),coverage:[298635466.0304444,Number.POSITIVE_INFINITY]}]},sc_lunar_flashlight:{groups:['moon','spacecraft'],occlusionRadius:0.00025,extentsRadius:0.0005,label:'Lunar Flashlight',parents:[[724019554,'earth'],[737164869,'']],trail:{length:10000000},model:{url:'$STATIC_ASSETS_URL/models/sc_lunar_flashlight/lunar_flashlight.gltf',shadowEntities:['earth']},controllers:[{type:'dynamo',url:'sc_lunar_flashlight/earth_v3'},{type:'align',primary:{type:'align',target:'moon',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis},secondary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis}}]},sc_lunar_icecube:{groups:['moon','spacecraft'],occlusionRadius:0.0002,extentsRadius:0.0012,label:'Lunar IceCube',parents:[[721864426,'earth'],[734111601,'moon']],trail:{length:undefined,lengthCoverages:[[3000000,Number.NEGATIVE_INFINITY,734111601],[441920,734111601,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_lunar_icecube/lunar_icecube.gltf',shadowEntities:['earth','moon']},controllers:[{type:'dynamo',url:'sc_lunar_icecube/earth/pos'},{type:'dynamo',url:'sc_lunar_icecube/moon/orb'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis},secondary:{type:'align',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}}]},sc_lunar_prospector:{groups:['moon','spacecraft'],occlusionRadius:0.00065300,extentsRadius:0.0022,label:'Lunar Prospector',parents:[[-62206800,'moon'],[-13402020,'']],trail:{length:7260.0},model:{url:'$STATIC_ASSETS_URL/models/sc_lunar_prospector/lunar_prospector.gltf',shadowEntities:['moon']},controllers:[{type:'animdata',url:'sc_lunar_prospector/moon/all',dataType:'pos'},{type:'align',primary:{type:'align',target:'moon',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg,periodInHours:0.008333}]},sc_lunar_reconnaissance_orbiter:{groups:['moon','spacecraft'],occlusionRadius:0.00272,extentsRadius:0.0038,label:'Lunar Reconnaissance Orbiter',parents:[[298635426.1844444,'earth'],[298929666,'moon']],trail:{length:7106.66,lengthCoverages:[[1000000,Number.NEGATIVE_INFINITY,299040641],[7106.66,299040641,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_lunar_reconnaissance_orbiter/LRO.gltf',rotate:[{z:-90}],shadowEntities:['moon']},controllers:[{type:'dynamo',url:'sc_lunar_reconnaissance_orbiter/earth/orb'},{type:'dynamo',url:'sc_lunar_reconnaissance_orbiter/moon/orb'},{type:'align',primary:{type:'velocity',target:'sc_lunar_reconnaissance_orbiter',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg},secondary:{type:'point',target:'moon',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}},{type:'dynamo',url:'sc_lunar_reconnaissance_orbiter/ori'}]},sc_smart_1:{groups:['moon','spacecraft'],occlusionRadius:0.0015,extentsRadius:0.006530,label:'SMART-1',parents:[[117977163.35299999,'moon'],[210585600,'']],trail:{length:273091.0},controllers:[{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity},{type:'animdata',url:'sc_smart_1/moon/all',dataType:'pos'}]},sc_themis_b:{groups:['moon','spacecraft'],occlusionRadius:0.000400,extentsRadius:0.00170,label:'ARTEMIS P1',parents:[[366638466.1829504,'moon'],[694267209.1839211,'']],trail:{length:94838.0},model:{url:'$STATIC_ASSETS_URL/models/sc_themis/themis.gltf',shadowEntities:['moon']},controllers:[{type:'animdata',url:'sc_themis_b/moon/all',dataType:'pos'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis}},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis,periodInHours:0.0008333}]},sc_themis_c:{groups:['moon','spacecraft'],occlusionRadius:0.000400,extentsRadius:0.00170,label:'ARTEMIS P2',parents:[[366638466.1829504,'moon'],[694267209.1839211,'']],trail:{length:204186.0},model:{url:'$STATIC_ASSETS_URL/models/sc_themis/themis.gltf',shadowEntities:['moon']},controllers:[{type:'animdata',url:'sc_themis_c/moon/all',dataType:'pos'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis}},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis,periodInHours:0.0008333}]}})}),"../pioneer/scripts/src/entities/mars_moons.js": + /*!*****************************************************!*\ + !*** ../pioneer/scripts/src/entities/mars_moons.js ***! + \*****************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({phobos:{groups:['mars','moons'],radius:14.0,label:'Phobos',parents:[[Number.NEGATIVE_INFINITY,'mars']],trail:{length:undefined,color:[0.89,0.51,0.35,0.7]},model:{url:'$STATIC_ASSETS_URL/models/phobos/phobos.gltf',scale:[1,1,1],rotate:[{z:90},{y:90}],shadowEntities:['mars']},controllers:[{type:'dynamo',url:'phobos/mars/orb'},{type:'dynamo',url:'phobos/ori'}]},deimos:{groups:['mars','moons'],radius:8.70951,label:'Deimos',parents:[[Number.NEGATIVE_INFINITY,'mars']],trail:{length:undefined,color:[0.89,0.51,0.35,0.7]},model:{url:'$STATIC_ASSETS_URL/models/deimos/deimos.gltf',scale:[1,1,1],rotate:[{y:-180}],shadowEntities:['mars']},controllers:[{type:'dynamo',url:'deimos/mars/orb'},{type:'dynamo',url:'deimos/ori'}]}})}),"../pioneer/scripts/src/entities/mars_spacecraft.js": + /*!**********************************************************!*\ + !*** ../pioneer/scripts/src/entities/mars_spacecraft.js ***! + \**********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({sc_mars_2020:{groups:['mars','spacecraft','landers'],occlusionRadius:0.0015,extentsRadius:0.003,label:'Mars 2020',parents:[[649385564,'earth'],[649595376,'sun'],[666932224,'mars'],[666952859,'sc_mars_2020_landing_site']],trail:{length:10000000.0,lengthCoverages:[[10000000,649385564,666932224],[3000,666932224,666953098.003000],[9676800,666953098.003000+9676800,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_mars_2020/cruise_whole/msl_cruise_stage.gltf',rotate:[{x:-90}],shadowEntities:['mars']},controllers:[{type:'dynamo',url:'sc_mars_2020/earth/orb'},{type:'dynamo',url:'sc_mars_2020/sun/orb'},{type:'dynamo',url:'sc_mars_2020/mars/pos'},{type:'dynamo',url:'sc_mars_2020/surface/lin'},{type:'custom',func:(entity)=>{const controller=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController);controller.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-0.125148,0.026867,-0.023641));return controller},coverage:[666952859,666953098.003000]},{type:'dynamo',url:'sc_mars_2020/quat'},{type:'dynamo',url:'sc_mars_2020/surface/quat_v2'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:0.00833333333,relativeToTime:649385564,coverage:[649385564,666952859]},{type:'rotateByEntityOrientation',entityForOrientation:'mars',coverage:[666952859,Number.POSITIVE_INFINITY]},{type:'custom',func:(entity)=>{const groundClamp=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.GroundClampController);groundClamp.setDistanceFromGround(0.001);groundClamp.setGroundComponentRef('mars','cmts');groundClamp.setUp(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg);groundClamp.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(666953086.614,Number.POSITIVE_INFINITY));return groundClamp}},{type:'coverage',coverage:[666953086.614,Number.POSITIVE_INFINITY],enter:(entity)=>{const div=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent);div.getDiv().innerHTML.replace('Mars 2020','Perseverance')},exit:(entity)=>{const div=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent);div.getDiv().innerHTML.replace('Perseverance','Mars 2020')}},{type:'coverage',coverage:[666953098.003000,666953098.003000+9676800],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setStartTime(666953098.003000);trail.setRelativeStartTime(!1)}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeStartTime(!0)}}},{type:'coverage',coverage:[666932224,Number.POSITIVE_INFINITY],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!0)}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!1)}}},{type:'coverage',coverage:[666953086.614,Number.POSITIVE_INFINITY],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_2020/rover/perseverance.gltf');model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.5,-0.5,0.5,-0.5));model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0,0,0.001))},exit:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_2020/cruise_whole/msl_cruise_stage.gltf');model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.7071067811865478,-0.7071067811865472,0,0));model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0,0,0))}},{type:'coverage',coverage:[666953098.003000,Number.POSITIVE_INFINITY],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setIgnoreDistance(!0)}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setIgnoreDistance(!1)}}},{type:'coverage',coverage:[666952458,666953086.614],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setHiddenObject('solar_panels',!0);model.setHiddenObject('frame_etc',!0)}},exit:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setHiddenObject('solar_panels',!1);model.setHiddenObject('frame_etc',!1)}}},{type:'coverage',coverage:[666953086.614,Number.POSITIVE_INFINITY],update:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.resetPoints()}},updateInterval:10}]},sc_mars_2020_landing_site:{groups:['mars','sc_mars_2020','sites'],radius:0.001,systemRadius:200,label:'Mars 2020 Landing Site',parents:[[649385563.6433017,'mars']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(0.32191947313922714,1.351772964399859,-2.2364351843552868),coverage:[649385563.6433017,Number.POSITIVE_INFINITY]}]},sc_mars_science_laboratory:{groups:['mars','spacecraft','landers'],occlusionRadius:0.001515,extentsRadius:0.004,label:'Mars Science Laboratory',parents:[[375594733,'earth'],[376039259,'sun'],[397477501,'mars'],[397502386.832,'sc_mars_science_laboratory_landing_site']],trail:{length:10000000,lengthCoverages:[[10000000,375594733,397501373],[3000,397501373,397502386.832+9676800],[9676800,397502386.832+9676800,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_mars_science_laboratory/cruise/msl_cruisestage.gltf',rotate:[{x:-90}],shadowEntities:['mars']},controllers:[{type:'dynamo',url:'sc_mars_science_laboratory/earth/orb'},{type:'dynamo',url:'sc_mars_science_laboratory/sun/orb'},{type:'dynamo',url:'sc_mars_science_laboratory/mars/orb'},{type:'dynamo',url:'sc_mars_science_laboratory/edl/pos'},{type:'custom',func:(entity)=>{const controller=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController);controller.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.002583,0.002995,0.001937));return controller},coverage:[397501373,397502386.832]},{type:'dynamo',url:'sc_mars_science_laboratory/surface/lin_v2'},{type:'dynamo',url:'sc_mars_science_laboratory/quat'},{type:'dynamo',url:'sc_mars_science_laboratory/surface/quat_v2'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:0.00833333333,relativeToTime:375594733,coverage:[375594733,397501866]},{type:'rotateByEntityOrientation',entityForOrientation:'mars',rotatingOrientation:!1,coverage:[397501373,Number.POSITIVE_INFINITY]},{type:'rotateByEntityOrientation',entityForOrientation:'mars',rotatingPosition:!1,coverage:[397502386.832,Number.POSITIVE_INFINITY]},{type:'custom',func:(entity)=>{const groundClamp=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.GroundClampController);groundClamp.setDistanceFromGround(0.00098);groundClamp.setGroundComponentRef('mars','cmts');groundClamp.setUp(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg);groundClamp.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(397502386.832,Number.POSITIVE_INFINITY));return groundClamp}},{type:'coverage',coverage:[397502386.832,Number.POSITIVE_INFINITY],enter:(entity)=>{const div=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent);div.getDiv().innerHTML.replace('Mars Science Laboratory','Curiosity')},exit:(entity)=>{const div=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent);div.getDiv().innerHTML.replace('Curiosity','Mars Science Laboratory')}},{type:'coverage',coverage:[397501373,Number.POSITIVE_INFINITY],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!0)}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!1)}}},{type:'coverage',coverage:[397502324,Number.POSITIVE_INFINITY],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_science_laboratory/rover/curiosity_static.gltf');model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.5,-0.5,0.5,-0.5));model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0,0,0.001))}},exit:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_science_laboratory/cruise/msl_cruisestage.gltf');model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.7071067811865478,-0.7071067811865472,0,0));model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0,0,0))}}},{type:'coverage',coverage:[397502386.832,Number.POSITIVE_INFINITY],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setIgnoreDistance(!0)}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setIgnoreDistance(!1)}}},{type:'coverage',coverage:[397501758,397502386.832],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setHiddenObject('solar_panels',!0);model.setHiddenObject('frame_etc',!0)}},exit:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setHiddenObject('solar_panels',!1);model.setHiddenObject('frame_etc',!1)}}},{type:'coverage',coverage:[397502386.832,Number.POSITIVE_INFINITY],update:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.resetPoints()}},updateInterval:10}]},sc_mars_science_laboratory_landing_site:{groups:['mars','sc_mars_science_laboratory','sites'],occlusionRadius:0.001515,extentsRadius:0.004,systemRadius:200,label:'Curiosity Landing Site',parents:[[375594732.3829685,'mars']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(-4.589466996319/180*Math.PI,137.441632996891/180*Math.PI,-4.927711819685555),coverage:[375594732.3829685,Number.POSITIVE_INFINITY]}]},sc_mars_exploration_rover_1:{groups:['mars','spacecraft','landers'],occlusionRadius:0.0013,extentsRadius:0.0026,label:'Opportunity',parents:[[110911022.184,'earth'],[111234172,'sun'],[128262836,'mars'],[128278419,'sc_mars_exploration_rover_1_landing_site'],[581920316.8566707,'']],trail:{length:6720.0,lengthCoverages:[[10000000,Number.NEGATIVE_INFINITY,128262836],[6720.0,128262836,128278419],[0,128278523.336,581920316.856]]},model:{url:'$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/cruise/mpf_mera_merb_cruise.gltf',rotate:[{x:90}]},controllers:[{type:'dynamo',url:'sc_mars_exploration_rover_1/earth/orb'},{type:'dynamo',url:'sc_mars_exploration_rover_1/sun/orb'},{type:'dynamo',url:'sc_mars_exploration_rover_1/mars/pos'},{type:'dynamo',url:'sc_mars_exploration_rover_1/edl/pos'},{type:'dynamo',url:'sc_mars_exploration_rover_1/surface/pos'},{type:'align',primary:{type:'velocity',target:'sc_mars_exploration_rover_1',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg},secondary:{type:'align',target:'mars',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis},coverage:[Number.NEGATIVE_INFINITY,128278523.336]},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity,coverage:[128278523.336,581920316.856]},{type:'coverage',coverage:[128278419,581920316.856],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!0)}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!1)}}},{type:'coverage',coverage:[128278523.336,581920316.856],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/rover/mer_static.gltf')}},exit:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/cruise/mpf_mera_merb_cruise.gltf')}}},{type:'coverage',coverage:[Number.NEGATIVE_INFINITY,128262836],enter:(entity)=>{const align=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController);if(align!==null){align.setPrimaryAlignType('point');align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis);align.setPrimaryTargetEntity('sun')}},exit:(entity)=>{const align=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController);if(align!==null){align.setPrimaryAlignType('velocity');align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg);align.setPrimaryTargetEntity('sc_mars_exploration_rover_1')}}}],postCreateFunction:(entity)=>{const rotate=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.RotateController);const rot90=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion();rot90.setFromAxes(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis,pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg,undefined);rotate.setRotation(rot90);rotate.setRotatingOrientation(!1);rotate.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(128278419,581920316.856));const rotateByEntityOrientation=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.RotateByEntityOrientationController,'landingRotateByEntity',entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController));rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(128278419,581920316.856))}},sc_mars_exploration_rover_1_landing_site:{groups:['mars','sc_mars_exploration_rover_1','sites'],radius:0.001,systemRadius:200,label:'Opportunity Landing Site',parents:[[110911022.184,'mars']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(-0.034003934569818886,-0.09644392740547784,-2.018490164449304),coverage:[110911022.184,Number.POSITIVE_INFINITY]}]},sc_mars_exploration_rover_2:{groups:['mars','spacecraft','landers'],occlusionRadius:0.0013,extentsRadius:0.0026,label:'Spirit',parents:[[108541883.184,'earth'],[108887371,'sun'],[126444477,'mars'],[126462105,'sc_mars_exploration_rover_2_landing_site'],[322567479.3896215,'']],trail:{length:6720.0,lengthCoverages:[[10000000,Number.NEGATIVE_INFINITY,126444477],[6720.0,126444477,126462105],[0,126462396.105800,322567479.389620]]},model:{url:'$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/cruise/mpf_mera_merb_cruise.gltf',rotate:[{x:90}]},controllers:[{type:'dynamo',url:'sc_mars_exploration_rover_2/earth/orb'},{type:'dynamo',url:'sc_mars_exploration_rover_2/sun/orb'},{type:'dynamo',url:'sc_mars_exploration_rover_2/mars/pos'},{type:'dynamo',url:'sc_mars_exploration_rover_2/edl/pos'},{type:'dynamo',url:'sc_mars_exploration_rover_2/surface/pos'},{type:'rotateByEntityOrientation',coverage:[126462105,322567479.389620]},{type:'align',primary:{type:'velocity',target:'sc_mars_exploration_rover_2',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg},secondary:{type:'align',target:'mars',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis},coverage:[Number.NEGATIVE_INFINITY,126462105]},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity,coverage:[126462105,322567479.389620]},{type:'coverage',coverage:[126462105,322567479.389620],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!0)}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!1)}}},{type:'coverage',coverage:[126462396.105800,322567479.389620],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/rover/mer_static.gltf')}},exit:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setUrl('$STATIC_ASSETS_URL/models/sc_mars_exploration_rover/cruise/mpf_mera_merb_cruise.gltf')}}},{type:'coverage',coverage:[Number.NEGATIVE_INFINITY,126444477],enter:(entity)=>{const align=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController);if(align!==null){align.setPrimaryAlignType('point');align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis);align.setPrimaryTargetEntity('sun')}},exit:(entity)=>{const align=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController);if(align!==null){align.setPrimaryAlignType('velocity');align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg);align.setPrimaryTargetEntity('sc_mars_exploration_rover_2')}}}],postCreateFunction:(entity)=>{const rotate=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.RotateController);const rot90=new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion();rot90.setFromAxes(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis,pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg,undefined);rotate.setRotation(rot90);rotate.setRotatingOrientation(!1);rotate.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(126462105,322567479.389620))}},sc_mars_exploration_rover_2_landing_site:{groups:['mars','sc_mars_exploration_rover_2','sites'],radius:0.001,systemRadius:200,label:'Spirit Landing Site',parents:[[108541883.184,'mars']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(-0.25432749290990797,3.062677242395019,-2.614394925059969),coverage:[108541883.184,Number.POSITIVE_INFINITY]}]},sc_insight:{groups:['mars','spacecraft','landers'],radius:0.00306,label:'InSight',parents:[[578795968.9654216,'earth'],[579182469.185,'sun'],[596376069.183,'mars']],trail:{length:32137022.16,lengthCoverages:[[32137022.16,Number.NEGATIVE_INFINITY,596376069.183],[14400,596376069.183,596533471.284-3600],[3600,596533471.284-3600,596533602],[0,596533602,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_insight/lander/insight.gltf',rotate:[{y:90}]},controllers:[{type:'dynamo',url:'sc_insight/earth/pos'},{type:'dynamo',url:'sc_insight/sun/orb'},{type:'dynamo',url:'sc_insight/mars/orb'},{type:'dynamo',url:'sc_insight_edl/mars/pos'},{type:'align',primary:{type:'point',target:'mars',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg},secondary:{type:'align',target:'mars',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis},coverage:[578795968.9654216,596533602]},{type:'dynamo',url:'sc_insight/ori'},{type:'dynamo',url:'sc_insight_edl/ori'},{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(0.07881611091588075,2.3734709256393973,-2.996371903616364),llaOnSpheroidEntity:'mars',coverage:[596533602,Number.POSITIVE_INFINITY]},{type:'coverage',coverage:[596533471.284-3600,596533602],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!0)}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!1)}}},{type:'coverage',coverage:[578795968.9654216,596533602],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setUrl('$STATIC_ASSETS_URL/models/sc_insight/cruise/model.gltf');model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(Math.sqrt(0.5),0,Math.sqrt(0.5),0));model.setTranslation(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero)}}},{type:'coverage',coverage:[596533602,Number.POSITIVE_INFINITY],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(model!==null){model.setUrl('$STATIC_ASSETS_URL/models/sc_insight/lander/insight.gltf');model.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(Math.sqrt(0.5),Math.sqrt(0.5),0,0));model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0,0,0.00085))}}}]},sc_insight_landing_site:{groups:['mars','sc_insight','sites'],radius:0.001,systemRadius:200,label:'InSight Landing Site',parents:[[578795968.9654216,'mars'],[596533602,'']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(0.07881611091588075,2.3734709256393973,-2.996371903616364),coverage:[578795968.9654216,596533602]}]},sc_marco_a:{groups:['mars','spacecraft'],radius:0.00044375,label:'MarCO A',parents:[[578796051,'earth'],[579182469.185,'sun'],[596376069.183,'mars'],[596552080,'sun'],[631152000,'']],trail:{length:6720.0,lengthCoverages:[[10000000,Number.NEGATIVE_INFINITY,579182469.185],[6720.0,579182469.185,596552080],[10000000,596552080,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_marco/model.gltf'},controllers:[{type:'dynamo',url:'sc_marco_a/earth/orb'},{type:'dynamo',url:'sc_marco_a/sun/1/orb'},{type:'dynamo',url:'sc_marco_a/mars/orb'},{type:'dynamo',url:'sc_marco_a/sun/2/orb'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis}}]},sc_marco_b:{groups:['mars','spacecraft'],radius:0.00044375,label:'MarCO B',parents:[[578796051,'earth'],[579182469.185,'sun'],[596376069.183,'mars'],[596552080,'sun'],[631152000,'']],trail:{length:6720.0,lengthCoverages:[[10000000,Number.NEGATIVE_INFINITY,579182469.185],[6720.0,579182469.185,596552080],[10000000,596552080,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_marco/model.gltf'},controllers:[{type:'dynamo',url:'sc_marco_b/earth/orb'},{type:'dynamo',url:'sc_marco_b/sun/1/orb'},{type:'dynamo',url:'sc_marco_b/mars/orb'},{type:'dynamo',url:'sc_marco_b/sun/2/orb'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis}}]},sc_mars_odyssey:{groups:['mars','spacecraft'],occlusionRadius:0.0013,extentsRadius:0.004,label:'Mars Odyssey',parents:[[39932700,'earth'],[40233664,'sun'],[57128464,'mars']],trail:{length:6727.0,lengthCoverages:[[10000000,Number.NEGATIVE_INFINITY,57128464],[6727.0,57128464,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_mars_odyssey/mars_odyssey.gltf',environmentMap:{cubemap:'$STATIC_ASSETS_URL/env_maps/park_gray/$FACE.jpg'},shadowEntities:['mars','deimos','phobos']},controllers:[{type:'dynamo',url:'sc_mars_odyssey/earth/orb'},{type:'dynamo',url:'sc_mars_odyssey/sun/orb'},{type:'dynamo',url:'sc_mars_odyssey/mars/orb'},{type:'align',primary:{type:'point',target:'mars',axis:new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-0.95630475596,0.29237170472,0)},secondary:{type:'velocity',target:'sc_mars_odyssey',axis:new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.29237170472,0.95630475596,0)}},{type:'dynamo',url:'sc_mars_odyssey/ori'}]},sc_mars_reconnaissance_orbiter:{groups:['mars','spacecraft'],radius:0.0068,label:'Mars Reconnaissance Orbiter',parents:[[177122516,'earth'],[177429664,'sun'],[195285665,'mars']],trail:{length:6720.0,lengthCoverages:[[10000000,Number.NEGATIVE_INFINITY,195285665],[6720.0,195285665,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_mars_reconnaissance_orbiter/MRO.gltf',environmentMap:{cubemap:'$STATIC_ASSETS_URL/env_maps/park_gray/$FACE.jpg'},shadowEntities:['mars','deimos','phobos']},controllers:[{type:'dynamo',url:'sc_mars_reconnaissance_orbiter/earth/orb'},{type:'dynamo',url:'sc_mars_reconnaissance_orbiter/sun/orb'},{type:'dynamo',url:'sc_mars_reconnaissance_orbiter/mars/orb'},{type:'align',primary:{type:'point',target:'mars',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_mars_reconnaissance_orbiter',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis}},{type:'dynamo',url:'sc_mars_reconnaissance_orbiter/ori'}]},sc_maven:{groups:['mars','spacecraft'],radius:0.0057,label:'MAVEN',parents:[[438074509.3428109,'earth'],[438296467,'sun'],[464590867,'mars']],trail:{length:16139.0},model:{url:'$STATIC_ASSETS_URL/models/sc_maven/Maven.gltf',rotate:[{x:90},{z:90}],environmentMap:{cubemap:'$STATIC_ASSETS_URL/env_maps/park_gray/$FACE.jpg'},shadowEntities:['mars','deimos','phobos']},controllers:[{type:'dynamo',url:'sc_maven/earth/orb'},{type:'dynamo',url:'sc_maven/sun/orb'},{type:'dynamo',url:'sc_maven/mars/orb'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}},{type:'dynamo',url:'sc_maven/ori'}]},sc_mars_express:{groups:['mars','spacecraft'],radius:0.006,label:'Mars Express',parents:[[107853140.59600002,'earth'],[108232264,'sun'],[125539264,'mars']],trail:{length:25000.0,lengthCoverages:[[10000000,Number.NEGATIVE_INFINITY,126749131],[12720.0,126749131,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_mars_express/mars_express.gltf',rotate:[{x:90},{z:-180}],environmentMap:{cubemap:'$STATIC_ASSETS_URL/env_maps/park_gray/$FACE.jpg'},shadowEntities:['mars','deimos','phobos']},controllers:[{type:'dynamo',url:'sc_mars_express/earth/orb'},{type:'dynamo',url:'sc_mars_express/sun/orb'},{type:'dynamo',url:'sc_mars_express/mars/orb'},{type:'align',primary:{type:'point',target:'mars',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg}},{type:'dynamo',url:'sc_mars_express/ori'}]},sc_phoenix:{groups:['mars','spacecraft'],radius:0.0027,label:'Phoenix',parents:[[239496427,'earth'],[239618121,'sun'],[265008306,'mars'],[265030318,'sc_phoenix_landing_site'],[278942465,'']],trail:{length:45411186.0,lengthCoverages:[[45411186,Number.NEGATIVE_INFINITY,265008306],[50000,265008306,265030318],[500,265030318,265030769],[0,265030769,278942465]]},model:{url:'$STATIC_ASSETS_URL/models/sc_phoenix/cruise/phoenix_cruise.gltf',rotate:[{z:90}]},controllers:[{type:'dynamo',url:'sc_phoenix/earth/orb'},{type:'dynamo',url:'sc_phoenix/sun/orb'},{type:'dynamo',url:'sc_phoenix/mars/orb'},{type:'dynamo',url:'sc_phoenix/phx_topo/pos'},{type:'dynamo',url:'sc_phoenix/ori'},{type:'fixed',position:new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.027059368126568832,0.013878235928918032,-0.04367634407940447),coverage:[265030769,278942465]},{type:'rotateByEntityOrientation',rotatingOrientation:!1,coverage:[265030769,278942465]},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg}},{type:'coverage',coverage:[265030324-7*60,Number.POSITIVE_INFINITY],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);model.setUrl('$STATIC_ASSETS_URL/models/sc_phoenix/edl/phoenix_edl.gltf')},exit:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);model.setUrl('$STATIC_ASSETS_URL/models/sc_phoenix/cruise/phoenix_cruise.gltf')}}],postCreateFunction:(entity)=>{entity.addParentChangedCallback((entity,_,newParent)=>{if(newParent!==null){const parentName=newParent.getName();const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(parentName==='sc_phoenix_landing_site'){trail.setRelativeToEntity('mars');trail.setRelativeToEntityOrientation(!0)}else{trail.setRelativeToEntity('');trail.setRelativeToEntityOrientation(!1)}}})}},sc_phoenix_landing_site:{groups:['mars','sc_phoenix','sites'],radius:0.001,systemRadius:200,label:'Phoenix Landing Site',parents:[[239496427,'mars']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(1.1906355815662266,-2.1947740491302206,-2.5912352775421823),coverage:[239496427,Number.POSITIVE_INFINITY]}]},sc_trace_gas_orbiter:{groups:['mars','spacecraft'],radius:0.00875915,label:'Trace Gas Orbiter',parents:[[511257268,'earth'],[511941668,'sun'],[530107268,'mars']],trail:{length:6720.0,lengthCoverages:[[10000000,Number.NEGATIVE_INFINITY,530160041],[6720.0,530160041,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_trace_gas_orbiter/TGO.gltf',rotate:[{x:-90},{y:-90}],environmentMap:{cubemap:'$STATIC_ASSETS_URL/env_maps/park_gray/$FACE.jpg'},shadowEntities:['mars','deimos','phobos']},controllers:[{type:'dynamo',url:'sc_trace_gas_orbiter/earth/orb'},{type:'dynamo',url:'sc_trace_gas_orbiter/sun/orb'},{type:'dynamo',url:'sc_trace_gas_orbiter/mars/orb'},{type:'align',primary:{type:'point',target:'mars',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg},secondary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg}},{type:'dynamo',url:'sc_trace_gas_orbiter/ori'}],postCreateFunction:(entity)=>{let align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController);align.setJoint('right_array_1');align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis);align.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun');align=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController);align.setJoint('left_array_1');align.setPrimaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis);align.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis);align.setSecondaryAlignType('point');align.setSecondaryTargetEntity('sun')}},sc_mars_orbiter_mission:{groups:['mars','spacecraft'],radius:0.00275,label:'Mars Orbiter Mission',parents:[[623211069.1823474,'mars']],trail:{length:234146.0},controllers:[{type:'animdata',url:'sc_mars_orbiter_mission/mars',dataType:'pos'}]},sc_mars_global_surveyor:{groups:['mars','spacecraft'],occlusionRadius:0.003,extentsRadius:0.005,label:'Mars Global Surveyor',parents:[[-72699545,'mars'],[215697664.184,'']],trail:{length:7068.67},model:{url:'$STATIC_ASSETS_URL/models/sc_mars_global_surveyor/mars_global_surveyor.gltf',shadowEntities:['mars']},controllers:[{type:'animdata',url:'sc_mars_global_surveyor_mission',dataType:'pos'},{type:'align',primary:{type:'point',target:'mars',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg}}]},sc_mars_climate_orbiter:{groups:['mars','spacecraft'],radius:0.0011,label:'Mars Climate Orbiter',parents:[[-33318000,'sun'],[-8650375.816,'']],trail:{length:24587405.0*3.0},controllers:[{type:'animdata',url:'sc_mars_climate_orbiter',dataType:'pos'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},sc_mars_pathfinder:{groups:['mars','spacecraft'],radius:0.00033,label:'Mars Pathfinder',parents:[[-91704541,'sun'],[-78692880,'']],trail:{length:12874372.0*4.0},controllers:[{type:'animdata',url:'sc_mars_pathfinder',dataType:'pos'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},sc_mars_pathfinder_landing_site:{groups:['mars','sc_mars_pathfinder','sites'],radius:0.001,systemRadius:200,label:'Mars Pathfinder Landing Site',parents:[[-97045250.817,'mars']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(19.13*Math.PI/180,-33.22*Math.PI/180,0),coverage:[-97045250.817,Number.POSITIVE_INFINITY]}]},sc_mars_polar_lander:{groups:['mars','spacecraft'],radius:0.0018,label:'Mars Polar Lander',parents:[[-31298400,'sun'],[-2476735.816,'']],trail:{length:41109006.0},controllers:[{type:'animdata',url:'sc_mars_polar_lander',dataType:'pos'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},sc_viking_1_orbiter:{groups:['mars','spacecraft'],radius:0.0047,label:'Viking 1 Orbiter',parents:[[-742490410,'mars'],[-663249600,'']],trail:{length:88649.0},controllers:[{type:'animdata',url:'sc_viking_1_orbiter',dataType:'pos'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},sc_viking_1_lander_landing_site:{groups:['mars','sc_viking_1_lander','sites'],radius:0.001,systemRadius:200,label:'Viking 1 Lander Landing Site',parents:[[-768926233.817,'mars']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(22.27*Math.PI/180,312.05*Math.PI/180,0),coverage:[-768926233.817,Number.POSITIVE_INFINITY]}]},sc_viking_2_orbiter:{groups:['mars','spacecraft'],radius:0.0047,label:'Viking 2 Orbiter',parents:[[-738460186,'mars'],[-676517400,'']],trail:{length:98694.0},controllers:[{type:'animdata',url:'sc_viking_2_orbiter',dataType:'pos'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},sc_viking_2_lander_landing_site:{groups:['mars','sc_viking_2_lander','sites'],radius:0.001,systemRadius:200,label:'Viking 2 Lander Landing Site',parents:[[-767208013.818,'mars']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(47.64*Math.PI/180,-225.71*Math.PI/180,0),coverage:[-767208013.818,Number.POSITIVE_INFINITY]}]}})}),"../pioneer/scripts/src/entities/mercury_spacecraft.js": + /*!*************************************************************!*\ + !*** ../pioneer/scripts/src/entities/mercury_spacecraft.js ***! + \*************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({sc_messenger:{groups:['mercury','spacecraft'],occlusionRadius:0.00133,extentsRadius:0.0035,label:'MESSENGER',parents:[[144789279.39320505,'earth'],[145066469,'sun'],[175801890,'earth'],[176659095,'sun'],[214828942,'venus'],[215033751,'sun'],[234289415,'venus'],[234436749,'sun'],[253547108,'mercury'],[253671753,'sun'],[276485360,'mercury'],[276627276,'sun'],[307423681,'mercury'],[307651285,'sun'],[353474040,'mercury'],[483694028.351,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_messenger/Messenger.gltf',rotate:[{z:-90},{y:90}],shadowEntities:['mercury']},controllers:[{type:'dynamo',url:'sc_messenger/earth/launch/orb'},{type:'dynamo',url:'sc_messenger/sun/1/orb'},{type:'dynamo',url:'sc_messenger/earth/flyby/orb'},{type:'dynamo',url:'sc_messenger/sun/2/orb'},{type:'dynamo',url:'sc_messenger/venus/flyby1/orb'},{type:'dynamo',url:'sc_messenger/sun/3/orb'},{type:'dynamo',url:'sc_messenger/venus/flyby2/orb'},{type:'dynamo',url:'sc_messenger/sun/4/orb'},{type:'dynamo',url:'sc_messenger/mercury/flyby1/orb'},{type:'dynamo',url:'sc_messenger/sun/5/orb'},{type:'dynamo',url:'sc_messenger/mercury/flyby2/orb'},{type:'dynamo',url:'sc_messenger/sun/6/orb'},{type:'dynamo',url:'sc_messenger/mercury/flyby3/orb'},{type:'dynamo',url:'sc_messenger/sun/7/orb'},{type:'dynamo',url:'sc_messenger/mercury/orb'},{type:'align',primary:{type:'point',target:'mercury',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis},secondary:{type:'velocity',target:'sc_messenger',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}},{type:'dynamo',url:'sc_messenger/ori'}]},sc_messenger_impact_site:{groups:['mercury','sc_messenger','sites'],radius:0.001,label:'MESSENGER Impact Site',parents:[[Number.NEGATIVE_INFINITY,'mercury']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(0.9501527254431932,-2.615904550043192,-0.910251923861324),coverage:[483694028.351,Number.POSITIVE_INFINITY]}]}})}),"../pioneer/scripts/src/entities/minor_planets.js": + /*!********************************************************!*\ + !*** ../pioneer/scripts/src/entities/minor_planets.js ***! + \********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({'1_ceres':{groups:['dwarf planets'],radius:473.0,label:'Ceres',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},spheroid:{equatorialRadius:482.6,polarRadius:445.6,planetographic:!1},spheroidLOD:{textures:{color:{url:'1_ceres/color_$SIZE_$FACE.jpg',sizes:[16,512,4096]}}},controllers:[{type:'dynamo',url:'1_ceres/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'101955_bennu':{groups:['asteroids','NEOs','PHAs'],radius:0.246,label:'Bennu',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/101955_bennu/Bennu.gltf',rotate:[{x:83},{z:-168}],scale:0.0009956},controllers:[{type:'dynamo',url:'101955_bennu/sun/orb'},{type:'dynamo',url:'101955_bennu/ori'}]},'11351_leucus':{groups:['asteroids'],radius:17.0775,label:'Leucus',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:17.0775},controllers:[{type:'dynamo',url:'11351_leucus/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:445.732}]},'12923_zephyr':{groups:['asteroids','NEOs','PHAs'],radius:1.03,label:'Zephyr',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.03,1.03,1.03]},controllers:[{type:'dynamo',url:'12923_zephyr/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:3.891}]},'134340_pluto':{groups:['dwarf planets','moons','134340_pluto_barycenter'],radius:1187.0,label:'Pluto',labelFadeEntity:'sun',parents:[[Number.NEGATIVE_INFINITY,'134340_pluto_barycenter']],trail:{length:undefined},spheroid:{equatorialRadius:1187.0,polarRadius:1187.0,planetographic:!1},spheroidLOD:{textures:{color:{url:'134340_pluto/color_$SIZE_$FACE.png',sizes:[4,512,4096]}}},controllers:[{type:'dynamo',url:'134340_pluto/134340_pluto_barycenter/orb'},{type:'align',primary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis,target:'charon'},secondary:{type:'velocity',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis,target:'charon'}}]},'134340_pluto_barycenter':{groups:['134340_pluto','barycenters'],occlusionRadius:0.001,extentsRadius:28000,systemRadius:130153,label:'Barycenter',labelFadeEntity:'134340_pluto',trail:{length:undefined},parents:[[Number.NEGATIVE_INFINITY,'sun']],controllers:[{type:'dynamo',url:'134340_pluto_barycenter/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}],postCreateFunction:(entity)=>{const divComponent=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent);divComponent.setFadeWhenCloseToCamera(!1);entity.setCanOcclude(!1)}},'136108_haumea':{groups:['dwarf planets','TNOs'],radius:816.0,label:'Haumea',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/136108_haumea/haumea.gltf',scale:[1,1,1]},controllers:[{type:'dynamo',url:'136108_haumea/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},'136199_eris':{groups:['dwarf planets','TNOs'],radius:1163.0,label:'Eris',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},spheroid:{equatorialRadius:1163.0,polarRadius:1163.0,planetographic:!1},spheroidLOD:{textures:{color:{url:'136199_eris/color_$SIZE_$FACE.png',sizes:[4,512]}}},controllers:[{type:'dynamo',url:'136199_eris/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},'136472_makemake':{groups:['dwarf planets','TNOs'],radius:715.0,label:'Makemake',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},spheroid:{equatorialRadius:717.0,polarRadius:710.0,planetographic:!1},spheroidLOD:{textures:{color:{url:'136472_makemake/color_$SIZE_$FACE.png',sizes:[4,512]}}},controllers:[{type:'dynamo',url:'136472_makemake/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},'14827_hypnos':{groups:['asteroids','NEOs','PHAs'],radius:0.4535,label:'Hypnos',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.4535,0.4535,0.4535]},controllers:[{type:'dynamo',url:'14827_hypnos/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'15094_polymele':{groups:['asteroids'],radius:10.5375,label:'Polymele',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:10.5375},controllers:[{type:'dynamo',url:'15094_polymele/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:5.8607}]},'1566_icarus':{groups:['asteroids','NEOs','PHAs'],radius:0.805,label:'Icarus',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.805,0.800,0.585]},controllers:[{type:'dynamo',url:'1566_icarus/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:2.2726}]},'16_psyche':{groups:['asteroids'],radius:125.0,label:'16 Psyche',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/16_psyche/psycheAsteroid.gltf',scale:[100,100,100],rotate:[{x:90}]},controllers:[{type:'dynamo',url:'16_psyche/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},'1620_geographos':{groups:['asteroids','NEOs','PHAs'],radius:2.5,label:'Geographos',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.5,1.0,1.05]},controllers:[{type:'dynamo',url:'1620_geographos/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:5.224}]},'162173_ryugu':{groups:['asteroids','NEOs','PHAs'],radius:0.45,label:'Ryugu',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/162173_ryugu/ryugu.gltf',rotate:[{x:-90}]},controllers:[{type:'dynamo',url:'ssd/162173_ryugu/sun/orb'},{type:'dynamo',url:'162173_ryugu/ori'}]},'1862_apollo':{groups:['asteroids','NEOs','PHAs'],radius:0.75,label:'Apollo',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.75,0.75,0.75]},controllers:[{type:'dynamo',url:'1862_apollo/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:3.065}]},'1981_midas':{groups:['asteroids','NEOs','PHAs'],radius:0.975,label:'Midas',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.975,0.975,0.975]},controllers:[{type:'dynamo',url:'1981_midas/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:5.22}]},'1991_vg':{groups:['asteroids','NEOs'],radius:0.00425,label:'1991 VG',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.00425,0.00425,0.00425]},controllers:[{type:'dynamo',url:'1991_vg/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'1993_hd':{groups:['asteroids','asteroid belt'],radius:0.005,label:'1993 HD',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'1993_hd/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'1994_cc_a':{groups:['asteroids','NEOs','PHAs'],radius:0.325,label:'1994 CC',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.325,0.325,0.325]},controllers:[{type:'dynamo',url:'1994_cc_a/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:2.38860}]},'1996_xb27':{groups:['asteroids','NEOs'],radius:0.042,label:'1996 XB27',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.042,0.042,0.042]},controllers:[{type:'dynamo',url:'1996_xb27/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:1.195}]},'1998_ky26':{groups:['asteroids','NEOs'],radius:0.015,label:'1998 KY26',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.015,0.015,0.015]},controllers:[{type:'dynamo',url:'1998_ky26/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:0.1784}]},'1998_ml14':{groups:['asteroids','NEOs','PHAs'],radius:0.5,label:'1998 ML14',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.5,0.5,0.5]},controllers:[{type:'dynamo',url:'1998_ml14/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:14.28}]},'1998_qe2':{groups:['asteroids','NEOs','PHAs'],radius:1.375,label:'1998 QE2',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.375,1.375,1.375]},controllers:[{type:'dynamo',url:'1998_qe2/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:4.749}]},'1999_ao10':{groups:['asteroids','NEOs'],radius:0.025,label:'1999 AO10',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.025,0.025,0.025]},controllers:[{type:'dynamo',url:'1999_ao10/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'1999_cg9':{groups:['asteroids','NEOs'],radius:0.005,label:'1999 CG9',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'1999_cg9/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'1999_vx25':{groups:['asteroids','NEOs'],radius:0.005,label:'1999 VX25',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'1999_vx25/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2_pallas':{groups:['asteroids','asteroid belt'],radius:291,label:'Pallas',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[291,278,250]},controllers:[{type:'dynamo',url:'2_pallas/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:7.8132}]},'2000_ae205':{groups:['asteroids','NEOs'],radius:0.005,label:'2000 AE205',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2000_ae205/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2000_lg6':{groups:['asteroids','NEOs'],radius:0.005,label:'2000 LG6',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2000_lg6/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2000_sg344':{groups:['asteroids','NEOs'],radius:0.0185,label:'2000 SG344',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.0185,0.0185,0.0185]},controllers:[{type:'dynamo',url:'2000_sg344/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2001_bb16':{groups:['asteroids','NEOs'],radius:0.005,label:'2001 BB16',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2001_bb16/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2001_fr85':{groups:['asteroids','NEOs'],radius:0.005,label:'2001 FR85',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2001_fr85/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2001_gp2':{groups:['asteroids','NEOs'],radius:0.005,label:'2001 GP2',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2001_gp2/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2001_qj142':{groups:['asteroids','NEOs'],radius:0.005,label:'2001 QJ142',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2001_qj142/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2001_sn263_a':{groups:['asteroids','NEOs'],radius:1.45,label:'(153591) 2001 SN263',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.4,1.35,1.45]},controllers:[{type:'dynamo',url:'2001_sn263_a/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:3.423}]},'2003_sm84':{groups:['asteroids','NEOs'],radius:0.005,label:'2003 SM84',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2003_sm84/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2003_uv11':{groups:['asteroids','NEOs'],radius:0.13,label:'(503941) 2003 UV11',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.13,0.13,0.13]},controllers:[{type:'dynamo',url:'2003_uv11/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:18.25}]},'2003_yn107':{groups:['asteroids','NEOs'],radius:0.01,label:'2003 YN107',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.01,0.01,0.01]},controllers:[{type:'dynamo',url:'2003_yn107/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2005_er95':{groups:['asteroids','NEOs'],radius:0.005,label:'2003 ER95',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2005_er95/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2005_lc':{groups:['asteroids','NEOs'],radius:0.005,label:'2005 LC',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2005_lc/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2005_qp87':{groups:['asteroids','NEOs'],radius:0.005,label:'2005 QP87',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2005_qp87/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2005_yu55':{groups:['asteroids','NEOs'],radius:0.18,label:'2005 YU55',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.18,0.18,0.18]},controllers:[{type:'dynamo',url:'2005_yu55/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:18}]},'2006_bz147':{groups:['asteroids','NEOs'],radius:0.005,label:'2006 BZ147',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2006_bz147/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2006_jy26':{groups:['asteroids','NEOs'],radius:0.00475,label:'2006 JY26',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.00475,0.00475,0.00475]},controllers:[{type:'dynamo',url:'2006_jy26/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2006_qq56':{groups:['asteroids','NEOs'],radius:0.005,label:'2006 QQ56',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2006_qq56/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2006_rh120':{groups:['asteroids','NEOs'],radius:0.00125,label:'2006 RH120',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.00125,0.00125,0.00125]},controllers:[{type:'dynamo',url:'2006_rh120/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:0.04583}]},'2006_ub17':{groups:['asteroids','NEOs'],radius:0.005,label:'2006 UB17',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2006_ub17/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2007_tf15':{groups:['asteroids','NEOs'],radius:0.005,label:'2007 TF15',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2007_tf15/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2007_un12':{groups:['asteroids','NEOs'],radius:0.005,label:'2007 UN12',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2007_un12/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2007_vu6':{groups:['asteroids','NEOs'],radius:0.005,label:'2007 VU6',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2007_vu6/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2008_bt2':{groups:['asteroids','NEOs'],radius:0.005,label:'2008 BT2',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2008_bt2/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2008_cx118':{groups:['asteroids','NEOs'],radius:0.005,label:'2008 CX118',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2008_cx118/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2008_ea9':{groups:['asteroids','NEOs'],radius:0.005,label:'2008 EA9',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2008_ea9/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2008_el':{groups:['asteroids','NEOs'],radius:0.005,label:'2008 EL',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2008_el/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2008_hu4':{groups:['asteroids','NEOs'],radius:0.005,label:'2008 HU4',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2008_hu4/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2008_jl24':{groups:['asteroids','NEOs'],radius:0.005,label:'2008 JL24',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2008_jl24/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:0.05385}]},'2008_kt':{groups:['asteroids','NEOs'],radius:0.005,label:'2008 KT',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2008_kt/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2008_tc3':{groups:['asteroids','NEOs'],radius:0.00205,label:'2008 TC3',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.00205,0.00205,0.00205]},controllers:[{type:'dynamo',url:'2008_tc3/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:0.0269409}]},'2008_ts10':{groups:['asteroids','NEOs'],radius:0.005,label:'2008 TS10',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2008_ts10/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2008_ua202':{groups:['asteroids','NEOs'],radius:0.025,label:'2008 UA202',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.025,0.025,0.025]},controllers:[{type:'dynamo',url:'2008_ua202/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2009_bd':{groups:['asteroids','NEOs'],radius:0.0055,label:'2009 BD',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.0055,0.0055,0.0055]},controllers:[{type:'dynamo',url:'2009_bd/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2009_os5':{groups:['asteroids','NEOs'],radius:0.005,label:'2009 OS5',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2009_os5/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2009_rt1':{groups:['asteroids','NEOs'],radius:0.005,label:'2009 RT1',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2009_rt1/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2009_yf':{groups:['asteroids','NEOs'],radius:0.005,label:'2009 YF',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2009_yf/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2010_an61':{groups:['asteroids','NEOs'],radius:0.005,label:'2010 AN61',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2010_an61/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2010_dj':{groups:['asteroids','NEOs'],radius:0.005,label:'2010 DJ',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2010_dj/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2010_jw34':{groups:['asteroids','NEOs'],radius:0.005,label:'2010 JW34',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2010_jw34/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2010_tg19':{groups:['asteroids','NEOs'],radius:0.005,label:'2010 TG19',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2010_tg19/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2010_tn167':{groups:['asteroids','NEOs'],radius:0.005,label:'2010 TN167',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2010_tn167/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2010_ub':{groups:['asteroids','NEOs'],radius:0.005,label:'2010 UB',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.005,0.005,0.005]},controllers:[{type:'dynamo',url:'2010_ub/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2063_bacchus':{groups:['asteroids','NEOs'],radius:0.555,label:'Bacchus',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.555,0.265,0.25]},controllers:[{type:'dynamo',url:'2063_bacchus/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:14.904}]},'21_lutetia':{groups:['asteroids','asteroid belt'],radius:60.5,label:'Lutetia',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[60.5,50.5,37.5]},controllers:[{type:'dynamo',url:'21_lutetia/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:8.1655}]},'2101_adonis':{groups:['asteroids','NEOs','PHAs'],radius:0.2615,label:'Adonis',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.2615,0.2615,0.2615]},controllers:[{type:'dynamo',url:'2101_adonis/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'2102_tantalus':{groups:['asteroids','NEOs','PHAs'],radius:0.8245,label:'Tantalus',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.8245,0.8245,0.8245]},controllers:[{type:'dynamo',url:'2102_tantalus/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:2.384}]},'2135_aristaeus':{groups:['asteroids','NEOs','PHAs'],radius:0.5,label:'Aristaeus',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.5,0.5,0.5]},controllers:[{type:'dynamo',url:'2135_aristaeus/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'216_kleopatra':{groups:['asteroids','asteroid belt'],radius:138,label:'Kleopatra',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[138,47,39]},controllers:[{type:'dynamo',url:'216_kleopatra/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:5.385}]},'21900_orus':{groups:['asteroids'],radius:25.405,label:'Orus',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:25.405},controllers:[{type:'dynamo',url:'21900_orus/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:13.45}]},'225088_2007_or10':{groups:['dwarf planets','TNOs'],radius:615,label:'2007 OR10',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[615,615,596.55]},controllers:[{type:'dynamo',url:'225088_2007_or10/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:22.40}]},'2340_hathor':{groups:['asteroids','NEOs','PHAs'],radius:0.105,label:'Hathor',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.105,0.105,0.105]},controllers:[{type:'dynamo',url:'2340_hathor/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:3.350}]},'243_ida':{groups:['asteroids','asteroid belt'],radius:29.9,label:'Ida',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[18.6*1.3,25.4*1.3,59.8*1.3],rotate:[{y:90}]},controllers:[{type:'dynamo',url:'243_ida/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:4.634}]},'25143_itokawa':{groups:['asteroids','NEOs','PHAs'],radius:0.165,label:'Itokawa',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/25143_itokawa/itokawa.gltf',rotate:[{x:90}]},controllers:[{type:'dynamo',url:'25143_itokawa/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12.132}]},'253_mathilde':{groups:['asteroids','asteroid belt'],radius:33,label:'Mathilde',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[33,24,23]},controllers:[{type:'dynamo',url:'253_mathilde/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:417.7}]},'2867_steins':{groups:['asteroids','asteroid belt'],radius:3.415,label:'Šteins',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[3.415,2.85,2.21]},controllers:[{type:'dynamo',url:'2867_steins/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:6.049}]},'3_juno':{groups:['asteroids','asteroid belt'],radius:160,label:'Juno',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[160,133.5,100]},controllers:[{type:'dynamo',url:'3_juno/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:7.210}]},'3122_florence':{groups:['asteroids','NEOs','PHAs'],radius:2.2,label:'Florence',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.2,2.2,2.2]},controllers:[{type:'dynamo',url:'3122_florence/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:2.3581}]},'3200_phaethon':{groups:['asteroids','NEOs','PHAs'],radius:2.9,label:'Phaethon',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.9,2.9,2.9]},controllers:[{type:'dynamo',url:'3200_phaethon/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:3.604}]},'3362_khufu':{groups:['asteroids','NEOs','PHAs'],radius:0.35,label:'Khufu',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.35,0.35,0.35]},controllers:[{type:'dynamo',url:'3362_khufu/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'3548_eurybates':{groups:['asteroids'],radius:31.9425,label:'Eurybates',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:31.9425},controllers:[{type:'dynamo',url:'3548_eurybates/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:8.711}]},'367943_duende':{groups:['asteroids','NEOs'],radius:0.020,label:'Duende',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.01,0.01,0.02]},controllers:[{type:'dynamo',url:'367943_duende/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:9.485}]},'37655_illapa':{groups:['asteroids','NEOs','PHAs'],radius:0.75,label:'Illapa',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.75,0.75,0.75]},controllers:[{type:'dynamo',url:'37655_illapa/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:2.6556}]},'4_vesta':{groups:['asteroids','asteroid belt'],radius:262.7,label:'Vesta',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/4_vesta/4_vesta.gltf',rotate:[{x:90}]},controllers:[{type:'dynamo',url:'4_vesta/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'4015_wilson-harrington':{groups:['asteroids','NEOs','PHAs'],radius:2.0,label:'Wilson-Harrington',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2,2,2]},controllers:[{type:'dynamo',url:'4015_wilson-harrington/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:3.5736}]},'4179_toutatis':{groups:['asteroids','NEOs','PHAs'],radius:2.13,label:'Toutatis',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.35,1.015,2.13]},controllers:[{type:'dynamo',url:'4179_toutatis/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:176}]},'4183_cuno':{groups:['asteroids','NEOs','PHAs'],radius:1.8255,label:'Cuno',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.8255,1.8255,1.89255]},controllers:[{type:'dynamo',url:'4183_cuno/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:3.5595}]},'433_eros':{groups:['asteroids','NEOs'],radius:8.42,label:'Eros',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/433_eros/433_eros.gltf'},controllers:[{type:'dynamo',url:'433_eros/sun/orb'},{type:'dynamo',url:'433_eros/ori'}]},'4450_pan':{groups:['asteroids','NEOs','PHAs'],radius:0.5,label:'Pan',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.5,0.5,0.5]},controllers:[{type:'dynamo',url:'4450_pan/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:56.48}]},'4486_mithra':{groups:['asteroids','NEOs','PHAs'],radius:1.175,label:'Mithra',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.175,0.825,0.72]},controllers:[{type:'dynamo',url:'4486_mithra/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:67.5}]},'4769_castalia':{groups:['asteroids','NEOs','PHAs'],radius:0.9,label:'Castalia',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.4,0.4,0.9]},controllers:[{type:'dynamo',url:'4769_castalia/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:4.095}]},'486958_arrokoth':{groups:['TNOs'],radius:15.0,label:'Arrokoth',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/486958_arrokoth/mu69.gltf',scale:[1,1,1],rotate:[{x:-110},{y:180}]},controllers:[{type:'dynamo',url:'486958_arrokoth/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity},{type:'spin',axis:new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-6.121453676996425e-10,0.9396926211599973,0.34202014229786787),periodInHours:13}],postCreateFunction:(entity)=>{const spin=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.SpinController);if(spin!==null){spin.setReferenceAngle(0);spin.setReferenceTime(599590968)}}},'5011_ptah':{groups:['asteroids','NEOs','PHAs'],radius:0.78,label:'Ptah',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.78,0.78,0.78]},controllers:[{type:'dynamo',url:'5011_ptah/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:12}]},'52246_donaldjohanson':{groups:['asteroids'],radius:1.9475,label:'Donaldjohanson',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:1.9475},controllers:[{type:'dynamo',url:'52246_donaldjohanson/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},'5535_annefrank':{groups:['asteroids'],radius:2.412,label:'Annefrank',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:2.412},controllers:[{type:'dynamo',url:'5535_annefrank/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:15.12}]},'617_patroclus':{groups:['asteroids','617_patroclus_barycenter'],radius:64,label:'Patroclus',labelFadeEntity:'sun',parents:[[Number.NEGATIVE_INFINITY,'617_patroclus_barycenter']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[64,58,49],shadowEntities:['menoetius']},controllers:[{type:'align',primary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis,target:'menoetius'}}],postCreateFunction:(entity)=>{const oeController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController,undefined,entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController));const oe=new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements();oe.epoch=0;oe.eccentricity=0;oe.semiMajorAxis=664;oe.meanAngularMotion=0.00001697791;oe.meanAnomalyAtEpoch=Math.PI;oe.setOrbitOrientationFromElements(1.97244894756,0,0);oeController.addOrbitalElements(-1e100,oe);oeController.addOrbitalElements(+1e100,oe)}},'617_patroclus_barycenter':{groups:['asteroids'],radius:664,label:'Patroclus',labelFadeEntity:'617_patroclus',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},controllers:[{type:'dynamo',url:'617_patroclus/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}],postCreateFunction:(entity)=>{entity.setCanOcclude(!1)}},'6239_minos':{groups:['asteroids','NEOs','PHAs'],radius:0.237,label:'Minos',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.237,0.237,0.237]},controllers:[{type:'dynamo',url:'6239_minos/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:3.5558}]},'6489_golevka':{groups:['asteroids','NEOs','PHAs'],radius:0.265,label:'Golevka',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.265,0.265,0.265]},controllers:[{type:'dynamo',url:'6489_golevka/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:6.026}]},'65803_didymos':{groups:['asteroids','NEOs','PHAs'],radius:0.39,label:'Didymos',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/65803_didymos/Didymos.gltf',rotate:[{z:180},{x:-90}]},controllers:[{type:'dynamo',url:'65803_didymos/sun/orb'},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0,1,0,0)},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:2.2593,relativeToTime:0}]},'66391_moshup':{groups:['asteroids','NEOs','PHAs'],radius:0.766,label:'Moshup',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.766,0.7475,0.6735]},controllers:[{type:'dynamo',url:'66391_moshup/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:2.7645}]},'69230_hermes':{groups:['asteroids','NEOs','PHAs'],radius:0.425,label:'Hermes',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[0.425,0.425,0.425]},controllers:[{type:'dynamo',url:'69230_hermes/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:13.894}]},'90377_sedna':{groups:['dwarf planets','TNOs'],radius:497.5,label:'Sedna',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[497.5,497.5,497.5]},controllers:[{type:'dynamo',url:'90377_sedna/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:10.273}]},'951_gaspra':{groups:['asteroids','asteroid belt'],radius:9.1,label:'Gaspra',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/951_gaspra/gaspra.gltf'},controllers:[{type:'dynamo',url:'951_gaspra/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:7.042}]},'9969_braille':{groups:['asteroids','asteroid belt'],radius:1.05,label:'Braille',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.05,0.5,0.5]},controllers:[{type:'dynamo',url:'9969_braille/sun/orb'},{type:'spin',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,periodInHours:226.4}]},'99942_apophis':{groups:['asteroids','NEOs','PHAs'],radius:0.225,label:'Apophis',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/99942_apophis/apophis.gltf'},controllers:[{type:'dynamo',url:'99942_apophis/sun/orb'},{type:'spin',axis:new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.20112425201023415,0.46925803805904115,0.8598522715968735),periodInHours:30.4}]},'152830_dinkinesh':{groups:['asteroids'],radius:0.45,label:'Dinkinesh',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:0.45},controllers:[{type:'dynamo',url:'152830_dinkinesh/sun/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},charon:{groups:['134340_pluto','moons','134340_pluto_barycenter'],radius:603.5,label:'Charon',parents:[[Number.NEGATIVE_INFINITY,'134340_pluto_barycenter']],trail:{length:undefined},spheroid:{equatorialRadius:603.5,polarRadius:603.5,planetographic:!1},spheroidLOD:{textures:{color:{url:'charon/color_$SIZE_$FACE.png',sizes:[4,512,2048]}}},controllers:[{type:'dynamo',url:'charon/134340_pluto_barycenter/orb'},{type:'align',primary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis,target:'134340_pluto'},secondary:{type:'velocity',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis,target:'134340_pluto'}}]},dactyl:{groups:['243_ida','moons'],radius:0.7,label:'Dactyl',parents:[[Number.NEGATIVE_INFINITY,'243_ida']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[0.8,0.7,0.6],rotate:[{z:90}]},controllers:[{type:'align',primary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis,target:'243_ida'}}],postCreateFunction:(entity)=>{const oeController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController,undefined,entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.AlignController));const oe=new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements();oe.epoch=0;oe.eccentricity=0;oe.semiMajorAxis=90;oe.meanAngularMotion=8.726646e-5;oe.meanAnomalyAtEpoch=0;oe.orbitOrientation.set(0.8728453580255966,0.1876084386162498,-0.08948587100888229,0.4415159494547423);oeController.addOrbitalElements(-1e100,oe);oeController.addOrbitalElements(+1e100,oe)}},dimorphos:{groups:['65803_didymos','moons'],radius:0.085,label:'Dimorphos',parents:[[Number.NEGATIVE_INFINITY,'65803_didymos']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/dimorphos/Dimorphos.gltf'},controllers:[{type:'dynamo',url:'dimorphos/65803_didymos/orb'},{type:'align',primary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis,target:'65803_didymos'},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,target:'65803_didymos',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}}]},hiiaka:{groups:['136108_haumea','moons'],radius:160.0,label:'Hi\'iaka',parents:[[Number.NEGATIVE_INFINITY,'136108_haumea']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[160,160,160]},controllers:[{type:'align',primary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis,target:'136108_haumea'}}],postCreateFunction:(entity)=>{const oeController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController,undefined,entity.getControllerByType('align'));const oe=new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements();oe.epoch=0;oe.eccentricity=0.0513;oe.semiMajorAxis=49880;oe.meanAngularMotion=1.48049e-6;oe.meanAnomalyAtEpoch=0;oe.setOrbitOrientationFromElements(2.20532822965,0,0);oeController.addOrbitalElements(-1e100,oe);oeController.addOrbitalElements(+1e100,oe)}},hydra:{groups:['134340_pluto','moons','134340_pluto_barycenter'],radius:25.0,label:'Hydra',parents:[[Number.NEGATIVE_INFINITY,'134340_pluto_barycenter']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[25,25,25],shadowEntities:['134340_pluto']},controllers:[{type:'dynamo',url:'hydra/134340_pluto_barycenter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},kerberos:{groups:['134340_pluto','moons','134340_pluto_barycenter'],radius:8.25,label:'Kerberos',parents:[[Number.NEGATIVE_INFINITY,'134340_pluto_barycenter']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[8.25,8.25,8.25],shadowEntities:['134340_pluto']},controllers:[{type:'dynamo',url:'kerberos/134340_pluto_barycenter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},menoetius:{groups:['617_patroclus_barycenter','moons'],radius:58,label:'Menoetius',parents:[[Number.NEGATIVE_INFINITY,'617_patroclus_barycenter']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[58,54,45],shadowEntities:['617_patroclus']},controllers:[{type:'align',primary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis,target:'617_patroclus'}}],postCreateFunction:(entity)=>{const oeController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController,undefined,entity.getControllerByType('align'));const oe=new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements();oe.epoch=0;oe.eccentricity=0;oe.semiMajorAxis=664;oe.meanAngularMotion=0.00001697791;oe.meanAnomalyAtEpoch=0;oe.setOrbitOrientationFromElements(1.97244894756,0,0);oeController.addOrbitalElements(-1e100,oe);oeController.addOrbitalElements(+1e100,oe)}},namaka:{groups:['136108_haumea','moons'],radius:85.0,label:'Nāmaka',parents:[[Number.NEGATIVE_INFINITY,'136108_haumea']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[85,85,85]},controllers:[{type:'align',primary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxis,target:'136108_haumea'}}],postCreateFunction:(entity)=>{const oeController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController,undefined,entity.getControllerByType('align'));const oe=new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements();oe.epoch=0;oe.eccentricity=0.249;oe.semiMajorAxis=25657;oe.meanAngularMotion=3.9786e-6;oe.meanAnomalyAtEpoch=0;oe.setOrbitOrientationFromElements(1.97244894756,0,0);oeController.addOrbitalElements(-1e100,oe);oeController.addOrbitalElements(+1e100,oe)}},nix:{groups:['134340_pluto','moons','134340_pluto_barycenter'],radius:24.0,label:'Nix',parents:[[Number.NEGATIVE_INFINITY,'134340_pluto_barycenter']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[24,24,24],shadowEntities:['134340_pluto']},controllers:[{type:'dynamo',url:'nix/134340_pluto_barycenter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},styx:{groups:['134340_pluto','moons','134340_pluto_barycenter'],radius:5.5,label:'Styx',parents:[[Number.NEGATIVE_INFINITY,'134340_pluto_barycenter']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[5.5,5.5,5.5],shadowEntities:['134340_pluto']},controllers:[{type:'dynamo',url:'styx/134340_pluto_barycenter/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]}})}),"../pioneer/scripts/src/entities/neptune_moons.js": + /*!********************************************************!*\ + !*** ../pioneer/scripts/src/entities/neptune_moons.js ***! + \********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({despina:{groups:['neptune','moons','regular'],radius:90,label:'Despina',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[90,90,90],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'despina/neptune/orb'},{type:'dynamo',url:'despina/ori'}]},galatea:{groups:['neptune','moons','regular'],radius:102,label:'Galatea',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[102,102,102],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'galatea/neptune/orb'},{type:'dynamo',url:'galatea/ori'}]},halimede:{groups:['neptune','moons','irregular'],radius:31,label:'Halimede',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[31,31,31],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'halimede/neptune/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},hippocamp:{groups:['neptune','moons','regular'],radius:17.4,label:'Hippocamp',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[17.4,17.4,17.4],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'hippocamp/neptune/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},laomedeia:{groups:['neptune','moons','irregular'],radius:21,label:'Laomedeia',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[21,21,21],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'laomedeia/neptune/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},larissa:{groups:['neptune','moons','regular'],radius:108,label:'Larissa',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[108,108,108],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'larissa/neptune/orb'},{type:'dynamo',url:'larissa/ori'}]},naiad:{groups:['neptune','moons','regular'],radius:48,label:'Naiad',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[48,48,48],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'naiad/neptune/orb'},{type:'dynamo',url:'naiad/ori'}]},nereid:{groups:['neptune','moons','irregular'],radius:170.0,label:'Nereid',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[170,170,170],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'nereid/neptune/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},neso:{groups:['neptune','moons','irregular'],radius:30,label:'Neso',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[30,30,30],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'neso/neptune/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},proteus:{groups:['neptune','moons','regular'],radius:232.5,label:'Proteus',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/proteus/proteus.gltf',scale:[1,1,1]},controllers:[{type:'dynamo',url:'proteus/neptune/orb'},{type:'dynamo',url:'proteus/ori'}]},psamathe:{groups:['neptune','moons','irregular'],radius:20,label:'Psamathe',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[20,20,20],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'psamathe/neptune/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},sao:{groups:['neptune','moons','irregular'],radius:22,label:'Sao',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[22,22,22],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'sao/neptune/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},thalassa:{groups:['neptune','moons','regular'],radius:54,label:'Thalassa',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[54,54,54],shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'thalassa/neptune/orb'},{type:'dynamo',url:'thalassa/ori'}]},triton:{groups:['neptune','moons','irregular'],radius:1353.4,label:'Triton',parents:[[Number.NEGATIVE_INFINITY,'neptune']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},spheroid:{equatorialRadius:1353.4,polarRadius:1353.4,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'triton/color_$SIZE_$FACE.jpg',sizes:[16,512,4096]}},shadowEntities:['neptune']},controllers:[{type:'dynamo',url:'triton/neptune/orb'},{type:'dynamo',url:'triton/ori'}]}})}),"../pioneer/scripts/src/entities/outer_planet_spacecraft.js": + /*!******************************************************************!*\ + !*** ../pioneer/scripts/src/entities/outer_planet_spacecraft.js ***! + \******************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");var _controllers_keyframe_pointing_controller__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ../controllers/keyframe_pointing_controller */"../pioneer/scripts/src/controllers/keyframe_pointing_controller.js");var _controllers_keyframe_spin_controller__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ../controllers/keyframe_spin_controller */"../pioneer/scripts/src/controllers/keyframe_spin_controller.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({sc_juno:{groups:['jupiter','spacecraft'],occlusionRadius:0.001732,extentsRadius:0.010000,label:'Juno',parents:[[365836752.1832,'earth'],[366088266.183,'sun'],[434433667.182,'earth'],[434793667.182,'sun'],[519652868.184,'jupiter'],[676339597,'ganymede'],[676381521,'jupiter'],[717700360,'europa'],[717727733,'jupiter'],[757191924,'io'],[757203571,'jupiter'],[760247560,'io'],[760262808,'jupiter']],trail:{length:undefined,lengthCoverages:[[63072000,Number.NEGATIVE_INFINITY,519652868.184],[5184000,519652868.184,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_juno/Juno.gltf',rotate:[{x:90}],shadowEntities:['jupiter','europa','ganymede','callisto','io']},controllers:[{type:'dynamo',url:'sc_juno/earth/launch/orb'},{type:'dynamo',url:'sc_juno/sun/preflyby/orb'},{type:'dynamo',url:'sc_juno/earth/flyby/orb'},{type:'dynamo',url:'sc_juno/sun/postflyby/orb'},{type:'dynamo',url:'sc_juno/jupiter/orb'},{type:'dynamo',url:'sc_juno/ganymede/orb'},{type:'dynamo',url:'sc_juno/europa/orb'},{type:'dynamo',url:'sc_juno/io/1/orb'},{type:'dynamo',url:'sc_juno/io/2/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity,coverage:[365836752.1832,Number.POSITIVE_INFINITY]},{type:'dynamo',url:'sc_juno/ori'},{type:'coverage',coverage:[393471366,529748408+600],update:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);const cover=model.getThreeJsObjectByName('engine_cover');if(cover!==null){const time=entity.getScene().getEngine().getTime();const nextCloseIndex=pioneer__WEBPACK_IMPORTED_MODULE_1__.Sort.getIndex(time,junoEngineCoverOpenings,(a,b)=>a[1]{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);const cover=model.getThreeJsObjectByName('engine_cover');if(cover!==null){cover.rotation.x=Math.PI}}},{type:'coverage',coverage:[399637867.183,520959604.184],update:(entity)=>{const particleSpray=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent);const time=entity.getScene().getEngine().getTime();const nextCloseIndex=pioneer__WEBPACK_IMPORTED_MODULE_1__.Sort.getIndex(time,junoEngineBurns,(a,b)=>a[1]{const particleSpray=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent);particleSpray.setEnabled(!1)}},{type:'coverage',coverage:[519652868.184,Number.POSITIVE_INFINITY],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail){trail.setRelativeToEntity('jupiter')}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail){trail.setRelativeToEntity('')}}}],postCreateFunction:(entity)=>{const keyframePointing=entity.addControllerByClass(_controllers_keyframe_pointing_controller__WEBPACK_IMPORTED_MODULE_2__.KeyframePointingController);keyframePointing.setKeyframes(junoPointingKeyframes);keyframePointing.setDirection(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis);keyframePointing.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(365836752.1832,521025625));const keyframeSpin=entity.addControllerByClass(_controllers_keyframe_spin_controller__WEBPACK_IMPORTED_MODULE_3__.KeyframeSpinController);keyframeSpin.setKeyframes(junoSpinKeyframes);keyframeSpin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis);keyframeSpin.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(365836752.1832,521025625));keyframeSpin.setStartingAngle(-0.96);const particleSpray=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent);particleSpray.setNumberOfParticles(100);particleSpray.setSizeOfParticles(0.0003);particleSpray.setSpeedOfParticles(0.01);particleSpray.setColorOfParticles(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(1,0.75,0,0.25));particleSpray.setSpread(-3);particleSpray.setParticleSpacingRandom(!1);particleSpray.setLength(0.003);particleSpray.setOriginOffset(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0,0,-0.0017));particleSpray.setDirection(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg);particleSpray.setEnabled(!1)}},sc_cassini:{groups:['saturn','spacecraft'],occlusionRadius:0.0034,extentsRadius:0.005500,label:'Cassini',parents:[[-69820368.42763124,'earth'],[-69537536.818,'sun'],[-53179136.814,'venus'],[-53092736.814,'sun'],[-16495135.816,'venus'],[-16451935.816,'sun'],[-11951935.817,'earth'],[-11660335.817,'sun'],[139219264.185,'saturn'],[558743640,'']],dependents:['sc_huygens'],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_cassini/Cassini.gltf',rotate:[{x:-90},{z:180}],shadowEntities:['saturn','titan','enceladus','mimas','tethys']},controllers:[{type:'dynamo',url:'sc_cassini/earth/launch/orb'},{type:'dynamo',url:'sc_cassini/sun/1/orb'},{type:'dynamo',url:'sc_cassini/venus/flyby1/orb'},{type:'dynamo',url:'sc_cassini/sun/2/orb'},{type:'dynamo',url:'sc_cassini/venus/flyby2/orb'},{type:'dynamo',url:'sc_cassini/sun/3/orb'},{type:'dynamo',url:'sc_cassini/earth/flyby/orb'},{type:'dynamo',url:'sc_cassini/sun/4/orb'},{type:'dynamo',url:'sc_cassini/saturn/orb'},{type:'dynamo',url:'sc_cassini/quat'},{type:'coverage',coverage:[-13098535.817,534124760.143],update:(entity)=>{const particleSpray=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent);const time=entity.getScene().getEngine().getTime();const nextCloseIndex=pioneer__WEBPACK_IMPORTED_MODULE_1__.Sort.getIndex(time,cassiniEngineBurns,(a,b)=>a[1]{const particleSpray=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent);particleSpray.setEnabled(!1)}},{type:'coverage',coverage:[157212064.184,Number.POSITIVE_INFINITY],enter:(entity)=>{const modelComponent=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(modelComponent!==null){modelComponent.setHiddenObject('huygens_probe',!0)}},exit:(entity)=>{const modelComponent=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);if(modelComponent!==null){modelComponent.setHiddenObject('huygens_probe',!1)}}}],postCreateFunction:(entity)=>{const particleSpray=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ParticleSprayComponent);particleSpray.setNumberOfParticles(50);particleSpray.setSizeOfParticles(0.0003);particleSpray.setSpeedOfParticles(0.01);particleSpray.setColorOfParticles(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Color(1,0.75,0,0.25));particleSpray.setSpread(-3);particleSpray.setParticleSpacingRandom(!1);particleSpray.setLength(0.002);particleSpray.setOriginOffset(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0,0.00029,0.0033));particleSpray.setDirection(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis);particleSpray.setEnabled(!1)}},sc_galileo:{groups:['jupiter','spacecraft'],occlusionRadius:0.003,extentsRadius:0.0055,label:'Galileo',parents:[[-321964226.73959994,'earth'],[-321559829,'sun'],[-312199026,'venus'],[-311946958,'sun'],[-286252262,'earth'],[-285827020,'sun'],[-223105356,'earth'],[-222610262,'sun'],[-129268796,'jupiter'],[117442702,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_galileo/galileo.gltf',shadowEntities:['jupiter','earth','venus'],rotate:[{x:-90},{z:180}]},controllers:[{type:'dynamo',url:'sc_galileo/earth/launch/orb'},{type:'dynamo',url:'sc_galileo/sun/orb'},{type:'dynamo',url:'sc_galileo/venus/flyby/orb'},{type:'dynamo',url:'sc_galileo/earth/flyby1/orb'},{type:'dynamo',url:'sc_galileo/earth/flyby2/orb'},{type:'dynamo',url:'sc_galileo/jupiter/orb'},{type:'align',primary:{type:'point',target:'mercury',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis,target:'earth',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}},{type:'dynamo',url:'sc_galileo/quat'}],postCreateFunction:(entity)=>{const spin=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.SpinController);spin.setJoint('spinning_section');spin.setRate(3*2*Math.PI/60);spin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg,!0)}},sc_galileo_probe:{groups:['jupiter','spacecraft'],radius:0.00072,label:'Galileo Probe',parents:[[-321964226.73959994,'sc_galileo'],[-129268796,'jupiter'],[-128353980,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_galileo_probe/galileo_probe.gltf',rotate:[{x:-90}]},controllers:[{type:'dynamo',url:'sc_galileo_probe/galileo/orb'},{type:'dynamo',url:'sc_galileo_probe/jupiter/orb'},{type:'fixed',position:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero,orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity,coverage:[-321964226.73959994,-141114537.48322043]},{type:'coverage',coverage:[Number.NEGATIVE_INFINITY,-141114537.48322043],enter:(entity)=>{const div=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent);if(div!==null){div.setEnabled(!1)} + const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setEnabled(!1)} + const translateController=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController);translateController.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0,0,0.001))},exit:(entity)=>{const div=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.DivComponent);if(div!==null){div.setEnabled(!0)} + const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trail!==null){trail.setEnabled(!0)} + const translateController=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController);translateController.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-0.000016,0.000024,0.0007))}}],postCreateFunction:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0,0,-0.001));const translateController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController);translateController.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-0.000016,0.000024,0.0007));translateController.setRelativeToOrientation(!0);translateController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(-321964226.73959994,-128353980));const rotateByEntityOrientation=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.RotateByEntityOrientationController);rotateByEntityOrientation.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(-321964226.73959994,-141114537.48322043));const fixed=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.FixedController);fixed.setOrientation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.40004226980201746,0.3894033591393042,-0.7928008139628516,0.24453645053961984));fixed.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(-141114537.48322043,Number.POSITIVE_INFINITY))}},sc_huygens:{groups:['saturn','spacecraft','titan'],occlusionRadius:0.00130,extentsRadius:0.00130,label:'Huygens',parents:[[157212064.184,'saturn'],[158945582,'titan'],[158974766.184,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_huygens/Huygens.gltf',rotate:[{x:-90},{z:180}],shadowEntities:['saturn','titan','enceladus','mimas','tethys']},controllers:[{type:'dynamo',url:'sc_huygens/saturn/orb'},{type:'dynamo',url:'sc_huygens/titan/orb'},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.8295521744501194,0.09912464029342342,-0.04158756948048668,-0.5479853735424731)},{type:'custom',func:(entity)=>{const keyframeController1=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.KeyframeController);keyframeController1.addPositionKeyframe(158965616.707,new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-74.84608000701567,-3832.0774028380238,-305.9513410781612));keyframeController1.addPositionKeyframe(158965667.7750001,new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-168.19015737501377,-3541.733393771429,-291.12326824195395));keyframeController1.addPositionKeyframe(158965894.184,new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-376.8992769951708,-2686.9622048526126,-273.33138256355716));return keyframeController1}},{type:'custom',func:(entity)=>{const keyframeController2=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.KeyframeController);keyframeController2.addPositionKeyframe(158965894.184,new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-376.8992769951708,-2686.9622048526126,-273.33138256355716));keyframeController2.addPositionKeyframe(158974766.184,new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-251.2479743710496,-2548.813556954952,-266.5500089234507));return keyframeController2}},{type:'custom',func:(entity)=>{const translateController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TranslateController);translateController.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-0.0013,0,0.0011));translateController.setRelativeToOrientation(!0);translateController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(157212064.184,158974766.184));return translateController}},{type:'custom',func:(entity)=>{const keyframeSpin=entity.addControllerByClass(_controllers_keyframe_spin_controller__WEBPACK_IMPORTED_MODULE_3__.KeyframeSpinController);keyframeSpin.setKeyframes(huygensSpinKeyframes);keyframeSpin.setAxis(pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg);keyframeSpin.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Interval(157212064.184,Number.POSITIVE_INFINITY));return keyframeSpin}},{type:'coverage',coverage:[158965616.707,Number.POSITIVE_INFINITY],enter:(entity)=>{const trailComponent=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trailComponent!==null){trailComponent.setRelativeToEntityOrientation(!0)}},exit:(entity)=>{const trailComponent=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.TrailComponent);if(trailComponent!==null){trailComponent.setRelativeToEntityOrientation(!1)}}}],postCreateFunction:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.ModelComponent);model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.0013,0,-0.0011))}},sc_huygens_landing_site:{groups:['titan','sc_huygens','sites'],radius:0.001,systemRadius:200,label:'Huygens Landing Site',parents:[[157212064.184,'titan']],controllers:[{type:'fixed',llaOnSpheroid:new pioneer__WEBPACK_IMPORTED_MODULE_1__.LatLonAlt(-0.18453331247520502,2.9263055188728955,0),coverage:[157212064.184,Number.POSITIVE_INFINITY]}]},sc_juice:{groups:['jupiter','ganymede','spacecraft'],occlusionRadius:0.007,extentsRadius:0.0135,label:'JUICE',parents:[[734748207,'earth'],[735606318,'sun'],[777026548,'earth'],[778061110,'sun'],[809697014,'venus'],[810162491,'sun'],[843697642,'earth'],[844049179,'sun'],[916393497,'earth'],[916903199,'sun'],[994471790,'jupiter'],[1103217877,'ganymede']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_juice/juice.gltf',shadowEntities:['ganymede','jupiter','earth']},controllers:[{type:'dynamo',url:'sc_juice/earth/launch'},{type:'dynamo',url:'sc_juice/sun'},{type:'dynamo',url:'sc_juice/earth/flyby1'},{type:'dynamo',url:'sc_juice/venus/flyby'},{type:'dynamo',url:'sc_juice/earth/flyby2'},{type:'dynamo',url:'sc_juice/earth/flyby3'},{type:'dynamo',url:'sc_juice/jupiter'},{type:'dynamo',url:'sc_juice/ganymede'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg},secondary:{type:'align',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}},{type:'dynamo',url:'sc_juice/quat'}]},sc_pioneer_10:{groups:['sun','jupiter','spacecraft'],occlusionRadius:0.002118055,extentsRadius:0.003,label:'Pioneer 10',parents:[[-878291717.8145751,'earth'],[-878146409,'sun'],[-824046472,'jupiter'],[-822011429,'sun']],trail:{length:60*60*24*365*10},model:{url:'$STATIC_ASSETS_URL/models/sc_pioneer/pioneer.gltf',rotate:[{x:90}]},controllers:[{type:'dynamo',url:'sc_pioneer_10/earth/orb'},{type:'dynamo',url:'sc_pioneer_10/sun/1/orb'},{type:'dynamo',url:'sc_pioneer_10/jupiter/orb'},{type:'dynamo',url:'sc_pioneer_10/sun/2/orb'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis}}]},sc_pioneer_11:{groups:['sun','jupiter','saturn','spacecraft'],occlusionRadius:0.002118055,extentsRadius:0.003,label:'Pioneer 11',parents:[[-843816855.8143449,'earth'],[-843644357,'sun'],[-792658454,'jupiter'],[-790152245,'sun'],[-643302619,'saturn'],[-640194311,'sun']],trail:{length:60*60*24*365*10},model:{url:'$STATIC_ASSETS_URL/models/sc_pioneer/pioneer.gltf',rotate:[{x:90}]},controllers:[{type:'dynamo',url:'sc_pioneer_11/earth/orb'},{type:'dynamo',url:'sc_pioneer_11/sun/1/orb'},{type:'dynamo',url:'sc_pioneer_11/jupiter/orb'},{type:'dynamo',url:'sc_pioneer_11/sun/2/orb'},{type:'dynamo',url:'sc_pioneer_11/saturn/orb'},{type:'dynamo',url:'sc_pioneer_11/sun/3/orb'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis}}]},sc_voyager_1:{groups:['jupiter','saturn','sun','spacecraft'],occlusionRadius:0.00183,extentsRadius:0.0043000,label:'Voyager 1',parents:[[-704412035.617,'earth'],[-703530245,'sun'],[-660264745,'jupiter'],[-655057463,'sun'],[-606239665,'saturn'],[-600733702,'sun']],trail:{length:946080000,lengthCoverages:[[157680000,Number.NEGATIVE_INFINITY,377123932.454],[946080000,377123932.454,Number.POSITIVE_INFINITY],[5184000,-660264745,-655057463],[5184000,-606239665,-600733702]]},model:{url:'$STATIC_ASSETS_URL/models/sc_voyager/Voyager.gltf',rotate:[{x:-90}]},controllers:[{type:'dynamo',url:'sc_voyager_1/earth/orb'},{type:'dynamo',url:'sc_voyager_1/sun/1/orb'},{type:'dynamo',url:'sc_voyager_1/jupiter/orb'},{type:'dynamo',url:'sc_voyager_1/sun/2/orb'},{type:'dynamo',url:'sc_voyager_1/saturn/orb'},{type:'dynamo',url:'sc_voyager_1/sun/3/orb'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg}},{type:'dynamo',url:'sc_voyager_1/ori'}]},sc_voyager_2:{groups:['jupiter','saturn','uranus','neptune','sun','spacecraft'],occlusionRadius:0.00183,extentsRadius:0.0043000,label:'Voyager 2',parents:[[-705788847.817,'earth'],[-704774613,'sun'],[-650828783,'jupiter'],[-642276063,'sun'],[-582886481,'saturn'],[-574538624,'sun'],[-440395228,'uranus'],[-439259319,'sun'],[-327233138,'neptune'],[-326252606,'sun']],trail:{length:946080000,lengthCoverages:[[157680000,Number.NEGATIVE_INFINITY,651751314.724],[946080000,651751314.724,Number.POSITIVE_INFINITY],[5184000,-650828783,-642276063],[5184000,-582886481,-574538624],[5184000,-440395228,-439259319],[5184000,-327233138,-326252606]]},model:{url:'$STATIC_ASSETS_URL/models/sc_voyager/Voyager.gltf',rotate:[{x:-90}]},controllers:[{type:'dynamo',url:'sc_voyager_2/earth/orb'},{type:'dynamo',url:'sc_voyager_2/sun/1/orb'},{type:'dynamo',url:'sc_voyager_2/jupiter/orb'},{type:'dynamo',url:'sc_voyager_2/sun/2/orb'},{type:'dynamo',url:'sc_voyager_2/saturn/orb'},{type:'dynamo',url:'sc_voyager_2/sun/3/orb'},{type:'dynamo',url:'sc_voyager_2/uranus/orb'},{type:'dynamo',url:'sc_voyager_2/sun/4/orb'},{type:'dynamo',url:'sc_voyager_2/neptune/orb'},{type:'dynamo',url:'sc_voyager_2/sun/5/orb'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg}},{type:'dynamo',url:'sc_voyager_2/ori'}]}});const cassiniEngineBurns=[[-13098535.817,-13098146.797],[-12342535.817,-12342421.197],[-10612735.817,-10612663.357],[14274064.185,14274070.255],[36653454.185,36653459.605],[71128864.186,71128875.066],[105091264.185,105091282.755],[118339264.182,118339287.092],[138968824.185,138969181.735],[140692084.184,140692123.174],[141916392.184,141922237.024],[146548444.183,146551498.073],[147846664.183,147846668.693],[152302564.182,152302569.842],[154285264.183,154285267.193],[156518584.184,156518669.274],[157466284.184,157466438.074],[159139264.184,159139404.074],[160168144.185,160168264.795],[161978464.185,161978469.745],[163011064.185,163011104.295],[163869664.186,163869667.996],[164528404.186,164528414.466],[165853384.186,165853391.046],[166370464.186,166370502.696],[168008344.186,168008476.766],[174127084.184,174127086.454],[176341864.183,176341881.793],[176952124.183,176952139.533],[178261744.183,178261753.433],[178699444.183,178699535.673],[180420064.182,180420240.372],[182368684.182,182368777.962],[184039204.183,184039282.793],[185162584.183,185162597.343],[196273205.186,196273208.936],[197566385.186,197566387.476],[199978145.185,199978148.205],[202994705.185,202994717.245],[207734765.183,207734800.073],[211183265.182,211183306.302],[211500485.182,211500537.082],[212965745.182,212965786.692],[214371665.182,214371670.582],[216354545.183,216354568.983],[219456245.183,219456251.063],[219887345.184,219887389.034],[220835165.184,220835169.094],[221266265.184,221266275.434],[222644225.185,222644240.975],[224109485.185,224109487.885],[226090325.185,226090329.355],[227038025.186,227038032.946],[227469065.186,227469075.266],[228387005.186,228387008.496],[228846905.186,228846923.006],[230225585.186,230225608.176],[231577265.185,231577300.725],[232982885.185,232982919.625],[233930525.185,233930529.665],[234334565.185,234334641.855],[235309205.185,235309210.915],[235740245.184,235740294.424],[239704565.183,239704568.933],[242004965.183,242004968.253],[242979665.182,242979748.272],[244876985.182,244876993.442],[247203665.183,247203671.283],[248986685.183,248986692.503],[249417845.183,249417942.863],[250365665.183,250365669.503],[250801865.183,250801924.453],[252201785.184,252201798.884],[253728965.184,253728983.974],[255535625.185,255535853.415],[256682225.185,256682228.065],[257684225.185,257684269.165],[258146525.185,258146533.105],[258722525.186,258722543.076],[261147905.186,261147925.516],[262453685.186,262453688.326],[264259265.185,264259272.395],[267474305.184,267474379.954],[271073765.183,271073780.663],[272731805.183,272731887.753],[275208605.182,275208611.692],[276214805.182,276214829.892],[277127525.182,277127545.362],[277506665.182,277506708.062],[279455045.183,279455100.823],[279799805.183,279799837.073],[280747565.183,280747571.013],[282126485.183,282126503.483],[282471245.183,282471256.053],[286040946.185,286040974.915],[287532306.185,287532308.475],[289858866.186,289858897.046],[291603966.186,291603971.806],[292809906.186,292809948.366],[294188586.186,294188602.066],[295567266.185,295567279.505],[296945946.185,296945956.015],[297893586.185,297893599.995],[299272206.184,299272220.614],[300687786.184,300687808.034],[302066526.183,302066563.313],[303703506.183,303703583.793],[304824006.183,304824009.283],[305390946.183,305390972.583],[308925306.182,308925311.352],[309355506.182,309355530.682],[310684866.183,310684869.093],[312200586.183,312200601.223],[534124756.143,534124760.143]];const junoEngineCoverOpenings=[[393471366,393500886+600],[399019747,399882847+600],[400569547,400988287+600],[420541747,420794047+600],[454490527,454649587+600],[487136707,487309087+600],[519804068,521041148+600],[528958868,529748408+600]];const junoEngineBurns=[[399637867.183,399639659.183],[400933867.182,400935660.182],[420714067.185,420714067.185+5],[454572067.185,454572067.185+5],[487231267.185,487231267.185+5],[520957868.184,520959604.184]];const junoPointingKeyframes=([[365835906,'velocity'],[365836206,'sun'],[371908866,'sun'],[371909466,'earth'],[399631646,'earth'],[399632628,'sun'],[399635271,'sun'],[399636306,'-velocity'],[399640481,'-velocity'],[399641686,'sun'],[399700717,'sun'],[399641887,'earth'],[400927646,'earth'],[400928454,'sun'],[400931272,'sun'],[400932282,'-velocity'],[400936477,'-velocity'],[400937632,'sun'],[401003197,'sun'],[401009197,'earth'],[423014467,'earth'],[423014767,'sun'],[436924867,'sun'],[436925167,'earth'],[520954868,'earth'],[520955888,'-velocity'],[520960808,'-velocity'],[520962008,'sun'],[521018048,'sun'],[521025625,'earth']]);const junoSpinKeyframes=([[394545667,1*Math.PI/30],[394545967,2*Math.PI/30],[399636967,2*Math.PI/30],[399637264,5*Math.PI/30],[399637866,5*Math.PI/30],[399639659,5.5*Math.PI/30],[399639788,5.5*Math.PI/30],[399640072,2*Math.PI/30],[400932921,2*Math.PI/30],[400933214,5*Math.PI/30],[400933866,5*Math.PI/30],[400935660,5.5*Math.PI/30],[400935790,5.5*Math.PI/30],[400936068,2*Math.PI/30],[520956548,2*Math.PI/30],[520956848,5*Math.PI/30],[520960088,5*Math.PI/30],[520960388,2*Math.PI/30],[521025625,2*Math.PI/30]]);const huygensSpinKeyframes=([[157212064.184,7.5*Math.PI/30],[158965863.184,7.5*Math.PI/30],[158966163.184,2.6*Math.PI/30],[158966434.184,0],[158966883.184,-5.6*Math.PI/30],[158967123.184,-9.7*Math.PI/30],[158967363.184,-7.3*Math.PI/30],[158968263.184,-2.8*Math.PI/30],[158973723.184,-1*Math.PI/30]])}),"../pioneer/scripts/src/entities/planets_and_stars.js": + /*!************************************************************!*\ + !*** ../pioneer/scripts/src/entities/planets_and_stars.js ***! + \************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var _scene_helpers__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ../scene_helpers */"../pioneer/scripts/src/scene_helpers.js");var pioneer__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({observable_universe:{groups:['stars'],radius:5e23,systemRadius:5e23,label:'Observable Universe',parents:[],controllers:[{type:'fixed',position:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.Zero,orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}],postCreateFunction:(entity)=>{entity.setCanOcclude(!1)}},milky_way:{groups:['stars'],radius:1e18,systemRadius:1.3e+19,label:'Milky Way',parents:[[Number.NEGATIVE_INFINITY,'observable_universe']],controllers:[{type:'fixed',position:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.Zero,orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}],postCreateFunction:(entity,extraOptions)=>{entity.setCanOcclude(!1);const fixedController=entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.FixedController);const northPole=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3();const northPoleRa=192.85948120833*Math.PI/180;const northPoleDec=27.12825119444*Math.PI/180;northPole.x=Math.cos(northPoleRa)*Math.cos(northPoleDec);northPole.y=Math.sin(northPoleRa)*Math.cos(northPoleDec);northPole.z=Math.sin(northPoleDec);const center=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3();const centerRa=266.40499625*Math.PI/180;const centerDec=-28.93617241667*Math.PI/180;center.x=Math.cos(centerRa)*Math.cos(centerDec);center.y=Math.sin(centerRa)*Math.cos(centerDec);center.z=Math.sin(centerDec);const orientation=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion();orientation.setFromAxes(center,undefined,northPole);fixedController.setOrientation(orientation);if(extraOptions&&extraOptions.milkyWaySprite){const sprite=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpriteComponent);sprite.setTextureUrl('$STATIC_ASSETS_URL/sprites/milky_way.png');sprite.setSize(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector2(12e17,12e17));sprite.setTransparent(!0);sprite.setBlending('normal');sprite.setFadeDistance(12e15)} + const spinController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpinController);spinController.setAxis(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.8676661356982597,-0.19807638974470915,0.45598379452940485),!1);spinController.setRate(-2.192686e-17);spinController.setReferenceAngle(0);spinController.setReferenceTime(0)}},sun:{groups:['stars'],radius:695500,systemRadius:2.991957e+13,label:'Sun',parents:[[Number.NEGATIVE_INFINITY,'milky_way']],spheroid:{equatorialRadius:695500,polarRadius:695500,planetographic:!1},spheroidLOD:{features:['colorMapEmmissive'],textures:{color:{url:'sun/color_$SIZE_$FACE.png',sizes:[4,512]}}},controllers:[{type:'fixed',position:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.Zero,orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}],postCreateFunction:(entity,extraOptions)=>{const lightSourceComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.LightSourceComponent);lightSourceComponent.setAbsoluteMagnitude(4.83);const sunAtmosphere=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent);sunAtmosphere.setEmissivity(1.0);sunAtmosphere.setScaleHeight(2e5);sunAtmosphere.setDensity(8e-7);sunAtmosphere.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(255.0/255.0,255.0/255.0,64.0/255.0));const sunGlowSprite=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpriteComponent);sunGlowSprite.setBillboard(!0);sunGlowSprite.setTextureUrl('$STATIC_ASSETS_URL/sprites/sun_glow.png');sunGlowSprite.setSize(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector2(100,100));sunGlowSprite.setSizeUnits('pixels');sunGlowSprite.setTransparent(!0);sunGlowSprite.setColorMultiplier(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(1.0,1.0,0.5));sunGlowSprite.setRenderOrder(-2);const oeController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.OrbitalElementsController);const oe=new pioneer__WEBPACK_IMPORTED_MODULE_2__.OrbitalElements();oe.epoch=0;oe.eccentricity=0;oe.semiMajorAxis=246237071000000000.0;oe.meanAngularMotion=-2.192686e-17;oe.meanAnomalyAtEpoch=Math.PI;oe.orbitOrientation.set(-0.48894750765094835,-0.4832106839985283,0.19625375824756275,0.6992297419646486);oeController.addOrbitalElements(-1e100,oe);oeController.addOrbitalElements(+1e100,oe);if(extraOptions!==undefined&&extraOptions.skybox===!0){const skyboxComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SkyboxComponent);skyboxComponent.setTextureUrl('$STATIC_ASSETS_URL/textures/starmap_'+(extraOptions.skyboxResolution||2048)+'.jpg')} + if(extraOptions===undefined||(extraOptions.skybox===!0&&extraOptions.starfield===!0)||extraOptions.starfield!==!1){const galaxyComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.StarfieldComponent);galaxyComponent.setUrl('$STATIC_ASSETS_URL/stars/galaxies.0.bin');for(let i=0;i<6;i++){const starfieldComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.StarfieldComponent);starfieldComponent.setUrl('$STATIC_ASSETS_URL/stars/stars.'+i+'.bin')}} + if(extraOptions!==undefined&&extraOptions.heliosphere){const model=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);model.setUrl('$STATIC_ASSETS_URL/models/heliosphere/voyager_heliosphere.gltf');model.setScale(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(2.01e8,1.9e8,1.9e8));model.setForceLoaded(!0);const llaNose=new pioneer__WEBPACK_IMPORTED_MODULE_2__.LatLonAlt(0,-105*Math.PI/180,0);const xyzNose=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3();pioneer__WEBPACK_IMPORTED_MODULE_2__.Geometry.getXYZFromLLAOnSphere(xyzNose,llaNose,1);xyzNose.rotate(_scene_helpers__WEBPACK_IMPORTED_MODULE_1__.SceneHelpers.getEclipJ2000ToJ2000Rotation(),xyzNose);xyzNose.normalize(xyzNose);const rotation=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion();rotation.setFromVectorFromTo(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.9937396508197329,0.11171728072160429,0.0008692392338424033),xyzNose);model.setRotation(rotation)}}},mercury:{groups:['planets'],radius:2439.4,systemRadius:292764,label:'Mercury',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined,color:[0.6,0.6,0.6,0.7]},spheroid:{equatorialRadius:2439.4,polarRadius:2439.4,planetographic:!1},spheroidLOD:{textures:{color:{url:'mercury/color_$SIZE_$FACE.png',sizes:[4,512,4096]}}},controllers:[{type:'dynamo',url:'mercury/sun/orb'},{type:'dynamo',url:'mercury/ori'}]},venus:{groups:['planets'],radius:6051.8,systemRadius:726216,label:'Venus',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined,color:[0.9,0.80,0.45,0.7]},spheroid:{equatorialRadius:6051.8,polarRadius:6051.8,planetographic:!1},spheroidLOD:{textures:{color:{url:'venus/color_$SIZE_$FACE.png',sizes:[4,512]}}},controllers:[{type:'dynamo',url:'venus/sun/orb'},{type:'dynamo',url:'venus/ori'}],postCreateFunction:(entity)=>{const atmosphereComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent);atmosphereComponent.setScaleHeight(15.0);atmosphereComponent.setDensity(0.001);atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(213.0/255.0,160.0/255.0,94.0/255.0));atmosphereComponent.setSunBrightness(0.25)}},earth:{groups:['planets'],radius:6378.1,systemRadius:765372,label:'Earth',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined,color:[0.0,0.6,0.8,0.7]},spheroid:{equatorialRadius:6378.137,polarRadius:6356.752,planetographic:!0},spheroidLOD:{features:['normalMap','specularMap','nightMap','decalMap','nightMapEmmissive','shadowEntities'],textures:{color:{url:'earth/color_$SIZE_$FACE.png',sizes:[16,512,4096]},normal:{url:'earth/normal_$SIZE_$FACE.png',sizes:[16,512,4096]},specular:{url:'earth/specular_$SIZE_$FACE.png',sizes:[16,512,4096]},night:{url:'earth/night_$SIZE_$FACE.png',sizes:[16,512,4096]},decal:{url:'earth/cloud_$SIZE_$FACE.png',sizes:[16,512,4096]}},shadowEntities:['moon']},controllers:[{type:'dynamo',url:'earth/sun/orb'},{type:'dynamo',url:'earth/ori'}],postCreateFunction:(entity,extraOptions)=>{if(extraOptions&&extraOptions.clouds===!1){const spheroidLODComponent=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.SpheroidLODComponent);spheroidLODComponent.setTexture('decal','')} + const atmosphereComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent);atmosphereComponent.setScaleHeight(8.0);atmosphereComponent.setDensity(0.0015);atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(1.5*143.0/255.0,1.5*178.0/255.0,1.5*255.0/255.0));atmosphereComponent.setSunBrightness(2.0);atmosphereComponent.setSunsetColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(1,0.5,0));atmosphereComponent.setSunsetIntensity(1.2)}},mars:{groups:['planets'],radius:3396.2,systemRadius:46922,label:'Mars',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined,color:[0.89,0.51,0.35,0.7]},spheroid:{equatorialRadius:3396.19,polarRadius:3376.2,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'mars/color_$SIZE_$FACE.png',sizes:[4,512,4096]}},shadowEntities:['phobos','deimos']},controllers:[{type:'dynamo',url:'mars/sun/orb'},{type:'dynamo',url:'mars/ori'}],postCreateFunction:(entity)=>{const atmosphereComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent);atmosphereComponent.setScaleHeight(10.8);atmosphereComponent.setDensity(0.001);atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(225.0/255.0,178.0/255.0,112.0/255.0));atmosphereComponent.setSunBrightness(0.8);atmosphereComponent.setSunsetColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(10.0/255.0,75.0/255.0,140.0/255.0));atmosphereComponent.setSunsetIntensity(1.0)}},jupiter:{groups:['planets'],radius:71492,systemRadius:3782501,label:'Jupiter',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined,color:[0.95,0.71,0.64,0.7]},spheroid:{equatorialRadius:71492,polarRadius:66854,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'jupiter/color_$SIZE_$FACE.jpg',sizes:[16,512,4096]}},shadowEntities:['io','europa','ganymede','callisto']},controllers:[{type:'dynamo',url:'jupiter/sun/orb'},{type:'dynamo',url:'jupiter/ori'},{type:'coverage',coverage:[Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY],update:(entity)=>{if(entity.getOrientation().isNaN()){return} + const time=entity.getScene().getEngine().getTime();const rotations=jupiterRotationData.rotations;const currentDriftRate=(rotations[rotations.length-1][1]-rotations[rotations.length-2][1])/(rotations[rotations.length-1][0]-rotations[rotations.length-2][0]);let rate=currentDriftRate;let index=jupiterRotationData.hintIndex;if(time=rotations[rotations.length-1][0]){index=rotations.length-1}else if(time=0;i--){if(rotations[i][0]<=time&&time{const atmosphereComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent);atmosphereComponent.setScaleHeight(200.0);atmosphereComponent.setDensity(5.0e-5);atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(234.0/255.0,202.0/255.0,170.0/255.0));atmosphereComponent.setSunBrightness(0.25)}},saturn:{groups:['planets'],radius:60268,systemRadius:7184413,label:'Saturn',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},spheroid:{equatorialRadius:60268,polarRadius:54364,planetographic:!1},spheroidLOD:{features:['shadowEntities','shadowRings'],textures:{color:{url:'saturn/color_$SIZE_$FACE.png',sizes:[4,512]}},shadowEntities:['iapetus','dione','rhea','tethys','titan']},controllers:[{type:'dynamo',url:'saturn/sun/orb'},{type:'dynamo',url:'saturn/ori'}],postCreateFunction:(entity)=>{const ringsComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RingsComponent);ringsComponent.setInnerRadius(74270.580913);ringsComponent.setOuterRadius(140478.924731);ringsComponent.setTopTextureUrl('$STATIC_ASSETS_URL/sprites/saturn_rings_top.png');ringsComponent.setBottomTextureUrl('$STATIC_ASSETS_URL/sprites/saturn_rings_bottom.png');ringsComponent.setFadeDistance(250);ringsComponent.setShadowEntities(['iapetus','dione','rhea','tethys','titan']);const atmosphereComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent);atmosphereComponent.setScaleHeight(200.0);atmosphereComponent.setDensity(5.0e-5);atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(234.0/255.0,202.0/255.0,151.0/255.0))}},uranus:{groups:['planets'],radius:25559,systemRadius:1164893,label:'Uranus',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},spheroid:{equatorialRadius:25559,polarRadius:24973,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'uranus/color_$SIZE_$FACE.png',sizes:[4,256]}},shadowEntities:['titania','oberon','umbriel','ariel','miranda']},controllers:[{type:'dynamo',url:'uranus/sun/orb'},{type:'dynamo',url:'uranus/ori'}],postCreateFunction:(entity)=>{const ringsComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RingsComponent);ringsComponent.setInnerRadius(26840);ringsComponent.setOuterRadius(103000);ringsComponent.setTopTextureUrl('$STATIC_ASSETS_URL/sprites/uranus_rings.png');ringsComponent.setBottomTextureUrl('$STATIC_ASSETS_URL/sprites/uranus_rings.png');ringsComponent.setFadeDistance(250);ringsComponent.setShadowEntities(['miranda','ariel','umbriel','titania','oberon']);const atmosphereComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent);atmosphereComponent.setScaleHeight(200.0);atmosphereComponent.setDensity(5.0e-5);atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(147.0/255.0,183.0/255.0,201.0/255.0));atmosphereComponent.setSunsetColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(164.0/255.0,168.0/255.0,102.0/255.0));atmosphereComponent.setSunsetIntensity(1.0)}},neptune:{groups:['planets'],radius:24764,systemRadius:43213894,label:'Neptune',parents:[[Number.NEGATIVE_INFINITY,'sun']],trail:{length:undefined,color:[0.48,0.69,1.00,0.7]},spheroid:{equatorialRadius:24764,polarRadius:24341,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'neptune/color_$SIZE_$FACE.png',sizes:[4,256]}},shadowEntities:['triton','proteus','despina','galatea','larissa']},controllers:[{type:'dynamo',url:'neptune/sun/orb'},{type:'dynamo',url:'neptune/ori'}],postCreateFunction:(entity)=>{const ringsComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.RingsComponent);ringsComponent.setInnerRadius(40900);ringsComponent.setOuterRadius(62964);ringsComponent.setTopTextureUrl('$STATIC_ASSETS_URL/sprites/neptune_rings.png');ringsComponent.setBottomTextureUrl('$STATIC_ASSETS_URL/sprites/neptune_rings.png');ringsComponent.setFadeDistance(250);const atmosphereComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent);atmosphereComponent.setScaleHeight(200.0);atmosphereComponent.setDensity(5.0e-5);atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(138.0/255.0,160.0/255.0,255.0/255.0))}}});const jupiterRotationData={hintIndex:0,textureAngleOffset:-60.38,referenceTime:617098056,referenceAngleInSystemII:313.47,referenceAngleInSystemIII:305,offsetFactor:-0.000003074,rotations:[[-1136116758,15],[-1037534358,28],[-938951958,22],[-867931156,0],[-812721554,12],[-744292752,47],[-639143949,62],[-533822346,48],[-483883145,27],[-391953544,15],[102427264,85],[315576066,138],[615211269,312],[660052869,347]]}}),"../pioneer/scripts/src/entities/saturn_major_moons.js": + /*!*************************************************************!*\ + !*** ../pioneer/scripts/src/entities/saturn_major_moons.js ***! + \*************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var _entity_utils__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./entity_utils */"../pioneer/scripts/src/entities/entity_utils.js");var pioneer__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({dione:{groups:['saturn','moons','inner','major'],radius:561.7,label:'Dione',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},spheroid:{equatorialRadius:561.7,polarRadius:561.7,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'dione/color_$SIZE_$FACE.png',sizes:[4,512,2048]}},shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'dione/saturn/orb'},{type:'dynamo',url:'dione/ori'}]},enceladus:{groups:['saturn','moons','inner','major'],radius:252.1,label:'Enceladus',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},spheroid:{equatorialRadius:252.1,polarRadius:252.1,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'enceladus/color_$SIZE_$FACE.png',sizes:[4,512,2048]}},shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'enceladus/saturn/orb'},{type:'dynamo',url:'enceladus/ori'}],postCreateFunction:(entity)=>{_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[-25.20*0.8,-69.23*0.8,-240.99*0.8],[-0.0999,-0.2747,-0.9563]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[-61.73*0.8,-24.61*0.8,-243.08*0.8],[-0.2449,-0.0976,-0.9646]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[-35.82*0.8,-46.87*0.8,-245.00*0.8],[-0.1421,-0.1859,-0.9722]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[30.37*0.7,-17.54*0.7,-249.55*0.7],[0.1205,-0.0696,-0.9902]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[0.00*0.7,2.20*0.7,-251.99*0.7],[0,0.0087,-0.9999]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[-30.94*0.7,30.94*0.7,-248.17*0.7],[-0.1227,0.1227,-0.9848]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[45.99*0.7,-34.55*0.7,-245.35*0.7],[0.1824,-0.1371,-0.9736]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[-51.91*0.9,0.68*0.9,-246.59*0.9],[-0.2059,0.0026,-0.9785]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[-31.81*0.9,-13.36*0.9,-249.63*0.9],[-0.1262,-0.0530,-0.9905]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[-5.49*0.9,-29.77*0.9,-250.18*0.9],[-0.0217,-0.1181,-0.9927]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[16.54*0.9,-47.1*0.9,-247.01*0.9],[0.0656,-0.1869,-0.9801]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[-16.47*0.8,60.14*0.8,-244.16*0.8],[-0.0653,0.2386,-0.9689]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[51.52*0.8,23.97*0.8,-245.51*0.8],[0.2044,0.0951,-0.9742]);_entity_utils__WEBPACK_IMPORTED_MODULE_1__.EntityUtils.addGeyser(entity,100,0.1,20,0.002,4,[28.13*0.8,33.52*0.8,-248.17*0.8],[0.1116,0.1330,-0.9848])}},hyperion:{groups:['saturn','moons','outer','major'],radius:135.0,label:'Hyperion',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/hyperion/hyperion.gltf',scale:[1,1,1]},controllers:[{type:'dynamo',url:'hyperion/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity}]},iapetus:{groups:['saturn','moons','outer','major'],radius:735.6,label:'Iapetus',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},spheroid:{equatorialRadius:735.6,polarRadius:735.6,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'iapetus/color_$SIZE_$FACE.png',sizes:[4,512,2048]}},shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'iapetus/saturn/orb'},{type:'dynamo',url:'iapetus/ori'}]},mimas:{groups:['saturn','moons','inner','major'],radius:198.3,label:'Mimas',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/mimas/mimas.gltf',scale:[1,1,1]},controllers:[{type:'dynamo',url:'mimas/saturn/orb'},{type:'dynamo',url:'mimas/ori'}]},rhea:{groups:['saturn','moons','outer','major'],radius:764.3,label:'Rhea',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},spheroid:{equatorialRadius:764.3,polarRadius:764.3,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'rhea/color_$SIZE_$FACE.png',sizes:[4,512,2048]}},shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'rhea/saturn/orb'},{type:'dynamo',url:'rhea/ori'}]},tethys:{groups:['saturn','moons','inner','major'],radius:538.4,label:'Tethys',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},spheroid:{equatorialRadius:538.4,polarRadius:527.5,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'tethys/color_$SIZE_$FACE.png',sizes:[4,512,2048]}},shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'tethys/saturn/orb'},{type:'dynamo',url:'tethys/ori'}]},titan:{groups:['saturn','moons','outer','major'],radius:2575.0,label:'Titan',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},spheroid:{equatorialRadius:2575.0,polarRadius:2575.0,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'titan/color_$SIZE_$FACE.png',sizes:[4,512,1024]}},shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'titan/saturn/orb'},{type:'dynamo',url:'titan/ori'}],postCreateFunction:(entity)=>{const atmosphereComponent=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AtmosphereComponent);atmosphereComponent.setScaleHeight(75.0);atmosphereComponent.setDensity(0.0005);atmosphereComponent.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(179.0/255.0,145.0/255.0,53.0/255.0));atmosphereComponent.setSunsetColor(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Color(0.0/255.0,71.0/255.0,204.0/255.0));atmosphereComponent.setSunsetIntensity(0.5)}}})}),"../pioneer/scripts/src/entities/saturn_minor_moons.js": + /*!*************************************************************!*\ + !*** ../pioneer/scripts/src/entities/saturn_minor_moons.js ***! + \*************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({aegaeon:{groups:['saturn','moons','minor','ring moonlet'],radius:0.12,label:'Aegaeon',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.12,0.12,0.12],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'aegaeon/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},aegir:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Aegir',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'aegir/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},albiorix:{groups:['saturn','moons','minor','gallic'],radius:16.0,label:'Albiorix',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[16,16,16],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'albiorix/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},alvaldi:{groups:['saturn','moons','minor','norse'],radius:3,label:'Alvaldi',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:3,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'alvaldi/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},angrboda:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'Angrboda',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1.5,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'angrboda/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},anthe:{groups:['saturn','moons','minor','alkyonides'],radius:0.9,label:'Anthe',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[0.9,0.9,0.9],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'anthe/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},atlas:{groups:['saturn','moons','minor','ring shepherd'],radius:15.1,label:'Atlas',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[15.1,15.1,15.1],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'atlas/saturn/orb'},{type:'dynamo',url:'atlas/ori'}]},bebhionn:{groups:['saturn','moons','minor','gallic'],radius:3.0,label:'Bebhionn',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'bebhionn/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},beli:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'Beli',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1.5,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'beli/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},bergelmir:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Bergelmir',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'bergelmir/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},bestla:{groups:['saturn','moons','minor','norse'],radius:3.5,label:'Bestla',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[3.5,3.5,3.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'bestla/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},calypso:{groups:['saturn','moons','minor','trojan'],radius:10.7,label:'Calypso',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[10.7,10.7,10.7],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'calypso/saturn/orb'},{type:'dynamo',url:'calypso/ori'}]},daphnis:{groups:['saturn','moons','minor','ring shepherd'],radius:3.8,label:'Daphnis',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[3.8,3.8,3.8],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'daphnis/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},eggther:{groups:['saturn','moons','minor','norse'],radius:3,label:'Eggther',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:3,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'eggther/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},epimetheus:{groups:['saturn','moons','minor','co-orbital'],radius:58.1,label:'Epimetheus',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[58.1,58.1,58.1],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'epimetheus/saturn/orb'},{type:'dynamo',url:'epimetheus/ori'}]},erriapus:{groups:['saturn','moons','minor','gallic'],radius:5.0,label:'Erriapus',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[5,5,5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'erriapus/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},farbauti:{groups:['saturn','moons','minor','norse'],radius:2.5,label:'Farbauti',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.5,2.5,2.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'farbauti/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},fenrir:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'Fenrir',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2,2,2],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'fenrir/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},fornjot:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Fornjot',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'fornjot/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},geirrod:{groups:['saturn','moons','minor','norse'],radius:2,label:'Geirrod',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'geirrod/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},gerd:{groups:['saturn','moons','minor','norse'],radius:2,label:'Gerd',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'gerd/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},greip:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Greip',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'greip/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},gridr:{groups:['saturn','moons','minor','norse'],radius:2,label:'Gridr',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'gridr/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},gunnlod:{groups:['saturn','moons','minor','norse'],radius:2,label:'Gunnlod',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'gunnlod/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},hati:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Hati',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'hati/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},helene:{groups:['saturn','moons','minor','trojan'],radius:17.6,label:'Helene',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[17.6,17.6,17.6],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'helene/saturn/orb'},{type:'dynamo',url:'helene/ori'}]},hyrrokkin:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Hyrrokkin',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'hyrrokkin/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},ijiraq:{groups:['saturn','moons','minor','inuit'],radius:6.0,label:'Ijiraq',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[6,6,6],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'ijiraq/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},janus:{groups:['saturn','moons','minor','co-orbital'],radius:89.5,label:'Janus',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[89.5,89.5,89.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'janus/saturn/orb'},{type:'dynamo',url:'janus/ori'}]},jarnsaxa:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Jarnsaxa',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'jarnsaxa/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},kari:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Kari',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'kari/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},kiviuq:{groups:['saturn','moons','minor','inuit'],radius:8.0,label:'Kiviuq',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[8,8,8],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'kiviuq/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},loge:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Loge',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'loge/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},methone:{groups:['saturn','moons','minor','alkyonides'],radius:1.6,label:'Methone',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.6,1.6,1.6],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'methone/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},mundilfari:{groups:['saturn','moons','minor','norse'],radius:3.5,label:'Mundilfari',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[3.5,3.5,3.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'mundilfari/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},narvi:{groups:['saturn','moons','minor','norse'],radius:3.5,label:'Narvi',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[3.5,3.5,3.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'narvi/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},paaliaq:{groups:['saturn','moons','minor','inuit'],radius:11.0,label:'Paaliaq',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[11,11,11],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'paaliaq/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},pallene:{groups:['saturn','moons','minor','alkyonides'],radius:2.5,label:'Pallene',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.5,2.5,2.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'pallene/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},pan:{groups:['saturn','moons','minor','ring shepherd'],radius:14.1,label:'Pan',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[14.1,14.1,14.1],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'pan/saturn/orb'},{type:'dynamo',url:'pan/ori'}]},pandora:{groups:['saturn','moons','minor','ring shepherd'],radius:40.7,label:'Pandora',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[40.7,40.7,40.7],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'pandora/saturn/orb'},{type:'dynamo',url:'pandora/ori'}]},phoebe:{groups:['saturn','moons','minor','norse'],radius:106.5,label:'Phoebe',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/phoebe/phoebe.gltf'},controllers:[{type:'dynamo',url:'phoebe/saturn/orb'},{type:'dynamo',url:'phoebe/ori'}]},polydeuces:{groups:['saturn','moons','minor','trojan'],radius:1.3,label:'Polydeuces',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.3,1.3,1.3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'polydeuces/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},prometheus:{groups:['saturn','moons','minor','ring shepherd'],radius:43.1,label:'Prometheus',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[43.1,43.1,43.1],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'prometheus/saturn/orb'},{type:'dynamo',url:'prometheus/ori'}]},s_2004_s_7:{groups:['saturn','moons','minor','norse'],radius:3,label:'S/2004 S 7',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:3,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_7/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_12:{groups:['saturn','moons','minor','norse'],radius:2.5,label:'S/2004 S 12',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2.5,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_12/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_13:{groups:['saturn','moons','minor','norse'],radius:3,label:'S/2004 S 13',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:3,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_13/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_17:{groups:['saturn','moons','minor','norse'],radius:2,label:'S/2004 S 17',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_17/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_21:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2004 S 21',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1.5,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_21/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_24:{groups:['saturn','moons','minor','gallic'],radius:1.5,label:'S/2004 S 24',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1.5,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_24/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_28:{groups:['saturn','moons','minor','norse'],radius:2,label:'S/2004 S 28',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_28/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_31:{groups:['saturn','moons','minor','inuit'],radius:2,label:'S/2004 S 31',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_31/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_36:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2004 S 36',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1.5,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_36/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_37:{groups:['saturn','moons','minor','norse'],radius:2,label:'S/2004 S 37',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_37/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_39:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2004 S 39',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1.5,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_39/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_1:{groups:['saturn','moons','minor','norse'],radius:2.5,label:'S/2006 S 1',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2.5,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_1/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_3:{groups:['saturn','moons','minor','norse'],radius:3,label:'S/2006 S 3',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:3,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_3/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2007_s_2:{groups:['saturn','moons','minor','norse'],radius:3,label:'S/2007 S 2',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:3,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2007_s_2/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2007_s_3:{groups:['saturn','moons','minor','norse'],radius:2.5,label:'S/2007 S 3',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2.5,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2007_s_3/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2009_s_1:{groups:['saturn','moons','propeller moonlet'],radius:0.150,label:'S/2009 S 1',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:0.150,shadowEntities:['saturn']},controllers:[{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}],postCreateFunction:(entity)=>{const oeController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController,undefined,entity.getControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.FixedController));const oe=new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements();oe.epoch=0;oe.eccentricity=0;oe.semiMajorAxis=1.17e5;oe.meanAngularMotion=1.5472777e-4;oe.meanAnomalyAtEpoch=-1.5;oe.orbitOrientation.set(-0.9397445462795919,0.02005900203250964,-0.052689008288728606,-0.33719681579275607);oeController.addOrbitalElements(-1e100,oe);oeController.addOrbitalElements(+1e100,oe)}},s_2019_s_1:{groups:['saturn','moons','minor','inuit'],radius:3,label:'S/2019 S 1',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:3,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_1/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},saturn_lviii:{groups:['saturn','moons','minor','norse'],radius:2,label:'Saturn LVIII',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'saturn_lviii/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},saturn_lx:{groups:['saturn','moons','minor','inuit'],radius:2,label:'Saturn LX',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'saturn_lx/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},saturn_lxiv:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'Saturn LXIV',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:1.5,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'saturn_lxiv/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},siarnaq:{groups:['saturn','moons','minor','inuit'],radius:20.0,label:'Siarnaq',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[20,20,20],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'siarnaq/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},skathi:{groups:['saturn','moons','minor','norse'],radius:4.0,label:'Skathi',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[4,4,4],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'skathi/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},skoll:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Skoll',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'skoll/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},skrymir:{groups:['saturn','moons','minor','norse'],radius:2,label:'Skrymir',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'skrymir/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},surtur:{groups:['saturn','moons','minor','norse'],radius:3.0,label:'Surtur',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'surtur/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},suttungr:{groups:['saturn','moons','minor','norse'],radius:3.5,label:'Suttungr',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[3.5,3.5,3.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'suttungr/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},tarqeq:{groups:['saturn','moons','minor','inuit'],radius:3.0,label:'Tarqeq',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[3,3,3],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'tarqeq/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},tarvos:{groups:['saturn','moons','minor','gallic'],radius:7.5,label:'Tarvos',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[7.5,7.5,7.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'tarvos/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},telesto:{groups:['saturn','moons','minor','trojan'],radius:12.4,label:'Telesto',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[12.4,12.4,12.4],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'telesto/saturn/orb'},{type:'dynamo',url:'telesto/ori'}]},thiazzi:{groups:['saturn','moons','minor','norse'],radius:2,label:'Thiazzi',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:2,shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'thiazzi/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},thrymr:{groups:['saturn','moons','minor','norse'],radius:3.5,label:'Thrymr',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[3.5,3.5,3.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'thrymr/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},ymir:{groups:['saturn','moons','minor','norse'],radius:9.0,label:'Ymir',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:undefined,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[9,9,9],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'ymir/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_40:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2004 S 40',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:66061440,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_40/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_41:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2004 S 41',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:79022304,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_41/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_42:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2004 S 42',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:79998624,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_42/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_43:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2004 S 43',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:84678912,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_43/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_44:{groups:['saturn','moons','minor','norse'],radius:2.5,label:'S/2004 S 44',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:88660224,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.5,2.5,2.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_44/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_45:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2004 S 45',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:89743680,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_45/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_46:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2004 S 46',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:95694912,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_46/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_47:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2004 S 47',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:65879136,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_47/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_48:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2004 S 48',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:107343360,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_48/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_49:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2004 S 49',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:109231200,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_49/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_50:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2004 S 50',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:108902016,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_50/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_51:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2004 S 51',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:131278752,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_51/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_52:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2004 S 52',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:141175872,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_52/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2004_s_53:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2004 S 53',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:115986816,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2004_s_53/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2005_s_4:{groups:['saturn','moons','minor','inuit'],radius:2.5,label:'S/2005 S 4',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:38899008,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.5,2.5,2.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2005_s_4/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2005_s_5:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2005 S 5',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:101763648,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2005_s_5/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_10:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2006 S 10',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:84943296,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_10/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_11:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2006 S 11',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:90052992,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_11/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_12:{groups:['saturn','moons','minor','gallic'],radius:2.0,label:'S/2006 S 12',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:89428320,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_12/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_13:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2006 S 13',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:91638432,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_13/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_14:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2006 S 14',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:99591552,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_14/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_15:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2006 S 15',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:104886144,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_15/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_16:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2006 S 16',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:104329728,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_16/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_17:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2006 S 17',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:109259712,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_17/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_18:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2006 S 18',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:112181760,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_18/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_19:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2006 S 19',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:120038112,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_19/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_20:{groups:['saturn','moons','minor','norse'],radius:2.5,label:'S/2006 S 20',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:49012128,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.5,2.5,2.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_20/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2006_s_9:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2006 S 9',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:55977696,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2006_s_9/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2007_s_5:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2007 S 5',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:64530432,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2007_s_5/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2007_s_6:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2007 S 6',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:82036800,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2007_s_6/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2007_s_7:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2007 S 7',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:65170656,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2007_s_7/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2007_s_8:{groups:['saturn','moons','minor','gallic'],radius:2.0,label:'S/2007 S 8',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:72308160,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2007_s_8/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2007_s_9:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2007 S 9',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:93145248,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2007_s_9/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_10:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2019 S 10',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:97030656,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_10/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_11:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2019 S 11',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:96336000,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_11/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_12:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2019 S 12',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:98396640,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_12/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_13:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2019 S 13',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:98921088,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_13/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_14:{groups:['saturn','moons','minor','inuit'],radius:2.0,label:'S/2019 S 14',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:77167296,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_14/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_15:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2019 S 15',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:100357056,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_15/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_16:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2019 S 16',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:115877088,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_16/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_17:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2019 S 17',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:111576096,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_17/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_18:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2019 S 18',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:114657984,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_18/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_19:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2019 S 19',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:113879520,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_19/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_2:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2019 S 2',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:69104448,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_2/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_20:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2019 S 20',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:118838880,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_20/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_21:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2019 S 21',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:141378048,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_21/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_3:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2019 S 3',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:72380736,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_3/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_4:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2019 S 4',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:78128064,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_4/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_5:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2019 S 5',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:85568832,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_5/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_6:{groups:['saturn','moons','minor','inuit'],radius:2.0,label:'S/2019 S 6',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:79202880,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_6/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_7:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2019 S 7',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:93337056,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_7/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_8:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2019 S 8',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:94061952,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_8/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2019_s_9:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2019 S 9',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:94444704,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2019_s_9/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2020_s_1:{groups:['saturn','moons','minor','inuit'],radius:2.0,label:'S/2020 S 1',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:38975040,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2020_s_1/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2020_s_10:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2020 S 10',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:131951808,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2020_s_10/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2020_s_2:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2020 S 2',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:77552640,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2020_s_2/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2020_s_3:{groups:['saturn','moons','minor','inuit'],radius:1.5,label:'S/2020 S 3',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:78450336,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2020_s_3/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2020_s_4:{groups:['saturn','moons','minor','gallic'],radius:1.5,label:'S/2020 S 4',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:80085888,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2020_s_4/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2020_s_5:{groups:['saturn','moons','minor','inuit'],radius:1.5,label:'S/2020 S 5',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:80687232,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2020_s_5/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2020_s_6:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2020 S 6',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:100989504,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2020_s_6/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2020_s_7:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2020 S 7',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:74450880,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2020_s_7/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2020_s_8:{groups:['saturn','moons','minor','norse'],radius:1.5,label:'S/2020 S 8',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:106109568,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[1.5,1.5,1.5],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2020_s_8/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},s_2020_s_9:{groups:['saturn','moons','minor','norse'],radius:2.0,label:'S/2020 S 9',parents:[[Number.NEGATIVE_INFINITY,'saturn']],trail:{length:132621408,color:[0.72,0.65,0.52,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[2.0,2.0,2.0],shadowEntities:['saturn']},controllers:[{type:'dynamo',url:'s_2020_s_9/saturn/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]}})}),"../pioneer/scripts/src/entities/small_body_spacecraft.js": + /*!****************************************************************!*\ + !*** ../pioneer/scripts/src/entities/small_body_spacecraft.js ***! + \****************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var _animation__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ../animation */"../pioneer/scripts/src/animation.js");var pioneer__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({sc_dart:{groups:['small body spacecraft','asteroid spacecraft','65803_didymos','dimorphos','spacecraft'],occlusionRadius:0.0012,extentsRadius:0.00625,label:'DART',parents:[[691007069,'earth'],[691418893,'sun'],[717454117,'65803_didymos']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_dart/dart.gltf',shadowEntities:['earth']},controllers:[{type:'dynamo',url:'sc_dart/earth/orb'},{type:'dynamo',url:'sc_dart/sun/orb'},{type:'dynamo',url:'sc_dart/65803_didymos/pos'},{type:'custom',func:(entity)=>{const keyframeController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.KeyframeController);keyframeController.addPositionKeyframe(717503237,new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-10320.163052194115,13421.106828492655,5349.381737812169));keyframeController.addPositionKeyframe(717503237+2890.2383179924736,new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.9047084058613565,-0.7147384471771195,-0.30125475602973617));return keyframeController}},{type:'align',primary:{type:'velocity',target:'sc_dart',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg},secondary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},coverage:[Number.NEGATIVE_INFINITY,717454117]},{type:'align',primary:{type:'point',target:'dimorphos',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg},secondary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis},coverage:[717454117,Number.POSITIVE_INFINITY]}]},sc_dawn:{groups:['small body spacecraft','asteroid spacecraft','dwarf planet spacecraft','4_vesta','1_ceres','spacecraft'],occlusionRadius:0.000885,extentsRadius:0.00985,label:'Dawn',parents:[[244168849.8323595,'earth'],[244461608,'sun'],[288169447,'mars'],[288210177,'sun'],[363182466,'4_vesta'],[400075267,'sun'],[476712067,'1_ceres'],[594302469.184,'']],trail:{length:659889.75},model:{url:'$STATIC_ASSETS_URL/models/sc_dawn/model.gltf',rotate:[{z:-90}]},controllers:[{type:'dynamo',url:'sc_dawn/earth/orb'},{type:'dynamo',url:'sc_dawn/sun/1/orb'},{type:'dynamo',url:'sc_dawn/mars/orb'},{type:'dynamo',url:'sc_dawn/sun/2/orb'},{type:'dynamo',url:'sc_dawn/vesta/orb'},{type:'dynamo',url:'sc_dawn/sun/3/orb'},{type:'dynamo',url:'sc_dawn/ceres/orb'},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.9999478154504517,0.008904517167862874,0.004868284692665544,-0.0011729254143642916),coverage:[244168849.8323595,244171353.18400002]},{type:'dynamo',url:'sc_dawn/ori'}]},sc_deep_impact:{groups:['small body spacecraft','comet spacecraft','9p_tempel_1','103p_hartley_2','spacecraft'],occlusionRadius:0.001650,extentsRadius:0.00300,label:'Deep Impact',parents:[[158829812.068274,'earth'],[159287744,'sun'],[173560752,'9p_tempel_1'],[173923158,'sun'],[251798121,'earth'],[253531474,'sun'],[282984399,'earth'],[285405903,'sun'],[330384030,'earth'],[331534813,'sun'],[342017751,'103p_hartley_2'],[342368983,'sun'],[429192067,'']],trail:{length:47421459.0,lengthCoverages:[[362406,173560752,173923158],[1733353,251798121,253531474],[2421504,282984399,285405903],[1150783,330384030,331534813],[351232,342017751,342368983]]},model:{url:'$STATIC_ASSETS_URL/models/sc_deep_impact/deep_impact_wo_impactor.gltf',rotate:[{y:-90}]},controllers:[{type:'dynamo',url:'sc_deep_impact/earth/launch/orb'},{type:'dynamo',url:'sc_deep_impact/sun/orb'},{type:'dynamo',url:'sc_deep_impact/9p_tempel_1/pos'},{type:'dynamo',url:'sc_deep_impact/earth/flyby1/orb'},{type:'dynamo',url:'sc_deep_impact/earth/flyby2/orb'},{type:'dynamo',url:'sc_deep_impact/earth/flyby3/orb'},{type:'dynamo',url:'sc_deep_impact/103p_hartley_2/pos'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity},{type:'dynamo',url:'sc_deep_impact/quat'}]},sc_deep_impact_impactor:{groups:['small body spacecraft','comet spacecraft','9p_tempel_1','sc_deep_impact','spacecraft'],occlusionRadius:0.001,extentsRadius:0.00100,label:'Deep Impact Impactor',parents:[[158829812.068274,'sc_deep_impact'],[173642464.18400002,'9p_tempel_1'],[173727938.18158135,'']],trail:{length:27830.0},model:{url:'$STATIC_ASSETS_URL/models/sc_deep_impact_impactor/deep_impact_impactor.gltf',rotate:[{y:-90}]},controllers:[{type:'custom',func:(entity)=>{const keyframeController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.KeyframeController);keyframeController.addPositionKeyframe(173642464.18400002,new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.000713,-0.000055,0),'sc_deep_impact',undefined,'sc_deep_impact');keyframeController.addPositionKeyframe(173656621.40411958,new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-123095.24746842826,-48294.70341251187,61743.99881253781),'sc_deep_impact',173642464.18400002);keyframeController.addPositionKeyframe(173727938.18158135,new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(1.580046751199936,3.178179950746365,-0.628457454223176));return keyframeController}},{type:'fixed',position:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.000713,-0.000055,0),orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity,relativeToEntity:'sc_deep_impact',coverage:[158829812.068274,173642464.18400002]},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.9060465048532422,0.3173702681972099,0.2649483984949708,0.09032269948692226),coverage:[173642464.18400002,Number.POSITIVE_INFINITY]},{type:'dynamo',url:'sc_deep_impact_impactor/quat',coverage:[173642464.18400002,Number.POSITIVE_INFINITY]}]},sc_deep_impact_impactor_impact_site:{groups:['small body sites','comet sites','9p_tempel_1','sc_deep_impact','sc_deep_impact_impactor','sites'],radius:0.001,label:'Deep Impact Impactor Impact Site',parents:[[173727938.18158135,'9p_tempel_1']],controllers:[{type:'fixed',position:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(3.1153282512332603,-1.2860729555237982,-1.277920399403075),orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity,relativeToEntity:'9p_tempel_1',coverage:[173727938.18158135,Number.POSITIVE_INFINITY]}]},sc_deep_space_1:{groups:['small body spacecraft','asteroid spacecraft','9969_braille','spacecraft'],occlusionRadius:0.00125,extentsRadius:0.005000,label:'Deep Space 1',parents:[[-37470248,'earth'],[-36628312,'sun'],[-13523799,'9969_braille'],[-13496699,'sun'],[54458637,'19p_borrelly'],[54476825,'sun'],[61977664.184,'']],trail:{length:40845609.0,lengthCoverages:[[27100,-13523799,-13496699],[18188,54458637,54476825]]},model:{url:'$STATIC_ASSETS_URL/models/sc_deep_space_1/deep_space_1.gltf',rotate:[{x:90},{z:90}]},controllers:[{type:'dynamo',url:'sc_deep_space_1/earth/orb'},{type:'dynamo',url:'sc_deep_space_1/sun/orb'},{type:'dynamo',url:'sc_deep_space_1/9969_braille/pos'},{type:'dynamo',url:'sc_deep_space_1/19p_borrelly/pos'},{type:'align',primary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis,target:'earth'},secondary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxisNeg,target:'sun'}},{type:'dynamo',url:'sc_deep_space_1/quat'}]},sc_near_shoemaker:{groups:['small body spacecraft','asteroid spacecraft','253_mathilde','433_eros','spacecraft'],occlusionRadius:0.002,extentsRadius:0.0034000,label:'NEAR',parents:[[-122129937,'sun'],[-61397606,'earth'],[-60793811,'sun'],[-79403925,'253_mathilde'],[-79210250,'sun'],[-8425610,'433_eros'],[36675809.3654,'']],trail:{length:63919069.0,lengthCoverages:[[400000,-8425610,35279032.137],[0,35279032.137,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_near_shoemaker/near.gltf',rotate:[{x:90},{z:135}]},controllers:[{type:'custom',func:(entity)=>{const oeController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.OrbitalElementsController);const oe=new pioneer__WEBPACK_IMPORTED_MODULE_2__.OrbitalElements();oe.eccentricity=0.3722732412046076;oe.epoch=-122129937;oe.semiMajorAxis=235420679.8644008;oe.orbitOrientation.set(0.25408339907533106,0.05463135384055627,-0.18986948069810847,0.9467875272685549);oe.meanAngularMotion=1.0085301888805118e-7;oe.meanAnomalyAtEpoch=-0.005941352116228519;oeController.addOrbitalElements(-122129937,oe);oeController.addOrbitalElements(-113227200,oe);oeController.setCoverage(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Interval(-122129937,-113227200));return oeController}},{type:'dynamo',url:'sc_near_shoemaker/sun/orb'},{type:'dynamo',url:'sc_near_shoemaker/earth/flyby/orb'},{type:'dynamo',url:'sc_near_shoemaker/253_mathilde/pos'},{type:'dynamo',url:'sc_near_shoemaker/433_eros/orb'},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.5052018803124495,-0.11842169431143575,0.7652511949887616,-0.3809697770341459),coverage:[-122129937,-121953528.049046]},{type:'dynamo',url:'sc_near_shoemaker/quat'},{type:'fixed',position:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.930389249841349,4.935129554115763,-4.002004469114965),orientation:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.11222410400554989,0.7066112547219852,-0.6897721372150081,0.11099857612696495),coverage:[35279032.137,36675809.3654]},{type:'rotateByEntityOrientation',coverage:[35279032.137,36675809.3654]}]},sc_near_shoemaker_landing_site:{groups:['433_eros','sc_near_shoemaker','sites'],radius:0.001,systemRadius:200,label:'NEAR Shoemaker Landing Site',parents:[[36675809.3654,'433_eros']],controllers:[{type:'fixed',position:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.930389249841349,4.935129554115763,-4.002004469114965),orientation:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.11222410400554989,0.7066112547219852,-0.6897721372150081,0.11099857612696495),relativeToEntity:'433_eros',coverage:[36675809.3654,Number.POSITIVE_INFINITY]}]},sc_lucy:{groups:['small body spacecraft','asteroid spacecraft','52246_donaldjohanson','3548_eurybates','15094_polymele','11351_leucus','21900_orus','617_patroclus','menoetius','spacecraft'],occlusionRadius:0.002,extentsRadius:0.007125,label:'Lucy',parents:[[687656642.763,'earth'],[687915086,'sun'],[718960993,'earth'],[719531941,'sun'],[787134972,'earth'],[787532222,'sun'],[798252820,'52246_donaldjohanson'],[798584539,'sun'],[870652086,'3548_eurybates'],[872642047,'sun'],[872642047,'15094_polymele'],[875308504,'sun'],[891166024,'11351_leucus'],[894761809,'sun'],[909384911,'21900_orus'],[912190135,'sun'],[977590306,'earth'],[978108682,'sun'],[1046169596,'617_patroclus_barycenter'],[1047892376,'sun']],dependents:['152830_dinkinesh'],trail:{length:63919069.0,lengthCoverages:[[719531941-718960993,718960993,719531941],[787532222-787134972,787134972,787532222],[798584539-798252820,798252820,798584539],[872642047-870652086,870652086,872642047],[875308504-872642047,872642047,875308504],[894761809-891166024,891166024,894761809],[912190135-909384911,909384911,912190135],[978108682-977590306,977590306,978108682],[1047892376-1046169596,1046169596,1047892376]]},model:{url:'$STATIC_ASSETS_URL/models/sc_lucy/lucy.gltf',rotate:[{x:90},{z:90}]},controllers:[{type:'dynamo',url:'sc_lucy/earth/launch/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity},{type:'dynamo',url:'sc_lucy/sun/orb'},{type:'dynamo',url:'sc_lucy/earth/flyby1/orb'},{type:'dynamo',url:'sc_lucy/earth/flyby2/orb'},{type:'dynamo',url:'sc_lucy/52246_donaldjohanson/pos'},{type:'dynamo',url:'sc_lucy/3548_eurybates/pos'},{type:'dynamo',url:'sc_lucy/15094_polymele/pos'},{type:'dynamo',url:'sc_lucy/11351_leucus/pos'},{type:'dynamo',url:'sc_lucy/21900_orus/pos'},{type:'dynamo',url:'sc_lucy/earth/flyby3/orb'},{type:'dynamo',url:'sc_lucy/617_patroclus/pos'},{type:'align',primary:{type:'point',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis,target:'earth'},secondary:{type:'align',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis,target:'sun',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis}},{type:'dynamo',url:'sc_lucy/quat'}]},sc_new_horizons:{groups:['small body spacecraft','dwarf planet spacecraft','TNO spacecraft','134340_pluto','486958_arrokoth','spacecraft'],occlusionRadius:0.00135,extentsRadius:0.0026,label:'New Horizons',parents:[[190972278.33046317,'earth'],[191055829,'sun'],[225619606,'jupiter'],[226100665,'sun'],[490130161,'134340_pluto'],[490167848,'sun'],[598753684,'486958_arrokoth'],[600203601,'sun']],trail:{length:60*60*24*365*3},model:{url:'$STATIC_ASSETS_URL/models/sc_new_horizons/new_horizons.gltf',rotate:[{y:90}]},controllers:[{type:'dynamo',url:'sc_new_horizons/earth/orb'},{type:'dynamo',url:'sc_new_horizons/sun/1/orb'},{type:'dynamo',url:'sc_new_horizons/jupiter/orb'},{type:'dynamo',url:'sc_new_horizons/sun/2/orb'},{type:'dynamo',url:'sc_new_horizons/pluto/orb'},{type:'dynamo',url:'sc_new_horizons/sun/3/pos'},{type:'dynamo',url:'sc_new_horizons/mu69/pos'},{type:'dynamo',url:'sc_new_horizons/sun/4/pos'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis}},{type:'dynamo',url:'sc_new_horizons/ori/1'},{type:'dynamo',url:'sc_new_horizons/ori/2'}]},sc_rosetta:{groups:['small body spacecraft','comet spacecraft','67p_churyumov_gerasimenko','spacecraft'],occlusionRadius:0.001400,extentsRadius:0.016000,label:'Rosetta',parents:[[131491581.583,'earth'],[131901500,'sun'],[162704887,'earth'],[163831232,'sun'],[225623375,'mars'],[225657862,'sun'],[248111015,'earth'],[248475560,'sun'],[311055929,'earth'],[311664877,'sun'],[452394238,'67p_churyumov_gerasimenko'],[528503957.968,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_rosetta/rosettaPhilae.gltf',rotate:[{x:180},{z:90}]},controllers:[{type:'dynamo',url:'sc_rosetta/earth/launch/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity},{type:'dynamo',url:'sc_rosetta/sun/1/orb'},{type:'dynamo',url:'sc_rosetta/earth/flyby1/orb'},{type:'dynamo',url:'sc_rosetta/sun/2/orb'},{type:'dynamo',url:'sc_rosetta/mars/flyby/orb'},{type:'dynamo',url:'sc_rosetta/sun/3/orb'},{type:'dynamo',url:'sc_rosetta/earth/flyby2/orb'},{type:'dynamo',url:'sc_rosetta/sun/4/orb'},{type:'dynamo',url:'sc_rosetta/earth/flyby3/orb'},{type:'dynamo',url:'sc_rosetta/sun/5/orb'},{type:'dynamo',url:'sc_rosetta/67p_churyumov_gerasimenko/pos'},{type:'dynamo',url:'sc_rosetta/ori'},{type:'coverage',coverage:[469053367.183,Number.POSITIVE_INFINITY],enter:(entity)=>{const modelComponent=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);if(modelComponent!==null){modelComponent.setHiddenObject('Philae',!0)}},exit:(entity)=>{const modelComponent=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);if(modelComponent!==null){modelComponent.setHiddenObject('Philae',!1)}}},{type:'custom',func:(entity)=>{const solarPanelAlignLeft=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);solarPanelAlignLeft.setJoint('panels_01');solarPanelAlignLeft.setSecondaryAlignType('point');solarPanelAlignLeft.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis);solarPanelAlignLeft.setSecondaryTargetEntity('sun');return solarPanelAlignLeft}},{type:'custom',func:(entity)=>{const solarPanelAlignRight=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);solarPanelAlignRight.setJoint('panels_02');solarPanelAlignRight.setSecondaryAlignType('point');solarPanelAlignRight.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis);solarPanelAlignRight.setSecondaryTargetEntity('sun');return solarPanelAlignRight}}]},sc_rosetta_impact_site:{groups:['small body sites','comet sites','67p_churyumov_gerasimenko','sc_rosetta','sites'],radius:0.001,label:'Rosetta Impact Site',parents:[[528503957.968,'67p_churyumov_gerasimenko']],controllers:[{type:'fixed',position:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(1.7309310500292525,0.3509303067271947,1.1641920075039298),orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity,relativeToEntity:'67p_churyumov_gerasimenko',coverage:[528503957.968,Number.POSITIVE_INFINITY]}]},sc_osiris_rex:{groups:['small body spacecraft','asteroid spacecraft','101955_bennu','spacecraft'],occlusionRadius:0.001600,extentsRadius:0.005,label:'OSIRIS-REx',parents:[[526676400,'earth'],[527025408,'sun'],[558938468,'earth'],[559919190,'sun'],[591770603,'101955_bennu'],[674049669,'sun'],[748358886,'earth'],[749140122,'sun']],dependents:['sc_osiris_rex_src','99942_apophis'],trail:{length:102742.5,lengthCoverages:[[10000000,Number.NEGATIVE_INFINITY,599748661],[672000.0,599748661,668095733],[10000000,668095733,Number.POSITIVE_INFINITY]]},model:{url:'$STATIC_ASSETS_URL/models/sc_osiris_rex_v2/osiris_rex_articulated_panels.gltf',rotate:[{x:90}],shadowEntities:['bennu']},controllers:[{type:'dynamo',url:'sc_osiris_rex/earth/launch/orb'},{type:'dynamo',url:'sc_osiris_rex/sun/1/orb'},{type:'dynamo',url:'sc_osiris_rex/earth/flyby/orb'},{type:'dynamo',url:'sc_osiris_rex/sun/2/orb'},{type:'dynamo',url:'sc_osiris_rex/bennu/pos'},{type:'dynamo',url:'sc_osiris_rex/sun/3/orb'},{type:'dynamo',url:'sc_osiris_rex/earth/sample_return/orb'},{type:'dynamo',url:'sc_osiris_rex/sun/4/orb'},{type:'align',primary:{type:'point',target:'earth',axis:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.175109477645991,0.45028151394683397,0.8755473882299549)},secondary:{type:'align',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxis,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.ZAxis},coverage:[658200668.0606446,Number.POSITIVE_INFINITY]},{type:'dynamo',url:'sc_osiris_rex/ori'},{type:'custom',func:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeSubobjectVisibleAnimation(model,'Tagsam_housing_cover',!0,[[593036911,!1]])}},{type:'custom',func:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model,'Tagsam_rod_bottom','z',[[595442726,0],[595442726+1*180,-2.51758508612],[595442726+2*180,-2.51758508612],[595442726+3*180,0],[656502686-220*60,0],[656502686-220*60+360,-3.71758508612],[656502686+2*60+90,-3.71758508612],[656502686+2*60+90+180,0],[656502686+10*24*3600+0*180,0],[656502686+10*24*3600+2*180,-2.73771997401],[656502686+10*24*3600+4*180,0]])}},{type:'custom',func:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model,'Tagsam_rod_top','z',[[593728111,0],[593728111+2,0.15],[595442726,0.15],[595442726+1*180,2.73247002363],[595442726+2*180,2.73247002363],[595442726+3*180,0.15],[656502686-220*60,0.15],[656502686-220*60+360,3.73247002363],[656502686+2*60+90,3.73247002363],[656502686+2*60+90+180,0.15],[656502686+10*24*3600+0*180,0.15],[656502686+10*24*3600+1*180,1.16136826422],[656502686+10*24*3600+2*180,0.509601235],[656502686+10*24*3600+3*180,1.16136826422],[656502686+10*24*3600+4*180,0.15]])}},{type:'custom',func:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model,'tagsam_head','z',[[595442726+1*180,0],[595442726+1.5*180,1.57079632679],[595442726+2*180,1.57079632679],[656502686-220*60,0],[656502686-220*60+90,1.57079632679],[656502686+2*60,1.57079632679],[656502686+2*60+90,0],[656502686+10*24*3600,0],[656502686+10*24*3600+360,1.01463145268]])}},{type:'custom',func:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeSubobjectVisibleAnimation(model,'tagsam_head',!0,[[656502686+10*24*3600+360,!1]])}},{type:'custom',func:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model,'Gimbal_Base_Right','z',[[656501483+0*60,-70*Math.PI/180],[656501483+2*60,0],[656503242+0*60,0],[656503242+2*180,-70*Math.PI/180]])}},{type:'custom',func:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model,'Gimbal_Base_Left','z',[[656501483+0*60,-70*Math.PI/180],[656501483+2*60,0],[656503242+0*60,0],[656503242+2*180,-70*Math.PI/180]])}},{type:'custom',func:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model,'Gimbal_Pivot_Right','x',[[656501483+2*60,0],[656501483+4*60,38*Math.PI/180],[656503242,38*Math.PI/180],[656503242+2*60,0]])}},{type:'custom',func:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model,'Gimbal_Pivot_Left','x',[[656501483+2*60,0],[656501483+4*60,-38*Math.PI/180],[656503242,-38*Math.PI/180],[656503242+2*60,0]])}},{type:'custom',func:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);return _animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeSubobjectVisibleAnimation(model,'heatshield',!0,[[748824183.985732,!1]])}}]},sc_osiris_rex_src:{groups:['small body spacecraft','asteroid spacecraft','101955_bennu','sample return capsule'],occlusionRadius:0.0008,extentsRadius:0.0005,label:'OSIRIS-REx SRC',parents:[[748824183.985732,'sc_osiris_rex'],[748832190,'earth'],[748839215,'']],dependents:['sc_osiris_rex'],trail:{length:360},model:{url:'$STATIC_ASSETS_URL/models/sc_osiris_rex_v2/src/osiris_rex_heatshield.gltf',rotate:[{x:90}]},controllers:[{type:'dynamo',url:'sc_osiris_rex_src/sc_osiris_rex'},{type:'dynamo',url:'sc_osiris_rex_src/earth'},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(-0.7795827954678449,-0.23701239922750972,0.5441503490850964,-0.19994045416955505)},{type:'coverage',coverage:[748838642,748839373],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!0)}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!1)}}},{type:'custom',func:(entity)=>{const translate=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TranslateController);translate.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0,0,0.0012));translate.setRelativeToOrientation(!0);return translate},coverage:[748824183.985732,748839215]}],postCreateFunction:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);model.setTranslation(new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0,0,-0.0012))}},sc_philae:{groups:['small body spacecraft','comet spacecraft','67p_churyumov_gerasimenko','spacecraft','landers'],occlusionRadius:0.0006,extentsRadius:0.001,label:'Philae',parents:[[469053367.183,'67p_churyumov_gerasimenko'],[469078512.324,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_philae/philae.gltf',rotate:[{x:180},{z:90}]},controllers:[{type:'dynamo',url:'sc_philae/67p_churyumov_gerasimenko/pos'},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.05763938670269045,0.04093459828351704,0.6750586755218195,0.7343690110337115)},{type:'custom',func:(entity)=>{const originOffset=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.0021658104318583687,0.0011575046500869896,0.00011875498849156656);const modelOffset=new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(0.00147,0,0);const translateController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TranslateController);translateController.setTranslation(originOffset);const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);model.setTranslation(modelOffset);return translateController},coverage:[469053367.183,469078512.324]}]},sc_philae_landing_site:{groups:['small body sites','comet sites','67p_churyumov_gerasimenko','sc_philae','sites'],radius:0.001,systemRadius:200,label:'Philae Landing Site',parents:[[469078512.324,'67p_churyumov_gerasimenko']],controllers:[{type:'fixed',position:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(2.4452763955965984,-0.12110982508097201,-0.36032099522959377),orientation:pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion.Identity,relativeToEntity:'67p_churyumov_gerasimenko',coverage:[469078512.324,Number.POSITIVE_INFINITY]}]},sc_psyche:{groups:['small body spacecraft','asteroid spacecraft','16_psyche','spacecraft'],occlusionRadius:0.0031,extentsRadius:0.025,label:'Psyche',parents:[[750482453,'earth'],[750686758,'sun'],[831828698,'mars'],[832302380,'sun'],[931665741,'16_psyche']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_psyche/psyche.gltf',rotate:[{y:-90},{x:90}]},controllers:[{type:'dynamo',url:'sc_psyche/earth/orb'},{type:'dynamo',url:'sc_psyche/sun/orb'},{type:'dynamo',url:'sc_psyche/mars/orb'},{type:'dynamo',url:'sc_psyche/16_psyche/orb'},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.XAxisNeg}},{type:'custom',func:(entity)=>{const solarPanelAlignLeft=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);solarPanelAlignLeft.setJoint('ArrayGimbleLeft');solarPanelAlignLeft.setSecondaryAlignType('point');solarPanelAlignLeft.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis);solarPanelAlignLeft.setSecondaryTargetEntity('sun');return solarPanelAlignLeft}},{type:'custom',func:(entity)=>{const solarPanelAlignRight=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.AlignController);solarPanelAlignRight.setJoint('ArrayGimbleRight');solarPanelAlignRight.setSecondaryAlignType('point');solarPanelAlignRight.setSecondaryAxis(pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3.YAxis);solarPanelAlignRight.setSecondaryTargetEntity('sun');return solarPanelAlignRight}}]},sc_stardust:{groups:['small body spacecraft','comet spacecraft','81p_wild_2','9p_tempel_1','spacecraft'],occlusionRadius:0.00065,extentsRadius:0.003000,label:'Stardust',parents:[[-28304869.3,'earth'],[-28038699,'sun'],[32627842,'earth'],[33120541,'sun'],[89379733,'5535_annefrank'],[89550209,'sun'],[126009572,'81p_wild_2'],[126678668,'sun'],[190336290,'earth'],[190866114,'sun'],[284944970,'earth'],[285742028,'sun'],[350896766,'9p_tempel_1'],[351068113,'sun'],[354279666,'']],trail:{length:62659492.0},model:{url:'$STATIC_ASSETS_URL/models/sc_stardust/stardust_articulated.gltf',shadowEntities:['earth'],rotate:[{x:90},{z:90}]},controllers:[{type:'dynamo',url:'sc_stardust/earth/launch/orb'},{type:'dynamo',url:'sc_stardust/sun/orb'},{type:'dynamo',url:'sc_stardust/earth/flyby1/orb'},{type:'dynamo',url:'sc_stardust/5535_annefrank/pos'},{type:'dynamo',url:'sc_stardust/81p_wild_2/pos'},{type:'dynamo',url:'sc_stardust/earth/flyby2/orb'},{type:'dynamo',url:'sc_stardust/earth/flyby3/orb'},{type:'dynamo',url:'sc_stardust/9p_tempel_1/pos'},{type:'dynamo',url:'sc_stardust/quat'},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.382740492391079,-0.1080542417135509,-0.5511677923678098,-0.7335175941913997),coverage:[351017063,354279666]},{type:'coverage',coverage:[190576755.185-64.40161622339717,Number.POSITIVE_INFINITY],enter:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);for(const object of['Stardust_capsule','Stardust_tex_01_c','Stardust_tex_02_c','Stardust_tex_03_c','Stardust_tex_02_c2','Stardust_Sample_Collection1']){model.setHiddenObject(object,!0)}},exit:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);for(const object of['Stardust_capsule','Stardust_tex_01_c','Stardust_tex_02_c','Stardust_tex_03_c','Stardust_tex_02_c2','Stardust_Sample_Collection1']){model.setHiddenObject(object,!1)}}}],postCreateFunction:(entity)=>{const model=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.ModelComponent);const stardustAnimation=(angle,timeOffset,duration)=>{return([[4449664+timeOffset,angle],[4449664+timeOffset+duration,0],[10411264-timeOffset-duration,0],[10411264-timeOffset,angle],[81864064+timeOffset,angle],[81864064+timeOffset+duration,0],[92664064-timeOffset-duration,0],[92664064-timeOffset,angle],[125496064+timeOffset,angle],[125496064+timeOffset+duration,0],[126363664-timeOffset-duration,0],[126363664-timeOffset,angle]])};_animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model,'Stardust_capsule','x',stardustAnimation(1.481785,0,600));_animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model,'Stardust_Sample_Collection1','x',stardustAnimation(-Math.PI,610,300));_animation__WEBPACK_IMPORTED_MODULE_1__.Animation.makeJointRotationAnimation(model,'Stardust_Sample_Collection2','x',stardustAnimation(-Math.PI,920,300))}},sc_stardust_src:{groups:['small body spacecraft','comet spacecraft','81p_wild_2','earth','spacecraft'],occlusionRadius:0.0004,extentsRadius:0.0008,label:'Stardust SRC',parents:[[190576690.7833838,'sc_stardust'],[190576755.185,'earth'],[190591985.184,'']],trail:{length:14547.0},model:{url:'$STATIC_ASSETS_URL/models/sc_stardust_src/stardust_capsule.gltf',shadowEntities:['earth'],rotate:[{x:90},{z:90}]},controllers:[{type:'dynamo',url:'sc_stardust_src/earth/pos'},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_2__.Quaternion(0.5761056269233067,0.6860897901682099,0.2627910947477326,0.3582233199772653)},{type:'coverage',coverage:[190591100,Number.POSITIVE_INFINITY],enter:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!0);trail.setStartTime(1600)}},exit:(entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.TrailComponent);if(trail!==null){trail.setRelativeToEntityOrientation(!1);trail.setStartTime(18000)}}},{type:'custom',func:(entity)=>{const keyframeControllerRelease=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.KeyframeController);keyframeControllerRelease.addPositionKeyframe(190576755.185-64.40161622339717,new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.0010057,0,0.0001569),'sc_stardust',undefined,'sc_stardust',undefined);keyframeControllerRelease.addPositionKeyframe(190576755.185,new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-0.016734488308429718,-0.019199222326278687,-0.00404781848192215),'sc_stardust');return keyframeControllerRelease}},{type:'custom',func:(entity)=>{const keyframeControllerLand=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_2__.KeyframeController);keyframeControllerLand.addPositionKeyframe(190591163,new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-1979.4577357598625,-4478.591383446022,4136.322858267745),'earth');keyframeControllerLand.addPositionKeyframe(190591445.184,new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-1947.8360605285134,-4491.082890234251,4123.1018367103425),'earth');keyframeControllerLand.addPositionKeyframe(190591985.184,new pioneer__WEBPACK_IMPORTED_MODULE_2__.Vector3(-1918.7633689113482,-4478.864184129612,4103.897124245734),'earth');return keyframeControllerLand}},{type:'rotateByEntityOrientation',coverage:[190591163,190591985.184]}]}})}),"../pioneer/scripts/src/entities/solar_spacecraft.js": + /*!***********************************************************!*\ + !*** ../pioneer/scripts/src/entities/solar_spacecraft.js ***! + \***********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({sc_biosentinel:{groups:['sun','spacecraft'],occlusionRadius:0.0002,extentsRadius:0.0005,label:'BioSentinel',parents:[[721866289,'earth'],[722273637,'moon'],[722923565,'sun']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_biosentinel/biosentinel.gltf',shadowEntities:['moon']},controllers:[{type:'dynamo',url:'sc_biosentinel/earth/orb'},{type:'dynamo',url:'sc_biosentinel/moon/orb'},{type:'dynamo',url:'sc_biosentinel/sun/orb'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis},secondary:{type:'align',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis,targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis}}]},sc_kepler_space_telescope:{groups:['sun','spacecraft','telescope'],occlusionRadius:0.002350,extentsRadius:0.00400,label:'Kepler',parents:[[289679042.1855,'earth'],[290348743,'sun'],[595512069.183,'']],trail:{length:32190048},model:{url:'$STATIC_ASSETS_URL/models/sc_kepler/Kepler.gltf'},controllers:[{type:'dynamo',url:'sc_kepler/earth/orb'},{type:'dynamo',url:'sc_kepler/sun/orb'},{type:'align',primary:{type:'align',target:'sun',targetAxis:new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(0.25176480336,-0.66735243742,0.7009092643),axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis},secondary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.XAxisNeg}}]},sc_mariner_2:{groups:['sun','spacecraft'],occlusionRadius:0.002,extentsRadius:0.0025000,label:'Mariner 2',parents:[[-1178599240.703784,'sun'],[409233667.18358755,'']],trail:{length:29411352.0},controllers:[{type:'animdata',url:'sc_mariner_2',dataType:'pos'}]},sc_parker_solar_probe:{groups:['sun','spacecraft'],occlusionRadius:0.0015,extentsRadius:0.003,label:'Parker Solar Probe',parents:[[587333783.3431,'earth'],[587454078,'sun']],trail:{length:12942631.0},model:{url:'$STATIC_ASSETS_URL/models/sc_parker_solar_probe/PSP.gltf'},controllers:[{type:'dynamo',url:'sc_parker_solar_probe/earth/orb'},{type:'dynamo',url:'sc_parker_solar_probe/sun/orb'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg}}]},sc_spitzer:{groups:['sun','spacecraft'],occlusionRadius:0.0085,extentsRadius:0.004,label:'Spitzer',parents:[[115064804,'earth'],[115493678,'sun'],[633614469,'']],trail:{length:32167331.0},model:{url:'$STATIC_ASSETS_URL/models/sc_spitzer/SPITZER.gltf',rotate:[{z:-90},{x:-90}],shadowEntities:['venus','mercury']},controllers:[{type:'dynamo',url:'sc_spitzer/earth/orb'},{type:'dynamo',url:'sc_spitzer/sun/orb'},{type:'fixed',orientation:new pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion(0.5258297992951877,0.8139480432783324,-0.1400557906856776,-0.20341086625833524),coverage:[115064804,174548493]},{type:'dynamo',url:'sc_spitzer/quat'}]},sc_stereo_ahead:{groups:['sun','spacecraft'],occlusionRadius:0.003,extentsRadius:0.003000,label:'STEREO Ahead',parents:[[215097110,'earth'],[221418192,'sun']],trail:{length:29809031.0},model:{url:'$STATIC_ASSETS_URL/models/sc_stereo_ahead/stereo_a.gltf',rotate:[{x:90}],shadowEntities:['venus','mercury']},controllers:[{type:'dynamo',url:'sc_stereo_ahead/earth/orb'},{type:'dynamo',url:'sc_stereo_ahead/sun/orb'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_stereo_ahead',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg}}]},sc_stereo_behind:{groups:['sun','spacecraft'],occlusionRadius:0.003,extentsRadius:0.003000,label:'STEREO Behind',parents:[[215097110,'earth'],[224468337,'sun'],[527860868.182,'']],trail:{length:33473699.0},model:{url:'$STATIC_ASSETS_URL/models/sc_stereo_behind/stereo_b.gltf',rotate:[{x:90}],shadowEntities:['venus','mercury']},controllers:[{type:'dynamo',url:'sc_stereo_behind/earth/orb'},{type:'dynamo',url:'sc_stereo_behind/sun/orb'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_stereo_behind',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg}}]},sc_ulysses:{groups:['sun','spacecraft'],occlusionRadius:0.002,extentsRadius:0.002,label:'Ulysses',parents:[[-291488100,'sun'],[268142464.18410408,'']],trail:{length:140294739.0},model:{url:'$STATIC_ASSETS_URL/models/sc_ulysses/ulysses.gltf',shadowEntities:['venus','mercury']},controllers:[{type:'animdata',url:'sc_ulysses',dataType:'pos'},{type:'align',primary:{type:'point',target:'sun',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxis},secondary:{type:'velocity',target:'sc_ulysses',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxisNeg}}]},sc_wmap:{groups:['sun','spacecraft'],occlusionRadius:0.0026,extentsRadius:0.0026,label:'WMAP',parents:[[339422466.184,'sun'],[360158466.184,'']],trail:{length:60*60*24*365},controllers:[{type:'animdata',url:'sc_wmap',dataType:'pos'}]}})}),"../pioneer/scripts/src/entities/uranus_major_moons.js": + /*!*************************************************************!*\ + !*** ../pioneer/scripts/src/entities/uranus_major_moons.js ***! + \*************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({ariel:{groups:['uranus','moons','major'],radius:578.9,label:'Ariel',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},spheroid:{equatorialRadius:578.9,polarRadius:578.9,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'ariel/color_$SIZE_$FACE.png',sizes:[4,512]}},shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'ariel/uranus/orb'},{type:'dynamo',url:'ariel/ori'}]},miranda:{groups:['uranus','moons','major'],radius:235.8,label:'Miranda',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},spheroid:{equatorialRadius:235.8,polarRadius:235.8,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'miranda/color_$SIZE_$FACE.png',sizes:[4,256]}},shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'miranda/uranus/orb'},{type:'dynamo',url:'miranda/ori'}]},oberon:{groups:['uranus','moons','major'],radius:761.4,label:'Oberon',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},spheroid:{equatorialRadius:761.4,polarRadius:761.4,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'oberon/color_$SIZE_$FACE.png',sizes:[4,512]}},shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'oberon/uranus/orb'},{type:'dynamo',url:'oberon/ori'}]},titania:{groups:['uranus','moons','major'],radius:788.4,label:'Titania',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},spheroid:{equatorialRadius:788.4,polarRadius:788.4,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'titania/color_$SIZE_$FACE.png',sizes:[4,512]}},shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'titania/uranus/orb'},{type:'dynamo',url:'titania/ori'}]},umbriel:{groups:['uranus','moons','major'],radius:584.7,label:'Umbriel',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},spheroid:{equatorialRadius:584.7,polarRadius:584.7,planetographic:!1},spheroidLOD:{features:['shadowEntities'],textures:{color:{url:'umbriel/color_$SIZE_$FACE.png',sizes:[4,256]}},shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'umbriel/uranus/orb'},{type:'dynamo',url:'umbriel/ori'}]}})}),"../pioneer/scripts/src/entities/uranus_minor_moons.js": + /*!*************************************************************!*\ + !*** ../pioneer/scripts/src/entities/uranus_minor_moons.js ***! + \*************************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({belinda:{groups:['uranus','moons','minor','inner'],radius:45.0,label:'Belinda',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[45,45,45],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'belinda/uranus/orb'},{type:'dynamo',url:'belinda/ori'}]},bianca:{groups:['uranus','moons','minor','inner'],radius:25.7,label:'Bianca',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[25.7,25.7,25.7],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'bianca/uranus/orb'},{type:'dynamo',url:'bianca/ori'}]},caliban:{groups:['uranus','moons','minor','irregular'],radius:36,label:'Caliban',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[36,36,36],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'caliban/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},cordelia:{groups:['uranus','moons','minor','inner'],radius:20.1,label:'Cordelia',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[20.1,20.1,20.1],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'cordelia/uranus/orb'},{type:'dynamo',url:'cordelia/ori'}]},cressida:{groups:['uranus','moons','minor','inner'],radius:39.8,label:'Cressida',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[39.8,39.8,39.8],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'cressida/uranus/orb'},{type:'dynamo',url:'cressida/ori'}]},cupid:{groups:['uranus','moons','minor','inner'],radius:9.0,label:'Cupid',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[9,9,9],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'cupid/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},desdemona:{groups:['uranus','moons','minor','inner'],radius:32.0,label:'Desdemona',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[32,32,32],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'desdemona/uranus/orb'},{type:'dynamo',url:'desdemona/ori'}]},ferdinand:{groups:['uranus','moons','minor','irregular'],radius:10,label:'Ferdinand',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[10,10,10],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'ferdinand/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},francisco:{groups:['uranus','moons','minor','irregular'],radius:11,label:'Francisco',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[11,11,11],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'francisco/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},juliet:{groups:['uranus','moons','minor','inner'],radius:46.8,label:'Juliet',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[46.8,46.8,46.8],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'juliet/uranus/orb'},{type:'dynamo',url:'juliet/ori'}]},mab:{groups:['uranus','moons','minor','inner'],radius:12.5,label:'Mab',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[12.5,12.5,12.5],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'mab/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},margaret:{groups:['uranus','moons','minor','irregular'],radius:10,label:'Margaret',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[10,10,10],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'margaret/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},ophelia:{groups:['uranus','moons','minor','inner'],radius:22.4,label:'Ophelia',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[22.4,22.4,22.4],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'ophelia/uranus/orb'},{type:'dynamo',url:'ophelia/ori'}]},perdita:{groups:['uranus','moons','minor','inner'],radius:15.0,label:'Perdita',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[15,15,15],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'perdita/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},portia:{groups:['uranus','moons','minor','inner'],radius:67.6,label:'Portia',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[67.6,67.6,67.6],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'portia/uranus/orb'},{type:'dynamo',url:'portia/ori'}]},prospero:{groups:['uranus','moons','minor','irregular'],radius:25,label:'Prospero',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[25,25,25],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'prospero/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},puck:{groups:['uranus','moons','minor','inner'],radius:81.0,label:'Puck',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[81,81,81],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'puck/uranus/orb'},{type:'dynamo',url:'puck/ori'}]},rosalind:{groups:['uranus','moons','minor','inner'],radius:36.0,label:'Rosalind',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[36,36,36],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'rosalind/uranus/orb'},{type:'dynamo',url:'rosalind/ori'}]},setebos:{groups:['uranus','moons','minor','irregular'],radius:24,label:'Setebos',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[24,24,24],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'setebos/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},stephano:{groups:['uranus','moons','minor','irregular'],radius:16,label:'Stephano',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_2/generic_asteroid_2.gltf',scale:[16,16,16],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'stephano/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},sycorax:{groups:['uranus','moons','minor','irregular'],radius:82,label:'Sycorax',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_3/generic_asteroid_3.gltf',scale:[82,82,82],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'sycorax/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]},trinculo:{groups:['uranus','moons','minor','irregular'],radius:9,label:'Trinculo',parents:[[Number.NEGATIVE_INFINITY,'uranus']],trail:{length:undefined,color:[0.67,0.92,1.00,0.7]},model:{url:'$STATIC_ASSETS_URL/models/generic/asteroid_1/generic_asteroid_1.gltf',scale:[9,9,9],shadowEntities:['uranus']},controllers:[{type:'dynamo',url:'trinculo/uranus/orb'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity}]}})}),"../pioneer/scripts/src/entities/venus_spacecraft.js": + /*!***********************************************************!*\ + !*** ../pioneer/scripts/src/entities/venus_spacecraft.js ***! + \***********************************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ../entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.register({sc_magellan:{groups:['venus','spacecraft'],occlusionRadius:0.003200,extentsRadius:0.006000,label:'Magellan',parents:[[-336388283.36,'sun'],[-296448521.457,'venus'],[-164631538.81763855,'']],trail:{length:undefined},model:{url:'$STATIC_ASSETS_URL/models/sc_magellan/magellan.gltf',shadowEntities:['venus']},controllers:[{type:'dynamo',url:'sc_magellan/venus/orb'},{type:'custom',func:(entity)=>{const oeCruiseController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController);const oeCruise=new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements();oeCruise.epoch=-336394683.816;oeCruise.eccentricity=0.1791852824104108;oeCruise.semiMajorAxis=128280596.63956015;oeCruise.meanAngularMotion=2.5073465306679634e-7;oeCruise.meanAnomalyAtEpoch=2.9229288382327625;oeCruise.orbitOrientation.set(0.8728453580255966,0.1876084386162498,-0.08948587100888229,0.4415159494547423);oeCruiseController.addOrbitalElements(-336388283.360,oeCruise);oeCruiseController.addOrbitalElements(-296448521.457,oeCruise);return oeCruiseController}},{type:'custom',func:(entity)=>{const oeVOIController=entity.addControllerByClass(pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElementsController);const oeVOI=new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements();oeVOI.epoch=-296448521.457;oeVOI.eccentricity=1.272922970547487;oeVOI.semiMajorAxis=23358.593430196037;oeVOI.meanAngularMotion=0.00015965302516479147;oeVOI.meanAnomalyAtEpoch=-6.138103356108873;oeVOI.orbitOrientation.set(-0.49933963770188916,0.11817755769547109,0.7262027627540558,-0.45751889408554064);oeVOIController.addOrbitalElements(-296448521.457,oeVOI);oeVOIController.addOrbitalElements(-296410230.351,oeVOI);const oeVOI2=new pioneer__WEBPACK_IMPORTED_MODULE_1__.OrbitalElements();oeVOI2.epoch=-295884037.7511;oeVOI2.eccentricity=0.39186818222106645;oeVOI2.semiMajorAxis=10434.012201911135;oeVOI2.meanAngularMotion=0.000534773863104956;oeVOI2.meanAnomalyAtEpoch=-1.5165416917234864;oeVOI2.orbitOrientation.set(-0.4665778554219434,0.18802595119032475,0.7217932088991018,-0.47535871728198204);oeVOIController.addOrbitalElements(-296410230.351,oeVOI2);oeVOIController.addOrbitalElements(-295884037.7511,oeVOI2);return oeVOIController}},{type:'align',primary:{type:'point',target:'earth',axis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.YAxis},secondary:{type:'align',axis:new pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3(-Math.sqrt(0.5),Math.sqrt(0.5),0),target:'venus',targetAxis:pioneer__WEBPACK_IMPORTED_MODULE_1__.Vector3.ZAxisNeg}}]},sc_venus_express:{groups:['venus','spacecraft'],occlusionRadius:0.0009,extentsRadius:0.0040,label:'Venus Express',parents:[[184784702,'earth'],[185369766,'sun'],[197902579,'venus'],[473341201,'']],trail:{length:779592.165087551},controllers:[{type:'dynamo',url:'sc_venus_express/earth'},{type:'dynamo',url:'sc_venus_express/sun'},{type:'dynamo',url:'sc_venus_express/venus'},{type:'fixed',orientation:pioneer__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity},{type:'dynamo',url:'sc_venus_express/quat'}]}})}),"../pioneer/scripts/src/entity.js": + /*!****************************************!*\ + !*** ../pioneer/scripts/src/entity.js ***! + \****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Entity":function(){return Entity}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class Entity{static register(entities){for(const name in entities){if(Object.prototype.hasOwnProperty.call(entities,name)){this._entities.set(name,entities[name])}}} + static create(name,scene,extraOptions){const options=Entity._entities.get(name);if(options===undefined){throw new Error('Could not find the options for the entity with name '+name)} + return this.createFromOptions(name,options,scene,extraOptions)} + static createFromOptions(name,options,scene,extraOptions){let actualName=name;if(extraOptions){if(extraOptions.namePrefix){actualName=extraOptions.namePrefix+actualName} + if(extraOptions.nameSuffix){actualName=actualName+extraOptions.nameSuffix}} + let entity=scene.getEntity(actualName);if(entity!==null){return entity} + entity=scene.addEntity(actualName);try{if(options.radius){entity.setOcclusionRadius(options.radius);entity.setExtentsRadius(options.radius)} + if(options.occlusionRadius){entity.setOcclusionRadius(options.occlusionRadius)} + if(options.extentsRadius){entity.setExtentsRadius(options.extentsRadius)} + for(const[startTime,parentName]of options.parents){entity.addParentingTableEntry(startTime,parentName)} + if(options.label){const component=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.DivComponent);const div=component.getDiv();div.innerHTML=options.label;div.className='pioneer-label-div'} + if(options.labelFadeEntity){const divComponent=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.DivComponent);if(divComponent===null){throw new Error('There is no label.')} + divComponent.setFadeWhenCloseToEntity(options.labelFadeEntity)} + if(options.trail){const component=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.TrailComponent,options.trail.name);component.setStartTime(options.trail.length);if(options.trail.color){component.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(options.trail.color[0],options.trail.color[1],options.trail.color[2],options.trail.color[3]))}else{component.setColor(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Color(1,1,1,0.5))} + if(options.trail.relativeTo){component.setRelativeToEntity(options.trail.relativeTo)} + if(options.trail.lengthCoverages){const trailLength=options.trail.length;for(let i=0,l=options.trail.lengthCoverages.length;i{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.TrailComponent);if(trail!==null){trail.setStartTime(lengthCoverage[0])}});coverageController.setExitFunction((entity)=>{const trail=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.TrailComponent);if(trail!==null){trail.setStartTime(trailLength)}})}}} + if(options.spheroid){const component=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent,options.spheroid.name);component.setEquatorialRadius(options.spheroid.equatorialRadius);component.setPolarRadius(options.spheroid.polarRadius);component.setPlanetographic(options.spheroid.planetographic)} + if(options.spheroidLOD){const component=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidLODComponent,options.spheroidLOD.name??'basic');if(options.spheroidLOD.features){for(let i=0,l=options.spheroidLOD.features.length;i{return group.trim()});for(const[name,options]of Entity._entities){const entityGroups=options.groups;if(!entityGroups){continue} + let matches=!0;for(const group of groupsArray){if(!entityGroups.includes(group)){matches=!1}} + if(!matches){continue} + matchingEntityNames.add(name)}}else{for(const name of Entity._entities.keys()){matchingEntityNames.add(name)}} + return matchingEntityNames} + static getGroups(){const groups=new Set();for(const options of this._entities.values()){const entityGroups=options.groups;if(entityGroups!==undefined){for(let i=0;i{entity.setCanOcclude(!1);const thinModel=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent);thinModel.setUrl('$STATIC_ASSETS_URL/models/saturn/magnetosphere_thin/saturn_magnetosphere_thin.gltf');thinModel.setScale(1078.27002124);thinModel.setRotation(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(Math.sqrt(0.5),Math.sqrt(0.5),0,0));thinModel.setPixelRadiusVisibleInterval(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(4000,Number.POSITIVE_INFINITY));thinModel.setResourcesLoadedCallback(()=>{thinModel.getThreeJsObjects()[0].renderOrder=-1});const thickModel=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent);thickModel.setPixelRadiusVisibleInterval(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Interval(0,4000));thickModel.setResourcesLoadedCallback(()=>{thickModel.getThreeJsObjects()[0].renderOrder=-1})}},scene)}else{scene.removeEntity('saturn_magnetosphere')}} + static isEnabledSaturnMagnetosphere(scene){return scene.getEntity('saturn_magnetosphere')!==null} + static _createJupiterModelComponent(scene,name,fileName){const entity=scene.getEntity('jupiter');const model=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.ModelComponent,name);model.setUrl(`$STATIC_ASSETS_URL/models/${'jupiter'}/${name}/${'jupiter'}_${fileName}.gltf`);model.setScale(1337.08);const rotation1=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(Math.SQRT1_2,Math.SQRT1_2,0,0);const rotation2=new pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion(Math.SQRT1_2,0,0,Math.SQRT1_2);rotation1.mult(rotation2,rotation1);model.setRotation(rotation1)}} + const entityFeatureSetEnabledMap={jupiter:{auroras:Features.setEnabledJupiterAuroras,magnetosphere:Features.setEnabledJupiterMagnetosphere,radiationBelt:Features.setEnabledJupiterRadiationBelt},saturn:{magnetosphere:Features.setEnabledSaturnMagnetosphere}};const entityFeatureIsEnabledMap={jupiter:{auroras:Features.isEnabledJupiterAuroras,magnetosphere:Features.isEnabledJupiterMagnetosphere,radiationBelt:Features.isEnabledJupiterRadiationBelt},saturn:{magnetosphere:Features.isEnabledSaturnMagnetosphere}}}),"../pioneer/scripts/src/index.js": + /*!***************************************!*\ + !*** ../pioneer/scripts/src/index.js ***! + \***************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Cameras":function(){return _cameras__WEBPACK_IMPORTED_MODULE_0__.Cameras},"DateTime":function(){return _date_time__WEBPACK_IMPORTED_MODULE_1__.DateTime},"Entity":function(){return _entity__WEBPACK_IMPORTED_MODULE_2__.Entity},"Features":function(){return _features__WEBPACK_IMPORTED_MODULE_3__.Features},"Mapping":function(){return _mapping__WEBPACK_IMPORTED_MODULE_4__.Mapping},"Parenting":function(){return _parenting__WEBPACK_IMPORTED_MODULE_5__.Parenting},"Placemarks":function(){return _placemarks__WEBPACK_IMPORTED_MODULE_6__.Placemarks},"SceneHelpers":function(){return _scene_helpers__WEBPACK_IMPORTED_MODULE_7__.SceneHelpers},"Transitions":function(){return _transitions__WEBPACK_IMPORTED_MODULE_8__.Transitions},"AnnulusComponent":function(){return _components_annulus_component__WEBPACK_IMPORTED_MODULE_9__.AnnulusComponent},"CelestialGridComponent":function(){return _components_celestial_grid_component__WEBPACK_IMPORTED_MODULE_10__.CelestialGridComponent},"ConstellationsComponent":function(){return _components_constellations_component__WEBPACK_IMPORTED_MODULE_11__.ConstellationsComponent},"DiscGridComponent":function(){return _components_disc_grid_component__WEBPACK_IMPORTED_MODULE_12__.DiscGridComponent},"ShadowConeComponent":function(){return _components_shadow_cone_component__WEBPACK_IMPORTED_MODULE_13__.ShadowConeComponent},"OrbitLineComponent":function(){return _components_orbit_line_component__WEBPACK_IMPORTED_MODULE_14__.OrbitLineComponent},"TorusComponent":function(){return _components_torus_component__WEBPACK_IMPORTED_MODULE_15__.TorusComponent},"WMTSComponent":function(){return _components_wmts_component__WEBPACK_IMPORTED_MODULE_16__.WMTSComponent},"KeyframePointingController":function(){return _controllers_keyframe_pointing_controller__WEBPACK_IMPORTED_MODULE_17__.KeyframePointingController},"KeyframeSpinController":function(){return _controllers_keyframe_spin_controller__WEBPACK_IMPORTED_MODULE_18__.KeyframeSpinController},"PositionSumController":function(){return _controllers_position_sum_controller__WEBPACK_IMPORTED_MODULE_19__.PositionSumController},"ZoomFitController":function(){return _controllers_zoom_fit_controller__WEBPACK_IMPORTED_MODULE_20__.ZoomFitController}});var _cameras__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./cameras */"../pioneer/scripts/src/cameras.js");var _date_time__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./date_time */"../pioneer/scripts/src/date_time.js");var _entity__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./entity */"../pioneer/scripts/src/entity.js");var _features__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ./features */"../pioneer/scripts/src/features.js");var _mapping__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! ./mapping */"../pioneer/scripts/src/mapping.js");var _parenting__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(/*! ./parenting */"../pioneer/scripts/src/parenting.js");var _placemarks__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(/*! ./placemarks */"../pioneer/scripts/src/placemarks.js");var _scene_helpers__WEBPACK_IMPORTED_MODULE_7__=__webpack_require__(/*! ./scene_helpers */"../pioneer/scripts/src/scene_helpers.js");var _transitions__WEBPACK_IMPORTED_MODULE_8__=__webpack_require__(/*! ./transitions */"../pioneer/scripts/src/transitions.js");var _components_annulus_component__WEBPACK_IMPORTED_MODULE_9__=__webpack_require__(/*! ./components/annulus_component */"../pioneer/scripts/src/components/annulus_component.js");var _components_celestial_grid_component__WEBPACK_IMPORTED_MODULE_10__=__webpack_require__(/*! ./components/celestial_grid_component */"../pioneer/scripts/src/components/celestial_grid_component.js");var _components_constellations_component__WEBPACK_IMPORTED_MODULE_11__=__webpack_require__(/*! ./components/constellations_component */"../pioneer/scripts/src/components/constellations_component.js");var _components_disc_grid_component__WEBPACK_IMPORTED_MODULE_12__=__webpack_require__(/*! ./components/disc_grid_component */"../pioneer/scripts/src/components/disc_grid_component.js");var _components_shadow_cone_component__WEBPACK_IMPORTED_MODULE_13__=__webpack_require__(/*! ./components/shadow_cone_component */"../pioneer/scripts/src/components/shadow_cone_component.js");var _components_orbit_line_component__WEBPACK_IMPORTED_MODULE_14__=__webpack_require__(/*! ./components/orbit_line_component */"../pioneer/scripts/src/components/orbit_line_component.js");var _components_torus_component__WEBPACK_IMPORTED_MODULE_15__=__webpack_require__(/*! ./components/torus_component */"../pioneer/scripts/src/components/torus_component.js");var _components_wmts_component__WEBPACK_IMPORTED_MODULE_16__=__webpack_require__(/*! ./components/wmts_component */"../pioneer/scripts/src/components/wmts_component.js");var _controllers_keyframe_pointing_controller__WEBPACK_IMPORTED_MODULE_17__=__webpack_require__(/*! ./controllers/keyframe_pointing_controller */"../pioneer/scripts/src/controllers/keyframe_pointing_controller.js");var _controllers_keyframe_spin_controller__WEBPACK_IMPORTED_MODULE_18__=__webpack_require__(/*! ./controllers/keyframe_spin_controller */"../pioneer/scripts/src/controllers/keyframe_spin_controller.js");var _controllers_position_sum_controller__WEBPACK_IMPORTED_MODULE_19__=__webpack_require__(/*! ./controllers/position_sum_controller */"../pioneer/scripts/src/controllers/position_sum_controller.js");var _controllers_zoom_fit_controller__WEBPACK_IMPORTED_MODULE_20__=__webpack_require__(/*! ./controllers/zoom_fit_controller */"../pioneer/scripts/src/controllers/zoom_fit_controller.js");var _entities_planets_and_stars__WEBPACK_IMPORTED_MODULE_21__=__webpack_require__(/*! ./entities/planets_and_stars */"../pioneer/scripts/src/entities/planets_and_stars.js");var _entities_minor_planets__WEBPACK_IMPORTED_MODULE_22__=__webpack_require__(/*! ./entities/minor_planets */"../pioneer/scripts/src/entities/minor_planets.js");var _entities_comets__WEBPACK_IMPORTED_MODULE_23__=__webpack_require__(/*! ./entities/comets */"../pioneer/scripts/src/entities/comets.js");var _entities_earth_moon__WEBPACK_IMPORTED_MODULE_24__=__webpack_require__(/*! ./entities/earth_moon */"../pioneer/scripts/src/entities/earth_moon.js");var _entities_jupiter_regular_moons__WEBPACK_IMPORTED_MODULE_25__=__webpack_require__(/*! ./entities/jupiter_regular_moons */"../pioneer/scripts/src/entities/jupiter_regular_moons.js");var _entities_jupiter_irregular_moons__WEBPACK_IMPORTED_MODULE_26__=__webpack_require__(/*! ./entities/jupiter_irregular_moons */"../pioneer/scripts/src/entities/jupiter_irregular_moons.js");var _entities_mars_moons__WEBPACK_IMPORTED_MODULE_27__=__webpack_require__(/*! ./entities/mars_moons */"../pioneer/scripts/src/entities/mars_moons.js");var _entities_neptune_moons__WEBPACK_IMPORTED_MODULE_28__=__webpack_require__(/*! ./entities/neptune_moons */"../pioneer/scripts/src/entities/neptune_moons.js");var _entities_saturn_major_moons__WEBPACK_IMPORTED_MODULE_29__=__webpack_require__(/*! ./entities/saturn_major_moons */"../pioneer/scripts/src/entities/saturn_major_moons.js");var _entities_saturn_minor_moons__WEBPACK_IMPORTED_MODULE_30__=__webpack_require__(/*! ./entities/saturn_minor_moons */"../pioneer/scripts/src/entities/saturn_minor_moons.js");var _entities_uranus_major_moons__WEBPACK_IMPORTED_MODULE_31__=__webpack_require__(/*! ./entities/uranus_major_moons */"../pioneer/scripts/src/entities/uranus_major_moons.js");var _entities_uranus_minor_moons__WEBPACK_IMPORTED_MODULE_32__=__webpack_require__(/*! ./entities/uranus_minor_moons */"../pioneer/scripts/src/entities/uranus_minor_moons.js");var _entities_earth_spacecraft__WEBPACK_IMPORTED_MODULE_33__=__webpack_require__(/*! ./entities/earth_spacecraft */"../pioneer/scripts/src/entities/earth_spacecraft.js");var _entities_lunar_spacecraft__WEBPACK_IMPORTED_MODULE_34__=__webpack_require__(/*! ./entities/lunar_spacecraft */"../pioneer/scripts/src/entities/lunar_spacecraft.js");var _entities_mars_spacecraft__WEBPACK_IMPORTED_MODULE_35__=__webpack_require__(/*! ./entities/mars_spacecraft */"../pioneer/scripts/src/entities/mars_spacecraft.js");var _entities_mercury_spacecraft__WEBPACK_IMPORTED_MODULE_36__=__webpack_require__(/*! ./entities/mercury_spacecraft */"../pioneer/scripts/src/entities/mercury_spacecraft.js");var _entities_outer_planet_spacecraft__WEBPACK_IMPORTED_MODULE_37__=__webpack_require__(/*! ./entities/outer_planet_spacecraft */"../pioneer/scripts/src/entities/outer_planet_spacecraft.js");var _entities_small_body_spacecraft__WEBPACK_IMPORTED_MODULE_38__=__webpack_require__(/*! ./entities/small_body_spacecraft */"../pioneer/scripts/src/entities/small_body_spacecraft.js");var _entities_solar_spacecraft__WEBPACK_IMPORTED_MODULE_39__=__webpack_require__(/*! ./entities/solar_spacecraft */"../pioneer/scripts/src/entities/solar_spacecraft.js");var _entities_venus_spacecraft__WEBPACK_IMPORTED_MODULE_40__=__webpack_require__(/*! ./entities/venus_spacecraft */"../pioneer/scripts/src/entities/venus_spacecraft.js");var _entities_comparison__WEBPACK_IMPORTED_MODULE_41__=__webpack_require__(/*! ./entities/comparison */"../pioneer/scripts/src/entities/comparison.js")}),"../pioneer/scripts/src/mapping.js": + /*!*****************************************!*\ + !*** ../pioneer/scripts/src/mapping.js ***! + \*****************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Mapping":function(){return Mapping}});var pioneer__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class Mapping{static getTypes(entityName){return Mapping._types[entityName]??[]} + static async set(scene,entityName,type){await Mapping.setEnabled(scene,entityName,type,!0);for(const otherType of Mapping.getTypes(entityName)){if(otherType!==type){Mapping.setEnabled(scene,entityName,otherType,!1)}} + if(type!=='basic'){Mapping.setEnabled(scene,entityName,'basic',!1)}} + static async setEnabled(scene,entityName,type,enabled){if(type==='basic'){Mapping.setBasic(scene,entityName,enabled)}else if(type.startsWith('cmts')){await Mapping.setCMTS(scene,entityName,type,enabled)}else{throw new Error(`Invalid type ${type}.`)}} + static async setBasic(scene,entityName,enabled){const entity=scene.getEntity(entityName);if(entity===null){throw new Error(`No entity named '${entityName}' exists.`)} + const spheroidLOD=entity.getComponent('basic');if(spheroidLOD===null||spheroidLOD.getType()!=='spheroidLOD'){throw new Error(`The entity '${entityName}' does not have a spheroidLOD named 'basic'.`)} + spheroidLOD.setEnabled(enabled);if(enabled){spheroidLOD.setVisible(!1);await spheroidLOD.getLoadedPromise();spheroidLOD.setVisible(!0)}} + static async setCMTS(scene,entityName,type,enabled){const entity=scene.getEntity(entityName);if(entity===null){throw new Error(`No entity named '${entityName}' exists.`)} + if(enabled&&!entity.get('cmts')){const cmts=entity.addComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.CMTSComponent,type);if(entityName==='mars'){cmts.setBaseUrl('color','$DYNAMIC_ASSETS_URL/cmts/1/'+entityName+'/color');cmts.setBaseUrl('height','$DYNAMIC_ASSETS_URL/cmts/1/'+entityName+'/height');cmts.addTileOffset(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(700.6128653358727,3140.020080650305,1073.622947405036),1,12,1585,2747,1592,2752);cmts.addTileOffset(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(-2489.8644947661123,2286.2056005322775,-271.3458260440484),2,12,158,1811,169,1825);cmts.addTileOffset(new pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3(-2432.935716315694,2349.9743692542434,267.129381207100),2,9,8,284,8,284)}else if(entityName==='moon'){cmts.setBaseUrl('color','$DYNAMIC_ASSETS_URL/cmts/'+entityName+'/color');cmts.setBaseUrl('normal','$DYNAMIC_ASSETS_URL/cmts/'+entityName+'/normal');cmts.setBaseUrl('height','$DYNAMIC_ASSETS_URL/cmts/'+entityName+'/height')} + cmts.setVisible(!1);await cmts.getLoadedPromise();await cmts.getTilesLoadedPromise();cmts.setVisible(!0)}else if(!enabled&&entity.get('cmts')){entity.removeComponent(entity.getComponentByType('cmts'))}} + static _types={mars:['cmts']}}}),"../pioneer/scripts/src/parenting.js": + /*!*******************************************!*\ + !*** ../pioneer/scripts/src/parenting.js ***! + \*******************************************/ + (function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,{"Parenting":function(){return Parenting}});var _entity__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./entity */"../pioneer/scripts/src/entity.js");var pioneer__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! pioneer */"../pioneer/engine/src/index.js");class Parenting{static getParentOfEntity(entityName,time){const entityOptions=_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.getEntityOptions(entityName);if(entityOptions===undefined){throw new Error(`There are no entity options for ${entityName}.`)} + const parents=entityOptions.parents;const index=pioneer__WEBPACK_IMPORTED_MODULE_1__.Sort.getIndex(time,parents,isStartTimeLessThanTime);if(index0){return parents[index-1][1]}else{return''}} + static getAllAncestorsOfEntity(entityName){const parents=new Set();this._getAllAncestorsOfEntityRecursed(entityName,parents);return parents} + static _getAllAncestorsOfEntityRecursed(entityName,parents){const entityOptions=_entity__WEBPACK_IMPORTED_MODULE_0__.Entity.getEntityOptions(entityName);if(entityOptions===undefined||entityOptions.parents===undefined){return} + const parentTable=entityOptions.parents;for(const parentEntry of parentTable){const parentName=parentEntry[1];if(!parents.has(parentName)){parents.add(parentName);this._getAllAncestorsOfEntityRecursed(parentName,parents)}}}} + function isStartTimeLessThanTime(a,b){return a[0]{let timeSoFar=0;const intervalCheck=setInterval(()=>{const position=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();const orientation=pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.get();for(const entity of entities){const isInCoverage=entity.getPositionCoverage().contains(time);entity.getPositionAtTime(position,time);entity.getOrientationAtTime(orientation,time);const inPlace=!position.isNaN()&&!orientation.isNaN();if(!isInCoverage||inPlace){entities.delete(entity)}} + pioneer__WEBPACK_IMPORTED_MODULE_0__.Quaternion.pool.release(orientation);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(position);if(entities.size===0){clearInterval(intervalCheck);resolve()} + timeSoFar+=frequency;if(timeSoFar>=timeout){clearInterval(intervalCheck);let entitiesAsString='';for(const entity of entities){if(entitiesAsString!==''){entitiesAsString+=', '} + entitiesAsString+='\''+entity.getName()+'\''} + reject(new Error('Timed out ('+timeout+' seconds) while waiting for entities to be in place. The remaining entities were ['+entitiesAsString+'].'))}},frequency*1000.0)}).then(()=>scene.getEngine().waitUntilNextFrame())} + static llaToXYZ(out,entity,lla,inEntityFrame){const spheroid=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent);if(spheroid!==null){spheroid.xyzFromLLA(out,lla);if(!inEntityFrame){out.rotate(entity.getOrientation(),out)}}} + static xyzToLLA(out,entity,xyz,inEntityFrame){const spheroid=entity.getComponentByClass(pioneer__WEBPACK_IMPORTED_MODULE_0__.SpheroidComponent);if(spheroid!==null){const xyzInFrame=pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.get();if(inEntityFrame){xyzInFrame.copy(xyz)}else{xyzInFrame.rotateInverse(entity.getOrientation(),xyz)} + spheroid.llaFromXYZ(out,xyzInFrame);pioneer__WEBPACK_IMPORTED_MODULE_0__.Vector3.pool.release(xyzInFrame)}} + static getDependentEntities(entityName){const others=(new Set());this._getDependentEntitiesRecursed(entityName,others);others.delete(entityName);return others} + static _getDependentEntitiesRecursed(entityName,others){const entityOptions=_entity__WEBPACK_IMPORTED_MODULE_1__.Entity.getEntityOptions(entityName);if(entityOptions===undefined){return} + const otherEntityNames=(new Set());const parentTable=entityOptions.parents;for(const parentEntry of parentTable){if(parentEntry[1]!==''){otherEntityNames.add(parentEntry[1])}} + if(entityOptions.lightSource!==undefined){otherEntityNames.add(entityOptions.lightSource)} + if(entityOptions.trail!==undefined&&entityOptions.trail.relativeTo!==undefined){otherEntityNames.add(entityOptions.trail.relativeTo)} + for(let i=0,l=entityOptions.controllers.length;i1e-6){const aC=(r1-r0)/-a0*(r1+r0)/2+a0/2;const anglep1pcp0pc=Math.sign(a0)*Math.acos((r0*r1+(a0-aC)*(-aC))/Math.sqrt(r0*r0+(a0-aC)*(a0-aC))/Math.sqrt(r1*r1+aC*aC));const cosU=Math.cos(u*anglep1pcp0pc);const sinU=Math.sin(u*anglep1pcp0pc);r=(a0-aC)*sinU+r0*cosU;a=aC+(a0-aC)*cosU-r0*sinU}else{r=u*r1+(1-u)*r0;a=(1-u)*a0} + if(u===1){r=r1;a=0} + out.set(a,r)}}}),"./src/configs/scene_info.json": + /*!*************************************!*\ + !*** ./src/configs/scene_info.json ***! + \*************************************/ + (function(module){"use strict";module.exports=JSON.parse('{\ + "zoomMax":12000000000,\ + "dynamicEntityGroups":[\ + "spacecraft"\ + ],\ + "staticEntityGroups":[\ + "moons",\ + "stars",\ + "planets",\ + "dwarf planets"\ + ],\ + "staticEntities":[\ + "moon",\ + "sc_osiris_rex",\ + "sc_lucy",\ + "sc_psyche",\ + "sc_deep_impact",\ + "sc_deep_impact_impactor",\ + "sc_deep_space_1",\ + "sc_near_shoemaker",\ + "sc_stardust",\ + "sc_stardust_src",\ + "sc_dawn",\ + "sc_rosetta",\ + "sc_galileo",\ + "sc_philae",\ + "sc_dart",\ + "sc_new_horizons",\ + "sc_chandra"\ + ],\ + "title":{\ + "prefix":"Eyes on Asteroids",\ + "suffix":"NASA/JPL"\ + }\ + }')}),"./src/configs/story_info.json": + /*!*************************************!*\ + !*** ./src/configs/story_info.json ***! + \*************************************/ + (function(module){"use strict";module.exports=JSON.parse('[{"title":"Asteroids 101","path":"asteroids_101","questions":["What are asteroids?","What does this app show me?"]},{"title":"Close Approaches","path":"asteroids_close_approach","questions":["What is a close approach?","Are we in danger of impact?"]},{"title":"Missions","path":"asteroids_missions","questions":["Can we visit an asteroid?","What can missions achieve?"]}]')}),"./src/configs/time_info.json": + /*!************************************!*\ + !*** ./src/configs/time_info.json ***! + \************************************/ + (function(module){"use strict";module.exports=JSON.parse('{"limits":{"min":"1990-01-01T00:00:00Z","max":"2034-01-01T00:00:00Z"}}')}),"./src/configs/view_info.json": + /*!************************************!*\ + !*** ./src/configs/view_info.json ***! + \************************************/ + (function(module){"use strict";module.exports=JSON.parse('[\ + {\ + "class":"HomeView",\ + "name":"home",\ + "components":[\ + "breadcrumb",\ + "clock",\ + "clockShortcut"\ + ]\ + },\ + {\ + "class":"AsteroidView",\ + "name":"asteroid",\ + "components":[\ + "breadcrumb",\ + "clock",\ + "clockShortcut",\ + "asteroidPanel",\ + "loadIcon"\ + ]\ + },\ + {\ + "class":"WatchView",\ + "name":"watch",\ + "components":[\ + "watchPanel",\ + "breadcrumb",\ + "clock",\ + "clockShortcut"\ + ]\ + },\ + {\ + "class":"MissionView",\ + "name":"mission",\ + "components":[\ + "breadcrumb",\ + "clock",\ + "clockShortcut",\ + "missionPanel",\ + "loadIcon"\ + ]\ + },\ + {\ + "class":"FollowingView",\ + "name":"following",\ + "components":[\ + "breadcrumb",\ + "clock",\ + "clockShortcut",\ + "followingPanel",\ + "loadIcon",\ + "definitionOverlay"\ + ]\ + },\ + {\ + "class":"StoryView",\ + "name":"story",\ + "components":[\ + "clock",\ + "breadcrumb",\ + "story",\ + "overlay",\ + "definitionOverlay"\ + ]\ + }\ + ]')}),"./src/data/definitions.json": + /*!***********************************!*\ + !*** ./src/data/definitions.json ***! + \***********************************/ + (function(module){"use strict";module.exports=JSON.parse('{"asteroid":{"title":"Asteroid","html":"

        Sometimes called minor planets, asteroids are rocky, airless remnants left over from the early formation of our solar system about 4.6 billion years ago.

        Most of this ancient space rubble can be found orbiting the Sun between Mars and Jupiter within the main asteroid belt.

        Unlike comets, asteroids remain solid under extreme temperatures; this is due to their formation in the high heat, high density center of the solar nebula.

        Deep Dive into Asteroids 101
        ","related":["comet"]},"comet":{"title":"Comet","html":"

        Comets are frozen leftovers from the formation of the solar system composed of dust, rock, and ice. They range from a few kilometers, to hundreds of kilometers wide.

        As they orbit closer to the Sun, they heat up and spew gases and dust into a glowing head that can be larger than a planet. This material forms a tail that stretches millions of kilometers.

        Unlike asteroids, comets formed in areas of the solar nebula where it was cold enough for water and gases to freeze. Consequently, they are larger and rarer than asteroids, and tend to originate in the far reaches of the solar system.

        ","related":["asteroid"]},"neo":{"title":"NEO","html":"
        Near-Earth object

        A near-Earth object is any small solar system body whose orbit brings it within a certain distance of Earth. This distance is defined by having the closest approach to the sun, the perihelion, be within 1.3 AU

        A sub-category of the NEO is the PHO.

        ","related":["perihelion","au","pho"]},"pho":{"title":"PHO","html":"
        Potentially Hazardous Object

        To be defined as potentially hazardous, an object must be:

        • Larger than 150 meters (almost 500 feet), roughly twice as big as the Statue of Liberty is tall.
        • Approach Earth\'s orbit to within about 7.5 million kilometers (4.6 million miles). This can also be expressed as having a MOID of less than 0.05 AU (within 19.5 LDs).

        PHOs can be both asteroids and comets, but the vast majority are asteroids. Learn more about the PHO, Apophis below.

        Deep Dive into Close Approaches
        ","related":["asteroid","comet","moid","au","ld"]},"aphelion":{"title":"Aphelion","html":"

        The aphelion is the point in the orbit of an object at which it is farthest from the sun.

        The opposite case is called the perihelion.

        ","related":["perihelion"]},"perihelion":{"title":"Perihelion","html":"

        The perihelion is the point in the orbit of an object at which it is closest to the sun.

        The opposite case is called the aphelion.

        ","related":["aphelion"]},"moid":{"title":"MOID","html":"
        Minimum Orbit Intersection Distance

        The MOID is the minimum distance between the orbits of two objects. It indicates the closest possible approach of two objects to each other.

        For Earth, an object with a MOID of less than or equal to 0.05 AU is considered a possible Potentially Hazardous Object if it\'s large enough.

        ","related":["au","pho"]},"oumuamua":{"title":"Oumuamua","html":"
        First interstellar object

        Discovered on October 19, 2017, Oumuamua is unlike any asteroid previously observed.

        Although we don’t have a picture, its unusually shiny surface reflects sunlight with a variation factor of 10. This suggest a severely elongated shape, 5 to 10 times larger than its width. Along with its rapid speed and high eccentricity, it was determined to be of interstellar origin.

        Passing Earth on October 14, 2017 at approximately 0.1618 AU, Oumuamua is now exiting our solar system, unlikely to ever return.

        ","related":["au"]},"au":{"title":"AU","html":"
        Astronomical Unit

        An AU is defined as exactly 92,955,807.273 miles (149,597,871 kilometers), or roughly the distance between the Earth and the Sun.

        Jupiter orbits at about 5.2 times the Sun-Earth distance, so Jupiter’s distance from the Sun can be expressed as 5.2 AU.

        1 AU is equivalent to 389,174 LDs.

        ","related":["moid","ld"]},"ld":{"title":"LD","html":"
        Lunar Distance

        A lunar distance is defined exactly as 384,398 kilometers (238,854 miles); the average distance between the centers of the Earth and the Moon.

        More technically, it\'s the length of the semi-major axis of the geocentric lunar orbit.

        1 LD is equivalent to about 0.00257 AU.

        ","related":["au"]}}')}),"./src/data/heroes.json": + /*!******************************!*\ + !*** ./src/data/heroes.json ***! + \******************************/ + (function(module){"use strict";module.exports=JSON.parse('{"99942_apophis":{"stats":{"discovery":"

        Discovered on June 19, 2004 at the Kitt Peak National Observatory in Arizona.

        ","rotation":30.4},"approach":{"fact":"

        On April 13, 2029, the asteroid Apophis will pass less than 23,239 miles (37,399 kilometers) from our planet’s surface – just outside the distance of geosynchronous satellites, and closer to Earth than any similarly sized PHO in recorded history. At that time, Apophis will be visible to observers on the ground in the Eastern Hemisphere without the aid of a telescope or binoculars.

        "}},"4_vesta":{"stats":{"discovery":"

        One of the largest and earliest known asteroids, Vesta was discovered on March 29th, 1807, and was visited by the Dawn mission in 2011.

        ","rotation":5.342}},"433_eros":{"stats":{"discovery":"

        Discovered on August 13th, 1898, Eros was the first near-Earth Object (NEO) ever found, and the first asteroid ever orbited by a spacecraft, NEAR-Shoemaker.

        ","rotation":5.27},"approach":{"fact":"

        Eros will approach Earth within 0.39765 AU on November 30th, 2025.

        "}},"951_gaspra":{"stats":{"discovery":"

        Discovered in 1916, Gaspra is the first asteroid to be closely approached by a spacecraft, which was Galileo in 1991.

        ","rotation":7.042}},"243_ida":{"stats":{"discovery":"

        Discovered in 1884, Ida was visited by the Galileo spacecraft in August of 1993.

        ","rotation":4.634}},"81p_wild_2":{"stats":{"discovery":"

        This comet was discovered on January 6th, 1978, and was visited by the Stardust mission in January of 2004.

        "}},"9p_tempel_1":{"stats":{"discovery":"

        Discovered in 1867, comet Tempel 1 was the target of the Deep Impact mission, which physically collided with the comet on July 4th, 2005.

        ","rotation":40.7}},"21_lutetia":{"stats":{"discovery":"

        Discovered in 1852, the asteroid was visited by the European space probe Rosetta in July of 2010.

        ","rotation":8.1655}},"67p_churyumov_gerasimenko":{"stats":{"discovery":"

        Discovered in 1969, this comet was the first to be landed upon by a robotic mission from Earth, the European Space Agency\'s Rosetta mission. The Philae lander touched down in November of 2014.

        ","rotation":12.76},"approach":{"fact":"

        The comet approached Earth within 0.418 AU on November 12th, 2021, and then will approach again in November of 2034 at a distance of 0.4523 AU.

        "}},"1_ceres":{"stats":{"discovery":"

        Discovered in January of 1801, Ceres was the first asteroid ever found, though it was initially classified as a planet. It remained an asteroid until 2006, when it was reclassified as a dwarf planet.

        ","rotation":9.0741}},"101955_bennu":{"stats":{"discovery":"

        Discovered in September of 1999, Bennu was the subject of the OSIRIS-REx mission, which touched down on the asteroid and collected a sample of the surface on October 20th, 2020. OSIRIS-REx departed Bennu in 2021, and delivered the capsule with pieces of the asteroid to Earth on September 24, 2023.

        ","rotation":4.296},"approach":{"fact":"

        Bennu is a PHO, and will have multiple close approaches with Earth over time. The next close approach will be in 2023, at a distance of 0.497 AU

        "}},"103p_hartley_2":{"stats":{"discovery":"

        Discovered in 1986, Comet Hartley 2 was the target of the Deep Impact/EPOXI mission, which flew by in November of 2010.

        ","rotation":18.1},"approach":{"fact":"

        103p/Hartley 2 is classified as an NEO, and will approach Earth within 0.3826 AU on September 26th, 2023.

        "}},"25143_itokawa":{"stats":{"discovery":"

        Discovered in 1998, Itokawa was the first asteroid to be the target of a sample return mission. The Japanese space probe Hayabusa took a sample from the comet in November of 2005.

        ","rotation":12.132},"approach":{"fact":"

        Itokawa is classified as a PHO, and will next approach the Earth on March 6th, 2030, at a distance of 0.376 AU.

        "}},"16_psyche":{"stats":{"discovery":"

        Discovered in 1852, the Psyche asteroid is the subject of the upcoming Psyche mission which will launch no earlier than 2023.

        ","rotation":4.196}},"65803_didymos":{"stats":{"discovery":"

        Discovered in 1996, Didymos is part of a binary asteroid system with its smaller partner, Dimorphos. The DART mission targeted this system, successfully crashing a probe into Dimorphos on September 26th, 2022.

        ","rotation":2.2593},"approach":{"fact":"

        Didymos is a PHO, and approached Earth at a distance of 0.07123 AU on October 4th, 2022.

        "}},"dimorphos":{"stats":{"discovery":"

        First observed in 2003 (7 years after the discovery of Didymos), Dimorphos is the smaller twin of the Didymos binary asteroid system. The DART mission intentionally crashed into Dimorphos on September 26th, 2022, and successfully altered its orbit.

        ","rotation":11.92},"approach":{"fact":"

        Dimorphos and its binary system are classifed as a PHO, and approached Earth at a distance of 0.07123 AU on October 4th, 2022.

        "}},"52246_donaldjohanson":{"stats":{"discovery":"

        Discovered in 1981, and named after the paleoanthropologist who discovered the \\"Lucy\\" fossil, this will be the second small body that the Lucy mission will encounter in 2025.

        ","rotation":252}},"3548_eurybates":{"stats":{"discovery":"

        Discovered in 1973, Eurybates is the first Trojan Asteroid that the Lucy mission will visit in August of 2027. It has a small satellite named Queta.

        ","rotation":8.7}},"15094_polymele":{"stats":{"discovery":"

        Discovered in 1999, Polymele is a Trojan Asteroid that will be visited by the Lucy mission in September of 2027.

        ","rotation":5.86}},"11351_leucus":{"stats":{"discovery":"

        Discovered in 1997, Leucus is a Trojan Asteroid that will be visited by the Lucy mission in April of 2028.

        ","rotation":445.73}},"21900_orus":{"stats":{"discovery":"

        Discovered in 1999, Orus is a Trojan Asteroid that will be visited by the Lucy mission in November of 2028.

        ","rotation":13.45}},"617_patroclus":{"stats":{"discovery":"

        Discovered in 1906, Patroclus is a Trojan Asteroid that will be visited by the Lucy mission in 2033. In 2001, Patroclus was found to be part of a binary asteroid system with its smaller twin, named Menoetius.

        ","rotation":102.8}},"19p_borrelly":{"stats":{"discovery":"

        Discovered in 1904, comet Borrelly was the target of the Deep Space 1 mission, which flew by in September of 2001.

        "}},"5535_annefrank":{"stats":{"discovery":"

        Discovered in 1942, the main belt asteroid 5535 Annefrank was used as a practice flyby target by the Stardust mission on November 2nd, 2002.

        ","rotation":15.12}},"9969_braille":{"stats":{"discovery":"

        Discovered in 1992, Braille was visited by the Deep Space 1 mission on July 29th, 1999. The spacecraft passed within 26 km (16 miles) of the asteroid, which was the closest asteroid flyby ever at that time.

        ","rotation":226.4}},"162173_ryugu":{"stats":{"discovery":"

        Discovered in 1999, Ryugu was the target of the Hayabusa2 mission, which orbited the asteroid for a year and a half, landed small rovers on it, and collected samples that were returned to Earth in December of 2020.

        ","rotation":7.63},"approach":{"fact":"

        Ryugu is a PHO, and will next approach Earth at a distance of 0.373 AUs on June 3rd, 2025.

        "}},"152830_dinkinesh":{"stats":{"discovery":"

        Discovered in 1999, Dinkinesh will be the Lucy mission\'s first flyby target in early November of 2023. It will become the smallest main-belt asteroid ever visited.

        "}},"73p_schwassmann_wachmann_3":{"stats":{"discovery":"

        Discovered in 1930, 73P/Schwassmann-Wachmann 3 is a periodic comet that began to disintegrate as it approached the sun in 1995. Initially, it split into four distinct fragments, but later further split into more than sixty pieces.

        "},"category":"Comet","id":"73p_schwassmann_wachmann_3","iauName":"73P/Schwassmann Wachmann 3","displayName":"Schwassmann Wachmann 3"}}')}),"./src/data/stories/story_list.json": + /*!******************************************!*\ + !*** ./src/data/stories/story_list.json ***! + \******************************************/ + (function(module){"use strict";module.exports=JSON.parse('{"stories":{"asteroids_101":{"id":"asteroids_101","title":"Asteroids 101"},"asteroids_close_approach":{"id":"asteroids_close_approach","title":"What is a Close Approach?"},"asteroids_missions":{"id":"asteroids_missions","title":"Asteroid and Comet Missions"}},"external":{},"featured":[]}')}),"./src/data/tutorials.json": + /*!*********************************!*\ + !*** ./src/data/tutorials.json ***! + \*********************************/ + (function(module){"use strict";module.exports=JSON.parse('[{"id":"intro","title":"Welcome to
        Eyes on Asteroids!","description":"You are looking at a real-time visualization of every known asteroid or comet that is classified as a Near-Earth Object (NEO).
        With asteroids represented as blue points, and comets as white points, our database is updated daily to give you approximately {{getNeoTotal}} NEOs (and counting). Additionally, you can explore most of NASA\'s asteroid and comet missions (past and present), from Galileo, to Lucy and DART.","extra":"
        Extra fact:

        Farther from Earth, the full asteroid belt contains over a million members, with the majority lying between Mars and Jupiter.

        "},{"id":"nav3d","title":"Navigate 3D like an Expert","description":{"touch":"One finger controls your orbit in all directions. Pinch zoom for close inspection, large-scale overviews, and everything in-between.","desktop":"Left mouse click-and-drag controls your orbit in all directions. Scroll zoom for close inspection, macro overviews, and everything in-between."},"extra":{"desktop":"
        Secret tip:

        Use the \'A\', \'S\', \'D\', \'W\', \'Z\', and \'C\' keys only if you\'re a true expert. Hold the \'shift\' key to move even faster.

        "},"targetSelector":"#pioneer","mask":{"xSizeMult":0.6,"ySizeMult":0.25}},{"id":"labels","title":"Info on the Fly","description":"Select any label or icon in the 3D screen to fly to it and bring up an information panel.","extra":"
        Don\'t get lost:

        The top-left NASA logo or \'See all asteroids\' button will always take you back home.

        ","targetSelector":"#pioneer","mask":{"xSizeMult":0.6,"ySizeMult":0.25}},{"id":"time","title":"From 1990 to 2033
        You Control Time.","description":"Drag the time slider left to go backwards, or right to go forwards in time. The LIVE button will always return you to the present time.","extra":"
        A little trick:

        To go even faster, zoom out and try again.

        ","targetSelector":"#time-slider-container"},{"id":"learn","title":"Learn by Scrolling","description":"Select \'Learn\' to access three different scrollable stories about asteroids and comets, including a tour through NASA\'s historic missions.","targetSelector":"nav.navigation div:nth-child(1).clickable button","mask":{"xSizeMult":0.7,"ySizeMult":0.7}},{"id":"watch","title":"Keep an Eye Out!","description":"Select the \'Asteroid Watch\' option to see the next five closest approaches to Earth, complete with a countdown.","extra":"
        Hint:

        Don\'t forget to play with that time slider!

        ","targetSelector":"nav.navigation div:nth-child(2).clickable button","mask":{"xSizeMult":0.7,"ySizeMult":0.7}},{"id":"filters","title":"Filter your View","description":"Select \'Filters\' to see just the comets, or just the asteroids, or just the Potentially Hazardous Objects (PHOs).","targetSelector":"nav.navigation div:nth-child(3).clickable button","mask":{"xSizeMult":0.7,"ySizeMult":0.7}},{"id":"search","title":"Looking for Something?","description":"Type it in the search bar to look through our entire NEO database.","targetSelector":".search>span.icon-search","mask":{"xSizeMult":0.5,"ySizeMult":0.5}},{"id":"settings","title":"Fine Tuning","description":"Use the settings menu to toggle display layers, incrementally zoom, change the lighting when the sun is not enough, and go full-screen.","alternateDescription":"Use the settings menu to toggle display layers, incrementally zoom, and change the lighting when the sun is not enough.","extra":"
        Just in case:

        The info icon will take you back here if you ever need a recap.

        ","targetSelector":"div.settings","mask":{"xSizeMult":0.5}},{"id":"complete","title":"Dare Mighty Things","description":"You are now armed with all the knowledge to explore Eyes on Asteroids like a pro. Happy Learning!","extra":"
        One last secret:

        Watch out for any underlined text; it may lead you down a rabbit hole of space knowledge...

        "}]')}),"../eyes/src/data/entity_info.json": + /*!*****************************************!*\ + !*** ../eyes/src/data/entity_info.json ***! + !*** copied to ./entity_info.json ***! + \*****************************************/ + (function(module){"use strict";module.exports=JSON.parse('{"observable_universe":{"id":"observable_universe","displayName":"Observable universe","category":"Universe","searchable":false},"milky_way":{"id":"milky_way","displayName":"Milky way","category":"Galaxy","searchable":false},"sun":{"id":"sun","iauName":"Sun","category":"Star","subcategory":"Yellow Dwarf Star","planeEntity":"earth","keywords":["star","solar system"]},"mercury":{"id":"mercury","iauName":"Mercury","category":"Planet","subcategory":"Terrestrial","keywords":["terrestrial planet","solar system","planets"]},"venus":{"id":"venus","iauName":"Venus","category":"Planet","subcategory":"Terrestrial","keywords":["terrestrial planet","solar system","planets"]},"earth":{"id":"earth","iauName":"Earth","category":"Planet","subcategory":"Terrestrial","hasMoons":true,"planeEntity":"moon","keywords":["terrestrial planet","solar system","planets"]},"mars":{"id":"mars","iauName":"Mars","category":"Planet","subcategory":"Terrestrial","hasMoons":true,"keywords":["terrestrial planet","solar system","planets"]},"jupiter":{"id":"jupiter","iauName":"Jupiter","category":"Planet","subcategory":"Gas Giant","hasMoons":true,"keywords":["gas giant","solar system","planets"]},"saturn":{"id":"saturn","iauName":"Saturn","category":"Planet","subcategory":"Gas Giant","hasMoons":true,"keywords":["gas giant","solar system","planets"]},"neptune":{"id":"neptune","iauName":"Neptune","category":"Planet","subcategory":"Ice Giant","hasMoons":true,"keywords":["ice giant","solar system","planets"]},"uranus":{"id":"uranus","iauName":"Uranus","category":"Planet","subcategory":"Ice Giant","hasMoons":true,"keywords":["gas giant","solar system","planets","1781"]},"134340_pluto":{"id":"134340_pluto","iauName":"134340 Pluto","displayName":"Pluto","category":"Dwarf Planet","keywords":["dwarf planet","solar system","dwarf planet","trans-neptunian object","plutoid","kuiper belt object","plutino","synchronous","1930"]},"134340_pluto_barycenter":{"id":"134340_pluto_barycenter","displayName":"Pluto system","hasMoons":true,"comparisonFeature":false,"category":"Dwarf Planet","subcategory":"Barycenter","planeEntity":"134340_pluto","forceVisibleEntities":["134340_pluto"],"keywords":["barycenter"]},"617_patroclus_barycenter":{"id":"617_patroclus_barycenter","displayName":"Patroclus barycenter","category":"Asteroid","subcategory":"Barycenter","comparisonFeature":false,"forceVisibleEntities":["617_patroclus","menoetius"]},"21_lutetia":{"id":"21_lutetia","iauName":"21 Lutetia","displayName":"Lutetia","category":"Asteroid","keywords":["asteroid","asteroids","Rosetta"]},"253_mathilde":{"id":"253_mathilde","iauName":"253 Mathilde","displayName":"Mathilde","category":"Asteroid","keywords":["asteroid","asteroids"]},"11351_leucus":{"id":"11351_leucus","iauName":"11351 Leucus","displayName":"Leucus","category":"Asteroid","keywords":["asteroid","asteroids"]},"15094_polymele":{"id":"15094_polymele","iauName":"15094 Polymele","displayName":"Polymele","category":"Asteroid","keywords":["asteroid","asteroids"]},"21900_orus":{"id":"21900_orus","iauName":"21900 Orus","displayName":"Orus","category":"Asteroid","keywords":["asteroid","asteroids"]},"3548_eurybates":{"id":"3548_eurybates","iauName":"3548 Eurybates","displayName":"Eurybates","category":"Asteroid","keywords":["asteroid","asteroids"]},"5535_annefrank":{"id":"5535_annefrank","iauName":"5535 Annefrank","displayName":"Annefrank","category":"Asteroid","keywords":["asteroid","asteroids"]},"52246_donaldjohanson":{"id":"52246_donaldjohanson","iauName":"52246 Donaldjohanson","displayName":"Donaldjohanson","category":"Asteroid","keywords":["asteroid","asteroids"]},"617_patroclus":{"id":"617_patroclus","iauName":"617 Patroclus","displayName":"Patroclus","category":"Asteroid","keywords":["asteroid","asteroids"]},"951_gaspra":{"id":"951_gaspra","iauName":"951 Gaspra","displayName":"Gaspra","category":"Asteroid","keywords":["asteroid","asteroids"]},"2867_steins":{"id":"2867_steins","iauName":"2867 Steins","displayName":"Steins","category":"Asteroid","keywords":["asteroid","asteroids"]},"ariel":{"id":"ariel","iauName":"Ariel","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","uranus","moons","prograde","synchronous","1851"]},"90377_sedna":{"id":"90377_sedna","iauName":"90377 Sedna","displayName":"Sedna","category":"Dwarf Planet","keywords":["dwarf planet","asteroids"]},"99942_apophis":{"id":"99942_apophis","iauName":"99942 Apophis","displayName":"Apophis","category":"Asteroid","keywords":["asteroid","asteroids"]},"486958_arrokoth":{"id":"486958_arrokoth","iauName":"486958 Arrokoth","displayName":"Arrokoth","category":"Asteroid","subcategory":"Kuiper Belt Object","keywords":["mu69","asteroid","asteroids","tno","cubewano","distant minor planet","pt1","1110113y","ultima thule","2014","kuiper belt object"]},"101955_bennu":{"id":"101955_bennu","iauName":"101955 Bennu","displayName":"Bennu","category":"Asteroid","subcategory":"B-Type Asteroid","keywords":["asteroid","asteroids","apollo","neo","pha","1999 rq36","1999","b-type"]},"152830_dinkinesh":{"id":"152830_dinkinesh","iauName":"152830 Dinkinesh","displayName":"Dinkinesh","category":"Asteroid","keywords":["asteroid","asteroids"]},"16_psyche":{"id":"16_psyche","iauName":"16 Psyche","displayName":"16 Psyche","category":"Asteroid","subcategory":"M-Type Asteroid","keywords":["asteroid","asteroids","m-type"]},"1_ceres":{"id":"1_ceres","iauName":"1 Ceres","displayName":"Ceres","category":"Dwarf Planet","keywords":["dwarf planet","asteroids","asteroid belt","a899 of","1943 xb","1801"]},"2_pallas":{"id":"2_pallas","iauName":"2 Pallas","displayName":"Pallas","category":"Asteroid","keywords":["asteroid","asteroids"]},"3_juno":{"id":"3_juno","iauName":"3 Juno","displayName":"Juno","category":"Asteroid","keywords":["asteroid","asteroids"]},"216_kleopatra":{"id":"216_kleopatra","iauName":"216 Kleopatra","displayName":"Kleopatra","category":"Asteroid","keywords":["asteroid","asteroids"]},"243_ida":{"id":"243_ida","iauName":"243 Ida","displayName":"Ida","category":"Asteroid","keywords":["asteroid","asteroids"],"hasMoons":true},"1566_icarus":{"id":"1566_icarus","iauName":"1566 Icarus","displayName":"Icarus","category":"Asteroid","keywords":["asteroid","asteroids"]},"1620_geographos":{"id":"1620_geographos","iauName":"1620 Geographos","displayName":"Geographos","category":"Asteroid","keywords":["asteroid","asteroids"]},"1862_apollo":{"id":"1862_apollo","iauName":"1862 Apollo","displayName":"Apollo","category":"Asteroid","keywords":["asteroid","asteroids"]},"1981_midas":{"id":"1981_midas","iauName":"1981 Midas","displayName":"Midas","category":"Asteroid","keywords":["asteroid","asteroids"]},"2063_bacchus":{"id":"2063_bacchus","iauName":"2063 Bacchus","displayName":"Bacchus","category":"Asteroid","keywords":["asteroid","asteroids"]},"2101_adonis":{"id":"2101_adonis","iauName":"2101 Adonis","displayName":"Adonis","category":"Asteroid","keywords":["asteroid","asteroids"]},"2102_tantalus":{"id":"2102_tantalus","iauName":"2102 Tantalus","displayName":"Tantalus","category":"Asteroid","keywords":["asteroid","asteroids"]},"2135_aristaeus":{"id":"2135_aristaeus","iauName":"2135 Aristaeus","displayName":"Aristaeus","category":"Asteroid","keywords":["asteroid","asteroids"]},"2340_hathor":{"id":"2340_hathor","iauName":"2340 Hathor","displayName":"Hathor","category":"Asteroid","keywords":["asteroid","asteroids"]},"3122_florence":{"id":"3122_florence","iauName":"3122 Florence","displayName":"Florence","category":"Asteroid","keywords":["asteroid","asteroids"]},"3200_phaethon":{"id":"3200_phaethon","iauName":"3200 Phaethon","displayName":"Phaethon","category":"Asteroid","keywords":["asteroid","asteroids"]},"3362_khufu":{"id":"3362_khufu","iauName":"3362 Khufu","displayName":"Khufu","category":"Asteroid","keywords":["asteroid","asteroids"]},"4015_wilson-harrington":{"id":"4015_wilson-harrington","iauName":"4015 Wilson-Harrington","displayName":"Wilson-Harrington","category":"Asteroid","keywords":["asteroid","asteroids"]},"4179_toutatis":{"id":"4179_toutatis","iauName":"4179 Toutatis","displayName":"Toutatis","category":"Asteroid","keywords":["asteroid","asteroids"]},"4183_cuno":{"id":"4183_cuno","iauName":"4183 Cuno","displayName":"Cuno","category":"Asteroid","keywords":["asteroid","asteroids"]},"4450_pan":{"id":"4450_pan","iauName":"4450 Pan","displayName":"Pan","category":"Asteroid","keywords":["asteroid","asteroids","minor moon","saturn"]},"4486_mithra":{"id":"4486_mithra","iauName":"4486 Mithra","displayName":"Mithra","category":"Asteroid","keywords":["asteroid","asteroids"]},"4769_castalia":{"id":"4769_castalia","iauName":"4769 Castalia","displayName":"Castalia","category":"Asteroid","keywords":["asteroid","asteroids"]},"5011_ptah":{"id":"5011_ptah","iauName":"5011 Ptah","displayName":"Ptah","category":"Asteroid","keywords":["asteroid","asteroids"]},"6239_minos":{"id":"6239_minos","iauName":"6239 Minos","displayName":"Minos","category":"Asteroid","keywords":["asteroid","asteroids"]},"6489_golevka":{"id":"6489_golevka","iauName":"6489 Golevka","displayName":"Golevka","category":"Asteroid","keywords":["asteroid","asteroids"]},"9969_braille":{"id":"9969_braille","iauName":"9969 Braille","displayName":"Braille","category":"Asteroid","keywords":["asteroid","asteroids"]},"12923_zephyr":{"id":"12923_zephyr","iauName":"12923 Zephyr","displayName":"Zephyr","category":"Asteroid","keywords":["asteroid","asteroids"]},"14827_hypnos":{"id":"14827_hypnos","iauName":"14827 Hypnos","displayName":"Hypnos","category":"Asteroid","keywords":["asteroid","asteroids"]},"25143_itokawa":{"id":"25143_itokawa","iauName":"25143 Itokawa","displayName":"Itokawa","category":"Asteroid","keywords":["asteroid","asteroids"]},"37655_illapa":{"id":"37655_illapa","iauName":"37655 Illapa","displayName":"Illapa","category":"Asteroid","keywords":["asteroid","asteroids"]},"65803_didymos":{"id":"65803_didymos","iauName":"65803 Didymos","displayName":"Didymos","category":"Asteroid","keywords":["asteroid","asteroids"],"hasMoons":true},"69230_hermes":{"id":"69230_hermes","iauName":"69230 Hermes","displayName":"Hermes","category":"Asteroid","keywords":["asteroid","asteroids"]},"136199_eris":{"id":"136199_eris","iauName":"136199 Eris","displayName":"Eris","category":"Dwarf Planet","keywords":["asteroid","asteroids","dwarf planet","tno","plutoid","sdo","binary","dysnomia","2005"]},"136108_haumea":{"id":"136108_haumea","iauName":"136108 Haumea","displayName":"Haumea","category":"Dwarf Planet","keywords":["asteroid","asteroids","dwarf planet","plutoid","tno","cubewano","trinary","2003 el61","2004"],"hasMoons":true},"136472_makemake":{"id":"136472_makemake","iauName":"136472 Makemake","displayName":"Makemake","category":"Dwarf Planet","keywords":["asteroid","asteroids","dwarf planet","cubewano","scattered-near","kuiper belt","2005 fy9","2005"]},"162173_ryugu":{"id":"162173_ryugu","iauName":"162173 Ryugu","displayName":"Ryugu","category":"Asteroid","keywords":["asteroid","asteroids","neo","pha","b-type","c-type"]},"4_vesta":{"id":"4_vesta","iauName":"4 Vesta","displayName":"Vesta","category":"Asteroid","subcategory":"Protoplanet","keywords":["asteroid","asteroids","main belt","vesta family","1807","protoplanet"]},"433_eros":{"id":"433_eros","iauName":"433 Eros","displayName":"Eros","category":"Asteroid","subcategory":"S-Type Asteroid","keywords":["asteroid","asteroids","neo","1898","prograde"]},"callisto":{"id":"callisto","iauName":"Callisto","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","jupiter","moons","main group","galilean moons","prograde","synchronous","1610"]},"sc_chandra":{"id":"sc_chandra","iauName":"Chandra X-ray Observatory","category":"Spacecraft","subcategory":"Orbiter","keywords":["telescope","orbiter","earth","Columbia","X-ray","astrophysics"]},"charon":{"id":"charon","iauName":"Charon","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","pluto","moons","prograde","synchronous","1978"]},"67p_churyumov_gerasimenko":{"id":"67p_churyumov_gerasimenko","iauName":"67P/Churyumov-Gerasimenko","displayName":"67P/Churyumov-Gerasimenko","category":"Comet","subcategory":"Short-Period Comet","keywords":["comet","comets","jupiter-family","1969 r1","1969 iv","1969h","1975 p1","1976 vii","1975i","1982 viii","1982f","1989 vi","1988i","1969","chury","short-period"]},"1p_halley":{"id":"1p_halley","iauName":"1P/Halley","displayName":"Halley","category":"Comet","subcategory":"Short-Period Comet","keywords":["comet","comets","short-period","1p/halley"]},"103p_hartley_2":{"id":"103p_hartley_2","iauName":"103P/Hartley","displayName":"Hartley 2","category":"Comet","keywords":["comet"]},"1i_oumuamua":{"id":"1i_oumuamua","iauName":"1I/\'Oumuamua","displayName":"Oumuamua","category":"Comet","keywords":["comet","comets","1i/oumuamua"]},"9p_tempel_1":{"id":"9p_tempel_1","iauName":"9P/Tempel 1","displayName":"Tempel 1","category":"Comet","subcategory":"Jupiter-Family Comet","keywords":["comet","comets","periodic","jupiter-family","9p/tempel","1867"]},"19p_borrelly":{"id":"19p_borrelly","iauName":"19P/Borrelly","displayName":"Borrelly","category":"Comet","subcategory":"Jupiter-Family Comet","keywords":["comet","comets","periodic","jupiter-family","19p/borrelly","Deep Space 1"]},"81p_wild_2":{"id":"81p_wild_2","iauName":"81P/Wild 2","displayName":"Wild 2","category":"Comet","subcategory":"Short-Period Comet","keywords":["comet","comets","81p/wild","1978 xi","1984 xiv","1990 xxviii","1978"]},"adrastea":{"id":"adrastea","iauName":"Adrastea","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"aegaeon":{"id":"aegaeon","iauName":"Aegaeon","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"aegir":{"id":"aegir","iauName":"Aegir","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"aitne":{"id":"aitne","iauName":"Aitne","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"albiorix":{"id":"albiorix","iauName":"Albiorix","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"amalthea":{"id":"amalthea","iauName":"Amalthea","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"ananke":{"id":"ananke","iauName":"Ananke","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"anthe":{"id":"anthe","iauName":"Anthe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"aoede":{"id":"aoede","iauName":"Aoede","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"arche":{"id":"arche","iauName":"Arche","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"atlas":{"id":"atlas","iauName":"Atlas","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"autonoe":{"id":"autonoe","iauName":"Autonoe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"bebhionn":{"id":"bebhionn","iauName":"Bebhionn","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"belinda":{"id":"belinda","iauName":"Belinda","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"bergelmir":{"id":"bergelmir","iauName":"Bergelmir","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"bestla":{"id":"bestla","iauName":"Bestla","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"bianca":{"id":"bianca","iauName":"Bianca","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"c_2010_x1":{"id":"c_2010_x1","iauName":"C/2010 X1","displayName":"Elenin","category":"Comet","keywords":["comet"]},"c_2012_s1":{"id":"c_2012_s1","iauName":"C/2012 S1","displayName":"ISON","category":"Comet","keywords":["comet"]},"caliban":{"id":"caliban","iauName":"Caliban","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"callirrhoe":{"id":"callirrhoe","iauName":"Callirrhoe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"calypso":{"id":"calypso","iauName":"Calypso","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"carme":{"id":"carme","iauName":"Carme","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"carpo":{"id":"carpo","iauName":"Carpo","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"chaldene":{"id":"chaldene","iauName":"Chaldene","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"cordelia":{"id":"cordelia","iauName":"Cordelia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"cressida":{"id":"cressida","iauName":"Cressida","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"cupid":{"id":"cupid","iauName":"Cupid","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"cyllene":{"id":"cyllene","iauName":"Cyllene","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"dactyl":{"id":"dactyl","iauName":"243 Ida I Dactyl","displayName":"Dactyl","category":"Moon","subcategory":"Major Moon","keywords":["asteroid","minor moon","ida"]},"daphnis":{"id":"daphnis","iauName":"Daphnis","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"deimos":{"id":"deimos","iauName":"Deimos","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","mars","moons","synchronous","1877"]},"desdemona":{"id":"desdemona","iauName":"Desdemona","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"despina":{"id":"despina","iauName":"Despina","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"dia":{"id":"dia","iauName":"Dia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"dimorphos":{"id":"dimorphos","iauName":"Dimorphos","category":"Moon","subcategory":"Major Moon","keywords":["minor moon","solar system","65803 Didymos","asteroid"]},"dione":{"id":"dione","iauName":"Dione","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","inner moons","prograde","synchronous","1684"]},"sc_dscovr":{"id":"sc_dscovr","iauName":"DSCOVR","category":"Spacecraft","subcategory":"Orbiter","keywords":["earth","orbiter","Deep Space Climate Observatory"]},"eirene":{"id":"eirene","iauName":"Eirene","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"elara":{"id":"elara","iauName":"Elara","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"enceladus":{"id":"enceladus","iauName":"Enceladus","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","inner moons","prograde","synchronous","1789"]},"epimetheus":{"id":"epimetheus","iauName":"Epimetheus","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"erinome":{"id":"erinome","iauName":"Erinome","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"erriapus":{"id":"erriapus","iauName":"Erriapus","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"ersa":{"id":"ersa","iauName":"Ersa","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"euanthe":{"id":"euanthe","iauName":"Euanthe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"eukelade":{"id":"eukelade","iauName":"Eukelade","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"eupheme":{"id":"eupheme","iauName":"Eupheme","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"euporie":{"id":"euporie","iauName":"Euporie","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"europa":{"id":"europa","iauName":"Europa","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","jupiter","moons","main group","galilean moons","prograde","synchronous","1610"],"ignoreDependentWhenUnloading":["sc_juno"]},"eurydome":{"id":"eurydome","iauName":"Eurydome","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"farbauti":{"id":"farbauti","iauName":"Farbauti","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"fenrir":{"id":"fenrir","iauName":"Fenrir","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"galatea":{"id":"galatea","iauName":"Galatea","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"ganymede":{"id":"ganymede","iauName":"Ganymede","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","jupiter","moons","main group","galilean moons","prograde","synchronous","1610"],"ignoreDependentWhenUnloading":["sc_juno"]},"greip":{"id":"greip","iauName":"Greip","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"c_1995_o1":{"id":"c_1995_o1","iauName":"C/1995 O1","displayName":"Hale-Bopp","category":"Comet","subcategory":"Long-Period Comet","keywords":["comet","solar system","The Great Comet of 1997","C/1995 O1","1995"]},"ferdinand":{"id":"ferdinand","iauName":"Ferdinand","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"fornjot":{"id":"fornjot","iauName":"Fornjot","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"francisco":{"id":"francisco","iauName":"Francisco","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"halimede":{"id":"halimede","iauName":"Halimede","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"harpalyke":{"id":"harpalyke","iauName":"Harpalyke","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"hati":{"id":"hati","iauName":"Hati","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"hegemone":{"id":"hegemone","iauName":"Hegemone","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"helene":{"id":"helene","iauName":"Helene","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"helike":{"id":"helike","iauName":"Helike","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"hermippe":{"id":"hermippe","iauName":"Hermippe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"herse":{"id":"herse","iauName":"Herse","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"hiiaka":{"id":"hiiaka","iauName":"Hi\'iaka","displayName":"Hi\'iaka","category":"Moon","subcategory":"Major Moon","keywords":["asteroid","minor moon","haumea"]},"himalia":{"id":"himalia","iauName":"Himalia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"hippocamp":{"id":"hippocamp","iauName":"Hippocamp","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"hydra":{"id":"hydra","iauName":"Hydra","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","pluto","moons","outer moons"]},"hyperion":{"id":"hyperion","iauName":"Hyperion","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","outer moons","prograde","1848"]},"hyrrokkin":{"id":"hyrrokkin","iauName":"Hyrrokkin","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"iapetus":{"id":"iapetus","iauName":"Iapetus","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","outer moons","prograde","synchronous","1671"]},"io":{"id":"io","iauName":"Io","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","jupiter","moons","main group","galilean moons","prograde","synchronous","1610"],"ignoreDependentWhenUnloading":["sc_juno"]},"ijiraq":{"id":"ijiraq","iauName":"Ijiraq","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"iocaste":{"id":"iocaste","iauName":"Iocaste","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"isonoe":{"id":"isonoe","iauName":"Isonoe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"janus":{"id":"janus","iauName":"Janus","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"jarnsaxa":{"id":"jarnsaxa","iauName":"Jarnsaxa","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"juliet":{"id":"juliet","iauName":"Juliet","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"jupiter_li":{"id":"jupiter_li","iauName":"Jupiter LI","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lii":{"id":"jupiter_lii","iauName":"Jupiter LII","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_liv":{"id":"jupiter_liv","iauName":"Jupiter LIV","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lix":{"id":"jupiter_lix","iauName":"Jupiter LIX","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lv":{"id":"jupiter_lv","iauName":"Jupiter LV","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lvi":{"id":"jupiter_lvi","iauName":"Jupiter LVI","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxi":{"id":"jupiter_lxi","iauName":"Jupiter LXI","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxiii":{"id":"jupiter_lxiii","iauName":"Jupiter LXIII","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxiv":{"id":"jupiter_lxiv","iauName":"Jupiter LXIV","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxix":{"id":"jupiter_lxix","iauName":"Jupiter LXIX","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxvi":{"id":"jupiter_lxvi","iauName":"Jupiter LXVI","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxvii":{"id":"jupiter_lxvii","iauName":"Jupiter LXVI","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxviii":{"id":"jupiter_lxviii","iauName":"Jupiter LXVIII","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxx":{"id":"jupiter_lxx","iauName":"Jupiter LXX","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"jupiter_lxxii":{"id":"jupiter_lxxii","iauName":"Jupiter LXXII","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"kale":{"id":"kale","iauName":"Kale","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"kallichore":{"id":"kallichore","iauName":"Kallichore","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"kalyke":{"id":"kalyke","iauName":"Kalyke","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"kari":{"id":"kari","iauName":"Kari","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"kerberos":{"id":"kerberos","iauName":"Kerberos","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","pluto","moons"]},"kiviuq":{"id":"kiviuq","iauName":"Kiviuq","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"kore":{"id":"kore","iauName":"Kore","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"laomedeia":{"id":"laomedeia","iauName":"Laomedeia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"larissa":{"id":"larissa","iauName":"Larissa","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"leda":{"id":"leda","iauName":"Leda","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"loge":{"id":"loge","iauName":"Loge","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"lysithea":{"id":"lysithea","iauName":"Lysithea","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"mab":{"id":"mab","iauName":"Mab","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"margaret":{"id":"margaret","iauName":"Margaret","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"megaclite":{"id":"megaclite","iauName":"Megaclite","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons","jupiter xix","S/2000 J 8"]},"menoetius":{"id":"menoetius","iauName":"Menoetius","displayName":"Menoetius","category":"Asteroid","keywords":["asteroid","asteroids","solar system","617 Patroclus"]},"methone":{"id":"methone","iauName":"Methone","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"metis":{"id":"metis","iauName":"Metis","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"mimas":{"id":"mimas","iauName":"Mimas","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","inner moons","prograde","synchronous","1789","death star"]},"miranda":{"id":"miranda","iauName":"Miranda","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","uranus","moons","prograde","synchronous","1948"]},"mneme":{"id":"mneme","iauName":"Mneme","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"moon":{"id":"moon","iauName":"Moon","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","earth","moons","synchronous"]},"mundilfari":{"id":"mundilfari","iauName":"Mundilfari","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"naiad":{"id":"naiad","iauName":"Naiad","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"namaka":{"id":"namaka","iauName":"Namaka","displayName":"Namaka","category":"Moon","subcategory":"Major Moon","keywords":["asteroid","minor moon","haumea"]},"narvi":{"id":"narvi","iauName":"Narvi","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"nix":{"id":"nix","iauName":"Nix","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","pluto","moons"]},"nereid":{"id":"nereid","iauName":"Nereid","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons","irregular moons","prograde","1949"]},"neso":{"id":"neso","iauName":"Neso","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"oberon":{"id":"oberon","iauName":"Oberon","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","uranus","moons","prograde","synchronous","1787"]},"ophelia":{"id":"ophelia","iauName":"Ophelia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"orthosie":{"id":"orthosie","iauName":"Orthosie","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"paaliaq":{"id":"paaliaq","iauName":"Paaliaq","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"pallene":{"id":"pallene","iauName":"Pallene","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"pan":{"id":"pan","iauName":"Pan","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"pandia":{"id":"pandia","iauName":"Pandia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"pandora":{"id":"pandora","iauName":"Pandora","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"pasiphae":{"id":"pasiphae","iauName":"Pasiphae","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"pasithee":{"id":"pasithee","iauName":"Pasithee","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"perdita":{"id":"perdita","iauName":"Perdita","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"philophrosyne":{"id":"philophrosyne","iauName":"Philophrosyne","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"phobos":{"id":"phobos","iauName":"Phobos","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","mars","moons","synchronous","1877"]},"phoebe":{"id":"phoebe","iauName":"Phoebe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","norse group","retrograde","1899"]},"polydeuces":{"id":"polydeuces","iauName":"Polydeuces","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"portia":{"id":"portia","iauName":"Portia","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"praxidike":{"id":"praxidike","iauName":"Praxidike","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"prometheus":{"id":"prometheus","iauName":"Prometheus","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"prospero":{"id":"prospero","iauName":"Prospero","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"proteus":{"id":"proteus","iauName":"Proteus","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons","regular moons","prograde","synchronous","1989"]},"psamathe":{"id":"psamathe","iauName":"Psamathe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"puck":{"id":"puck","iauName":"Puck","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"rhea":{"id":"rhea","iauName":"Rhea","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","outer moons","prograde","synchronous","1672"]},"rosalind":{"id":"rosalind","iauName":"Rosalind","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"s_2003_j_10":{"id":"s_2003_j_10","iauName":"S/2003 J 10","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_12":{"id":"s_2003_j_12","iauName":"S/2003 J 12","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_16":{"id":"s_2003_j_16","iauName":"S/2003 J 16","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_2":{"id":"s_2003_j_2","iauName":"S/2003 J 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_23":{"id":"s_2003_j_23","iauName":"S/2003 J 23","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_24":{"id":"s_2003_j_24","iauName":"S/2003 J 24","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_4":{"id":"s_2003_j_4","iauName":"S/2003 J 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2003_j_9":{"id":"s_2003_j_9","iauName":"S/2003 J 9","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2004_s_7":{"id":"s_2004_s_7","iauName":"S/2004 S 7","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_12":{"id":"s_2004_s_12","iauName":"S/2004 S 12","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_13":{"id":"s_2004_s_13","iauName":"S/2004 S 13","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_17":{"id":"s_2004_s_17","iauName":"S/2004 S 17","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_21":{"id":"s_2004_s_21","iauName":"S/2004 S 21","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_24":{"id":"s_2004_s_24","iauName":"S/2004 S 24","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_28":{"id":"s_2004_s_28","iauName":"S/2004 S 28","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_31":{"id":"s_2004_s_31","iauName":"S/2004 S 31","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_36":{"id":"s_2004_s_36","iauName":"S/2004 S 36","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_37":{"id":"s_2004_s_37","iauName":"S/2004 S 37","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_39":{"id":"s_2004_s_39","iauName":"S/2004 S 39","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_40":{"id":"s_2004_s_40","iauName":"S/2004 S 40","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_41":{"id":"s_2004_s_41","iauName":"S/2004 S 41","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_42":{"id":"s_2004_s_42","iauName":"S/2004 S 42","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_43":{"id":"s_2004_s_43","iauName":"S/2004 S 43","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_44":{"id":"s_2004_s_44","iauName":"S/2004 S 44","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_45":{"id":"s_2004_s_45","iauName":"S/2004 S 45","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_46":{"id":"s_2004_s_46","iauName":"S/2004 S 46","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_47":{"id":"s_2004_s_47","iauName":"S/2004 S 47","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_48":{"id":"s_2004_s_48","iauName":"S/2004 S 48","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_49":{"id":"s_2004_s_49","iauName":"S/2004 S 49","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_50":{"id":"s_2004_s_50","iauName":"S/2004 S 50","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_51":{"id":"s_2004_s_51","iauName":"S/2004 S 51","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_52":{"id":"s_2004_s_52","iauName":"S/2004 S 52","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2004_s_53":{"id":"s_2004_s_53","iauName":"S/2004 S 53","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2005_s_4":{"id":"s_2005_s_4","iauName":"S/2005 S 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2005_s_5":{"id":"s_2005_s_5","iauName":"S/2005 S 5","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_1":{"id":"s_2006_s_1","iauName":"S/2006 S 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_10":{"id":"s_2006_s_10","iauName":"S/2006 S 10","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_11":{"id":"s_2006_s_11","iauName":"S/2006 S 11","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_12":{"id":"s_2006_s_12","iauName":"S/2006 S 12","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_13":{"id":"s_2006_s_13","iauName":"S/2006 S 13","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_14":{"id":"s_2006_s_14","iauName":"S/2006 S 14","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_15":{"id":"s_2006_s_15","iauName":"S/2006 S 15","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_16":{"id":"s_2006_s_16","iauName":"S/2006 S 16","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_17":{"id":"s_2006_s_17","iauName":"S/2006 S 17","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_18":{"id":"s_2006_s_18","iauName":"S/2006 S 18","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_19":{"id":"s_2006_s_19","iauName":"S/2006 S 19","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_20":{"id":"s_2006_s_20","iauName":"S/2006 S 20","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_3":{"id":"s_2006_s_3","iauName":"S/2006 S 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2006_s_9":{"id":"s_2006_s_9","iauName":"S/2006 S 9","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_2":{"id":"s_2007_s_2","iauName":"S/2007 S 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_3":{"id":"s_2007_s_3","iauName":"S/2007 S 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_5":{"id":"s_2007_s_5","iauName":"S/2007 S 5","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_6":{"id":"s_2007_s_6","iauName":"S/2007 S 6","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_7":{"id":"s_2007_s_7","iauName":"S/2007 S 7","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_8":{"id":"s_2007_s_8","iauName":"S/2007 S 8","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2007_s_9":{"id":"s_2007_s_9","iauName":"S/2007 S 9","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2009_s_1":{"id":"s_2009_s_1","iauName":"S/2009 S 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2011_j_3":{"id":"s_2011_j_3","iauName":"S/2011 J 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2016_j_3":{"id":"s_2016_j_3","iauName":"S/2016 J 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2016_j_4":{"id":"s_2016_j_4","iauName":"S/2016 J 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2018_j_2":{"id":"s_2018_j_2","iauName":"S/2018 J 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2018_j_3":{"id":"s_2018_j_3","iauName":"S/2018 J 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2018_j_4":{"id":"s_2018_j_4","iauName":"S/2018 J 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2019_s_1":{"id":"s_2019_s_1","iauName":"S/2019 S 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_10":{"id":"s_2019_s_10","iauName":"S/2019 S 10","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_11":{"id":"s_2019_s_11","iauName":"S/2019 S 11","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_12":{"id":"s_2019_s_12","iauName":"S/2019 S 12","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_13":{"id":"s_2019_s_13","iauName":"S/2019 S 13","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_14":{"id":"s_2019_s_14","iauName":"S/2019 S 14","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_15":{"id":"s_2019_s_15","iauName":"S/2019 S 15","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_16":{"id":"s_2019_s_16","iauName":"S/2019 S 16","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_17":{"id":"s_2019_s_17","iauName":"S/2019 S 17","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_18":{"id":"s_2019_s_18","iauName":"S/2019 S 18","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_19":{"id":"s_2019_s_19","iauName":"S/2019 S 19","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_2":{"id":"s_2019_s_2","iauName":"S/2019 S 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_20":{"id":"s_2019_s_20","iauName":"S/2019 S 20","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_21":{"id":"s_2019_s_21","iauName":"S/2019 S 21","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_3":{"id":"s_2019_s_3","iauName":"S/2019 S 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_4":{"id":"s_2019_s_4","iauName":"S/2019 S 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_5":{"id":"s_2019_s_5","iauName":"S/2019 S 5","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_6":{"id":"s_2019_s_6","iauName":"S/2019 S 6","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_7":{"id":"s_2019_s_7","iauName":"S/2019 S 7","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_8":{"id":"s_2019_s_8","iauName":"S/2019 S 8","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2019_s_9":{"id":"s_2019_s_9","iauName":"S/2019 S 9","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_1":{"id":"s_2020_s_1","iauName":"S/2020 S 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_10":{"id":"s_2020_s_10","iauName":"S/2020 S 10","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_2":{"id":"s_2020_s_2","iauName":"S/2020 S 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_3":{"id":"s_2020_s_3","iauName":"S/2020 S 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_4":{"id":"s_2020_s_4","iauName":"S/2020 S 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_5":{"id":"s_2020_s_5","iauName":"S/2020 S 5","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_6":{"id":"s_2020_s_6","iauName":"S/2020 S 6","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_7":{"id":"s_2020_s_7","iauName":"S/2020 S 7","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_8":{"id":"s_2020_s_8","iauName":"S/2020 S 8","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2020_s_9":{"id":"s_2020_s_9","iauName":"S/2020 S 9","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"s_2021_j_1":{"id":"s_2021_j_1","iauName":"S/2021 J 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2021_j_2":{"id":"s_2021_j_2","iauName":"S/2021 J 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2021_j_3":{"id":"s_2021_j_3","iauName":"S/2021 J 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2021_j_4":{"id":"s_2021_j_4","iauName":"S/2021 J 4","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2021_j_5":{"id":"s_2021_j_5","iauName":"S/2021 J 5","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2021_j_6":{"id":"s_2021_j_6","iauName":"S/2021 J 6","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2022_j_1":{"id":"s_2022_j_1","iauName":"S/2022 J 1","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2022_j_2":{"id":"s_2022_j_2","iauName":"S/2022 J 2","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"s_2022_j_3":{"id":"s_2022_j_3","iauName":"S/2022 J 3","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"sao":{"id":"sao","iauName":"Sao","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"gridr":{"id":"gridr","iauName":"Gridr","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S20","saturn liv"]},"angrboda":{"id":"angrboda","iauName":"Angrboda","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S22","saturn lv"]},"skrymir":{"id":"skrymir","iauName":"Skrymir","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S23","saturn lvi"]},"gerd":{"id":"gerd","iauName":"Gerd","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S25","saturn lvii"]},"saturn_lviii":{"id":"saturn_lviii","iauName":"Saturn LVIII","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"eggther":{"id":"eggther","iauName":"Eggther","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S27","saturn lix"]},"saturn_lx":{"id":"saturn_lx","iauName":"Saturn LX","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"beli":{"id":"beli","iauName":"Beli","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S30","saturn lxi"]},"gunnlod":{"id":"gunnlod","iauName":"Gunnlod","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S32","saturn lxii"]},"thiazzi":{"id":"thiazzi","iauName":"Thiazzi","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S33","saturn lxiii"]},"saturn_lxiv":{"id":"saturn_lxiv","iauName":"Saturn LXIV","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"alvaldi":{"id":"alvaldi","iauName":"Alvaldi","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S35","saturn lxv"]},"geirrod":{"id":"geirrod","iauName":"Geirrod","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons","S/2004 S38","saturn lxvi"]},"setebos":{"id":"setebos","iauName":"Setebos","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"siarnaq":{"id":"siarnaq","iauName":"Siarnaq","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"sinope":{"id":"sinope","iauName":"Sinope","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"skathi":{"id":"skathi","iauName":"Skathi","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"skoll":{"id":"skoll","iauName":"Skoll","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"sponde":{"id":"sponde","iauName":"Sponde","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"stephano":{"id":"stephano","iauName":"Stephano","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"styx":{"id":"styx","iauName":"Styx","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","pluto","moons"]},"surtur":{"id":"surtur","iauName":"Surtur","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"suttungr":{"id":"suttungr","iauName":"Suttungr","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"sycorax":{"id":"sycorax","iauName":"Sycorax","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"tarqeq":{"id":"tarqeq","iauName":"Tarqeq","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"tarvos":{"id":"tarvos","iauName":"Tarvos","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"taygete":{"id":"taygete","iauName":"Taygete","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"telesto":{"id":"telesto","iauName":"Telesto","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"tethys":{"id":"tethys","iauName":"Tethys","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","inner moons","prograde","synchronous","1684"]},"thalassa":{"id":"thalassa","iauName":"Thalassa","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","neptune","moons"]},"thebe":{"id":"thebe","iauName":"Thebe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"thelxinoe":{"id":"thelxinoe","iauName":"Thelxinoe","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"themisto":{"id":"themisto","iauName":"Themisto","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"thrymr":{"id":"thrymr","iauName":"Thrymr","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"thyone":{"id":"thyone","iauName":"Thyone","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"titan":{"id":"titan","iauName":"Titan","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","saturn","moons","outer moons","prograde","synchronous","1655"]},"titania":{"id":"titania","iauName":"Titania","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","uranus","moons","prograde","synchronous","1787"]},"trinculo":{"id":"trinculo","iauName":"Trinculo","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","uranus","moons"]},"triton":{"id":"triton","iauName":"Triton","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","neptune","moons","irregular moons","retrograde","synchronous","1846"]},"umbriel":{"id":"umbriel","iauName":"Umbriel","category":"Moon","subcategory":"Major Moon","keywords":["major moon","solar system","uranus","moons","prograde","synchronous","1851"]},"ymir":{"id":"ymir","iauName":"Ymir","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","saturn","moons"]},"sc_ace":{"id":"sc_ace","iauName":"ACE","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_acrimsat":{"id":"sc_acrimsat","iauName":"ACRIMSAT","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_acs3":{"id":"sc_acs3","iauName":"ACS3","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"],"disabled":true},"sc_aqua":{"id":"sc_aqua","iauName":"Aqua","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_artemis_1":{"id":"sc_artemis_1","iauName":"Artemis I","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_aura":{"id":"sc_aura","iauName":"Aura","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_biosentinel":{"id":"sc_biosentinel","iauName":"BioSentinel","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_calipso":{"id":"sc_calipso","iauName":"CALIPSO","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_capstone":{"id":"sc_capstone","iauName":"CAPSTONE","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_cassini":{"id":"sc_cassini","iauName":"Cassini","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","saturn"],"hasEvents":true},"sc_clementine":{"id":"sc_clementine","iauName":"Clementine","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_cloudsat":{"id":"sc_cloudsat","iauName":"CloudSat","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_cluster_ii_fm5":{"id":"sc_cluster_ii_fm5","iauName":"Rumba","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_cluster_ii_fm6":{"id":"sc_cluster_ii_fm6","iauName":"Salsa","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_cluster_ii_fm7":{"id":"sc_cluster_ii_fm7","iauName":"Samba","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_cluster_ii_fm8":{"id":"sc_cluster_ii_fm8","iauName":"Tango","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_1":{"id":"sc_cygnss_1","iauName":"CYGNSS 1","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_2":{"id":"sc_cygnss_2","iauName":"CYGNSS 2","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_3":{"id":"sc_cygnss_3","iauName":"CYGNSS 3","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_4":{"id":"sc_cygnss_4","iauName":"CYGNSS 4","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_5":{"id":"sc_cygnss_5","iauName":"CYGNSS 5","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_6":{"id":"sc_cygnss_6","iauName":"CYGNSS 6","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_7":{"id":"sc_cygnss_7","iauName":"CYGNSS 7","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_cygnss_8":{"id":"sc_cygnss_8","iauName":"CYGNSS 8","category":"Spacecraft","subcategory":"Orbiter","constellation":"CYGNSS","keywords":["spacecraft","earth","orbiter"]},"sc_dart":{"id":"sc_dart","iauName":"DART","category":"Spacecraft","subcategory":"Impactor","altName":"boom","keywords":["spacecraft","65803_didymos","dimorphos","asteroid"],"hasEvents":true},"sc_dawn":{"id":"sc_dawn","iauName":"Dawn","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","vesta","ceres","small body mission"],"related":{"asteroid":["4_vesta","1_ceres"]},"hasEvents":true},"sc_deep_impact":{"id":"sc_deep_impact","iauName":"Deep Impact","category":"Spacecraft","subcategory":"Flyby","altName":"DI","keywords":["spacecraft","tempel 1","small body mission"],"related":{"comet":["9p_temp_1"]},"hasEvents":true},"sc_deep_impact_impactor":{"id":"sc_deep_impact_impactor","iauName":"Deep Impact Impactor","category":"Spacecraft","subcategory":"Impactor","altName":"DII","keywords":["spacecraft","tempel 1","small body mission"],"related":{"comet":["9p_temp_1"]},"hasEvents":true},"sc_deep_impact_impactor_impact_site":{"id":"sc_deep_impact_impactor_impact_site","displayName":"Deep Impact Impactor Impact Site","category":"Landing site","comparisonFeature":false},"sc_deep_space_1":{"id":"sc_deep_space_1","iauName":"Deep Space 1","category":"Spacecraft","subcategory":"Flyby","altName":"DS1","keywords":["spacecraft","9660 Braille","19p/Borrelly","small body mission"],"related":{"asteroid":["9969_braille"],"comet":["19p_borrelly"]},"hasEvents":true},"sc_eo_1":{"id":"sc_eo_1","iauName":"EO-1","category":"Spacecraft","subcategory":"Orbiter","altName":"Earth Observing-1","keywords":["spacecraft","earth","orbiter"]},"sc_euclid":{"id":"sc_euclid","iauName":"Euclid","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","telescope"],"disabled":false},"sc_europa_clipper":{"id":"sc_europa_clipper","iauName":"Europa Clipper","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","europa"]},"sc_explorer_1":{"id":"sc_explorer_1","iauName":"Explorer 1","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_galileo":{"id":"sc_galileo","iauName":"Galileo","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","outer planet mission","orbiter","jupiter"],"hasEvents":true},"sc_galileo_probe":{"id":"sc_galileo_probe","iauName":"Galileo Probe","category":"Spacecraft","subcategory":"Lander","keywords":["spacecraft","outer planet mission","orbiter","jupiter"],"hasEvents":true},"sc_geotail":{"id":"sc_geotail","iauName":"Geotail","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_gpm":{"id":"sc_gpm","iauName":"GPM","category":"Spacecraft","subcategory":"Orbiter","altName":"Global Precipitation Measurement","keywords":["spacecraft","earth","orbiter"]},"sc_grace_1":{"id":"sc_grace_1","iauName":"GRACE-1","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_grace_2":{"id":"sc_grace_2","iauName":"GRACE-2","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_grace_fo1":{"id":"sc_grace_fo1","iauName":"GRACE-FO1","category":"Spacecraft","subcategory":"Orbiter","altName":"GRACE Follow-On","keywords":["spacecraft","earth","orbiter"]},"sc_grace_fo2":{"id":"sc_grace_fo2","iauName":"GRACE-FO2","category":"Spacecraft","subcategory":"Orbiter","altName":"GRACE Follow-On","keywords":["spacecraft","earth","orbiter"]},"sc_grail_a":{"id":"sc_grail_a","iauName":"GRAIL A","category":"Spacecraft","subcategory":"Orbiter","altName":"Ebb","keywords":["spacecraft","moon","orbiter","ebb"]},"sc_grail_b":{"id":"sc_grail_b","iauName":"GRAIL B","category":"Spacecraft","subcategory":"Orbiter","altName":"Flow","keywords":["spacecraft","moon","orbiter","flow"]},"sc_grifex":{"id":"sc_grifex","iauName":"GRIFEX","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_hubble_space_telescope":{"id":"sc_hubble_space_telescope","iauName":"Hubble Space Telescope","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","telescope","1990"]},"sc_huygens":{"id":"sc_huygens","iauName":"Huygens","category":"Spacecraft","subcategory":"Lander","keywords":["spacecraft","titan","cassini","lander"],"hasEvents":true},"sc_ibex":{"id":"sc_ibex","iauName":"IBEX","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_icesat_2":{"id":"sc_icesat_2","iauName":"ICESat-2","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_image":{"id":"sc_image","iauName":"IMAGE","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_insight":{"id":"sc_insight","iauName":"InSight","category":"Spacecraft","subcategory":"Lander","keywords":["spacecraft","mars","lander","seismic","2018"],"landingDate":"2018-11-26T19:45:00"},"sc_ipex":{"id":"sc_ipex","iauName":"IPEX","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_isas":{"id":"sc_isas","iauName":"ISAS","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_iss":{"id":"sc_iss","iauName":"International Space Station","category":"Spacecraft","subcategory":"Orbiter","altName":"ISS","keywords":["iss","international","international space","station","earth","orbiter","1998","emit","ecostress","oco-3"],"customDistance":0.1},"sc_iss_ecostress":{"id":"sc_iss_ecostress","iauName":"ECOSTRESS","category":"Instrument","cameraOptions":{"forwardVector":"-y-axis"},"comparisonFeature":false,"keywords":["spacecraft","earth","iss","orbiter"]},"sc_iss_emit":{"id":"sc_iss_emit","iauName":"EMIT","category":"Instrument","cameraOptions":{"forwardVector":"y-axis","distance":0.006},"comparisonFeature":false,"altName":"Earth Surface Mineral Dust Source Investigation","keywords":["spacecraft","earth","iss","orbiter"]},"sc_iss_oco_3":{"id":"sc_iss_oco_3","iauName":"OCO-3","category":"Instrument","cameraOptions":{"forwardVector":"-y-axis"},"comparisonFeature":false,"altName":"Orbiting Carbon Observatory 3","keywords":["spacecraft","earth","iss","orbiter"]},"sc_iss_rapidscat":{"id":"sc_iss_rapidscat","iauName":"RapidScat","category":"Instrument","cameraOptions":{"upVector":"-y-axis","forwardVector":"x-axis","distance":0.007},"comparisonFeature":false,"keywords":["spacecraft","earth","iss","orbiter"]},"sc_ixpe":{"id":"sc_ixpe","iauName":"IXPE","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","telescope","2021","x-ray","imaging x-ray polarimetry explorer","cosmic x-rays"]},"sc_jason_1":{"id":"sc_jason_1","iauName":"Jason-1","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_jason_2":{"id":"sc_jason_2","iauName":"Jason-2/OSTM","category":"Spacecraft","subcategory":"Orbiter","altName":"OSTM","keywords":["spacecraft","earth","orbiter","jason-2"]},"sc_jason_3":{"id":"sc_jason_3","iauName":"Jason-3","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_juice":{"id":"sc_juice","iauName":"Juice","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","jupiter","orbiter"]},"sc_juno":{"id":"sc_juno","iauName":"Juno","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","jupiter","orbiter","gravity","magnetic field","atmosphere","junocam","bruh","2011"],"customDistance":0.04,"hasEvents":true},"sc_jwst":{"id":"sc_jwst","iauName":"James Webb Space Telescope","category":"Spacecraft","subcategory":"Orbiter","altName":"James Webb Space Telescope","keywords":["spacecraft","earth","orbiter","telescope","jwst"],"hasEvents":true},"sc_kepler_space_telescope":{"id":"sc_kepler_space_telescope","iauName":"Kepler","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","telescope"]},"sc_ladee":{"id":"sc_ladee","iauName":"LADEE","category":"Spacecraft","subcategory":"Orbiter","altName":"Lunar Atmosphere and Dust Environment Explorer","keywords":["spacecraft","moon","orbiter"]},"sc_landsat_7":{"id":"sc_landsat_7","iauName":"Landsat 7","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_landsat_8":{"id":"sc_landsat_8","iauName":"Landsat 8","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_landsat_9":{"id":"sc_landsat_9","iauName":"Landsat 9","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_lcross":{"id":"sc_lcross","iauName":"LCROSS","category":"Spacecraft","subcategory":"Orbiter","altName":"Lunar Crater Observation and Sensing Satellite","keywords":["spacecraft","moon","orbiter"],"hasEvents":true},"sc_lucy":{"id":"sc_lucy","iauName":"Lucy","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"],"hasEvents":true},"sc_lunar_flashlight":{"id":"sc_lunar_flashlight","iauName":"Lunar Flashlight","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_lunar_icecube":{"id":"sc_lunar_icecube","iauName":"Lunar IceCube","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_lunar_prospector":{"id":"sc_lunar_prospector","iauName":"Lunar Prospector","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_lunar_reconnaissance_orbiter":{"id":"sc_lunar_reconnaissance_orbiter","iauName":"Lunar Reconnaissance Orbiter","category":"Spacecraft","subcategory":"Orbiter","altName":"LRO","keywords":["spacecraft","moon","orbiter","lro","temperature","imaging","albedo","polar","2009"]},"sc_lunar_trailblazer":{"id":"sc_lunar_trailblazer","iauName":"Lunar Trailblazer","category":"Spacecraft","subcategory":"Orbiter","altName":"","keywords":["spacecraft","moon","orbiter","lunar","trailblazer","water"],"disabled":true},"sc_lunir":{"id":"sc_lunir","iauName":"Lunar Reconnaissance Orbiter","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter","artemis"],"disabled":true},"sc_magellan":{"id":"sc_magellan","iauName":"Magellan","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","inner planet mission","venus"]},"sc_marco_a":{"id":"sc_marco_a","iauName":"MarCO A","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","insight","cubesat"]},"sc_marco_b":{"id":"sc_marco_b","iauName":"MarCO B","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","insight","cubesat"]},"sc_mars_2020":{"id":"sc_mars_2020","iauName":"Mars 2020 (Perseverance)","category":"Spacecraft","subcategory":"Rover","altName":"Percy","keywords":["spacecraft","mars","lander","rover","perseverance","mars 2020","mars2020","m2020"],"landingDate":"2021-02-18T20:55:00"},"sc_mars_2020_landing_site":{"id":"sc_mars_2020_landing_site","displayName":"Perseverance Rover landing site","category":"Landing site","comparisonFeature":false},"sc_mars_exploration_rover_1_landing_site":{"id":"sc_mars_exploration_rover_1_landing_site","displayName":"Opportunity Rover landing site","category":"Landing site","comparisonFeature":false},"sc_mars_exploration_rover_1":{"id":"sc_mars_exploration_rover_1","iauName":"Mars Exploration Rover B (Opportunity)","displayName":"Opportunity","category":"Spacecraft","subcategory":"Rover","keywords":["spacecraft","mars","lander","rover","opportunity","meridiani planum","2003","MER-B","MER-1","mer b"],"landingDate":"2004-01-25T04:54:00"},"sc_mars_exploration_rover_2_landing_site":{"id":"sc_mars_exploration_rover_2_landing_site","displayName":"Spirit Rover landing site","category":"Landing site","comparisonFeature":false},"sc_mars_exploration_rover_2":{"id":"sc_mars_exploration_rover_2","iauName":"Mars Exploration Rover A (Spirit)","displayName":"Spirit","category":"Spacecraft","subcategory":"Rover","keywords":["spacecraft","mars","lander","rover","spirit","MER-A","MER-2","mer a"],"landingDate":"2004-01-25T04:54:00"},"sc_mars_express":{"id":"sc_mars_express","iauName":"Mars Express","category":"Spacecraft","subcategory":"Orbiter","altName":"MEX","keywords":["spacecraft","mars","orbiter","water","geology","atmosphere","surface","relay","2003"]},"sc_mars_global_surveyor":{"id":"sc_mars_global_surveyor","iauName":"Mars Global Surveyor","category":"Spacecraft","subcategory":"Orbiter","altName":"MGS","keywords":["spacecraft","mars","MGS"]},"sc_mars_odyssey":{"id":"sc_mars_odyssey","iauName":"Mars Odyssey","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","mars","orbiter","elements","minerals","hydrogen","water","polar","radiation","relay","2001"]},"sc_mars_reconnaissance_orbiter":{"id":"sc_mars_reconnaissance_orbiter","iauName":"Mars Reconnaissance Orbiter","category":"Spacecraft","subcategory":"Orbiter","altName":"MRO","keywords":["spacecraft","mars","orbiter","mro","water","dust","atmosphere","relay","2005"]},"sc_mars_science_laboratory_landing_site":{"id":"sc_mars_science_laboratory_landing_site","displayName":"Curiosity Rover landing site","category":"Landing site","comparisonFeature":false},"sc_mars_science_laboratory":{"id":"sc_mars_science_laboratory","iauName":"Mars Science Laboratory (Curiosity)","displayName":"Mars Science Laboratory (Curiosity)","category":"Spacecraft","subcategory":"Rover","altName":"MSL","keywords":["spacecraft","mars","lander","rover","msl","curiosity","microbes","habitability","2011"],"landingDate":"2012-08-06T05:32:00"},"sc_maven":{"id":"sc_maven","iauName":"MAVEN","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","mars","orbiter","atmosphere","ionosphere","solar wind","relay","2013"]},"sc_messenger":{"id":"sc_messenger","iauName":"MESSENGER","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","mercury","orbiter"]},"sc_messenger_impact_site":{"id":"sc_messenger_impact_site","displayName":"MESSENGER Impact Site","category":"Landing site","comparisonFeature":false},"sc_mcubed_2":{"id":"sc_mcubed_2","iauName":"M-Cubed 2","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_mms_1":{"id":"sc_mms_1","iauName":"MMS 1","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_mms_2":{"id":"sc_mms_2","iauName":"MMS 2","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_mms_3":{"id":"sc_mms_3","iauName":"MMS 3","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_mms_4":{"id":"sc_mms_4","iauName":"MMS 4","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_near_shoemaker":{"id":"sc_near_shoemaker","iauName":"NEAR Shoemaker","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","eros","orbiter"],"related":{"asteroid":["433_eros"]},"hasEvents":true},"sc_new_horizons":{"id":"sc_new_horizons","iauName":"New Horizons","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","pluto","flyby","imager","spectrometer","ultraviolet","solar wind","extended mission","2006"],"hasEvents":true},"sc_nustar":{"id":"sc_nustar","iauName":"NuSTAR","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","telescope","X-ray","astrophysics"]},"sc_oco_2":{"id":"sc_oco_2","iauName":"OCO-2","category":"Spacecraft","subcategory":"Orbiter","altName":"Orbiting Carbon Observatory 2","keywords":["spacecraft","earth","orbiter"]},"sc_osiris_rex":{"id":"sc_osiris_rex","iauName":"OSIRIS-APEX","category":"Spacecraft","subcategory":"Orbiter","altName":"ORX","keywords":["spacecraft","bennu","apex","osiris-apex","lander","sample return","asteroids","chemistry","mineralogy","2016"],"related":{"asteroid":["101955_bennu","99942_apophis"]},"hasEvents":true},"sc_osiris_rex_src":{"id":"sc_osiris_rex_src","iauName":"OSIRIS-REx Sample Return Capsule","category":"Spacecraft","subcategory":"Flyby","altName":"ORX SRC","keywords":["spacecraft","Bennu","orbiter","sc_osiris_rex","SRC","sample return"],"related":{"asteroid":["101955_bennu"]},"hasEvents":true},"sc_pace":{"id":"sc_pace","iauName":"PACE","altName":"Plankton, Aerosol, Cloud, ocean Ecosystem","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_parker_solar_probe":{"id":"sc_parker_solar_probe","iauName":"Parker Solar Probe","category":"Spacecraft","subcategory":"Orbiter","altName":"PSP","keywords":["spacecraft","psp"]},"sc_philae":{"id":"sc_philae","iauName":"Philae","category":"Spacecraft","subcategory":"Lander","keywords":["spacecraft","67P/Churyumov-Gerasimenko","lander","Rosetta"],"related":{"comet":["67p_churyumov_gerasimenko"]},"hasEvents":true},"sc_phoenix":{"id":"sc_phoenix","iauName":"Phoenix","category":"Spacecraft","subcategory":"Lander","altName":"PHX","keywords":["spacecraft","mars","lander"],"landingDate":"2008-05-25T23:53:44"},"sc_phoenix_landing_site":{"id":"sc_phoenix_landing_site","displayName":"Phoenix landing site","category":"Landing site","comparisonFeature":false},"sc_pioneer_10":{"id":"sc_pioneer_10","iauName":"Pioneer 10","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","jupiter","callisto","ganymede","europa","io","flyby","outer planets","interstellar","1972"],"hasEvents":true},"sc_pioneer_11":{"id":"sc_pioneer_11","iauName":"Pioneer 11","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","jupiter","callisto","ganymede","io","europa","amalthea","saturn","iapetus","phoebe","hyperion","epimetheus","atlas","dione","mimas","janus","tethys","enceladus","calypso","rhea","titan","flyby","magnetic field","solar wind","outer planets","interstellar","1973"],"hasEvents":true},"sc_polar":{"id":"sc_polar","iauName":"Polar","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_prefire_1":{"id":"sc_prefire_1","iauName":"PREFIRE-1","category":"Spacecraft","subcategory":"Orbiter","constellation":"PREFIRE","keywords":["spacecraft","earth","orbiter"]},"sc_prefire_2":{"id":"sc_prefire_2","iauName":"PREFIRE-2","category":"Spacecraft","subcategory":"Orbiter","constellation":"PREFIRE","keywords":["spacecraft","earth","orbiter"]},"sc_psyche":{"id":"sc_psyche","iauName":"Psyche","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","16 Psyche","orbiter"],"related":{"asteroid":["16_psyche"]},"hasEvents":true},"sc_quikscat":{"id":"sc_quikscat","iauName":"QuikSCAT","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_raincube":{"id":"sc_raincube","iauName":"RainCube","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","cubesat"]},"sc_rbsp_a":{"id":"sc_rbsp_a","iauName":"Van Allen Probe A","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_rbsp_b":{"id":"sc_rbsp_b","iauName":"Van Allen Probe B","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_sac_d":{"id":"sc_sac_d","iauName":"Aquarius","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_rosetta":{"id":"sc_rosetta","iauName":"Rosetta","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","small body mission","67P/Churyumov-Gerasimenko"],"related":{"comet":["67p_churyumov_gerasimenko"]},"hasEvents":true},"sc_sdo":{"id":"sc_sdo","iauName":"Solar Dynamics Observatory","category":"Spacecraft","subcategory":"Orbiter","altName":"SDO","keywords":["spacecraft","earth","orbiter"]},"sc_sentinel_6":{"id":"sc_sentinel_6","iauName":"Sentinel-6 Michael Freilich","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter","2020","sea level","jason","jason-cs","copernicus","topex/poseidon"]},"sc_smap":{"id":"sc_smap","iauName":"SMAP","category":"Spacecraft","subcategory":"Orbiter","altName":"Soil Moisture Active Passive","keywords":["spacecraft","earth","orbiter"]},"sc_soho":{"id":"sc_soho","iauName":"SOHO","category":"Spacecraft","subcategory":"Orbiter","altName":"Solar and Heliospheric Observatory","keywords":["spacecraft","sun","orbiter"]},"sc_sorce":{"id":"sc_sorce","iauName":"SORCE","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_spitzer":{"id":"sc_spitzer","iauName":"Spitzer Space Telescope","category":"Spacecraft","subcategory":"Orbiter","altName":"SIRTF","keywords":["spacecraft","sun","orbiter","sirtf","space infrared telescope facility","spitzer space telescope","2003"]},"sc_stardust":{"id":"sc_stardust","iauName":"Stardust","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","Wild-2","orbiter"],"related":{"comet":["81p_wild_2"]},"hasEvents":true},"sc_stardust_src":{"id":"sc_stardust_src","iauName":"Stardust Sample Return Capsule","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","Wild-2","orbiter"],"related":{"comet":["81p_wild_2"]}},"sc_starling_1":{"id":"sc_starling_1","iauName":"Starling-1","category":"Spacecraft","subcategory":"Orbiter","constellation":"STARLING","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_starling_2":{"id":"sc_starling_2","iauName":"Starling-2","category":"Spacecraft","subcategory":"Orbiter","constellation":"STARLING","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_starling_3":{"id":"sc_starling_3","iauName":"Starling-3","category":"Spacecraft","subcategory":"Orbiter","constellation":"STARLING","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_starling_4":{"id":"sc_starling_4","iauName":"Starling-4","category":"Spacecraft","subcategory":"Orbiter","constellation":"STARLING","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_stereo_ahead":{"id":"sc_stereo_ahead","iauName":"STEREO Ahead","category":"Spacecraft","subcategory":"Orbiter","altName":"STA","keywords":["spacecraft","sun","orbiter","solar terrestrial relations observatory","stereoscopic","coronal mass ejections","cme","2006"]},"sc_stereo_behind":{"id":"sc_stereo_behind","iauName":"STEREO Behind","category":"Spacecraft","subcategory":"Orbiter","altName":"STB","keywords":["spacecraft","sun","orbiter","solar terrestrial relations observatory","stereoscopic","coronal mass ejections","cme","2006"]},"sc_tdrs_3":{"id":"sc_tdrs_3","iauName":"TDRS-3","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_5":{"id":"sc_tdrs_5","iauName":"TDRS-5","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_6":{"id":"sc_tdrs_6","iauName":"TDRS-6","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_7":{"id":"sc_tdrs_7","iauName":"TDRS-7","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_8":{"id":"sc_tdrs_8","iauName":"TDRS-8","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_9":{"id":"sc_tdrs_9","iauName":"TDRS-9","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_10":{"id":"sc_tdrs_10","iauName":"TDRS-10","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_11":{"id":"sc_tdrs_11","iauName":"TDRS-11","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_12":{"id":"sc_tdrs_12","iauName":"TDRS-12","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_tdrs_13":{"id":"sc_tdrs_13","iauName":"TDRS-13","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","orbiter"]},"sc_suomi_npp":{"id":"sc_suomi_npp","iauName":"Suomi NPP","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_swot":{"id":"sc_swot","iauName":"SWOT","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_tempo":{"id":"sc_tempo","iauName":"TEMPO","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_terra":{"id":"sc_terra","iauName":"Terra","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_tess":{"id":"sc_tess","iauName":"TESS","category":"Spacecraft","subcategory":"Orbiter","altName":"Transiting Exoplanet Survey Satellite","keywords":["spacecraft","earth","telescope","transiting exoplanet survey satellite","orbiter","2018","exoplanets"]},"sc_themis_a":{"id":"sc_themis_a","iauName":"THEMIS-A","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_themis_b":{"id":"sc_themis_b","iauName":"ARTEMIS P1","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_themis_c":{"id":"sc_themis_c","iauName":"ARTEMIS P2","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","moon","orbiter"]},"sc_themis_d":{"id":"sc_themis_d","iauName":"THEMIS-D","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_themis_e":{"id":"sc_themis_e","iauName":"THEMIS-E","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_trace_gas_orbiter":{"id":"sc_trace_gas_orbiter","iauName":"Trace Gas Orbiter","category":"Spacecraft","subcategory":"Orbiter","altName":"TGO","keywords":["spacecraft","mars","orbiter","tgo","atmosphere","relay","2016"]},"sc_trmm":{"id":"sc_trmm","iauName":"TRMM","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","earth","orbiter"]},"sc_tropics_03":{"id":"sc_tropics_03","iauName":"TROPICS-03","category":"Spacecraft","subcategory":"Orbiter","constellation":"TROPICS","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_tropics_05":{"id":"sc_tropics_05","iauName":"TROPICS-05","category":"Spacecraft","subcategory":"Orbiter","constellation":"TROPICS","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_tropics_06":{"id":"sc_tropics_06","iauName":"TROPICS-06","category":"Spacecraft","subcategory":"Orbiter","constellation":"TROPICS","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_tropics_07":{"id":"sc_tropics_07","iauName":"TROPICS-07","category":"Spacecraft","subcategory":"Orbiter","constellation":"TROPICS","keywords":["spacecraft","earth","orbiter"],"disabled":false},"sc_tropics_01":{"id":"sc_tropics_01","iauName":"TROPICS-01","category":"Spacecraft","subcategory":"Orbiter","constellation":"TROPICS","keywords":["spacecraft","earth","orbiter","tropics pathfinder","pathfinder"],"disabled":false},"sc_ulysses":{"id":"sc_ulysses","iauName":"Ulysses","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","sun","orbiter"]},"sc_voyager_1":{"id":"sc_voyager_1","iauName":"Voyager 1","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","jupiter","saturn","flyby","imaging","vger","radio science","infrared","ultraviolet","magnetometer","plasma","1977"],"hasEvents":true},"sc_voyager_2":{"id":"sc_voyager_2","iauName":"Voyager 2","category":"Spacecraft","subcategory":"Flyby","keywords":["spacecraft","jupiter","saturn","uranus","vger","neptune","flyby","imaging","radio science","infrared","ultraviolet","magnetometer","plasma","1977"],"hasEvents":true},"sc_wind":{"id":"sc_wind","iauName":"WIND","category":"Spacecraft","subcategory":"Orbiter","keywords":["spacecraft","solar wind","earth","orbiter"]},"valetudo":{"id":"valetudo","iauName":"Valetudo","category":"Moon","subcategory":"Minor Moon","keywords":["minor moon","solar system","jupiter","moons"]},"scientist":{"id":"scientist","displayName":"Scientist","category":"Human","searchable":false},"school_bus":{"id":"school_bus","displayName":"School Bus","category":"Vehicle","searchable":false},"rose_bowl":{"id":"rose_bowl","displayName":"Stadium","category":"Building","searchable":false}}')})});var __webpack_module_cache__={};function __webpack_require__(moduleId){var cachedModule=__webpack_module_cache__[moduleId];if(cachedModule!==undefined){return cachedModule.exports} + var module=__webpack_module_cache__[moduleId]={id:moduleId,loaded:!1,exports:{}};__webpack_modules__[moduleId].call(module.exports,module,module.exports,__webpack_require__);module.loaded=!0;return module.exports} + __webpack_require__.m=__webpack_modules__;!function(){var deferred=[];__webpack_require__.O=function(result,chunkIds,fn,priority){if(chunkIds){priority=priority||0;for(var i=deferred.length;i>0&&deferred[i-1][2]>priority;i--)deferred[i]=deferred[i-1];deferred[i]=[chunkIds,fn,priority];return} + var notFulfilled=Infinity;for(var i=0;i=priority)&&Object.keys(__webpack_require__.O).every(function(key){return __webpack_require__.O[key](chunkIds[j])})){chunkIds.splice(j--,1)}else{fulfilled=!1;if(priority

        Sometimes called minor planets, asteroids are rocky, airless remnants left over from the early formation of our solar system about 4.6 billion years ago.

        Most of this ancient space rubble can be found orbiting the Sun between Mars and Jupiter within the main asteroid belt.

        Unlike comets, asteroids remain solid under extreme temperatures; this is due to their formation in the high heat, high density center of the solar nebula.

        Deep Dive into Asteroids 101
        ", + "related": [ + "comet" + ] + }, + "comet": { + "title": "Comet", + "html": "

        Comets are frozen leftovers from the formation of the solar system composed of dust, rock, and ice. They range from a few kilometers, to hundreds of kilometers wide.

        As they orbit closer to the Sun, they heat up and spew gases and dust into a glowing head that can be larger than a planet. This material forms a tail that stretches millions of kilometers.

        Unlike asteroids, comets formed in areas of the solar nebula where it was cold enough for water and gases to freeze. Consequently, they are larger and rarer than asteroids, and tend to originate in the far reaches of the solar system.

        ", + "related": [ + "asteroid" + ] + }, + "neo": { + "title": "NEO", + "html": "
        Near-Earth object

        A near-Earth object is any small solar system body whose orbit brings it within a certain distance of Earth. This distance is defined by having the closest approach to the sun, the perihelion, be within 1.3 AU

        A sub-category of the NEO is the PHO.

        ", + "related": [ + "perihelion", + "au", + "pho" + ] + }, + "pho": { + "title": "PHO", + "html":"
        Potentially Hazardous Object

        To be defined as potentially hazardous, an object must be:

        • Larger than 150 meters (almost 500 feet), roughly twice as big as the Statue of Liberty is tall.
        • Approach Earth's orbit to within about 7.5 million kilometers (4.6 million miles). This can also be expressed as having a MOID of less than 0.05 AU (within 19.5 LDs).

        PHOs can be both asteroids and comets, but the vast majority are asteroids. Learn more about the PHO, Apophis below.

        Deep Dive into Close Approaches
        ", + "related": [ + "asteroid", + "comet", + "moid", + "au", + "ld" + ] + }, + "aphelion": { + "title": "Aphelion", + "html": "

        The aphelion is the point in the orbit of an object at which it is farthest from the sun.

        The opposite case is called the perihelion.

        ", + "related": [ + "perihelion" + ] + }, + "perihelion": { + "title": "Perihelion", + "html": "

        The perihelion is the point in the orbit of an object at which it is closest to the sun.

        The opposite case is called the aphelion.

        ", + "related": [ + "aphelion" + ] + }, + "moid": { + "title": "MOID", + "html": "
        Minimum Orbit Intersection Distance

        The MOID is the minimum distance between the orbits of two objects. It indicates the closest possible approach of two objects to each other.

        For Earth, an object with a MOID of less than or equal to 0.05 AU is considered a possible Potentially Hazardous Object if it's large enough.

        ", + "related": [ + "au", + "pho" + ] + }, + "oumuamua": { + "title": "Oumuamua", + "html": "
        First interstellar object

        Discovered on October 19, 2017, Oumuamua is unlike any asteroid previously observed.

        Although we don’t have a picture, its unusually shiny surface reflects sunlight with a variation factor of 10. This suggest a severely elongated shape, 5 to 10 times larger than its width. Along with its rapid speed and high eccentricity, it was determined to be of interstellar origin.

        Passing Earth on October 14, 2017 at approximately 0.1618 AU, Oumuamua is now exiting our solar system, unlikely to ever return.

        ", + "related": [ + "au" + ] + }, + "au": { + "title": "AU", + "html": "
        Astronomical Unit

        An AU is defined as exactly 92,955,807.273 miles (149,597,871 kilometers), or roughly the distance between the Earth and the Sun.

        Jupiter orbits at about 5.2 times the Sun-Earth distance, so Jupiter’s distance from the Sun can be expressed as 5.2 AU.

        1 AU is equivalent to 389,174 LDs.

        ", + "related": [ + "moid", + "ld" + ] + }, + "ld": { + "title": "LD", + "html":"
        Lunar Distance

        A lunar distance is defined exactly as 384,398 kilometers (238,854 miles); the average distance between the centers of the Earth and the Moon.

        More technically, it's the length of the semi-major axis of the geocentric lunar orbit.

        1 LD is equivalent to about 0.00257 AU.

        ", + "related": [ + "au" + ] + } +} \ No newline at end of file diff --git a/experiences/asteroids/web/src/data/entity_info.json b/experiences/asteroids/web/src/data/entity_info.json new file mode 100644 index 0000000..fc03d97 --- /dev/null +++ b/experiences/asteroids/web/src/data/entity_info.json @@ -0,0 +1,6823 @@ +{ + "observable_universe": { + "id": "observable_universe", + "displayName": "Observable universe", + "category": "Universe", + "searchable": false + }, + "milky_way": { + "id": "milky_way", + "displayName": "Milky way", + "category": "Galaxy", + "searchable": false + }, + "sun": { + "id": "sun", + "iauName": "Sun", + "category": "Star", + "subcategory": "Yellow Dwarf Star", + "planeEntity": "earth", + "keywords": [ + "star", + "solar system" + ] + }, + "mercury": { + "id": "mercury", + "iauName": "Mercury", + "category": "Planet", + "subcategory": "Terrestrial", + "keywords": [ + "terrestrial planet", + "solar system", + "planets" + ] + }, + "venus": { + "id": "venus", + "iauName": "Venus", + "category": "Planet", + "subcategory": "Terrestrial", + "keywords": [ + "terrestrial planet", + "solar system", + "planets" + ] + }, + "earth": { + "id": "earth", + "iauName": "Earth", + "category": "Planet", + "subcategory": "Terrestrial", + "hasMoons": true, + "planeEntity": "moon", + "keywords": [ + "terrestrial planet", + "solar system", + "planets" + ] + }, + "mars": { + "id": "mars", + "iauName": "Mars", + "category": "Planet", + "subcategory": "Terrestrial", + "hasMoons": true, + "keywords": [ + "terrestrial planet", + "solar system", + "planets" + ] + }, + "jupiter": { + "id": "jupiter", + "iauName": "Jupiter", + "category": "Planet", + "subcategory": "Gas Giant", + "hasMoons": true, + "keywords": [ + "gas giant", + "solar system", + "planets" + ] + }, + "saturn": { + "id": "saturn", + "iauName": "Saturn", + "category": "Planet", + "subcategory": "Gas Giant", + "hasMoons": true, + "keywords": [ + "gas giant", + "solar system", + "planets" + ] + }, + "neptune": { + "id": "neptune", + "iauName": "Neptune", + "category": "Planet", + "subcategory": "Ice Giant", + "hasMoons": true, + "keywords": [ + "ice giant", + "solar system", + "planets" + ] + }, + "uranus": { + "id": "uranus", + "iauName": "Uranus", + "category": "Planet", + "subcategory": "Ice Giant", + "hasMoons": true, + "keywords": [ + "gas giant", + "solar system", + "planets", + "1781" + ] + }, + "134340_pluto": { + "id": "134340_pluto", + "iauName": "134340 Pluto", + "displayName": "Pluto", + "category": "Dwarf Planet", + "keywords": [ + "dwarf planet", + "solar system", + "dwarf planet", + "trans-neptunian object", + "plutoid", + "kuiper belt object", + "plutino", + "synchronous", + "1930" + ] + }, + "134340_pluto_barycenter": { + "id": "134340_pluto_barycenter", + "displayName": "Pluto system", + "hasMoons": true, + "comparisonFeature": false, + "category": "Dwarf Planet", + "subcategory": "Barycenter", + "planeEntity": "134340_pluto", + "forceVisibleEntities": [ + "134340_pluto" + ], + "keywords": [ + "barycenter" + ] + }, + "617_patroclus_barycenter": { + "id": "617_patroclus_barycenter", + "displayName": "Patroclus barycenter", + "category": "Asteroid", + "subcategory": "Barycenter", + "comparisonFeature": false, + "forceVisibleEntities": [ + "617_patroclus", + "menoetius" + ] + }, + "21_lutetia": { + "id": "21_lutetia", + "iauName": "21 Lutetia", + "displayName": "Lutetia", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids", + "Rosetta" + ] + }, + "253_mathilde": { + "id": "253_mathilde", + "iauName": "253 Mathilde", + "displayName": "Mathilde", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "11351_leucus": { + "id": "11351_leucus", + "iauName": "11351 Leucus", + "displayName": "Leucus", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "15094_polymele": { + "id": "15094_polymele", + "iauName": "15094 Polymele", + "displayName": "Polymele", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "21900_orus": { + "id": "21900_orus", + "iauName": "21900 Orus", + "displayName": "Orus", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "3548_eurybates": { + "id": "3548_eurybates", + "iauName": "3548 Eurybates", + "displayName": "Eurybates", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "5535_annefrank": { + "id": "5535_annefrank", + "iauName": "5535 Annefrank", + "displayName": "Annefrank", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "52246_donaldjohanson": { + "id": "52246_donaldjohanson", + "iauName": "52246 Donaldjohanson", + "displayName": "Donaldjohanson", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "617_patroclus": { + "id": "617_patroclus", + "iauName": "617 Patroclus", + "displayName": "Patroclus", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "951_gaspra": { + "id": "951_gaspra", + "iauName": "951 Gaspra", + "displayName": "Gaspra", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "2867_steins": { + "id": "2867_steins", + "iauName": "2867 Steins", + "displayName": "Steins", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "ariel": { + "id": "ariel", + "iauName": "Ariel", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "uranus", + "moons", + "prograde", + "synchronous", + "1851" + ] + }, + "90377_sedna": { + "id": "90377_sedna", + "iauName": "90377 Sedna", + "displayName": "Sedna", + "category": "Dwarf Planet", + "keywords": [ + "dwarf planet", + "asteroids" + ] + }, + "99942_apophis": { + "id": "99942_apophis", + "iauName": "99942 Apophis", + "displayName": "Apophis", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "486958_arrokoth": { + "id": "486958_arrokoth", + "iauName": "486958 Arrokoth", + "displayName": "Arrokoth", + "category": "Asteroid", + "subcategory": "Kuiper Belt Object", + "keywords": [ + "mu69", + "asteroid", + "asteroids", + "tno", + "cubewano", + "distant minor planet", + "pt1", + "1110113y", + "ultima thule", + "2014", + "kuiper belt object" + ] + }, + "101955_bennu": { + "id": "101955_bennu", + "iauName": "101955 Bennu", + "displayName": "Bennu", + "category": "Asteroid", + "subcategory": "B-Type Asteroid", + "keywords": [ + "asteroid", + "asteroids", + "apollo", + "neo", + "pha", + "1999 rq36", + "1999", + "b-type" + ] + }, + "152830_dinkinesh": { + "id": "152830_dinkinesh", + "iauName": "152830 Dinkinesh", + "displayName": "Dinkinesh", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "16_psyche": { + "id": "16_psyche", + "iauName": "16 Psyche", + "displayName": "16 Psyche", + "category": "Asteroid", + "subcategory": "M-Type Asteroid", + "keywords": [ + "asteroid", + "asteroids", + "m-type" + ] + }, + "1_ceres": { + "id": "1_ceres", + "iauName": "1 Ceres", + "displayName": "Ceres", + "category": "Dwarf Planet", + "keywords": [ + "dwarf planet", + "asteroids", + "asteroid belt", + "a899 of", + "1943 xb", + "1801" + ] + }, + "2_pallas": { + "id": "2_pallas", + "iauName": "2 Pallas", + "displayName": "Pallas", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "3_juno": { + "id": "3_juno", + "iauName": "3 Juno", + "displayName": "Juno", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "216_kleopatra": { + "id": "216_kleopatra", + "iauName": "216 Kleopatra", + "displayName": "Kleopatra", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "243_ida": { + "id": "243_ida", + "iauName": "243 Ida", + "displayName": "Ida", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ], + "hasMoons": true + }, + "1566_icarus": { + "id": "1566_icarus", + "iauName": "1566 Icarus", + "displayName": "Icarus", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "1620_geographos": { + "id": "1620_geographos", + "iauName": "1620 Geographos", + "displayName": "Geographos", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "1862_apollo": { + "id": "1862_apollo", + "iauName": "1862 Apollo", + "displayName": "Apollo", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "1981_midas": { + "id": "1981_midas", + "iauName": "1981 Midas", + "displayName": "Midas", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "2063_bacchus": { + "id": "2063_bacchus", + "iauName": "2063 Bacchus", + "displayName": "Bacchus", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "2101_adonis": { + "id": "2101_adonis", + "iauName": "2101 Adonis", + "displayName": "Adonis", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "2102_tantalus": { + "id": "2102_tantalus", + "iauName": "2102 Tantalus", + "displayName": "Tantalus", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "2135_aristaeus": { + "id": "2135_aristaeus", + "iauName": "2135 Aristaeus", + "displayName": "Aristaeus", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "2340_hathor": { + "id": "2340_hathor", + "iauName": "2340 Hathor", + "displayName": "Hathor", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "3122_florence": { + "id": "3122_florence", + "iauName": "3122 Florence", + "displayName": "Florence", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "3200_phaethon": { + "id": "3200_phaethon", + "iauName": "3200 Phaethon", + "displayName": "Phaethon", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "3362_khufu": { + "id": "3362_khufu", + "iauName": "3362 Khufu", + "displayName": "Khufu", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "4015_wilson-harrington": { + "id": "4015_wilson-harrington", + "iauName": "4015 Wilson-Harrington", + "displayName": "Wilson-Harrington", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "4179_toutatis": { + "id": "4179_toutatis", + "iauName": "4179 Toutatis", + "displayName": "Toutatis", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "4183_cuno": { + "id": "4183_cuno", + "iauName": "4183 Cuno", + "displayName": "Cuno", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "4450_pan": { + "id": "4450_pan", + "iauName": "4450 Pan", + "displayName": "Pan", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids", + "minor moon", + "saturn" + ] + }, + "4486_mithra": { + "id": "4486_mithra", + "iauName": "4486 Mithra", + "displayName": "Mithra", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "4769_castalia": { + "id": "4769_castalia", + "iauName": "4769 Castalia", + "displayName": "Castalia", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "5011_ptah": { + "id": "5011_ptah", + "iauName": "5011 Ptah", + "displayName": "Ptah", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "6239_minos": { + "id": "6239_minos", + "iauName": "6239 Minos", + "displayName": "Minos", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "6489_golevka": { + "id": "6489_golevka", + "iauName": "6489 Golevka", + "displayName": "Golevka", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "9969_braille": { + "id": "9969_braille", + "iauName": "9969 Braille", + "displayName": "Braille", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "12923_zephyr": { + "id": "12923_zephyr", + "iauName": "12923 Zephyr", + "displayName": "Zephyr", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "14827_hypnos": { + "id": "14827_hypnos", + "iauName": "14827 Hypnos", + "displayName": "Hypnos", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "25143_itokawa": { + "id": "25143_itokawa", + "iauName": "25143 Itokawa", + "displayName": "Itokawa", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "37655_illapa": { + "id": "37655_illapa", + "iauName": "37655 Illapa", + "displayName": "Illapa", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "65803_didymos": { + "id": "65803_didymos", + "iauName": "65803 Didymos", + "displayName": "Didymos", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ], + "hasMoons": true + }, + "69230_hermes": { + "id": "69230_hermes", + "iauName": "69230 Hermes", + "displayName": "Hermes", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids" + ] + }, + "136199_eris": { + "id": "136199_eris", + "iauName": "136199 Eris", + "displayName": "Eris", + "category": "Dwarf Planet", + "keywords": [ + "asteroid", + "asteroids", + "dwarf planet", + "tno", + "plutoid", + "sdo", + "binary", + "dysnomia", + "2005" + ] + }, + "136108_haumea": { + "id": "136108_haumea", + "iauName": "136108 Haumea", + "displayName": "Haumea", + "category": "Dwarf Planet", + "keywords": [ + "asteroid", + "asteroids", + "dwarf planet", + "plutoid", + "tno", + "cubewano", + "trinary", + "2003 el61", + "2004" + ], + "hasMoons": true + }, + "136472_makemake": { + "id": "136472_makemake", + "iauName": "136472 Makemake", + "displayName": "Makemake", + "category": "Dwarf Planet", + "keywords": [ + "asteroid", + "asteroids", + "dwarf planet", + "cubewano", + "scattered-near", + "kuiper belt", + "2005 fy9", + "2005" + ] + }, + "162173_ryugu": { + "id": "162173_ryugu", + "iauName": "162173 Ryugu", + "displayName": "Ryugu", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids", + "neo", + "pha", + "b-type", + "c-type" + ] + }, + "4_vesta": { + "id": "4_vesta", + "iauName": "4 Vesta", + "displayName": "Vesta", + "category": "Asteroid", + "subcategory": "Protoplanet", + "keywords": [ + "asteroid", + "asteroids", + "main belt", + "vesta family", + "1807", + "protoplanet" + ] + }, + "433_eros": { + "id": "433_eros", + "iauName": "433 Eros", + "displayName": "Eros", + "category": "Asteroid", + "subcategory": "S-Type Asteroid", + "keywords": [ + "asteroid", + "asteroids", + "neo", + "1898", + "prograde" + ] + }, + "callisto": { + "id": "callisto", + "iauName": "Callisto", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "jupiter", + "moons", + "main group", + "galilean moons", + "prograde", + "synchronous", + "1610" + ] + }, + "sc_chandra": { + "id": "sc_chandra", + "iauName": "Chandra X-ray Observatory", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "telescope", + "orbiter", + "earth", + "Columbia", + "X-ray", + "astrophysics" + ] + }, + "charon": { + "id": "charon", + "iauName": "Charon", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "pluto", + "moons", + "prograde", + "synchronous", + "1978" + ] + }, + "67p_churyumov_gerasimenko": { + "id": "67p_churyumov_gerasimenko", + "iauName": "67P/Churyumov-Gerasimenko", + "displayName": "67P/Churyumov-Gerasimenko", + "category": "Comet", + "subcategory": "Short-Period Comet", + "keywords": [ + "comet", + "comets", + "jupiter-family", + "1969 r1", + "1969 iv", + "1969h", + "1975 p1", + "1976 vii", + "1975i", + "1982 viii", + "1982f", + "1989 vi", + "1988i", + "1969", + "chury", + "short-period" + ] + }, + "1p_halley": { + "id": "1p_halley", + "iauName": "1P/Halley", + "displayName": "Halley", + "category": "Comet", + "subcategory": "Short-Period Comet", + "keywords": [ + "comet", + "comets", + "short-period", + "1p/halley" + ] + }, + "103p_hartley_2": { + "id": "103p_hartley_2", + "iauName": "103P/Hartley", + "displayName": "Hartley 2", + "category": "Comet", + "keywords": [ + "comet" + ] + }, + "1i_oumuamua": { + "id": "1i_oumuamua", + "iauName":"1I/'Oumuamua", + "displayName": "Oumuamua", + "category": "Comet", + "keywords": [ + "comet", + "comets", + "1i/oumuamua" + ] + }, + "9p_tempel_1": { + "id": "9p_tempel_1", + "iauName": "9P/Tempel 1", + "displayName": "Tempel 1", + "category": "Comet", + "subcategory": "Jupiter-Family Comet", + "keywords": [ + "comet", + "comets", + "periodic", + "jupiter-family", + "9p/tempel", + "1867" + ] + }, + "19p_borrelly": { + "id": "19p_borrelly", + "iauName": "19P/Borrelly", + "displayName": "Borrelly", + "category": "Comet", + "subcategory": "Jupiter-Family Comet", + "keywords": [ + "comet", + "comets", + "periodic", + "jupiter-family", + "19p/borrelly", + "Deep Space 1" + ] + }, + "81p_wild_2": { + "id": "81p_wild_2", + "iauName": "81P/Wild 2", + "displayName": "Wild 2", + "category": "Comet", + "subcategory": "Short-Period Comet", + "keywords": [ + "comet", + "comets", + "81p/wild", + "1978 xi", + "1984 xiv", + "1990 xxviii", + "1978" + ] + }, + "adrastea": { + "id": "adrastea", + "iauName": "Adrastea", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "aegaeon": { + "id": "aegaeon", + "iauName": "Aegaeon", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "aegir": { + "id": "aegir", + "iauName": "Aegir", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "aitne": { + "id": "aitne", + "iauName": "Aitne", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "albiorix": { + "id": "albiorix", + "iauName": "Albiorix", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "amalthea": { + "id": "amalthea", + "iauName": "Amalthea", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "ananke": { + "id": "ananke", + "iauName": "Ananke", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "anthe": { + "id": "anthe", + "iauName": "Anthe", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "aoede": { + "id": "aoede", + "iauName": "Aoede", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "arche": { + "id": "arche", + "iauName": "Arche", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "atlas": { + "id": "atlas", + "iauName": "Atlas", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "autonoe": { + "id": "autonoe", + "iauName": "Autonoe", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "bebhionn": { + "id": "bebhionn", + "iauName": "Bebhionn", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "belinda": { + "id": "belinda", + "iauName": "Belinda", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "bergelmir": { + "id": "bergelmir", + "iauName": "Bergelmir", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "bestla": { + "id": "bestla", + "iauName": "Bestla", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "bianca": { + "id": "bianca", + "iauName": "Bianca", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "c_2010_x1": { + "id": "c_2010_x1", + "iauName": "C/2010 X1", + "displayName": "Elenin", + "category": "Comet", + "keywords": [ + "comet" + ] + }, + "c_2012_s1": { + "id": "c_2012_s1", + "iauName": "C/2012 S1", + "displayName": "ISON", + "category": "Comet", + "keywords": [ + "comet" + ] + }, + "caliban": { + "id": "caliban", + "iauName": "Caliban", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "callirrhoe": { + "id": "callirrhoe", + "iauName": "Callirrhoe", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "calypso": { + "id": "calypso", + "iauName": "Calypso", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "carme": { + "id": "carme", + "iauName": "Carme", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "carpo": { + "id": "carpo", + "iauName": "Carpo", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "chaldene": { + "id": "chaldene", + "iauName": "Chaldene", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "cordelia": { + "id": "cordelia", + "iauName": "Cordelia", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "cressida": { + "id": "cressida", + "iauName": "Cressida", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "cupid": { + "id": "cupid", + "iauName": "Cupid", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "cyllene": { + "id": "cyllene", + "iauName": "Cyllene", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "dactyl": { + "id": "dactyl", + "iauName": "243 Ida I Dactyl", + "displayName": "Dactyl", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "asteroid", + "minor moon", + "ida" + ] + }, + "daphnis": { + "id": "daphnis", + "iauName": "Daphnis", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "deimos": { + "id": "deimos", + "iauName": "Deimos", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "mars", + "moons", + "synchronous", + "1877" + ] + }, + "desdemona": { + "id": "desdemona", + "iauName": "Desdemona", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "despina": { + "id": "despina", + "iauName": "Despina", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "dia": { + "id": "dia", + "iauName": "Dia", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "dimorphos": { + "id": "dimorphos", + "iauName": "Dimorphos", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "minor moon", + "solar system", + "65803 Didymos", + "asteroid" + ] + }, + "dione": { + "id": "dione", + "iauName": "Dione", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "saturn", + "moons", + "inner moons", + "prograde", + "synchronous", + "1684" + ] + }, + "sc_dscovr": { + "id": "sc_dscovr", + "iauName": "DSCOVR", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "earth", + "orbiter", + "Deep Space Climate Observatory" + ] + }, + "eirene": { + "id": "eirene", + "iauName": "Eirene", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "elara": { + "id": "elara", + "iauName": "Elara", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "enceladus": { + "id": "enceladus", + "iauName": "Enceladus", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "saturn", + "moons", + "inner moons", + "prograde", + "synchronous", + "1789" + ] + }, + "epimetheus": { + "id": "epimetheus", + "iauName": "Epimetheus", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "erinome": { + "id": "erinome", + "iauName": "Erinome", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "erriapus": { + "id": "erriapus", + "iauName": "Erriapus", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "ersa": { + "id": "ersa", + "iauName": "Ersa", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "euanthe": { + "id": "euanthe", + "iauName": "Euanthe", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "eukelade": { + "id": "eukelade", + "iauName": "Eukelade", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "eupheme": { + "id": "eupheme", + "iauName": "Eupheme", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "euporie": { + "id": "euporie", + "iauName": "Euporie", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "europa": { + "id": "europa", + "iauName": "Europa", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "jupiter", + "moons", + "main group", + "galilean moons", + "prograde", + "synchronous", + "1610" + ], + "ignoreDependentWhenUnloading": [ + "sc_juno" + ] + }, + "eurydome": { + "id": "eurydome", + "iauName": "Eurydome", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "farbauti": { + "id": "farbauti", + "iauName": "Farbauti", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "fenrir": { + "id": "fenrir", + "iauName": "Fenrir", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "galatea": { + "id": "galatea", + "iauName": "Galatea", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "ganymede": { + "id": "ganymede", + "iauName": "Ganymede", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "jupiter", + "moons", + "main group", + "galilean moons", + "prograde", + "synchronous", + "1610" + ], + "ignoreDependentWhenUnloading": [ + "sc_juno" + ] + }, + "greip": { + "id": "greip", + "iauName": "Greip", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "c_1995_o1": { + "id": "c_1995_o1", + "iauName": "C/1995 O1", + "displayName": "Hale-Bopp", + "category": "Comet", + "subcategory": "Long-Period Comet", + "keywords": [ + "comet", + "solar system", + "The Great Comet of 1997", + "C/1995 O1", + "1995" + ] + }, + "ferdinand": { + "id": "ferdinand", + "iauName": "Ferdinand", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "fornjot": { + "id": "fornjot", + "iauName": "Fornjot", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "francisco": { + "id": "francisco", + "iauName": "Francisco", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "halimede": { + "id": "halimede", + "iauName": "Halimede", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "harpalyke": { + "id": "harpalyke", + "iauName": "Harpalyke", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "hati": { + "id": "hati", + "iauName": "Hati", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "hegemone": { + "id": "hegemone", + "iauName": "Hegemone", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "helene": { + "id": "helene", + "iauName": "Helene", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "helike": { + "id": "helike", + "iauName": "Helike", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "hermippe": { + "id": "hermippe", + "iauName": "Hermippe", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "herse": { + "id": "herse", + "iauName": "Herse", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "hiiaka": { + "id": "hiiaka", + "iauName":"Hi'iaka", + "displayName":"Hi'iaka", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "asteroid", + "minor moon", + "haumea" + ] + }, + "himalia": { + "id": "himalia", + "iauName": "Himalia", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "hippocamp": { + "id": "hippocamp", + "iauName": "Hippocamp", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "hydra": { + "id": "hydra", + "iauName": "Hydra", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "pluto", + "moons", + "outer moons" + ] + }, + "hyperion": { + "id": "hyperion", + "iauName": "Hyperion", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "outer moons", + "prograde", + "1848" + ] + }, + "hyrrokkin": { + "id": "hyrrokkin", + "iauName": "Hyrrokkin", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "iapetus": { + "id": "iapetus", + "iauName": "Iapetus", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "saturn", + "moons", + "outer moons", + "prograde", + "synchronous", + "1671" + ] + }, + "io": { + "id": "io", + "iauName": "Io", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "jupiter", + "moons", + "main group", + "galilean moons", + "prograde", + "synchronous", + "1610" + ], + "ignoreDependentWhenUnloading": [ + "sc_juno" + ] + }, + "ijiraq": { + "id": "ijiraq", + "iauName": "Ijiraq", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "iocaste": { + "id": "iocaste", + "iauName": "Iocaste", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "isonoe": { + "id": "isonoe", + "iauName": "Isonoe", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "janus": { + "id": "janus", + "iauName": "Janus", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "jarnsaxa": { + "id": "jarnsaxa", + "iauName": "Jarnsaxa", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "juliet": { + "id": "juliet", + "iauName": "Juliet", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "jupiter_li": { + "id": "jupiter_li", + "iauName": "Jupiter LI", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lii": { + "id": "jupiter_lii", + "iauName": "Jupiter LII", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_liv": { + "id": "jupiter_liv", + "iauName": "Jupiter LIV", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lix": { + "id": "jupiter_lix", + "iauName": "Jupiter LIX", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lv": { + "id": "jupiter_lv", + "iauName": "Jupiter LV", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lvi": { + "id": "jupiter_lvi", + "iauName": "Jupiter LVI", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lxi": { + "id": "jupiter_lxi", + "iauName": "Jupiter LXI", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lxiii": { + "id": "jupiter_lxiii", + "iauName": "Jupiter LXIII", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lxiv": { + "id": "jupiter_lxiv", + "iauName": "Jupiter LXIV", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lxix": { + "id": "jupiter_lxix", + "iauName": "Jupiter LXIX", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lxvi": { + "id": "jupiter_lxvi", + "iauName": "Jupiter LXVI", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lxvii": { + "id": "jupiter_lxvii", + "iauName": "Jupiter LXVI", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lxviii": { + "id": "jupiter_lxviii", + "iauName": "Jupiter LXVIII", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lxx": { + "id": "jupiter_lxx", + "iauName": "Jupiter LXX", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "jupiter_lxxii": { + "id": "jupiter_lxxii", + "iauName": "Jupiter LXXII", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "kale": { + "id": "kale", + "iauName": "Kale", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "kallichore": { + "id": "kallichore", + "iauName": "Kallichore", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "kalyke": { + "id": "kalyke", + "iauName": "Kalyke", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "kari": { + "id": "kari", + "iauName": "Kari", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "kerberos": { + "id": "kerberos", + "iauName": "Kerberos", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "pluto", + "moons" + ] + }, + "kiviuq": { + "id": "kiviuq", + "iauName": "Kiviuq", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "kore": { + "id": "kore", + "iauName": "Kore", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "laomedeia": { + "id": "laomedeia", + "iauName": "Laomedeia", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "larissa": { + "id": "larissa", + "iauName": "Larissa", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "leda": { + "id": "leda", + "iauName": "Leda", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "loge": { + "id": "loge", + "iauName": "Loge", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "lysithea": { + "id": "lysithea", + "iauName": "Lysithea", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "mab": { + "id": "mab", + "iauName": "Mab", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "margaret": { + "id": "margaret", + "iauName": "Margaret", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "megaclite": { + "id": "megaclite", + "iauName": "Megaclite", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons", + "jupiter xix", + "S/2000 J 8" + ] + }, + "menoetius": { + "id": "menoetius", + "iauName": "Menoetius", + "displayName": "Menoetius", + "category": "Asteroid", + "keywords": [ + "asteroid", + "asteroids", + "solar system", + "617 Patroclus" + ] + }, + "methone": { + "id": "methone", + "iauName": "Methone", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "metis": { + "id": "metis", + "iauName": "Metis", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "mimas": { + "id": "mimas", + "iauName": "Mimas", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "saturn", + "moons", + "inner moons", + "prograde", + "synchronous", + "1789", + "death star" + ] + }, + "miranda": { + "id": "miranda", + "iauName": "Miranda", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "uranus", + "moons", + "prograde", + "synchronous", + "1948" + ] + }, + "mneme": { + "id": "mneme", + "iauName": "Mneme", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "moon": { + "id": "moon", + "iauName": "Moon", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "earth", + "moons", + "synchronous" + ] + }, + "mundilfari": { + "id": "mundilfari", + "iauName": "Mundilfari", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "naiad": { + "id": "naiad", + "iauName": "Naiad", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "namaka": { + "id": "namaka", + "iauName": "Namaka", + "displayName": "Namaka", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "asteroid", + "minor moon", + "haumea" + ] + }, + "narvi": { + "id": "narvi", + "iauName": "Narvi", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "nix": { + "id": "nix", + "iauName": "Nix", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "pluto", + "moons" + ] + }, + "nereid": { + "id": "nereid", + "iauName": "Nereid", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons", + "irregular moons", + "prograde", + "1949" + ] + }, + "neso": { + "id": "neso", + "iauName": "Neso", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "oberon": { + "id": "oberon", + "iauName": "Oberon", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "uranus", + "moons", + "prograde", + "synchronous", + "1787" + ] + }, + "ophelia": { + "id": "ophelia", + "iauName": "Ophelia", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "orthosie": { + "id": "orthosie", + "iauName": "Orthosie", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "paaliaq": { + "id": "paaliaq", + "iauName": "Paaliaq", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "pallene": { + "id": "pallene", + "iauName": "Pallene", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "pan": { + "id": "pan", + "iauName": "Pan", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "pandia": { + "id": "pandia", + "iauName": "Pandia", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "pandora": { + "id": "pandora", + "iauName": "Pandora", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "pasiphae": { + "id": "pasiphae", + "iauName": "Pasiphae", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "pasithee": { + "id": "pasithee", + "iauName": "Pasithee", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "perdita": { + "id": "perdita", + "iauName": "Perdita", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "philophrosyne": { + "id": "philophrosyne", + "iauName": "Philophrosyne", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "phobos": { + "id": "phobos", + "iauName": "Phobos", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "mars", + "moons", + "synchronous", + "1877" + ] + }, + "phoebe": { + "id": "phoebe", + "iauName": "Phoebe", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "norse group", + "retrograde", + "1899" + ] + }, + "polydeuces": { + "id": "polydeuces", + "iauName": "Polydeuces", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "portia": { + "id": "portia", + "iauName": "Portia", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "praxidike": { + "id": "praxidike", + "iauName": "Praxidike", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "prometheus": { + "id": "prometheus", + "iauName": "Prometheus", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "prospero": { + "id": "prospero", + "iauName": "Prospero", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "proteus": { + "id": "proteus", + "iauName": "Proteus", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons", + "regular moons", + "prograde", + "synchronous", + "1989" + ] + }, + "psamathe": { + "id": "psamathe", + "iauName": "Psamathe", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "puck": { + "id": "puck", + "iauName": "Puck", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "rhea": { + "id": "rhea", + "iauName": "Rhea", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "saturn", + "moons", + "outer moons", + "prograde", + "synchronous", + "1672" + ] + }, + "rosalind": { + "id": "rosalind", + "iauName": "Rosalind", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "s_2003_j_10": { + "id": "s_2003_j_10", + "iauName": "S/2003 J 10", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2003_j_12": { + "id": "s_2003_j_12", + "iauName": "S/2003 J 12", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2003_j_16": { + "id": "s_2003_j_16", + "iauName": "S/2003 J 16", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2003_j_2": { + "id": "s_2003_j_2", + "iauName": "S/2003 J 2", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2003_j_23": { + "id": "s_2003_j_23", + "iauName": "S/2003 J 23", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2003_j_24": { + "id": "s_2003_j_24", + "iauName": "S/2003 J 24", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2003_j_4": { + "id": "s_2003_j_4", + "iauName": "S/2003 J 4", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2003_j_9": { + "id": "s_2003_j_9", + "iauName": "S/2003 J 9", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2004_s_7": { + "id": "s_2004_s_7", + "iauName": "S/2004 S 7", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_12": { + "id": "s_2004_s_12", + "iauName": "S/2004 S 12", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_13": { + "id": "s_2004_s_13", + "iauName": "S/2004 S 13", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_17": { + "id": "s_2004_s_17", + "iauName": "S/2004 S 17", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_21": { + "id": "s_2004_s_21", + "iauName": "S/2004 S 21", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_24": { + "id": "s_2004_s_24", + "iauName": "S/2004 S 24", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_28": { + "id": "s_2004_s_28", + "iauName": "S/2004 S 28", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_31": { + "id": "s_2004_s_31", + "iauName": "S/2004 S 31", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_36": { + "id": "s_2004_s_36", + "iauName": "S/2004 S 36", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_37": { + "id": "s_2004_s_37", + "iauName": "S/2004 S 37", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_39": { + "id": "s_2004_s_39", + "iauName": "S/2004 S 39", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_40": { + "id": "s_2004_s_40", + "iauName": "S/2004 S 40", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_41": { + "id": "s_2004_s_41", + "iauName": "S/2004 S 41", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_42": { + "id": "s_2004_s_42", + "iauName": "S/2004 S 42", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_43": { + "id": "s_2004_s_43", + "iauName": "S/2004 S 43", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_44": { + "id": "s_2004_s_44", + "iauName": "S/2004 S 44", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_45": { + "id": "s_2004_s_45", + "iauName": "S/2004 S 45", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_46": { + "id": "s_2004_s_46", + "iauName": "S/2004 S 46", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_47": { + "id": "s_2004_s_47", + "iauName": "S/2004 S 47", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_48": { + "id": "s_2004_s_48", + "iauName": "S/2004 S 48", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_49": { + "id": "s_2004_s_49", + "iauName": "S/2004 S 49", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_50": { + "id": "s_2004_s_50", + "iauName": "S/2004 S 50", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_51": { + "id": "s_2004_s_51", + "iauName": "S/2004 S 51", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_52": { + "id": "s_2004_s_52", + "iauName": "S/2004 S 52", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2004_s_53": { + "id": "s_2004_s_53", + "iauName": "S/2004 S 53", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2005_s_4": { + "id": "s_2005_s_4", + "iauName": "S/2005 S 4", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2005_s_5": { + "id": "s_2005_s_5", + "iauName": "S/2005 S 5", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_1": { + "id": "s_2006_s_1", + "iauName": "S/2006 S 1", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_10": { + "id": "s_2006_s_10", + "iauName": "S/2006 S 10", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_11": { + "id": "s_2006_s_11", + "iauName": "S/2006 S 11", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_12": { + "id": "s_2006_s_12", + "iauName": "S/2006 S 12", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_13": { + "id": "s_2006_s_13", + "iauName": "S/2006 S 13", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_14": { + "id": "s_2006_s_14", + "iauName": "S/2006 S 14", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_15": { + "id": "s_2006_s_15", + "iauName": "S/2006 S 15", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_16": { + "id": "s_2006_s_16", + "iauName": "S/2006 S 16", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_17": { + "id": "s_2006_s_17", + "iauName": "S/2006 S 17", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_18": { + "id": "s_2006_s_18", + "iauName": "S/2006 S 18", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_19": { + "id": "s_2006_s_19", + "iauName": "S/2006 S 19", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_20": { + "id": "s_2006_s_20", + "iauName": "S/2006 S 20", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_3": { + "id": "s_2006_s_3", + "iauName": "S/2006 S 3", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2006_s_9": { + "id": "s_2006_s_9", + "iauName": "S/2006 S 9", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2007_s_2": { + "id": "s_2007_s_2", + "iauName": "S/2007 S 2", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2007_s_3": { + "id": "s_2007_s_3", + "iauName": "S/2007 S 3", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2007_s_5": { + "id": "s_2007_s_5", + "iauName": "S/2007 S 5", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2007_s_6": { + "id": "s_2007_s_6", + "iauName": "S/2007 S 6", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2007_s_7": { + "id": "s_2007_s_7", + "iauName": "S/2007 S 7", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2007_s_8": { + "id": "s_2007_s_8", + "iauName": "S/2007 S 8", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2007_s_9": { + "id": "s_2007_s_9", + "iauName": "S/2007 S 9", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2009_s_1": { + "id": "s_2009_s_1", + "iauName": "S/2009 S 1", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2011_j_3": { + "id": "s_2011_j_3", + "iauName": "S/2011 J 3", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2016_j_3": { + "id": "s_2016_j_3", + "iauName": "S/2016 J 3", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2016_j_4": { + "id": "s_2016_j_4", + "iauName": "S/2016 J 4", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2018_j_2": { + "id": "s_2018_j_2", + "iauName": "S/2018 J 2", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2018_j_3": { + "id": "s_2018_j_3", + "iauName": "S/2018 J 3", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2018_j_4": { + "id": "s_2018_j_4", + "iauName": "S/2018 J 4", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2019_s_1": { + "id": "s_2019_s_1", + "iauName": "S/2019 S 1", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_10": { + "id": "s_2019_s_10", + "iauName": "S/2019 S 10", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_11": { + "id": "s_2019_s_11", + "iauName": "S/2019 S 11", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_12": { + "id": "s_2019_s_12", + "iauName": "S/2019 S 12", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_13": { + "id": "s_2019_s_13", + "iauName": "S/2019 S 13", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_14": { + "id": "s_2019_s_14", + "iauName": "S/2019 S 14", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_15": { + "id": "s_2019_s_15", + "iauName": "S/2019 S 15", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_16": { + "id": "s_2019_s_16", + "iauName": "S/2019 S 16", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_17": { + "id": "s_2019_s_17", + "iauName": "S/2019 S 17", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_18": { + "id": "s_2019_s_18", + "iauName": "S/2019 S 18", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_19": { + "id": "s_2019_s_19", + "iauName": "S/2019 S 19", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_2": { + "id": "s_2019_s_2", + "iauName": "S/2019 S 2", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_20": { + "id": "s_2019_s_20", + "iauName": "S/2019 S 20", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_21": { + "id": "s_2019_s_21", + "iauName": "S/2019 S 21", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_3": { + "id": "s_2019_s_3", + "iauName": "S/2019 S 3", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_4": { + "id": "s_2019_s_4", + "iauName": "S/2019 S 4", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_5": { + "id": "s_2019_s_5", + "iauName": "S/2019 S 5", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_6": { + "id": "s_2019_s_6", + "iauName": "S/2019 S 6", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_7": { + "id": "s_2019_s_7", + "iauName": "S/2019 S 7", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_8": { + "id": "s_2019_s_8", + "iauName": "S/2019 S 8", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2019_s_9": { + "id": "s_2019_s_9", + "iauName": "S/2019 S 9", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2020_s_1": { + "id": "s_2020_s_1", + "iauName": "S/2020 S 1", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2020_s_10": { + "id": "s_2020_s_10", + "iauName": "S/2020 S 10", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2020_s_2": { + "id": "s_2020_s_2", + "iauName": "S/2020 S 2", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2020_s_3": { + "id": "s_2020_s_3", + "iauName": "S/2020 S 3", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2020_s_4": { + "id": "s_2020_s_4", + "iauName": "S/2020 S 4", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2020_s_5": { + "id": "s_2020_s_5", + "iauName": "S/2020 S 5", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2020_s_6": { + "id": "s_2020_s_6", + "iauName": "S/2020 S 6", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2020_s_7": { + "id": "s_2020_s_7", + "iauName": "S/2020 S 7", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2020_s_8": { + "id": "s_2020_s_8", + "iauName": "S/2020 S 8", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2020_s_9": { + "id": "s_2020_s_9", + "iauName": "S/2020 S 9", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "s_2021_j_1": { + "id": "s_2021_j_1", + "iauName": "S/2021 J 1", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2021_j_2": { + "id": "s_2021_j_2", + "iauName": "S/2021 J 2", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2021_j_3": { + "id": "s_2021_j_3", + "iauName": "S/2021 J 3", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2021_j_4": { + "id": "s_2021_j_4", + "iauName": "S/2021 J 4", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2021_j_5": { + "id": "s_2021_j_5", + "iauName": "S/2021 J 5", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2021_j_6": { + "id": "s_2021_j_6", + "iauName": "S/2021 J 6", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2022_j_1": { + "id": "s_2022_j_1", + "iauName": "S/2022 J 1", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2022_j_2": { + "id": "s_2022_j_2", + "iauName": "S/2022 J 2", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "s_2022_j_3": { + "id": "s_2022_j_3", + "iauName": "S/2022 J 3", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "sao": { + "id": "sao", + "iauName": "Sao", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "gridr": { + "id": "gridr", + "iauName": "Gridr", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "S/2004 S20", + "saturn liv" + ] + }, + "angrboda": { + "id": "angrboda", + "iauName": "Angrboda", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "S/2004 S22", + "saturn lv" + ] + }, + "skrymir": { + "id": "skrymir", + "iauName": "Skrymir", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "S/2004 S23", + "saturn lvi" + ] + }, + "gerd": { + "id": "gerd", + "iauName": "Gerd", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "S/2004 S25", + "saturn lvii" + ] + }, + "saturn_lviii": { + "id": "saturn_lviii", + "iauName": "Saturn LVIII", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "eggther": { + "id": "eggther", + "iauName": "Eggther", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "S/2004 S27", + "saturn lix" + ] + }, + "saturn_lx": { + "id": "saturn_lx", + "iauName": "Saturn LX", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "beli": { + "id": "beli", + "iauName": "Beli", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "S/2004 S30", + "saturn lxi" + ] + }, + "gunnlod": { + "id": "gunnlod", + "iauName": "Gunnlod", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "S/2004 S32", + "saturn lxii" + ] + }, + "thiazzi": { + "id": "thiazzi", + "iauName": "Thiazzi", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "S/2004 S33", + "saturn lxiii" + ] + }, + "saturn_lxiv": { + "id": "saturn_lxiv", + "iauName": "Saturn LXIV", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "alvaldi": { + "id": "alvaldi", + "iauName": "Alvaldi", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "S/2004 S35", + "saturn lxv" + ] + }, + "geirrod": { + "id": "geirrod", + "iauName": "Geirrod", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons", + "S/2004 S38", + "saturn lxvi" + ] + }, + "setebos": { + "id": "setebos", + "iauName": "Setebos", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "siarnaq": { + "id": "siarnaq", + "iauName": "Siarnaq", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "sinope": { + "id": "sinope", + "iauName": "Sinope", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "skathi": { + "id": "skathi", + "iauName": "Skathi", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "skoll": { + "id": "skoll", + "iauName": "Skoll", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "sponde": { + "id": "sponde", + "iauName": "Sponde", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "stephano": { + "id": "stephano", + "iauName": "Stephano", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "styx": { + "id": "styx", + "iauName": "Styx", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "pluto", + "moons" + ] + }, + "surtur": { + "id": "surtur", + "iauName": "Surtur", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "suttungr": { + "id": "suttungr", + "iauName": "Suttungr", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "sycorax": { + "id": "sycorax", + "iauName": "Sycorax", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "tarqeq": { + "id": "tarqeq", + "iauName": "Tarqeq", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "tarvos": { + "id": "tarvos", + "iauName": "Tarvos", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "taygete": { + "id": "taygete", + "iauName": "Taygete", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "telesto": { + "id": "telesto", + "iauName": "Telesto", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "tethys": { + "id": "tethys", + "iauName": "Tethys", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "saturn", + "moons", + "inner moons", + "prograde", + "synchronous", + "1684" + ] + }, + "thalassa": { + "id": "thalassa", + "iauName": "Thalassa", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "neptune", + "moons" + ] + }, + "thebe": { + "id": "thebe", + "iauName": "Thebe", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "thelxinoe": { + "id": "thelxinoe", + "iauName": "Thelxinoe", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "themisto": { + "id": "themisto", + "iauName": "Themisto", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "thrymr": { + "id": "thrymr", + "iauName": "Thrymr", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "thyone": { + "id": "thyone", + "iauName": "Thyone", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "titan": { + "id": "titan", + "iauName": "Titan", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "saturn", + "moons", + "outer moons", + "prograde", + "synchronous", + "1655" + ] + }, + "titania": { + "id": "titania", + "iauName": "Titania", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "uranus", + "moons", + "prograde", + "synchronous", + "1787" + ] + }, + "trinculo": { + "id": "trinculo", + "iauName": "Trinculo", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "uranus", + "moons" + ] + }, + "triton": { + "id": "triton", + "iauName": "Triton", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "neptune", + "moons", + "irregular moons", + "retrograde", + "synchronous", + "1846" + ] + }, + "umbriel": { + "id": "umbriel", + "iauName": "Umbriel", + "category": "Moon", + "subcategory": "Major Moon", + "keywords": [ + "major moon", + "solar system", + "uranus", + "moons", + "prograde", + "synchronous", + "1851" + ] + }, + "ymir": { + "id": "ymir", + "iauName": "Ymir", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "saturn", + "moons" + ] + }, + "sc_ace": { + "id": "sc_ace", + "iauName": "ACE", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_acrimsat": { + "id": "sc_acrimsat", + "iauName": "ACRIMSAT", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_acs3": { + "id": "sc_acs3", + "iauName": "ACS3", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "disabled": true + }, + "sc_aqua": { + "id": "sc_aqua", + "iauName": "Aqua", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_artemis_1": { + "id": "sc_artemis_1", + "iauName": "Artemis I", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ] + }, + "sc_aura": { + "id": "sc_aura", + "iauName": "Aura", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_biosentinel": { + "id": "sc_biosentinel", + "iauName": "BioSentinel", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ] + }, + "sc_calipso": { + "id": "sc_calipso", + "iauName": "CALIPSO", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_capstone": { + "id": "sc_capstone", + "iauName": "CAPSTONE", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ] + }, + "sc_cassini": { + "id": "sc_cassini", + "iauName": "Cassini", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "saturn" + ], + "hasEvents": true + }, + "sc_clementine": { + "id": "sc_clementine", + "iauName": "Clementine", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ] + }, + "sc_cloudsat": { + "id": "sc_cloudsat", + "iauName": "CloudSat", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cluster_ii_fm5": { + "id": "sc_cluster_ii_fm5", + "iauName": "Rumba", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cluster_ii_fm6": { + "id": "sc_cluster_ii_fm6", + "iauName": "Salsa", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cluster_ii_fm7": { + "id": "sc_cluster_ii_fm7", + "iauName": "Samba", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cluster_ii_fm8": { + "id": "sc_cluster_ii_fm8", + "iauName": "Tango", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cygnss_1": { + "id": "sc_cygnss_1", + "iauName": "CYGNSS 1", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "CYGNSS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cygnss_2": { + "id": "sc_cygnss_2", + "iauName": "CYGNSS 2", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "CYGNSS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cygnss_3": { + "id": "sc_cygnss_3", + "iauName": "CYGNSS 3", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "CYGNSS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cygnss_4": { + "id": "sc_cygnss_4", + "iauName": "CYGNSS 4", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "CYGNSS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cygnss_5": { + "id": "sc_cygnss_5", + "iauName": "CYGNSS 5", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "CYGNSS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cygnss_6": { + "id": "sc_cygnss_6", + "iauName": "CYGNSS 6", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "CYGNSS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cygnss_7": { + "id": "sc_cygnss_7", + "iauName": "CYGNSS 7", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "CYGNSS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_cygnss_8": { + "id": "sc_cygnss_8", + "iauName": "CYGNSS 8", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "CYGNSS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_dart": { + "id": "sc_dart", + "iauName": "DART", + "category": "Spacecraft", + "subcategory": "Impactor", + "altName": "boom", + "keywords": [ + "spacecraft", + "65803_didymos", + "dimorphos", + "asteroid" + ], + "hasEvents": true + }, + "sc_dawn": { + "id": "sc_dawn", + "iauName": "Dawn", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "vesta", + "ceres", + "small body mission" + ], + "related": { + "asteroid": [ + "4_vesta", + "1_ceres" + ] + }, + "hasEvents": true + }, + "sc_deep_impact": { + "id": "sc_deep_impact", + "iauName": "Deep Impact", + "category": "Spacecraft", + "subcategory": "Flyby", + "altName": "DI", + "keywords": [ + "spacecraft", + "tempel 1", + "small body mission" + ], + "related": { + "comet": [ + "9p_temp_1" + ] + }, + "hasEvents": true + }, + "sc_deep_impact_impactor": { + "id": "sc_deep_impact_impactor", + "iauName": "Deep Impact Impactor", + "category": "Spacecraft", + "subcategory": "Impactor", + "altName": "DII", + "keywords": [ + "spacecraft", + "tempel 1", + "small body mission" + ], + "related": { + "comet": [ + "9p_temp_1" + ] + }, + "hasEvents": true + }, + "sc_deep_impact_impactor_impact_site": { + "id": "sc_deep_impact_impactor_impact_site", + "displayName": "Deep Impact Impactor Impact Site", + "category": "Landing site", + "comparisonFeature": false + }, + "sc_deep_space_1": { + "id": "sc_deep_space_1", + "iauName": "Deep Space 1", + "category": "Spacecraft", + "subcategory": "Flyby", + "altName": "DS1", + "keywords": [ + "spacecraft", + "9660 Braille", + "19p/Borrelly", + "small body mission" + ], + "related": { + "asteroid": [ + "9969_braille" + ], + "comet": [ + "19p_borrelly" + ] + }, + "hasEvents": true + }, + "sc_eo_1": { + "id": "sc_eo_1", + "iauName": "EO-1", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "Earth Observing-1", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_euclid": { + "id": "sc_euclid", + "iauName": "Euclid", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter", + "telescope" + ], + "disabled": false + }, + "sc_europa_clipper": { + "id": "sc_europa_clipper", + "iauName": "Europa Clipper", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter", + "europa" + ] + }, + "sc_explorer_1": { + "id": "sc_explorer_1", + "iauName": "Explorer 1", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_galileo": { + "id": "sc_galileo", + "iauName": "Galileo", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "outer planet mission", + "orbiter", + "jupiter" + ], + "hasEvents": true + }, + "sc_galileo_probe": { + "id": "sc_galileo_probe", + "iauName": "Galileo Probe", + "category": "Spacecraft", + "subcategory": "Lander", + "keywords": [ + "spacecraft", + "outer planet mission", + "orbiter", + "jupiter" + ], + "hasEvents": true + }, + "sc_geotail": { + "id": "sc_geotail", + "iauName": "Geotail", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_gpm": { + "id": "sc_gpm", + "iauName": "GPM", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "Global Precipitation Measurement", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_grace_1": { + "id": "sc_grace_1", + "iauName": "GRACE-1", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_grace_2": { + "id": "sc_grace_2", + "iauName": "GRACE-2", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_grace_fo1": { + "id": "sc_grace_fo1", + "iauName": "GRACE-FO1", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "GRACE Follow-On", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_grace_fo2": { + "id": "sc_grace_fo2", + "iauName": "GRACE-FO2", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "GRACE Follow-On", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_grail_a": { + "id": "sc_grail_a", + "iauName": "GRAIL A", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "Ebb", + "keywords": [ + "spacecraft", + "moon", + "orbiter", + "ebb" + ] + }, + "sc_grail_b": { + "id": "sc_grail_b", + "iauName": "GRAIL B", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "Flow", + "keywords": [ + "spacecraft", + "moon", + "orbiter", + "flow" + ] + }, + "sc_grifex": { + "id": "sc_grifex", + "iauName": "GRIFEX", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_hubble_space_telescope": { + "id": "sc_hubble_space_telescope", + "iauName": "Hubble Space Telescope", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter", + "telescope", + "1990" + ] + }, + "sc_huygens": { + "id": "sc_huygens", + "iauName": "Huygens", + "category": "Spacecraft", + "subcategory": "Lander", + "keywords": [ + "spacecraft", + "titan", + "cassini", + "lander" + ], + "hasEvents": true + }, + "sc_ibex": { + "id": "sc_ibex", + "iauName": "IBEX", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_icesat_2": { + "id": "sc_icesat_2", + "iauName": "ICESat-2", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_image": { + "id": "sc_image", + "iauName": "IMAGE", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_insight": { + "id": "sc_insight", + "iauName": "InSight", + "category": "Spacecraft", + "subcategory": "Lander", + "keywords": [ + "spacecraft", + "mars", + "lander", + "seismic", + "2018" + ], + "landingDate": "2018-11-26T19:45:00" + }, + "sc_ipex": { + "id": "sc_ipex", + "iauName": "IPEX", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_isas": { + "id": "sc_isas", + "iauName": "ISAS", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_iss": { + "id": "sc_iss", + "iauName": "International Space Station", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "ISS", + "keywords": [ + "iss", + "international", + "international space", + "station", + "earth", + "orbiter", + "1998", + "emit", + "ecostress", + "oco-3" + ], + "customDistance": 0.1 + }, + "sc_iss_ecostress": { + "id": "sc_iss_ecostress", + "iauName": "ECOSTRESS", + "category": "Instrument", + "cameraOptions": { + "forwardVector": "-y-axis" + }, + "comparisonFeature": false, + "keywords": [ + "spacecraft", + "earth", + "iss", + "orbiter" + ] + }, + "sc_iss_emit": { + "id": "sc_iss_emit", + "iauName": "EMIT", + "category": "Instrument", + "cameraOptions": { + "forwardVector": "y-axis", + "distance": 0.006 + }, + "comparisonFeature": false, + "altName": "Earth Surface Mineral Dust Source Investigation", + "keywords": [ + "spacecraft", + "earth", + "iss", + "orbiter" + ] + }, + "sc_iss_oco_3": { + "id": "sc_iss_oco_3", + "iauName": "OCO-3", + "category": "Instrument", + "cameraOptions": { + "forwardVector": "-y-axis" + }, + "comparisonFeature": false, + "altName": "Orbiting Carbon Observatory 3", + "keywords": [ + "spacecraft", + "earth", + "iss", + "orbiter" + ] + }, + "sc_iss_rapidscat": { + "id": "sc_iss_rapidscat", + "iauName": "RapidScat", + "category": "Instrument", + "cameraOptions": { + "upVector": "-y-axis", + "forwardVector": "x-axis", + "distance": 0.007 + }, + "comparisonFeature": false, + "keywords": [ + "spacecraft", + "earth", + "iss", + "orbiter" + ] + }, + "sc_ixpe": { + "id": "sc_ixpe", + "iauName": "IXPE", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter", + "telescope", + "2021", + "x-ray", + "imaging x-ray polarimetry explorer", + "cosmic x-rays" + ] + }, + "sc_jason_1": { + "id": "sc_jason_1", + "iauName": "Jason-1", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_jason_2": { + "id": "sc_jason_2", + "iauName": "Jason-2/OSTM", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "OSTM", + "keywords": [ + "spacecraft", + "earth", + "orbiter", + "jason-2" + ] + }, + "sc_jason_3": { + "id": "sc_jason_3", + "iauName": "Jason-3", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_juice": { + "id": "sc_juice", + "iauName": "Juice", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "jupiter", + "orbiter" + ] + }, + "sc_juno": { + "id": "sc_juno", + "iauName": "Juno", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "jupiter", + "orbiter", + "gravity", + "magnetic field", + "atmosphere", + "junocam", + "bruh", + "2011" + ], + "customDistance": 0.04, + "hasEvents": true + }, + "sc_jwst": { + "id": "sc_jwst", + "iauName": "James Webb Space Telescope", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "James Webb Space Telescope", + "keywords": [ + "spacecraft", + "earth", + "orbiter", + "telescope", + "jwst" + ], + "hasEvents": true + }, + "sc_kepler_space_telescope": { + "id": "sc_kepler_space_telescope", + "iauName": "Kepler", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter", + "telescope" + ] + }, + "sc_ladee": { + "id": "sc_ladee", + "iauName": "LADEE", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "Lunar Atmosphere and Dust Environment Explorer", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ] + }, + "sc_landsat_7": { + "id": "sc_landsat_7", + "iauName": "Landsat 7", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_landsat_8": { + "id": "sc_landsat_8", + "iauName": "Landsat 8", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_landsat_9": { + "id": "sc_landsat_9", + "iauName": "Landsat 9", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_lcross": { + "id": "sc_lcross", + "iauName": "LCROSS", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "Lunar Crater Observation and Sensing Satellite", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ], + "hasEvents": true + }, + "sc_lucy": { + "id": "sc_lucy", + "iauName": "Lucy", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "hasEvents": true + }, + "sc_lunar_flashlight": { + "id": "sc_lunar_flashlight", + "iauName": "Lunar Flashlight", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ] + }, + "sc_lunar_icecube": { + "id": "sc_lunar_icecube", + "iauName": "Lunar IceCube", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ] + }, + "sc_lunar_prospector": { + "id": "sc_lunar_prospector", + "iauName": "Lunar Prospector", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ] + }, + "sc_lunar_reconnaissance_orbiter": { + "id": "sc_lunar_reconnaissance_orbiter", + "iauName": "Lunar Reconnaissance Orbiter", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "LRO", + "keywords": [ + "spacecraft", + "moon", + "orbiter", + "lro", + "temperature", + "imaging", + "albedo", + "polar", + "2009" + ] + }, + "sc_lunar_trailblazer": { + "id": "sc_lunar_trailblazer", + "iauName": "Lunar Trailblazer", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "", + "keywords": [ + "spacecraft", + "moon", + "orbiter", + "lunar", + "trailblazer", + "water" + ], + "disabled": true + }, + "sc_lunir": { + "id": "sc_lunir", + "iauName": "Lunar Reconnaissance Orbiter", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "moon", + "orbiter", + "artemis" + ], + "disabled": true + }, + "sc_magellan": { + "id": "sc_magellan", + "iauName": "Magellan", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "inner planet mission", + "venus" + ] + }, + "sc_marco_a": { + "id": "sc_marco_a", + "iauName": "MarCO A", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "insight", + "cubesat" + ] + }, + "sc_marco_b": { + "id": "sc_marco_b", + "iauName": "MarCO B", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "insight", + "cubesat" + ] + }, + "sc_mars_2020": { + "id": "sc_mars_2020", + "iauName": "Mars 2020 (Perseverance)", + "category": "Spacecraft", + "subcategory": "Rover", + "altName": "Percy", + "keywords": [ + "spacecraft", + "mars", + "lander", + "rover", + "perseverance", + "mars 2020", + "mars2020", + "m2020" + ], + "landingDate": "2021-02-18T20:55:00" + }, + "sc_mars_2020_landing_site": { + "id": "sc_mars_2020_landing_site", + "displayName": "Perseverance Rover landing site", + "category": "Landing site", + "comparisonFeature": false + }, + "sc_mars_exploration_rover_1_landing_site": { + "id": "sc_mars_exploration_rover_1_landing_site", + "displayName": "Opportunity Rover landing site", + "category": "Landing site", + "comparisonFeature": false + }, + "sc_mars_exploration_rover_1": { + "id": "sc_mars_exploration_rover_1", + "iauName": "Mars Exploration Rover B (Opportunity)", + "displayName": "Opportunity", + "category": "Spacecraft", + "subcategory": "Rover", + "keywords": [ + "spacecraft", + "mars", + "lander", + "rover", + "opportunity", + "meridiani planum", + "2003", + "MER-B", + "MER-1", + "mer b" + ], + "landingDate": "2004-01-25T04:54:00" + }, + "sc_mars_exploration_rover_2_landing_site": { + "id": "sc_mars_exploration_rover_2_landing_site", + "displayName": "Spirit Rover landing site", + "category": "Landing site", + "comparisonFeature": false + }, + "sc_mars_exploration_rover_2": { + "id": "sc_mars_exploration_rover_2", + "iauName": "Mars Exploration Rover A (Spirit)", + "displayName": "Spirit", + "category": "Spacecraft", + "subcategory": "Rover", + "keywords": [ + "spacecraft", + "mars", + "lander", + "rover", + "spirit", + "MER-A", + "MER-2", + "mer a" + ], + "landingDate": "2004-01-25T04:54:00" + }, + "sc_mars_express": { + "id": "sc_mars_express", + "iauName": "Mars Express", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "MEX", + "keywords": [ + "spacecraft", + "mars", + "orbiter", + "water", + "geology", + "atmosphere", + "surface", + "relay", + "2003" + ] + }, + "sc_mars_global_surveyor": { + "id": "sc_mars_global_surveyor", + "iauName": "Mars Global Surveyor", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "MGS", + "keywords": [ + "spacecraft", + "mars", + "MGS" + ] + }, + "sc_mars_odyssey": { + "id": "sc_mars_odyssey", + "iauName": "Mars Odyssey", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "mars", + "orbiter", + "elements", + "minerals", + "hydrogen", + "water", + "polar", + "radiation", + "relay", + "2001" + ] + }, + "sc_mars_reconnaissance_orbiter": { + "id": "sc_mars_reconnaissance_orbiter", + "iauName": "Mars Reconnaissance Orbiter", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "MRO", + "keywords": [ + "spacecraft", + "mars", + "orbiter", + "mro", + "water", + "dust", + "atmosphere", + "relay", + "2005" + ] + }, + "sc_mars_science_laboratory_landing_site": { + "id": "sc_mars_science_laboratory_landing_site", + "displayName": "Curiosity Rover landing site", + "category": "Landing site", + "comparisonFeature": false + }, + "sc_mars_science_laboratory": { + "id": "sc_mars_science_laboratory", + "iauName": "Mars Science Laboratory (Curiosity)", + "displayName": "Mars Science Laboratory (Curiosity)", + "category": "Spacecraft", + "subcategory": "Rover", + "altName": "MSL", + "keywords": [ + "spacecraft", + "mars", + "lander", + "rover", + "msl", + "curiosity", + "microbes", + "habitability", + "2011" + ], + "landingDate": "2012-08-06T05:32:00" + }, + "sc_maven": { + "id": "sc_maven", + "iauName": "MAVEN", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "mars", + "orbiter", + "atmosphere", + "ionosphere", + "solar wind", + "relay", + "2013" + ] + }, + "sc_messenger": { + "id": "sc_messenger", + "iauName": "MESSENGER", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "mercury", + "orbiter" + ] + }, + "sc_messenger_impact_site": { + "id": "sc_messenger_impact_site", + "displayName": "MESSENGER Impact Site", + "category": "Landing site", + "comparisonFeature": false + }, + "sc_mcubed_2": { + "id": "sc_mcubed_2", + "iauName": "M-Cubed 2", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_mms_1": { + "id": "sc_mms_1", + "iauName": "MMS 1", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_mms_2": { + "id": "sc_mms_2", + "iauName": "MMS 2", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_mms_3": { + "id": "sc_mms_3", + "iauName": "MMS 3", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_mms_4": { + "id": "sc_mms_4", + "iauName": "MMS 4", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_near_shoemaker": { + "id": "sc_near_shoemaker", + "iauName": "NEAR Shoemaker", + "category": "Spacecraft", + "subcategory": "Flyby", + "keywords": [ + "spacecraft", + "eros", + "orbiter" + ], + "related": { + "asteroid": [ + "433_eros" + ] + }, + "hasEvents": true + }, + "sc_new_horizons": { + "id": "sc_new_horizons", + "iauName": "New Horizons", + "category": "Spacecraft", + "subcategory": "Flyby", + "keywords": [ + "spacecraft", + "pluto", + "flyby", + "imager", + "spectrometer", + "ultraviolet", + "solar wind", + "extended mission", + "2006" + ], + "hasEvents": true + }, + "sc_nustar": { + "id": "sc_nustar", + "iauName": "NuSTAR", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "telescope", + "X-ray", + "astrophysics" + ] + }, + "sc_oco_2": { + "id": "sc_oco_2", + "iauName": "OCO-2", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "Orbiting Carbon Observatory 2", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_osiris_rex": { + "id": "sc_osiris_rex", + "iauName": "OSIRIS-APEX", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "ORX", + "keywords": [ + "spacecraft", + "bennu", + "apex", + "osiris-apex", + "lander", + "sample return", + "asteroids", + "chemistry", + "mineralogy", + "2016" + ], + "related": { + "asteroid": [ + "101955_bennu", + "99942_apophis" + ] + }, + "hasEvents": true + }, + "sc_osiris_rex_src": { + "id": "sc_osiris_rex_src", + "iauName": "OSIRIS-REx Sample Return Capsule", + "category": "Spacecraft", + "subcategory": "Flyby", + "altName": "ORX SRC", + "keywords": [ + "spacecraft", + "Bennu", + "orbiter", + "sc_osiris_rex", + "SRC", + "sample return" + ], + "related": { + "asteroid": [ + "101955_bennu" + ] + }, + "hasEvents": true + }, + "sc_pace": { + "id": "sc_pace", + "iauName": "PACE", + "altName": "Plankton, Aerosol, Cloud, ocean Ecosystem", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "disabled": false + }, + "sc_parker_solar_probe": { + "id": "sc_parker_solar_probe", + "iauName": "Parker Solar Probe", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "PSP", + "keywords": [ + "spacecraft", + "psp" + ] + }, + "sc_philae": { + "id": "sc_philae", + "iauName": "Philae", + "category": "Spacecraft", + "subcategory": "Lander", + "keywords": [ + "spacecraft", + "67P/Churyumov-Gerasimenko", + "lander", + "Rosetta" + ], + "related": { + "comet": [ + "67p_churyumov_gerasimenko" + ] + }, + "hasEvents": true + }, + "sc_phoenix": { + "id": "sc_phoenix", + "iauName": "Phoenix", + "category": "Spacecraft", + "subcategory": "Lander", + "altName": "PHX", + "keywords": [ + "spacecraft", + "mars", + "lander" + ], + "landingDate": "2008-05-25T23:53:44" + }, + "sc_phoenix_landing_site": { + "id": "sc_phoenix_landing_site", + "displayName": "Phoenix landing site", + "category": "Landing site", + "comparisonFeature": false + }, + "sc_pioneer_10": { + "id": "sc_pioneer_10", + "iauName": "Pioneer 10", + "category": "Spacecraft", + "subcategory": "Flyby", + "keywords": [ + "spacecraft", + "jupiter", + "callisto", + "ganymede", + "europa", + "io", + "flyby", + "outer planets", + "interstellar", + "1972" + ], + "hasEvents": true + }, + "sc_pioneer_11": { + "id": "sc_pioneer_11", + "iauName": "Pioneer 11", + "category": "Spacecraft", + "subcategory": "Flyby", + "keywords": [ + "spacecraft", + "jupiter", + "callisto", + "ganymede", + "io", + "europa", + "amalthea", + "saturn", + "iapetus", + "phoebe", + "hyperion", + "epimetheus", + "atlas", + "dione", + "mimas", + "janus", + "tethys", + "enceladus", + "calypso", + "rhea", + "titan", + "flyby", + "magnetic field", + "solar wind", + "outer planets", + "interstellar", + "1973" + ], + "hasEvents": true + }, + "sc_polar": { + "id": "sc_polar", + "iauName": "Polar", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_prefire_1": { + "id": "sc_prefire_1", + "iauName": "PREFIRE-1", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "PREFIRE", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_prefire_2": { + "id": "sc_prefire_2", + "iauName": "PREFIRE-2", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "PREFIRE", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_psyche": { + "id": "sc_psyche", + "iauName": "Psyche", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "16 Psyche", + "orbiter" + ], + "related": { + "asteroid": [ + "16_psyche" + ] + }, + "hasEvents": true + }, + "sc_quikscat": { + "id": "sc_quikscat", + "iauName": "QuikSCAT", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_raincube": { + "id": "sc_raincube", + "iauName": "RainCube", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "cubesat" + ] + }, + "sc_rbsp_a": { + "id": "sc_rbsp_a", + "iauName": "Van Allen Probe A", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_rbsp_b": { + "id": "sc_rbsp_b", + "iauName": "Van Allen Probe B", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_sac_d": { + "id": "sc_sac_d", + "iauName": "Aquarius", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_rosetta": { + "id": "sc_rosetta", + "iauName": "Rosetta", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "small body mission", + "67P/Churyumov-Gerasimenko" + ], + "related": { + "comet": [ + "67p_churyumov_gerasimenko" + ] + }, + "hasEvents": true + }, + "sc_sdo": { + "id": "sc_sdo", + "iauName": "Solar Dynamics Observatory", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "SDO", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_sentinel_6": { + "id": "sc_sentinel_6", + "iauName": "Sentinel-6 Michael Freilich", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter", + "2020", + "sea level", + "jason", + "jason-cs", + "copernicus", + "topex/poseidon" + ] + }, + "sc_smap": { + "id": "sc_smap", + "iauName": "SMAP", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "Soil Moisture Active Passive", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_soho": { + "id": "sc_soho", + "iauName": "SOHO", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "Solar and Heliospheric Observatory", + "keywords": [ + "spacecraft", + "sun", + "orbiter" + ] + }, + "sc_sorce": { + "id": "sc_sorce", + "iauName": "SORCE", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_spitzer": { + "id": "sc_spitzer", + "iauName": "Spitzer Space Telescope", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "SIRTF", + "keywords": [ + "spacecraft", + "sun", + "orbiter", + "sirtf", + "space infrared telescope facility", + "spitzer space telescope", + "2003" + ] + }, + "sc_stardust": { + "id": "sc_stardust", + "iauName": "Stardust", + "category": "Spacecraft", + "subcategory": "Flyby", + "keywords": [ + "spacecraft", + "Wild-2", + "orbiter" + ], + "related": { + "comet": [ + "81p_wild_2" + ] + }, + "hasEvents": true + }, + "sc_stardust_src": { + "id": "sc_stardust_src", + "iauName": "Stardust Sample Return Capsule", + "category": "Spacecraft", + "subcategory": "Flyby", + "keywords": [ + "spacecraft", + "Wild-2", + "orbiter" + ], + "related": { + "comet": [ + "81p_wild_2" + ] + } + }, + "sc_starling_1": { + "id": "sc_starling_1", + "iauName": "Starling-1", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "STARLING", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "disabled": false + }, + "sc_starling_2": { + "id": "sc_starling_2", + "iauName": "Starling-2", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "STARLING", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "disabled": false + }, + "sc_starling_3": { + "id": "sc_starling_3", + "iauName": "Starling-3", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "STARLING", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "disabled": false + }, + "sc_starling_4": { + "id": "sc_starling_4", + "iauName": "Starling-4", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "STARLING", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "disabled": false + }, + "sc_stereo_ahead": { + "id": "sc_stereo_ahead", + "iauName": "STEREO Ahead", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "STA", + "keywords": [ + "spacecraft", + "sun", + "orbiter", + "solar terrestrial relations observatory", + "stereoscopic", + "coronal mass ejections", + "cme", + "2006" + ] + }, + "sc_stereo_behind": { + "id": "sc_stereo_behind", + "iauName": "STEREO Behind", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "STB", + "keywords": [ + "spacecraft", + "sun", + "orbiter", + "solar terrestrial relations observatory", + "stereoscopic", + "coronal mass ejections", + "cme", + "2006" + ] + }, + "sc_tdrs_3": { + "id": "sc_tdrs_3", + "iauName": "TDRS-3", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "orbiter" + ] + }, + "sc_tdrs_5": { + "id": "sc_tdrs_5", + "iauName": "TDRS-5", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "orbiter" + ] + }, + "sc_tdrs_6": { + "id": "sc_tdrs_6", + "iauName": "TDRS-6", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "orbiter" + ] + }, + "sc_tdrs_7": { + "id": "sc_tdrs_7", + "iauName": "TDRS-7", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "orbiter" + ] + }, + "sc_tdrs_8": { + "id": "sc_tdrs_8", + "iauName": "TDRS-8", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "orbiter" + ] + }, + "sc_tdrs_9": { + "id": "sc_tdrs_9", + "iauName": "TDRS-9", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "orbiter" + ] + }, + "sc_tdrs_10": { + "id": "sc_tdrs_10", + "iauName": "TDRS-10", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "orbiter" + ] + }, + "sc_tdrs_11": { + "id": "sc_tdrs_11", + "iauName": "TDRS-11", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "orbiter" + ] + }, + "sc_tdrs_12": { + "id": "sc_tdrs_12", + "iauName": "TDRS-12", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "orbiter" + ] + }, + "sc_tdrs_13": { + "id": "sc_tdrs_13", + "iauName": "TDRS-13", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "orbiter" + ] + }, + "sc_suomi_npp": { + "id": "sc_suomi_npp", + "iauName": "Suomi NPP", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_swot": { + "id": "sc_swot", + "iauName": "SWOT", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_tempo": { + "id": "sc_tempo", + "iauName": "TEMPO", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_terra": { + "id": "sc_terra", + "iauName": "Terra", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_tess": { + "id": "sc_tess", + "iauName": "TESS", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "Transiting Exoplanet Survey Satellite", + "keywords": [ + "spacecraft", + "earth", + "telescope", + "transiting exoplanet survey satellite", + "orbiter", + "2018", + "exoplanets" + ] + }, + "sc_themis_a": { + "id": "sc_themis_a", + "iauName": "THEMIS-A", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_themis_b": { + "id": "sc_themis_b", + "iauName": "ARTEMIS P1", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ] + }, + "sc_themis_c": { + "id": "sc_themis_c", + "iauName": "ARTEMIS P2", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "moon", + "orbiter" + ] + }, + "sc_themis_d": { + "id": "sc_themis_d", + "iauName": "THEMIS-D", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_themis_e": { + "id": "sc_themis_e", + "iauName": "THEMIS-E", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_trace_gas_orbiter": { + "id": "sc_trace_gas_orbiter", + "iauName": "Trace Gas Orbiter", + "category": "Spacecraft", + "subcategory": "Orbiter", + "altName": "TGO", + "keywords": [ + "spacecraft", + "mars", + "orbiter", + "tgo", + "atmosphere", + "relay", + "2016" + ] + }, + "sc_trmm": { + "id": "sc_trmm", + "iauName": "TRMM", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ] + }, + "sc_tropics_03": { + "id": "sc_tropics_03", + "iauName": "TROPICS-03", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "TROPICS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "disabled": false + }, + "sc_tropics_05": { + "id": "sc_tropics_05", + "iauName": "TROPICS-05", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "TROPICS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "disabled": false + }, + "sc_tropics_06": { + "id": "sc_tropics_06", + "iauName": "TROPICS-06", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "TROPICS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "disabled": false + }, + "sc_tropics_07": { + "id": "sc_tropics_07", + "iauName": "TROPICS-07", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "TROPICS", + "keywords": [ + "spacecraft", + "earth", + "orbiter" + ], + "disabled": false + }, + "sc_tropics_01": { + "id": "sc_tropics_01", + "iauName": "TROPICS-01", + "category": "Spacecraft", + "subcategory": "Orbiter", + "constellation": "TROPICS", + "keywords": [ + "spacecraft", + "earth", + "orbiter", + "tropics pathfinder", + "pathfinder" + ], + "disabled": false + }, + "sc_ulysses": { + "id": "sc_ulysses", + "iauName": "Ulysses", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "sun", + "orbiter" + ] + }, + "sc_voyager_1": { + "id": "sc_voyager_1", + "iauName": "Voyager 1", + "category": "Spacecraft", + "subcategory": "Flyby", + "keywords": [ + "spacecraft", + "jupiter", + "saturn", + "flyby", + "imaging", + "vger", + "radio science", + "infrared", + "ultraviolet", + "magnetometer", + "plasma", + "1977" + ], + "hasEvents": true + }, + "sc_voyager_2": { + "id": "sc_voyager_2", + "iauName": "Voyager 2", + "category": "Spacecraft", + "subcategory": "Flyby", + "keywords": [ + "spacecraft", + "jupiter", + "saturn", + "uranus", + "vger", + "neptune", + "flyby", + "imaging", + "radio science", + "infrared", + "ultraviolet", + "magnetometer", + "plasma", + "1977" + ], + "hasEvents": true + }, + "sc_wind": { + "id": "sc_wind", + "iauName": "WIND", + "category": "Spacecraft", + "subcategory": "Orbiter", + "keywords": [ + "spacecraft", + "solar wind", + "earth", + "orbiter" + ] + }, + "valetudo": { + "id": "valetudo", + "iauName": "Valetudo", + "category": "Moon", + "subcategory": "Minor Moon", + "keywords": [ + "minor moon", + "solar system", + "jupiter", + "moons" + ] + }, + "scientist": { + "id": "scientist", + "displayName": "Scientist", + "category": "Human", + "searchable": false + }, + "school_bus": { + "id": "school_bus", + "displayName": "School Bus", + "category": "Vehicle", + "searchable": false + }, + "rose_bowl": { + "id": "rose_bowl", + "displayName": "Stadium", + "category": "Building", + "searchable": false + } +} \ No newline at end of file diff --git a/experiences/asteroids/web/src/data/heroes.json b/experiences/asteroids/web/src/data/heroes.json new file mode 100644 index 0000000..b70d690 --- /dev/null +++ b/experiences/asteroids/web/src/data/heroes.json @@ -0,0 +1,197 @@ +{ + "99942_apophis": { + "stats": { + "discovery":"

        Discovered on June 19, 2004 at the Kitt Peak National Observatory in Arizona.

        ", + "rotation": 30.4 + }, + "approach": { + "fact":"

        On April 13, 2029, the asteroid Apophis will pass less than 23,239 miles (37,399 kilometers) from our planet’s surface – just outside the distance of geosynchronous satellites, and closer to Earth than any similarly sized PHO in recorded history. At that time, Apophis will be visible to observers on the ground in the Eastern Hemisphere without the aid of a telescope or binoculars.

        " + } + }, + "4_vesta": { + "stats": { + "discovery":"

        One of the largest and earliest known asteroids, Vesta was discovered on March 29th, 1807, and was visited by the Dawn mission in 2011.

        ", + "rotation": 5.342 + } + }, + "433_eros": { + "stats": { + "discovery":"

        Discovered on August 13th, 1898, Eros was the first near-Earth Object (NEO) ever found, and the first asteroid ever orbited by a spacecraft, NEAR-Shoemaker.

        ", + "rotation": 5.27 + }, + "approach": { + "fact":"

        Eros will approach Earth within 0.39765 AU on November 30th, 2025.

        " + } + }, + "951_gaspra": { + "stats": { + "discovery":"

        Discovered in 1916, Gaspra is the first asteroid to be closely approached by a spacecraft, which was Galileo in 1991.

        ", + "rotation": 7.042 + } + }, + "243_ida": { + "stats": { + "discovery":"

        Discovered in 1884, Ida was visited by the Galileo spacecraft in August of 1993.

        ", + "rotation": 4.634 + } + }, + "81p_wild_2": { + "stats": { + "discovery":"

        This comet was discovered on January 6th, 1978, and was visited by the Stardust mission in January of 2004.

        " + } + }, + "9p_tempel_1": { + "stats": { + "discovery":"

        Discovered in 1867, comet Tempel 1 was the target of the Deep Impact mission, which physically collided with the comet on July 4th, 2005.

        ", + "rotation": 40.7 + } + }, + "21_lutetia": { + "stats": { + "discovery":"

        Discovered in 1852, the asteroid was visited by the European space probe Rosetta in July of 2010.

        ", + "rotation": 8.1655 + } + }, + "67p_churyumov_gerasimenko": { + "stats": { + "discovery":"

        Discovered in 1969, this comet was the first to be landed upon by a robotic mission from Earth, the European Space Agency's Rosetta mission. The Philae lander touched down in November of 2014.

        ", + "rotation": 12.76 + }, + "approach": { + "fact":"

        The comet approached Earth within 0.418 AU on November 12th, 2021, and then will approach again in November of 2034 at a distance of 0.4523 AU.

        " + } + }, + "1_ceres": { + "stats": { + "discovery":"

        Discovered in January of 1801, Ceres was the first asteroid ever found, though it was initially classified as a planet. It remained an asteroid until 2006, when it was reclassified as a dwarf planet.

        ", + "rotation": 9.0741 + } + }, + "101955_bennu": { + "stats": { + "discovery":"

        Discovered in September of 1999, Bennu was the subject of the OSIRIS-REx mission, which touched down on the asteroid and collected a sample of the surface on October 20th, 2020. OSIRIS-REx departed Bennu in 2021, and delivered the capsule with pieces of the asteroid to Earth on September 24, 2023.

        ", + "rotation": 4.296 + }, + "approach": { + "fact":"

        Bennu is a PHO, and will have multiple close approaches with Earth over time. The next close approach will be in 2023, at a distance of 0.497 AU

        " + } + }, + "103p_hartley_2": { + "stats": { + "discovery":"

        Discovered in 1986, Comet Hartley 2 was the target of the Deep Impact/EPOXI mission, which flew by in November of 2010.

        ", + "rotation": 18.1 + }, + "approach": { + "fact":"

        103p/Hartley 2 is classified as an NEO, and will approach Earth within 0.3826 AU on September 26th, 2023.

        " + } + }, + "25143_itokawa": { + "stats": { + "discovery":"

        Discovered in 1998, Itokawa was the first asteroid to be the target of a sample return mission. The Japanese space probe Hayabusa took a sample from the comet in November of 2005.

        ", + "rotation": 12.132 + }, + "approach": { + "fact":"

        Itokawa is classified as a PHO, and will next approach the Earth on March 6th, 2030, at a distance of 0.376 AU.

        " + } + }, + "16_psyche": { + "stats": { + "discovery":"

        Discovered in 1852, the Psyche asteroid is the subject of the upcoming Psyche mission which will launch no earlier than 2023.

        ", + "rotation": 4.196 + } + }, + "65803_didymos": { + "stats": { + "discovery":"

        Discovered in 1996, Didymos is part of a binary asteroid system with its smaller partner, Dimorphos. The DART mission targeted this system, successfully crashing a probe into Dimorphos on September 26th, 2022.

        ", + "rotation": 2.2593 + }, + "approach": { + "fact":"

        Didymos is a PHO, and approached Earth at a distance of 0.07123 AU on October 4th, 2022.

        " + } + }, + "dimorphos": { + "stats": { + "discovery":"

        First observed in 2003 (7 years after the discovery of Didymos), Dimorphos is the smaller twin of the Didymos binary asteroid system. The DART mission intentionally crashed into Dimorphos on September 26th, 2022, and successfully altered its orbit.

        ", + "rotation": 11.92 + }, + "approach": { + "fact":"

        Dimorphos and its binary system are classifed as a PHO, and approached Earth at a distance of 0.07123 AU on October 4th, 2022.

        " + } + }, + "52246_donaldjohanson": { + "stats": { + "discovery":"

        Discovered in 1981, and named after the paleoanthropologist who discovered the \"Lucy\" fossil, this will be the second small body that the Lucy mission will encounter in 2025.

        ", + "rotation": 252 + } + }, + "3548_eurybates": { + "stats": { + "discovery":"

        Discovered in 1973, Eurybates is the first Trojan Asteroid that the Lucy mission will visit in August of 2027. It has a small satellite named Queta.

        ", + "rotation": 8.7 + } + }, + "15094_polymele": { + "stats": { + "discovery":"

        Discovered in 1999, Polymele is a Trojan Asteroid that will be visited by the Lucy mission in September of 2027.

        ", + "rotation": 5.86 + } + }, + "11351_leucus": { + "stats": { + "discovery":"

        Discovered in 1997, Leucus is a Trojan Asteroid that will be visited by the Lucy mission in April of 2028.

        ", + "rotation": 445.73 + } + }, + "21900_orus": { + "stats": { + "discovery":"

        Discovered in 1999, Orus is a Trojan Asteroid that will be visited by the Lucy mission in November of 2028.

        ", + "rotation": 13.45 + } + }, + "617_patroclus": { + "stats": { + "discovery":"

        Discovered in 1906, Patroclus is a Trojan Asteroid that will be visited by the Lucy mission in 2033. In 2001, Patroclus was found to be part of a binary asteroid system with its smaller twin, named Menoetius.

        ", + "rotation": 102.8 + } + }, + "19p_borrelly": { + "stats": { + "discovery":"

        Discovered in 1904, comet Borrelly was the target of the Deep Space 1 mission, which flew by in September of 2001.

        " + } + }, + "5535_annefrank": { + "stats": { + "discovery":"

        Discovered in 1942, the main belt asteroid 5535 Annefrank was used as a practice flyby target by the Stardust mission on November 2nd, 2002.

        ", + "rotation": 15.12 + } + }, + "9969_braille": { + "stats": { + "discovery":"

        Discovered in 1992, Braille was visited by the Deep Space 1 mission on July 29th, 1999. The spacecraft passed within 26 km (16 miles) of the asteroid, which was the closest asteroid flyby ever at that time.

        ", + "rotation": 226.4 + } + }, + "162173_ryugu": { + "stats": { + "discovery":"

        Discovered in 1999, Ryugu was the target of the Hayabusa2 mission, which orbited the asteroid for a year and a half, landed small rovers on it, and collected samples that were returned to Earth in December of 2020.

        ", + "rotation": 7.63 + }, + "approach": { + "fact":"

        Ryugu is a PHO, and will next approach Earth at a distance of 0.373 AUs on June 3rd, 2025.

        " + } + }, + "152830_dinkinesh": { + "stats": { + "discovery":"

        Discovered in 1999, Dinkinesh will be the Lucy mission's first flyby target in early November of 2023. It will become the smallest main-belt asteroid ever visited.

        " + } + }, + "73p_schwassmann_wachmann_3": { + "stats": { + "discovery":"

        Discovered in 1930, 73P/Schwassmann-Wachmann 3 is a periodic comet that began to disintegrate as it approached the sun in 1995. Initially, it split into four distinct fragments, but later further split into more than sixty pieces.

        " + }, + "category": "Comet", + "id": "73p_schwassmann_wachmann_3", + "iauName": "73P/Schwassmann Wachmann 3", + "displayName": "Schwassmann Wachmann 3" + } +} \ No newline at end of file diff --git a/experiences/asteroids/web/src/data/stories/story_list.json b/experiences/asteroids/web/src/data/stories/story_list.json new file mode 100644 index 0000000..7c166ce --- /dev/null +++ b/experiences/asteroids/web/src/data/stories/story_list.json @@ -0,0 +1,18 @@ +{ + "stories": { + "asteroids_101": { + "id": "asteroids_101", + "title": "Asteroids 101" + }, + "asteroids_close_approach": { + "id": "asteroids_close_approach", + "title": "What is a Close Approach?" + }, + "asteroids_missions": { + "id": "asteroids_missions", + "title": "Asteroid and Comet Missions" + } + }, + "external": {}, + "featured": [] +} \ No newline at end of file diff --git a/experiences/asteroids/web/src/data/tutorials.json b/experiences/asteroids/web/src/data/tutorials.json new file mode 100644 index 0000000..abf298c --- /dev/null +++ b/experiences/asteroids/web/src/data/tutorials.json @@ -0,0 +1,100 @@ +[ + { + "id": "intro", + "title": "Welcome to
        Eyes on Asteroids!", + "description":"You are looking at a real-time visualization of every known asteroid or comet that is classified as a Near-Earth Object (NEO).
        With asteroids represented as blue points, and comets as white points, our database is updated daily to give you approximately {{getNeoTotal}} NEOs (and counting). Additionally, you can explore most of NASA's asteroid and comet missions (past and present), from Galileo, to Lucy and DART.", + "extra": "
        Extra fact:

        Farther from Earth, the full asteroid belt contains over a million members, with the majority lying between Mars and Jupiter.

        " + }, + { + "id": "nav3d", + "title": "Navigate 3D like an Expert", + "description": { + "touch": "One finger controls your orbit in all directions. Pinch zoom for close inspection, large-scale overviews, and everything in-between.", + "desktop": "Left mouse click-and-drag controls your orbit in all directions. Scroll zoom for close inspection, macro overviews, and everything in-between." + }, + "extra": { + "desktop":"
        Secret tip:

        Use the 'A', 'S', 'D', 'W', 'Z', and 'C' keys only if you're a true expert. Hold the 'shift' key to move even faster.

        " + }, + "targetSelector": "#pioneer", + "mask": { + "xSizeMult": 0.6, + "ySizeMult": 0.25 + } + }, + { + "id": "labels", + "title": "Info on the Fly", + "description": "Select any label or icon in the 3D screen to fly to it and bring up an information panel.", + "extra":"
        Don't get lost:

        The top-left NASA logo or 'See all asteroids' button will always take you back home.

        ", + "targetSelector": "#pioneer", + "mask": { + "xSizeMult": 0.6, + "ySizeMult": 0.25 + } + }, + { + "id": "time", + "title": "From 1990 to 2033
        You Control Time.", + "description": "Drag the time slider left to go backwards, or right to go forwards in time. The LIVE button will always return you to the present time.", + "extra": "
        A little trick:

        To go even faster, zoom out and try again.

        ", + "targetSelector": "#time-slider-container" + }, + { + "id": "learn", + "title": "Learn by Scrolling", + "description":"Select 'Learn' to access three different scrollable stories about asteroids and comets, including a tour through NASA's historic missions.", + "targetSelector": "nav.navigation div:nth-child(1).clickable button", + "mask": { + "xSizeMult": 0.7, + "ySizeMult": 0.7 + } + }, + { + "id": "watch", + "title": "Keep an Eye Out!", + "description":"Select the 'Asteroid Watch' option to see the next five closest approaches to Earth, complete with a countdown.", + "extra":"
        Hint:

        Don't forget to play with that time slider!

        ", + "targetSelector": "nav.navigation div:nth-child(2).clickable button", + "mask": { + "xSizeMult": 0.7, + "ySizeMult": 0.7 + } + }, + { + "id": "filters", + "title": "Filter your View", + "description":"Select 'Filters' to see just the comets, or just the asteroids, or just the Potentially Hazardous Objects (PHOs).", + "targetSelector": "nav.navigation div:nth-child(3).clickable button", + "mask": { + "xSizeMult": 0.7, + "ySizeMult": 0.7 + } + }, + { + "id": "search", + "title": "Looking for Something?", + "description": "Type it in the search bar to look through our entire NEO database.", + "targetSelector": ".search>span.icon-search", + "mask": { + "xSizeMult": 0.5, + "ySizeMult": 0.5 + } + }, + { + "id": "settings", + "title": "Fine Tuning", + "description": "Use the settings menu to toggle display layers, incrementally zoom, change the lighting when the sun is not enough, and go full-screen.", + "alternateDescription": "Use the settings menu to toggle display layers, incrementally zoom, and change the lighting when the sun is not enough.", + "extra": "
        Just in case:

        The info icon will take you back here if you ever need a recap.

        ", + "targetSelector": "div.settings", + "mask": { + "xSizeMult": 0.5 + } + }, + { + "id": "complete", + "title": "Dare Mighty Things", + "description": "You are now armed with all the knowledge to explore Eyes on Asteroids like a pro. Happy Learning!", + "extra": "
        One last secret:

        Watch out for any underlined text; it may lead you down a rabbit hole of space knowledge...

        " + } +] \ No newline at end of file diff --git a/experiences/asteroids/web/story-content.js b/experiences/asteroids/web/story-content.js new file mode 100644 index 0000000..f9ee073 --- /dev/null +++ b/experiences/asteroids/web/story-content.js @@ -0,0 +1,268 @@ +const asteroidsSlides = [ + { + storyLength: 5, + index: 1, + title: "Asteroids and Comets 101", + info: ["Control the screen by pressing forward or back"], + }, + { + storyLength: 5, + index: 2, + info: [ + "Asteroids and comets are remnants left over from the early formation of our solar system 4.6 billion years ago.\ + Asteroids are mostly rocky bodies that formed closer to the Sun than Jupiter, while comets formed farther from \ + the Sun and contain substantial amounts of frozen ices. The vast majority of these small bodies are asteroids, \ + and most of them reside within the main belt, between the orbits of Mars and Jupiter.", + ], + }, + { + storyLength: 5, + index: 3, + info: [ + "Asteroids range in size from Vesta (shown on screen) – one of the largest at about 329 miles (530 kilometers) \ + in diameter – to bodies that are as small as 3 feet (1 meter) across. Most asteroids are small: the total mass \ + of all of them combined is far less than that of the Earth’s Moon.", + + "Asteroids less than about one meter across are called meteoroids, and are generally too small to be detected by\ + telescopes. Meteoroids (or asteroids) that happen to hit Earth’s atmosphere become visible as meteors and \ + largely disintegrate. Larger asteroids (car-sized or bus-sized) produce bright meteors called fireballs or \ + bolides, but they also mostly disintegrate. Any solid leftover pieces that make it all the way to the ground \ + are called meteorites.", + ], + }, + { + storyLength: 5, + index: 4, + info: [ + "Comets (like 67P/Churyumov-Gerasimenko, shown on screen) also have dust and rock, but also contain large \ + amounts of various frozen ices. Comets generally follow long elliptical orbits in which they spend most of \ + their time far from the Sun, where the ices can remain frozen.", + + "When a comet’s orbit brings it closer to the Sun, the ices start heating up, creating explosive jets which spew\ + out gas and dust. The expelled material forms into a cloud around the solid nucleus called the “coma”, that can\ + be larger than a planet. The material is also swept back away from the Sun into diffuse tails that can stretch \ + for millions of miles. Eventually, after thousands of orbits, a comet’s ices will be depleted. Some objects now\ + classified as asteroids may simply be “dead” comets.", + ], + }, + { + storyLength: 5, + index: 5, + info: [ + "Many asteroids orbit nearby. On occasion, one impacts our planet. For example, the dinosaurs are thought to \ + have been made extinct by the impact of a large asteroid 6-9 miles wide (10-15 km) that collided with Earth 66 \ + million years ago.", + + "NASA established the\ + \ + Planetary Defense Coordination Office (PDCO)\ + to manage its ongoing mission of planetary defense, which includes tracking potentially hazardous objects.\ + The PDCO has a lead role in coordinating U.S. government planning for response to an actual impact threat, and \ + is supported by the\ + \ + Center for Near-Earth Object Studies (CNEOS)\ + ,\ + which is NASA’s center for computing asteroid and comet orbits and their odds of impacting Earth.", + + 'For more on close approaches, try the "Close Approach" lesson under the "Learn" tab.', + ], + }, +]; + +const closeApproachesSlides = [ + { + storyLength: 7, + index: 1, + title: "What is a Close Approach?", + info: ["Control the screen by pressing forward or back"], + }, + { + storyLength: 7, + index: 2, + info: [ + "Some asteroids will inevitably approach Earth, and these are tracked by NASA. The\ + \ + Center for Near-Earth Object Studies (CNEOS)\ + \ + computes the orbits of asteroids and comets and their odds of impacting Earth. The orbits of all asteroids \ + shown on screen are publicly available from NASA’s\ + \ + Solar System Dynamics (SSD)\ + \ + group.", + ], + }, + { + storyLength: 7, + index: 3, + info: [ + "Apophis is a near-Earth asteroid more than 1000 feet (over 300 meters) in size that will harmlessly pass close \ + to Earth on April 13, 2029. When it was discovered in 2004, the asteroid caused a stir because initial \ + calculations indicated a small possibility it would impact Earth.", + ], + }, + { + storyLength: 7, + index: 4, + info: [ + "It’s now predicted the asteroid will safely pass about 23,189 miles (37,320 kilometers) from our planet’s \ + surface. While that’s a safe distance, it’s close enough that the asteroid will come between Earth and our \ + Moon, which is about 238,855 miles (384,400 kilometers) away. It’s also near the distance that some spacecraft \ + orbit Earth.", + + "This asteroid has the official designation of being both a “Near Earth Object” and a “Potentially Hazardous \ + Object.”", + ], + replay: true, + }, + { + storyLength: 7, + index: 5, + title: "What is a Near Earth Object (NEO)?", + info: [ + "Over millions of years, some main belt asteroids have been influenced by collisions and gravitational \ + interactions with planets that have gradually changed their orbits so that they now pass through Earth’s \ + general region of space. These are the Near-Earth Objects (NEOs).
        Specifically, an NEO is defined as an \ + asteroid or comet whose orbit brings it to within 1.3 astronomical units (\ + \ + AU\ + \ + s) of the sun. Near-Earth Comets (NECs) are further restricted to only those with “short” orbital periods less \ + than 200 years.", + ], + }, + { + storyLength: 7, + index: 6, + title: "What is a Potentially Hazardous Object?", + info: [ + "A Potentially Hazardous Object (PHO) is a Near-Earth Object (NEO) that is at least 140 meters (460 feet) \ + in size, and whose orbit approaches Earth’s orbit to within 0.05 AU (7,480,000 km or 4,675,000 miles). PHOs\ + are “potentially hazardous” only in a long-term sense: almost all are not currently on Earth-crossing \ + orbits, but their orbits are close enough that over hundreds or thousands of years, they may evolve to \ + become Earth-crossing.", + ], + }, + { + storyLength: 7, + index: 7, + info: [ + 'Explore the next 5 closest approaches through the "Watch" tab. These are continuously updated, as NASA is \ + constantly on the lookout.', + ], + }, +]; + +const missionSlides = [ + { + storyLength: 11, + index: 1, + title: "Asteroid and Comet Missions", + info: ["Control the screen by pressing forward or back"], + }, + { + storyLength: 11, + index: 2, + info: [ + "NASA and other space agencies have sent spacecraft to visit, photograph, sample, and even collide with various \ + asteroids like Bennu, Vesta, and Eros, and the comets Tempel 1, 19P/Borrelly, and 67P Churyumov-Gerasimenko \ + (shown on screen with the Rosetta spacecraft).", + ], + }, + { + storyLength: 11, + index: 3, + info: [ + "The very first mission to both orbit and land on an asteroid was the NEAR mission (Near Earth Asteroid \ + Rendezvous, later renamed NEAR Shoemaker after the renowned geologist Eugene Shoemaker). The mission \ + successfully orbited the asteroid Eros for a year, and ended the mission by landing on the surface on February \ + 12th, 2001.", + ], + }, + { + storyLength: 11, + index: 4, + info: [ + "NASA has also sent several missions to study comets. On the 4th of July, 2005, NASA’s Deep Impact mission \ + actually collided with a comet named Tempel 1 (9P/Tempel). The spacecraft (Deep Impact) sent a washing-machine \ + sized probe (the Deep Impact Impactor) to hit the comet itself, and then flew through the resulting cloud of \ + space debris to analyze the composition. The comet’s nucleus had more dust and less ice than models had \ + suggested.", + ], + replay: true, + }, + { + storyLength: 11, + index: 5, + info: [ + "The Dawn mission was the first to orbit an object in the main asteroid belt, as well as the first mission to \ + orbit two separate destinations.", + + "Dawn spent over a year in orbit around Vesta, from July of 2011 until September of 2012. Dawn mapped Vesta's \ + geology, composition, cratering record and more.", + ], + }, + { + storyLength: 11, + index: 6, + info: [ + "Dawn then traveled to Ceres, which is the largest object in the asteroid belt. (Ceres is still considered to be\ + an asteroid, but was designated as a dwarf planet in 2006.) The spacecraft arrived in 2015 and continued to \ + collect data until running out of thruster fuel.", + + "Dawn found abundant proof of water ice in the higher latitudes, as well as active geological features. Dawn \ + remains in orbit around Ceres but will eventually impact the surface.", + ], + }, + { + storyLength: 11, + index: 7, + info: [ + "Other missions actually take samples of asteroids and comets. The Stardust mission flew by the comet Wild 2 and\ + collected samples from the dust trail of the comet, as well as interstellar dust.", + + "These samples were later brought back to Earth via a detachable sample return capsule, which re-entered Earth’s\ + atmosphere on January 15th, 2006. The sample capsule landed in Utah and the millions of dust particles are \ + still being studied to this day.", + ], + }, + { + storyLength: 11, + index: 8, + info: [ + "In October of 2020, the OSIRIS-REx mission successfully sampled the surface of the asteroid Bennu, collecting \ + approximately 60 grams of surface material. The mission successfully dropped off the sample return capsule to \ + Earth on September 24th, 2023, and is now on course to visit the asteroid Apophis.", + ], + }, + { + storyLength: 11, + index: 9, + info: [ + "NASA has several new missions to investigate asteroids, including Lucy and Psyche. Each mission promises to \ + unlock further secrets of the formation and evolution of our solar system by studying asteroids. The Lucy \ + mission is investigating the ancient Trojan asteroids that share Jupiter’s orbit, and the Psyche mission \ + (shown on screen) is en route to the unique metal asteroid 16 Psyche.", + ], + }, + { + storyLength: 11, + index: 10, + info: [ + "The Double Asteroid Redirection Test, or DART, is a NASA mission that could be a plot from a Hollywood movie. \ + As the very first planetary defense test mission, DART will test whether a spacecraft impact could deflect the \ + orbit of an asteroid. Even a slight change in the orbit of an asteroid could avert a collision with Earth if \ + the change happens early enough. DART successfully impacted the asteroid moon Dimorphos, which is in a binary \ + system with the larger asteroid Didymos. The orbital period of Dimorphos changed by 33 minutes.", + ], + replay: true, + }, + { + storyLength: 11, + index: 11, + info: [ + "NASA and other space agencies will continue to send robotic explorers throughout our solar system.", + "The journey of discovery is just beginning.", + ], + }, +]; diff --git a/experiences/asteroids/web/vendors.css b/experiences/asteroids/web/vendors.css new file mode 100644 index 0000000..9cee249 --- /dev/null +++ b/experiences/asteroids/web/vendors.css @@ -0,0 +1,646 @@ +/*!********************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/node_modules/overlayscrollbars/css/OverlayScrollbars.css ***! + \********************************************************************************************************************************************************************************************************************/ +/*! + * OverlayScrollbars + * https://github.com/KingSora/OverlayScrollbars + * + * Version: 1.13.0 + * + * Copyright KingSora | Rene Haas. + * https://github.com/KingSora + * + * Released under the MIT license. + * Date: 02.08.2020 + */ + +/* +OVERLAY SCROLLBARS CORE: +*/ + +html.os-html, +html.os-html > .os-host { + display: block; + overflow: hidden; + box-sizing: border-box; + height: 100% !important; + width: 100% !important; + min-width: 100% !important; + min-height: 100% !important; + margin: 0 !important; + position: absolute !important; /* could be position: fixed; but it causes issues on iOS (-webkit-overflow-scrolling: touch) */ +} +html.os-html > .os-host > .os-padding { + position: absolute; /* could be position: fixed; but it causes issues on iOS (-webkit-overflow-scrolling: touch) */ +} +body.os-dragging, +body.os-dragging * { + cursor: default; +} +.os-host, +.os-host-textarea { + position: relative; + overflow: visible !important; + flex-direction: column; + flex-wrap: nowrap; + justify-content: flex-start; + align-content: flex-start; + -webkit-box-align: start; + -ms-flex-align: start; + -ms-grid-row-align: flex-start; + align-items: flex-start; +} +.os-host-flexbox { + overflow: hidden !important; + display: flex; +} +.os-host-flexbox > .os-size-auto-observer { + height: inherit !important; +} +.os-host-flexbox > .os-content-glue { + flex-grow: 1; + flex-shrink: 0; +} +.os-host-flexbox > .os-size-auto-observer, +.os-host-flexbox > .os-content-glue { + min-height: 0; + min-width: 0; + flex-grow: 0; + flex-shrink: 1; + flex-basis: auto; +} +#os-dummy-scrollbar-size { + position: fixed; + opacity: 0; + -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)'; + visibility: hidden; + overflow: scroll; + height: 500px; + width: 500px; +} +#os-dummy-scrollbar-size > div { + width: 200%; + height: 200%; + margin: 10px 0; +} +/* fix restricted measuring */ +#os-dummy-scrollbar-size:before, +#os-dummy-scrollbar-size:after, +.os-content:before, +.os-content:after { + content: ''; + display: table; + width: 0.01px; + height: 0.01px; + line-height: 0; + font-size: 0; + flex-grow: 0; + flex-shrink: 0; + visibility: hidden; +} +#os-dummy-scrollbar-size, +.os-viewport { + -ms-overflow-style: scrollbar !important; +} +.os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size, +.os-viewport-native-scrollbars-invisible.os-viewport { + scrollbar-width: none !important; +} +.os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size::-webkit-scrollbar, +.os-viewport-native-scrollbars-invisible.os-viewport::-webkit-scrollbar, +.os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size::-webkit-scrollbar-corner, +.os-viewport-native-scrollbars-invisible.os-viewport::-webkit-scrollbar-corner { + display: none !important; + width: 0px !important; + height: 0px !important; + visibility: hidden !important; + background: transparent !important; +} +.os-content-glue { + box-sizing: inherit; + max-height: 100%; + max-width: 100%; + width: 100%; + pointer-events: none; +} +.os-padding { + box-sizing: inherit; + direction: inherit; + position: absolute; + overflow: visible; + padding: 0; + margin: 0; + left: 0; + top: 0; + bottom: 0; + right: 0; + width: auto !important; + height: auto !important; + z-index: 0; +} +.os-host-overflow > .os-padding { + overflow: hidden; +} +.os-viewport { + direction: inherit !important; + box-sizing: inherit !important; + resize: none !important; + outline: none !important; + position: absolute; + overflow: hidden; + top: 0; + left: 0; + bottom: 0; + right: 0; + padding: 0; + margin: 0; + -webkit-overflow-scrolling: touch; +} +.os-content-arrange { + position: absolute; + z-index: -1; + min-height: 1px; + min-width: 1px; + pointer-events: none; +} +.os-content { + direction: inherit; + box-sizing: border-box !important; + position: relative; + display: block; + height: 100%; + width: 100%; + height: 100%; + width: 100%; + visibility: visible; +} +.os-content > .os-textarea { + box-sizing: border-box !important; + direction: inherit !important; + background: transparent !important; + outline: 0px none transparent !important; + overflow: hidden !important; + position: absolute !important; + display: block !important; + top: 0 !important; + left: 0 !important; + margin: 0 !important; + border-radius: 0px !important; + float: none !important; + filter: none !important; + border: none !important; + resize: none !important; + transform: none !important; + max-width: none !important; + max-height: none !important; + box-shadow: none !important; + perspective: none !important; + opacity: 1 !important; + z-index: 1 !important; + clip: auto !important; + vertical-align: baseline !important; + padding: 0px; +} +.os-host-rtl > .os-padding > .os-viewport > .os-content > .os-textarea { + right: 0 !important; +} +.os-content > .os-textarea-cover { + z-index: -1; + pointer-events: none; +} +.os-content > .os-textarea[wrap='off'] { + white-space: pre !important; + margin: 0px !important; +} +.os-text-inherit { + font-family: inherit; + font-size: inherit; + font-weight: inherit; + font-style: inherit; + font-variant: inherit; + text-transform: inherit; + text-decoration: inherit; + text-indent: inherit; + text-align: inherit; + text-shadow: inherit; + text-overflow: inherit; + letter-spacing: inherit; + word-spacing: inherit; + line-height: inherit; + unicode-bidi: inherit; + direction: inherit; + color: inherit; + cursor: text; +} +.os-resize-observer, +.os-resize-observer-host { + box-sizing: inherit; + display: block; + visibility: hidden; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + overflow: hidden; + pointer-events: none; + z-index: -1; +} +.os-resize-observer-host { + padding: inherit; + border: inherit; + border-color: transparent; + border-style: solid; + box-sizing: border-box; +} +.os-resize-observer-host.observed { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; +} +.os-resize-observer-host > .os-resize-observer, +.os-resize-observer-host.observed > .os-resize-observer { + height: 200%; + width: 200%; + padding: inherit; + border: inherit; + margin: 0; + display: block; + box-sizing: content-box; +} +.os-resize-observer-host.observed > .os-resize-observer, +.os-resize-observer-host.observed > .os-resize-observer:before { + display: flex; + position: relative; + flex-grow: 1; + flex-shrink: 0; + flex-basis: auto; + box-sizing: border-box; +} +.os-resize-observer-host.observed > .os-resize-observer:before { + content: ''; + box-sizing: content-box; + padding: inherit; + border: inherit; + margin: 0; +} +.os-size-auto-observer { + box-sizing: inherit !important; + height: 100%; + width: inherit; + max-width: 1px; + position: relative; + float: left; + max-height: 1px; + overflow: hidden; + z-index: -1; + padding: 0; + margin: 0; + pointer-events: none; + flex-grow: inherit; + flex-shrink: 0; + flex-basis: 0; +} +.os-size-auto-observer > .os-resize-observer { + width: 1000%; + height: 1000%; + min-height: 1px; + min-width: 1px; +} +.os-resize-observer-item { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + overflow: hidden; + z-index: -1; + opacity: 0; + direction: ltr !important; + flex: none !important; +} +.os-resize-observer-item-final { + position: absolute; + left: 0; + top: 0; + transition: none !important; + flex: none !important; +} +.os-resize-observer { + -webkit-animation-duration: 0.001s; + animation-duration: 0.001s; + -webkit-animation-name: os-resize-observer-dummy-animation; + animation-name: os-resize-observer-dummy-animation; +} +object.os-resize-observer { + box-sizing: border-box !important; +} +@-webkit-keyframes os-resize-observer-dummy-animation { + from { + z-index: 0; + } + to { + z-index: -1; + } +} +@keyframes os-resize-observer-dummy-animation { + from { + z-index: 0; + } + to { + z-index: -1; + } +} + +/* +CUSTOM SCROLLBARS AND CORNER CORE: +*/ + +.os-host-transition > .os-scrollbar, +.os-host-transition > .os-scrollbar-corner { + transition: opacity 0.3s, visibility 0.3s, top 0.3s, right 0.3s, bottom 0.3s, left 0.3s; +} +html.os-html > .os-host > .os-scrollbar { + position: absolute; /* could be position: fixed; but it causes issues on iOS (-webkit-overflow-scrolling: touch) */ + z-index: 999999; /* highest z-index of the page */ +} +.os-scrollbar, +.os-scrollbar-corner { + position: absolute; + opacity: 1; + -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=100)'; + z-index: 1; +} +.os-scrollbar-corner { + bottom: 0; + right: 0; +} +.os-scrollbar { + pointer-events: none; +} +.os-scrollbar-track { + pointer-events: auto; + position: relative; + height: 100%; + width: 100%; + padding: 0 !important; + border: none !important; +} +.os-scrollbar-handle { + pointer-events: auto; + position: absolute; + width: 100%; + height: 100%; +} +.os-scrollbar-handle-off, +.os-scrollbar-track-off { + pointer-events: none; +} +.os-scrollbar.os-scrollbar-unusable, +.os-scrollbar.os-scrollbar-unusable * { + pointer-events: none !important; +} +.os-scrollbar.os-scrollbar-unusable .os-scrollbar-handle { + opacity: 0 !important; +} +.os-scrollbar-horizontal { + bottom: 0; + left: 0; +} +.os-scrollbar-vertical { + top: 0; + right: 0; +} +.os-host-rtl > .os-scrollbar-horizontal { + right: 0; +} +.os-host-rtl > .os-scrollbar-vertical { + right: auto; + left: 0; +} +.os-host-rtl > .os-scrollbar-corner { + right: auto; + left: 0; +} +.os-scrollbar-auto-hidden, +.os-padding + .os-scrollbar-corner, +.os-host-resize-disabled.os-host-scrollbar-horizontal-hidden > .os-scrollbar-corner, +.os-host-scrollbar-horizontal-hidden > .os-scrollbar-horizontal, +.os-host-resize-disabled.os-host-scrollbar-vertical-hidden > .os-scrollbar-corner, +.os-host-scrollbar-vertical-hidden > .os-scrollbar-vertical, +.os-scrollbar-horizontal.os-scrollbar-auto-hidden + .os-scrollbar-vertical + .os-scrollbar-corner, +.os-scrollbar-horizontal + .os-scrollbar-vertical.os-scrollbar-auto-hidden + .os-scrollbar-corner, +.os-scrollbar-horizontal.os-scrollbar-auto-hidden + .os-scrollbar-vertical.os-scrollbar-auto-hidden + .os-scrollbar-corner { + opacity: 0; + visibility: hidden; + pointer-events: none; +} +.os-scrollbar-corner-resize-both { + cursor: nwse-resize; +} +.os-host-rtl > .os-scrollbar-corner-resize-both { + cursor: nesw-resize; +} +.os-scrollbar-corner-resize-horizontal { + cursor: ew-resize; +} +.os-scrollbar-corner-resize-vertical { + cursor: ns-resize; +} +.os-dragging .os-scrollbar-corner.os-scrollbar-corner-resize { + cursor: default; +} +.os-host-resize-disabled.os-host-scrollbar-horizontal-hidden > .os-scrollbar-vertical { + top: 0; + bottom: 0; +} +.os-host-resize-disabled.os-host-scrollbar-vertical-hidden > .os-scrollbar-horizontal, +.os-host-rtl.os-host-resize-disabled.os-host-scrollbar-vertical-hidden > .os-scrollbar-horizontal { + right: 0; + left: 0; +} +.os-scrollbar:hover, +.os-scrollbar-corner.os-scrollbar-corner-resize { + opacity: 1 !important; + visibility: visible !important; +} +.os-scrollbar-corner.os-scrollbar-corner-resize { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgICB3aWR0aD0iMTAiICAgaGVpZ2h0PSIxMCIgICB2ZXJzaW9uPSIxLjEiPiAgPGcgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsLTEwNDIuMzYyMikiICAgICBzdHlsZT0iZGlzcGxheTppbmxpbmUiPiAgICA8cGF0aCAgICAgICBzdHlsZT0iZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eTowLjQ5NDExNzY1O2ZpbGwtcnVsZTpldmVub2RkO3N0cm9rZTpub25lIiAgICAgICBkPSJtIDcuNDI0MjE4NywxMDQyLjM2MjIgYyAtMC43MjM1NzkyLDAgLTEuMzEwMTU2MiwwLjU4NjYgLTEuMzEwMTU2MiwxLjMxMDIgMCwwLjI5OSAwLjEwNDM0MTksMC41NzEgMC4yNzI5NDkyLDAuNzkxNSAwLjIwOTEwMjQsMC4xNDEzIDAuNDY1NjIwNiwwLjIxODQgMC43MzY5NjI5LDAuMjE4NCAwLjcyMzU3OTMsMCAxLjMxMDE1NjMsLTAuNTg2NiAxLjMxMDE1NjMsLTEuMzEwMiAwLC0wLjI3MTMgLTAuMDc3MDkzLC0wLjUyNzggLTAuMjE4MzU5NCwtMC43MzcgLTAuMjIwNDk0MSwtMC4xNjg2IC0wLjQ5MjU0NDMsLTAuMjcyOSAtMC43OTE1NTI4LC0wLjI3MjkgeiBtIDAsMy4wODQzIGMgLTAuNzIzNTc5MiwwIC0xLjMxMDE1NjIsMC41ODY2IC0xLjMxMDE1NjIsMS4zMTAyIDAsMC4yOTkgMC4xMDQzNDE5LDAuNTcxIDAuMjcyOTQ5MiwwLjc5MTUgMC4yMDkxMDI0LDAuMTQxMyAwLjQ2NTYyMDYsMC4yMTg0IDAuNzM2OTYyOSwwLjIxODQgMC43MjM1NzkzLDAgMS4zMTAxNTYzLC0wLjU4NjYgMS4zMTAxNTYzLC0xLjMxMDIgMCwtMC4yNzEzIC0wLjA3NzA5MywtMC41Mjc4IC0wLjIxODM1OTQsLTAuNzM2OSAtMC4yMjA0OTQxLC0wLjE2ODYgLTAuNDkyNTQ0MywtMC4yNzMgLTAuNzkxNTUyOCwtMC4yNzMgeiBtIC0zLjA4NDMyNjEsMCBjIC0wLjcyMzU3OTMsMCAtMS4zMTAxNTYzLDAuNTg2NiAtMS4zMTAxNTYzLDEuMzEwMiAwLDAuMjk5IDAuMTA0MzQxOSwwLjU3MSAwLjI3Mjk0OTIsMC43OTE1IDAuMjA5MTAyNCwwLjE0MTMgMC40NjU2MjA3LDAuMjE4NCAwLjczNjk2MjksMC4yMTg0IDAuNzIzNTc5MywwIDEuMzEwMTU2MywtMC41ODY2IDEuMzEwMTU2MywtMS4zMTAyIDAsLTAuMjcxMyAtMC4wNzcwOTMsLTAuNTI3OCAtMC4yMTgzNTk0LC0wLjczNjkgLTAuMjIwNDk0LC0wLjE2ODYgLTAuNDkyNTQ0MiwtMC4yNzMgLTAuNzkxNTUyNywtMC4yNzMgeiBtIC0zLjAyOTczNjQsMy4wMjk4IEMgMC41ODY1NzY5MywxMDQ4LjQ3NjMgMCwxMDQ5LjA2MjggMCwxMDQ5Ljc4NjQgYyAwLDAuMjk5IDAuMTA0MzQxOSwwLjU3MTEgMC4yNzI5NDkyMiwwLjc5MTYgMC4yMDkxMDIyOSwwLjE0MTIgMC40NjU2MjA2NSwwLjIxODMgMC43MzY5NjI4OCwwLjIxODMgMC43MjM1NzkzLDAgMS4zMTAxNTYzLC0wLjU4NjUgMS4zMTAxNTYzLC0xLjMxMDEgMCwtMC4yNzE0IC0wLjA3NzA5MywtMC41Mjc5IC0wLjIxODM1OTQsLTAuNzM3IC0wLjIyMDQ5NDEsLTAuMTY4NiAtMC40OTI1NDQzLC0wLjI3MjkgLTAuNzkxNTUyOCwtMC4yNzI5IHogbSAzLjAyOTczNjQsMCBjIC0wLjcyMzU3OTMsMCAtMS4zMTAxNTYzLDAuNTg2NSAtMS4zMTAxNTYzLDEuMzEwMSAwLDAuMjk5IDAuMTA0MzQxOSwwLjU3MTEgMC4yNzI5NDkyLDAuNzkxNiAwLjIwOTEwMjQsMC4xNDEyIDAuNDY1NjIwNywwLjIxODMgMC43MzY5NjI5LDAuMjE4MyAwLjcyMzU3OTMsMCAxLjMxMDE1NjMsLTAuNTg2NSAxLjMxMDE1NjMsLTEuMzEwMSAwLC0wLjI3MTQgLTAuMDc3MDkzLC0wLjUyNzkgLTAuMjE4MzU5NCwtMC43MzcgLTAuMjIwNDk0LC0wLjE2ODYgLTAuNDkyNTQ0MiwtMC4yNzI5IC0wLjc5MTU1MjcsLTAuMjcyOSB6IG0gMy4wODQzMjYxLDAgYyAtMC43MjM1NzkyLDAgLTEuMzEwMTU2MiwwLjU4NjUgLTEuMzEwMTU2MiwxLjMxMDEgMCwwLjI5OSAwLjEwNDM0MTksMC41NzExIDAuMjcyOTQ5MiwwLjc5MTYgMC4yMDkxMDI0LDAuMTQxMiAwLjQ2NTYyMDYsMC4yMTgzIDAuNzM2OTYyOSwwLjIxODMgMC43MjM1NzkzLDAgMS4zMTAxNTYzLC0wLjU4NjUgMS4zMTAxNTYzLC0xLjMxMDEgMCwtMC4yNzE0IC0wLjA3NzA5MywtMC41Mjc5IC0wLjIxODM1OTQsLTAuNzM3IC0wLjIyMDQ5NDEsLTAuMTY4NiAtMC40OTI1NDQzLC0wLjI3MjkgLTAuNzkxNTUyOCwtMC4yNzI5IHoiLz4gIDwvZz4gIDxnICAgICBzdHlsZT0iZGlzcGxheTppbmxpbmUiPiAgICA8cGF0aCAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpldmVub2RkO3N0cm9rZTpub25lIiAgICAgICBkPSJtIDguMjE1NzcxNSwwLjI3Mjk0OTIyIGMgMC4xNDEyNjY3LDAuMjA5MTAyMjkgMC4yMTgzNTk0LDAuNDY1NjIwNjUgMC4yMTgzNTk0LDAuNzM2OTYyODggMCwwLjcyMzU3OTMgLTAuNTg2NTc3LDEuMzEwMTU2MyAtMS4zMTAxNTYzLDEuMzEwMTU2MyAtMC4yNzEzNDIzLDAgLTAuNTI3ODYwNSwtMC4wNzcwOTMgLTAuNzM2OTYyOSwtMC4yMTgzNTk0IDAuMjM5NDEwNCwwLjMxMzA4NTkgMC42MTI2MzYyLDAuNTE4NjAzNSAxLjAzNzIwNywwLjUxODYwMzUgMC43MjM1NzkzLDAgMS4zMTAxNTYzLC0wLjU4NjU3NyAxLjMxMDE1NjMsLTEuMzEwMTU2MyAwLC0wLjQyNDU3MDc2IC0wLjIwNTUxNzYsLTAuNzk3Nzk2NTkgLTAuNTE4NjAzNSwtMS4wMzcyMDY5OCB6IG0gMCwzLjA4NDMyNjE4IGMgMC4xNDEyNjY3LDAuMjA5MTAyMyAwLjIxODM1OTQsMC40NjU2MjA2IDAuMjE4MzU5NCwwLjczNjk2MjkgMCwwLjcyMzU3OTMgLTAuNTg2NTc3LDEuMzEwMTU2MiAtMS4zMTAxNTYzLDEuMzEwMTU2MiAtMC4yNzEzNDIzLDAgLTAuNTI3ODYwNSwtMC4wNzcwOTMgLTAuNzM2OTYyOSwtMC4yMTgzNTkzIDAuMjM5NDEwNCwwLjMxMzA4NTkgMC42MTI2MzYyLDAuNTE4NjAzNSAxLjAzNzIwNywwLjUxODYwMzUgMC43MjM1NzkzLDAgMS4zMTAxNTYzLC0wLjU4NjU3NyAxLjMxMDE1NjMsLTEuMzEwMTU2MyAwLC0wLjQyNDU3MDggLTAuMjA1NTE3NiwtMC43OTc3OTY3IC0wLjUxODYwMzUsLTEuMDM3MjA3IHogbSAtMy4wODQzMjYyLDAgYyAwLjE0MTI2NjcsMC4yMDkxMDIzIDAuMjE4MzU5NCwwLjQ2NTYyMDYgMC4yMTgzNTk0LDAuNzM2OTYyOSAwLDAuNzIzNTc5MyAtMC41ODY1NzcsMS4zMTAxNTYyIC0xLjMxMDE1NjMsMS4zMTAxNTYyIC0wLjI3MTM0MjIsMCAtMC41Mjc4NjA1LC0wLjA3NzA5MyAtMC43MzY5NjI5LC0wLjIxODM1OTMgMC4yMzk0MTA0LDAuMzEzMDg1OSAwLjYxMjYzNjMsMC41MTg2MDM1IDEuMDM3MjA3MSwwLjUxODYwMzUgMC43MjM1NzkzLDAgMS4zMTAxNTYyLC0wLjU4NjU3NyAxLjMxMDE1NjIsLTEuMzEwMTU2MyAwLC0wLjQyNDU3MDggLTAuMjA1NTE3NSwtMC43OTc3OTY3IC0wLjUxODYwMzUsLTEuMDM3MjA3IHogTSAyLjEwMTcwOSw2LjM4NzAxMTcgYyAwLjE0MTI2NjcsMC4yMDkxMDI0IDAuMjE4MzU5NCwwLjQ2NTYyMDYgMC4yMTgzNTk0LDAuNzM2OTYyOSAwLDAuNzIzNTc5MyAtMC41ODY1NzcsMS4zMTAxNTYzIC0xLjMxMDE1NjMsMS4zMTAxNTYzIC0wLjI3MTM0MjIzLDAgLTAuNTI3ODYwNTksLTAuMDc3MDkzIC0wLjczNjk2Mjg4LC0wLjIxODM1OTQgMC4yMzk0MTAzOSwwLjMxMzA4NTkgMC42MTI2MzYyMiwwLjUxODYwMzUgMS4wMzcyMDY5OCwwLjUxODYwMzUgMC43MjM1NzkzLDAgMS4zMTAxNTYzLC0wLjU4NjU3NyAxLjMxMDE1NjMsLTEuMzEwMTU2MyAwLC0wLjQyNDU3MDggLTAuMjA1NTE3NiwtMC43OTc3OTY2IC0wLjUxODYwMzUsLTEuMDM3MjA3IHogbSAzLjAyOTczNjMsMCBjIDAuMTQxMjY2NywwLjIwOTEwMjQgMC4yMTgzNTk0LDAuNDY1NjIwNiAwLjIxODM1OTQsMC43MzY5NjI5IDAsMC43MjM1NzkzIC0wLjU4NjU3NywxLjMxMDE1NjMgLTEuMzEwMTU2MywxLjMxMDE1NjMgLTAuMjcxMzQyMiwwIC0wLjUyNzg2MDUsLTAuMDc3MDkzIC0wLjczNjk2MjksLTAuMjE4MzU5NCAwLjIzOTQxMDQsMC4zMTMwODU5IDAuNjEyNjM2MywwLjUxODYwMzUgMS4wMzcyMDcxLDAuNTE4NjAzNSAwLjcyMzU3OTMsMCAxLjMxMDE1NjIsLTAuNTg2NTc3IDEuMzEwMTU2MiwtMS4zMTAxNTYzIDAsLTAuNDI0NTcwOCAtMC4yMDU1MTc1LC0wLjc5Nzc5NjYgLTAuNTE4NjAzNSwtMS4wMzcyMDcgeiBtIDMuMDg0MzI2MiwwIGMgMC4xNDEyNjY3LDAuMjA5MTAyNCAwLjIxODM1OTQsMC40NjU2MjA2IDAuMjE4MzU5NCwwLjczNjk2MjkgMCwwLjcyMzU3OTMgLTAuNTg2NTc3LDEuMzEwMTU2MyAtMS4zMTAxNTYzLDEuMzEwMTU2MyAtMC4yNzEzNDIzLDAgLTAuNTI3ODYwNSwtMC4wNzcwOTMgLTAuNzM2OTYyOSwtMC4yMTgzNTk0IDAuMjM5NDEwNCwwLjMxMzA4NTkgMC42MTI2MzYyLDAuNTE4NjAzNSAxLjAzNzIwNywwLjUxODYwMzUgMC43MjM1NzkzLDAgMS4zMTAxNTYzLC0wLjU4NjU3NyAxLjMxMDE1NjMsLTEuMzEwMTU2MyAwLC0wLjQyNDU3MDggLTAuMjA1NTE3NiwtMC43OTc3OTY2IC0wLjUxODYwMzUsLTEuMDM3MjA3IHoiIC8+ICA8L2c+PC9zdmc+); + background-repeat: no-repeat; + background-position: 100% 100%; + pointer-events: auto !important; +} +.os-host-rtl > .os-scrollbar-corner.os-scrollbar-corner-resize { + transform: scale(-1, 1); +} +.os-host-overflow { + overflow: hidden !important; +} +.os-host-overflow-x { +} +.os-host-overflow-y { +} + +/* +THEMES: +*/ + +/* NONE THEME: */ +.os-theme-none > .os-scrollbar-horizontal, +.os-theme-none > .os-scrollbar-vertical, +.os-theme-none > .os-scrollbar-corner { + display: none !important; +} +.os-theme-none > .os-scrollbar-corner-resize { + display: block !important; + min-width: 10px; + min-height: 10px; +} +/* DARK & LIGHT THEME: */ +.os-theme-dark > .os-scrollbar-horizontal, +.os-theme-light > .os-scrollbar-horizontal { + right: 10px; + height: 10px; +} +.os-theme-dark > .os-scrollbar-vertical, +.os-theme-light > .os-scrollbar-vertical { + bottom: 10px; + width: 10px; +} +.os-theme-dark.os-host-rtl > .os-scrollbar-horizontal, +.os-theme-light.os-host-rtl > .os-scrollbar-horizontal { + left: 10px; + right: 0; +} +.os-theme-dark > .os-scrollbar-corner, +.os-theme-light > .os-scrollbar-corner { + height: 10px; + width: 10px; +} +.os-theme-dark > .os-scrollbar-corner, +.os-theme-light > .os-scrollbar-corner { + background-color: transparent; +} +.os-theme-dark > .os-scrollbar, +.os-theme-light > .os-scrollbar { + padding: 2px; + box-sizing: border-box; + background: transparent; +} +.os-theme-dark > .os-scrollbar.os-scrollbar-unusable, +.os-theme-light > .os-scrollbar.os-scrollbar-unusable { + background: transparent; +} +.os-theme-dark > .os-scrollbar > .os-scrollbar-track, +.os-theme-light > .os-scrollbar > .os-scrollbar-track { + background: transparent; +} +.os-theme-dark > .os-scrollbar-horizontal > .os-scrollbar-track > .os-scrollbar-handle, +.os-theme-light > .os-scrollbar-horizontal > .os-scrollbar-track > .os-scrollbar-handle { + min-width: 30px; +} +.os-theme-dark > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle, +.os-theme-light > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle { + min-height: 30px; +} +.os-theme-dark.os-host-transition > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle, +.os-theme-light.os-host-transition > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle { + transition: background-color 0.3s; +} +.os-theme-dark > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle, +.os-theme-light > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle, +.os-theme-dark > .os-scrollbar > .os-scrollbar-track, +.os-theme-light > .os-scrollbar > .os-scrollbar-track { + border-radius: 10px; +} +.os-theme-dark > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle { + background: rgba(0, 0, 0, 0.4); +} +.os-theme-light > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle { + background: rgba(255, 255, 255, 0.4); +} +.os-theme-dark > .os-scrollbar:hover > .os-scrollbar-track > .os-scrollbar-handle { + background: rgba(0, 0, 0, .55); +} +.os-theme-light > .os-scrollbar:hover > .os-scrollbar-track > .os-scrollbar-handle { + background: rgba(255, 255, 255, .55); +} +.os-theme-dark > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle.active { + background: rgba(0, 0, 0, .7); +} +.os-theme-light > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle.active { + background: rgba(255, 255, 255, .7); +} +.os-theme-dark > .os-scrollbar-horizontal .os-scrollbar-handle:before, +.os-theme-dark > .os-scrollbar-vertical .os-scrollbar-handle:before, +.os-theme-light > .os-scrollbar-horizontal .os-scrollbar-handle:before, +.os-theme-light > .os-scrollbar-vertical .os-scrollbar-handle:before { + content: ''; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + display: block; +} +.os-theme-dark.os-host-scrollbar-horizontal-hidden > .os-scrollbar-horizontal .os-scrollbar-handle:before, +.os-theme-dark.os-host-scrollbar-vertical-hidden > .os-scrollbar-vertical .os-scrollbar-handle:before, +.os-theme-light.os-host-scrollbar-horizontal-hidden > .os-scrollbar-horizontal .os-scrollbar-handle:before, +.os-theme-light.os-host-scrollbar-vertical-hidden > .os-scrollbar-vertical .os-scrollbar-handle:before { + display: none; +} +.os-theme-dark > .os-scrollbar-horizontal .os-scrollbar-handle:before, +.os-theme-light > .os-scrollbar-horizontal .os-scrollbar-handle:before { + top: -6px; + bottom: -2px; +} +.os-theme-dark > .os-scrollbar-vertical .os-scrollbar-handle:before, +.os-theme-light > .os-scrollbar-vertical .os-scrollbar-handle:before { + left: -6px; + right: -2px; +} +.os-host-rtl.os-theme-dark > .os-scrollbar-vertical .os-scrollbar-handle:before, +.os-host-rtl.os-theme-light > .os-scrollbar-vertical .os-scrollbar-handle:before { + right: -6px; + left: -2px; +} + +/*!************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/node_modules/tippy.js/dist/tippy.css ***! + \************************************************************************************************************************************************************************************************/ +.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} +/*!**********************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/node_modules/swiper/swiper.min.css ***! + \**********************************************************************************************************************************************************************************************/ +/** + * Swiper 7.0.9 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * https://swiperjs.com + * + * Copyright 2014-2021 Vladimir Kharlampidi + * + * Released under the MIT License + * + * Released on: October 18, 2021 + */ + +@font-face{font-family:swiper-icons;src:url('data:application/font-woff;charset=utf-8;base64, d09GRgABAAAAAAZgABAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAGRAAAABoAAAAci6qHkUdERUYAAAWgAAAAIwAAACQAYABXR1BPUwAABhQAAAAuAAAANuAY7+xHU1VCAAAFxAAAAFAAAABm2fPczU9TLzIAAAHcAAAASgAAAGBP9V5RY21hcAAAAkQAAACIAAABYt6F0cBjdnQgAAACzAAAAAQAAAAEABEBRGdhc3AAAAWYAAAACAAAAAj//wADZ2x5ZgAAAywAAADMAAAD2MHtryVoZWFkAAABbAAAADAAAAA2E2+eoWhoZWEAAAGcAAAAHwAAACQC9gDzaG10eAAAAigAAAAZAAAArgJkABFsb2NhAAAC0AAAAFoAAABaFQAUGG1heHAAAAG8AAAAHwAAACAAcABAbmFtZQAAA/gAAAE5AAACXvFdBwlwb3N0AAAFNAAAAGIAAACE5s74hXjaY2BkYGAAYpf5Hu/j+W2+MnAzMYDAzaX6QjD6/4//Bxj5GA8AuRwMYGkAPywL13jaY2BkYGA88P8Agx4j+/8fQDYfA1AEBWgDAIB2BOoAeNpjYGRgYNBh4GdgYgABEMnIABJzYNADCQAACWgAsQB42mNgYfzCOIGBlYGB0YcxjYGBwR1Kf2WQZGhhYGBiYGVmgAFGBiQQkOaawtDAoMBQxXjg/wEGPcYDDA4wNUA2CCgwsAAAO4EL6gAAeNpj2M0gyAACqxgGNWBkZ2D4/wMA+xkDdgAAAHjaY2BgYGaAYBkGRgYQiAHyGMF8FgYHIM3DwMHABGQrMOgyWDLEM1T9/w8UBfEMgLzE////P/5//f/V/xv+r4eaAAeMbAxwIUYmIMHEgKYAYjUcsDAwsLKxc3BycfPw8jEQA/gZBASFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTQZBgMAAMR+E+gAEQFEAAAAKgAqACoANAA+AEgAUgBcAGYAcAB6AIQAjgCYAKIArAC2AMAAygDUAN4A6ADyAPwBBgEQARoBJAEuATgBQgFMAVYBYAFqAXQBfgGIAZIBnAGmAbIBzgHsAAB42u2NMQ6CUAyGW568x9AneYYgm4MJbhKFaExIOAVX8ApewSt4Bic4AfeAid3VOBixDxfPYEza5O+Xfi04YADggiUIULCuEJK8VhO4bSvpdnktHI5QCYtdi2sl8ZnXaHlqUrNKzdKcT8cjlq+rwZSvIVczNiezsfnP/uznmfPFBNODM2K7MTQ45YEAZqGP81AmGGcF3iPqOop0r1SPTaTbVkfUe4HXj97wYE+yNwWYxwWu4v1ugWHgo3S1XdZEVqWM7ET0cfnLGxWfkgR42o2PvWrDMBSFj/IHLaF0zKjRgdiVMwScNRAoWUoH78Y2icB/yIY09An6AH2Bdu/UB+yxopYshQiEvnvu0dURgDt8QeC8PDw7Fpji3fEA4z/PEJ6YOB5hKh4dj3EvXhxPqH/SKUY3rJ7srZ4FZnh1PMAtPhwP6fl2PMJMPDgeQ4rY8YT6Gzao0eAEA409DuggmTnFnOcSCiEiLMgxCiTI6Cq5DZUd3Qmp10vO0LaLTd2cjN4fOumlc7lUYbSQcZFkutRG7g6JKZKy0RmdLY680CDnEJ+UMkpFFe1RN7nxdVpXrC4aTtnaurOnYercZg2YVmLN/d/gczfEimrE/fs/bOuq29Zmn8tloORaXgZgGa78yO9/cnXm2BpaGvq25Dv9S4E9+5SIc9PqupJKhYFSSl47+Qcr1mYNAAAAeNptw0cKwkAAAMDZJA8Q7OUJvkLsPfZ6zFVERPy8qHh2YER+3i/BP83vIBLLySsoKimrqKqpa2hp6+jq6RsYGhmbmJqZSy0sraxtbO3sHRydnEMU4uR6yx7JJXveP7WrDycAAAAAAAH//wACeNpjYGRgYOABYhkgZgJCZgZNBkYGLQZtIJsFLMYAAAw3ALgAeNolizEKgDAQBCchRbC2sFER0YD6qVQiBCv/H9ezGI6Z5XBAw8CBK/m5iQQVauVbXLnOrMZv2oLdKFa8Pjuru2hJzGabmOSLzNMzvutpB3N42mNgZGBg4GKQYzBhYMxJLMlj4GBgAYow/P/PAJJhLM6sSoWKfWCAAwDAjgbRAAB42mNgYGBkAIIbCZo5IPrmUn0hGA0AO8EFTQAA');font-weight:400;font-style:normal}:root{--swiper-theme-color:#007aff}.swiper{margin-left:auto;margin-right:auto;position:relative;overflow:hidden;list-style:none;padding:0;z-index:1}.swiper-vertical>.swiper-wrapper{flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:flex;transition-property:transform;box-sizing:content-box}.swiper-android .swiper-slide,.swiper-wrapper{transform:translate3d(0px,0,0)}.swiper-pointer-events{touch-action:pan-y}.swiper-pointer-events.swiper-vertical{touch-action:pan-x}.swiper-slide{flex-shrink:0;width:100%;height:100%;position:relative;transition-property:transform}.swiper-slide-invisible-blank{visibility:hidden}.swiper-autoheight,.swiper-autoheight .swiper-slide{height:auto}.swiper-autoheight .swiper-wrapper{align-items:flex-start;transition-property:transform,height}.swiper-3d,.swiper-3d.swiper-css-mode .swiper-wrapper{perspective:1200px}.swiper-3d .swiper-cube-shadow,.swiper-3d .swiper-slide,.swiper-3d .swiper-slide-shadow,.swiper-3d .swiper-slide-shadow-bottom,.swiper-3d .swiper-slide-shadow-left,.swiper-3d .swiper-slide-shadow-right,.swiper-3d .swiper-slide-shadow-top,.swiper-3d .swiper-wrapper{transform-style:preserve-3d}.swiper-3d .swiper-slide-shadow,.swiper-3d .swiper-slide-shadow-bottom,.swiper-3d .swiper-slide-shadow-left,.swiper-3d .swiper-slide-shadow-right,.swiper-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-3d .swiper-slide-shadow{background:rgba(0,0,0,.15)}.swiper-3d .swiper-slide-shadow-left{background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-3d .swiper-slide-shadow-right{background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-3d .swiper-slide-shadow-top{background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-3d .swiper-slide-shadow-bottom{background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-css-mode>.swiper-wrapper{overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.swiper-css-mode>.swiper-wrapper::-webkit-scrollbar{display:none}.swiper-css-mode>.swiper-wrapper>.swiper-slide{scroll-snap-align:start start}.swiper-horizontal.swiper-css-mode>.swiper-wrapper{-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory}.swiper-vertical.swiper-css-mode>.swiper-wrapper{-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory}.swiper-centered>.swiper-wrapper::before{content:'';flex-shrink:0;order:9999}.swiper-centered.swiper-horizontal>.swiper-wrapper>.swiper-slide:first-child{-webkit-margin-start:var(--swiper-centered-offset-before);margin-inline-start:var(--swiper-centered-offset-before)}.swiper-centered.swiper-horizontal>.swiper-wrapper::before{height:100%;min-height:1px;width:var(--swiper-centered-offset-after)}.swiper-centered.swiper-vertical>.swiper-wrapper>.swiper-slide:first-child{-webkit-margin-before:var(--swiper-centered-offset-before);margin-block-start:var(--swiper-centered-offset-before)}.swiper-centered.swiper-vertical>.swiper-wrapper::before{width:100%;min-width:1px;height:var(--swiper-centered-offset-after)}.swiper-centered>.swiper-wrapper>.swiper-slide{scroll-snap-align:center center} +/*!*********************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/node_modules/swiper/modules/navigation/navigation.min.css ***! + \*********************************************************************************************************************************************************************************************************************/ +:root{--swiper-navigation-size:44px}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:calc(var(--swiper-navigation-size)/ 44 * 27);height:var(--swiper-navigation-size);margin-top:calc(0px - (var(--swiper-navigation-size)/ 2));z-index:10;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--swiper-navigation-color,var(--swiper-theme-color))}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-next:after,.swiper-button-prev:after{font-family:swiper-icons;font-size:var(--swiper-navigation-size);text-transform:none!important;letter-spacing:0;text-transform:none;font-variant:initial;line-height:1}.swiper-button-prev,.swiper-rtl .swiper-button-next{left:10px;right:auto}.swiper-button-prev:after,.swiper-rtl .swiper-button-next:after{content:'prev'}.swiper-button-next,.swiper-rtl .swiper-button-prev{right:10px;left:auto}.swiper-button-next:after,.swiper-rtl .swiper-button-prev:after{content:'next'}.swiper-button-lock{display:none} +/*!*****************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/node_modules/swiper/modules/keyboard/keyboard.min.css ***! + \*****************************************************************************************************************************************************************************************************************/ + +/*!*********************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/node_modules/swiper/modules/mousewheel/mousewheel.min.css ***! + \*********************************************************************************************************************************************************************************************************************/ + +/*!*********************************************************************************************************************************************************************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!../eyes/node_modules/swiper/modules/pagination/pagination.min.css ***! + \*********************************************************************************************************************************************************************************************************************/ +.swiper-pagination{position:absolute;text-align:center;transition:.3s opacity;transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-horizontal>.swiper-pagination-bullets,.swiper-pagination-bullets.swiper-pagination-horizontal,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullets-dynamic{overflow:hidden;font-size:0}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transform:scale(.33);position:relative}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active{transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main{transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev{transform:scale(.33)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next{transform:scale(.33)}.swiper-pagination-bullet{width:var(--swiper-pagination-bullet-width,var(--swiper-pagination-bullet-size,8px));height:var(--swiper-pagination-bullet-height,var(--swiper-pagination-bullet-size,8px));display:inline-block;border-radius:50%;background:var(--swiper-pagination-bullet-inactive-color,#000);opacity:var(--swiper-pagination-bullet-inactive-opacity, .2)}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-bullet:only-child{display:none!important}.swiper-pagination-bullet-active{opacity:var(--swiper-pagination-bullet-opacity, 1);background:var(--swiper-pagination-color,var(--swiper-theme-color))}.swiper-pagination-vertical.swiper-pagination-bullets,.swiper-vertical>.swiper-pagination-bullets{right:10px;top:50%;transform:translate3d(0px,-50%,0)}.swiper-pagination-vertical.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:var(--swiper-pagination-bullet-vertical-gap,6px) 0;display:block}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{top:50%;transform:translateY(-50%);width:8px}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{display:inline-block;transition:.2s transform,.2s top}.swiper-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 var(--swiper-pagination-bullet-horizontal-gap,4px)}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{left:50%;transform:translateX(-50%);white-space:nowrap}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:.2s transform,.2s left}.swiper-horizontal.swiper-rtl>.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:.2s transform,.2s right}.swiper-pagination-progressbar{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:var(--swiper-pagination-color,var(--swiper-theme-color));position:absolute;left:0;top:0;width:100%;height:100%;transform:scale(0);transform-origin:left top}.swiper-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{transform-origin:right top}.swiper-horizontal>.swiper-pagination-progressbar,.swiper-pagination-progressbar.swiper-pagination-horizontal,.swiper-pagination-progressbar.swiper-pagination-vertical.swiper-pagination-progressbar-opposite,.swiper-vertical>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite{width:100%;height:4px;left:0;top:0}.swiper-horizontal>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-horizontal.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-vertical,.swiper-vertical>.swiper-pagination-progressbar{width:4px;height:100%;left:0;top:0}.swiper-pagination-lock{display:none} + +/*# sourceMappingURL=vendors.css.map*/ \ No newline at end of file diff --git a/experiences/asteroids/web/vendors.js b/experiences/asteroids/web/vendors.js new file mode 100644 index 0000000..fee9f43 --- /dev/null +++ b/experiences/asteroids/web/vendors.js @@ -0,0 +1,119440 @@ +(self["webpackChunkasteroids"] = self["webpackChunkasteroids"] || []).push([["vendors"],{ + +/***/ "../eyes/node_modules/overlayscrollbars/css/OverlayScrollbars.css": +/*!************************************************************************!*\ + !*** ../eyes/node_modules/overlayscrollbars/css/OverlayScrollbars.css ***! + \************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/node_modules/swiper/modules/keyboard/keyboard.min.css": +/*!*********************************************************************!*\ + !*** ../eyes/node_modules/swiper/modules/keyboard/keyboard.min.css ***! + \*********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/node_modules/swiper/modules/mousewheel/mousewheel.min.css": +/*!*************************************************************************!*\ + !*** ../eyes/node_modules/swiper/modules/mousewheel/mousewheel.min.css ***! + \*************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/node_modules/swiper/modules/navigation/navigation.min.css": +/*!*************************************************************************!*\ + !*** ../eyes/node_modules/swiper/modules/navigation/navigation.min.css ***! + \*************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/node_modules/swiper/modules/pagination/pagination.min.css": +/*!*************************************************************************!*\ + !*** ../eyes/node_modules/swiper/modules/pagination/pagination.min.css ***! + \*************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/node_modules/swiper/swiper.min.css": +/*!**************************************************!*\ + !*** ../eyes/node_modules/swiper/swiper.min.css ***! + \**************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/node_modules/tippy.js/dist/tippy.css": +/*!****************************************************!*\ + !*** ../eyes/node_modules/tippy.js/dist/tippy.css ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +// extracted by mini-css-extract-plugin + + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/createPopper.js": +/*!***************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/createPopper.js ***! + \***************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "popperGenerator": function() { return /* binding */ popperGenerator; }, +/* harmony export */ "createPopper": function() { return /* binding */ createPopper; }, +/* harmony export */ "detectOverflow": function() { return /* reexport safe */ _utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_13__["default"]; } +/* harmony export */ }); +/* harmony import */ var _dom_utils_getCompositeRect_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./dom-utils/getCompositeRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js"); +/* harmony import */ var _dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./dom-utils/getLayoutRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js"); +/* harmony import */ var _dom_utils_listScrollParents_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./dom-utils/listScrollParents.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js"); +/* harmony import */ var _dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./dom-utils/getOffsetParent.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js"); +/* harmony import */ var _dom_utils_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./dom-utils/getComputedStyle.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js"); +/* harmony import */ var _utils_orderModifiers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils/orderModifiers.js */ "../eyes/node_modules/@popperjs/core/lib/utils/orderModifiers.js"); +/* harmony import */ var _utils_debounce_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./utils/debounce.js */ "../eyes/node_modules/@popperjs/core/lib/utils/debounce.js"); +/* harmony import */ var _utils_validateModifiers_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils/validateModifiers.js */ "../eyes/node_modules/@popperjs/core/lib/utils/validateModifiers.js"); +/* harmony import */ var _utils_uniqueBy_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./utils/uniqueBy.js */ "../eyes/node_modules/@popperjs/core/lib/utils/uniqueBy.js"); +/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./utils/getBasePlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getBasePlacement.js"); +/* harmony import */ var _utils_mergeByName_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils/mergeByName.js */ "../eyes/node_modules/@popperjs/core/lib/utils/mergeByName.js"); +/* harmony import */ var _utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./utils/detectOverflow.js */ "../eyes/node_modules/@popperjs/core/lib/utils/detectOverflow.js"); +/* harmony import */ var _dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./dom-utils/instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); + + + + + + + + + + + + + + +var INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.'; +var INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.'; +var DEFAULT_OPTIONS = { + placement: 'bottom', + modifiers: [], + strategy: 'absolute' +}; + +function areValidElements() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return !args.some(function (element) { + return !(element && typeof element.getBoundingClientRect === 'function'); + }); +} + +function popperGenerator(generatorOptions) { + if (generatorOptions === void 0) { + generatorOptions = {}; + } + + var _generatorOptions = generatorOptions, + _generatorOptions$def = _generatorOptions.defaultModifiers, + defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, + _generatorOptions$def2 = _generatorOptions.defaultOptions, + defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; + return function createPopper(reference, popper, options) { + if (options === void 0) { + options = defaultOptions; + } + + var state = { + placement: 'bottom', + orderedModifiers: [], + options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), + modifiersData: {}, + elements: { + reference: reference, + popper: popper + }, + attributes: {}, + styles: {} + }; + var effectCleanupFns = []; + var isDestroyed = false; + var instance = { + state: state, + setOptions: function setOptions(setOptionsAction) { + var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction; + cleanupModifierEffects(); + state.options = Object.assign({}, defaultOptions, state.options, options); + state.scrollParents = { + reference: (0,_dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isElement)(reference) ? (0,_dom_utils_listScrollParents_js__WEBPACK_IMPORTED_MODULE_1__["default"])(reference) : reference.contextElement ? (0,_dom_utils_listScrollParents_js__WEBPACK_IMPORTED_MODULE_1__["default"])(reference.contextElement) : [], + popper: (0,_dom_utils_listScrollParents_js__WEBPACK_IMPORTED_MODULE_1__["default"])(popper) + }; // Orders the modifiers based on their dependencies and `phase` + // properties + + var orderedModifiers = (0,_utils_orderModifiers_js__WEBPACK_IMPORTED_MODULE_2__["default"])((0,_utils_mergeByName_js__WEBPACK_IMPORTED_MODULE_3__["default"])([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers + + state.orderedModifiers = orderedModifiers.filter(function (m) { + return m.enabled; + }); // Validate the provided modifiers so that the consumer will get warned + // if one of the modifiers is invalid for any reason + + if (true) { + var modifiers = (0,_utils_uniqueBy_js__WEBPACK_IMPORTED_MODULE_4__["default"])([].concat(orderedModifiers, state.options.modifiers), function (_ref) { + var name = _ref.name; + return name; + }); + (0,_utils_validateModifiers_js__WEBPACK_IMPORTED_MODULE_5__["default"])(modifiers); + + if ((0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_6__["default"])(state.options.placement) === _enums_js__WEBPACK_IMPORTED_MODULE_7__.auto) { + var flipModifier = state.orderedModifiers.find(function (_ref2) { + var name = _ref2.name; + return name === 'flip'; + }); + + if (!flipModifier) { + console.error(['Popper: "auto" placements require the "flip" modifier be', 'present and enabled to work.'].join(' ')); + } + } + + var _getComputedStyle = (0,_dom_utils_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_8__["default"])(popper), + marginTop = _getComputedStyle.marginTop, + marginRight = _getComputedStyle.marginRight, + marginBottom = _getComputedStyle.marginBottom, + marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can + // cause bugs with positioning, so we'll warn the consumer + + + if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) { + return parseFloat(margin); + })) { + console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' ')); + } + } + + runModifierEffects(); + return instance.update(); + }, + // Sync update – it will always be executed, even if not necessary. This + // is useful for low frequency updates where sync behavior simplifies the + // logic. + // For high frequency updates (e.g. `resize` and `scroll` events), always + // prefer the async Popper#update method + forceUpdate: function forceUpdate() { + if (isDestroyed) { + return; + } + + var _state$elements = state.elements, + reference = _state$elements.reference, + popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements + // anymore + + if (!areValidElements(reference, popper)) { + if (true) { + console.error(INVALID_ELEMENT_ERROR); + } + + return; + } // Store the reference and popper rects to be read by modifiers + + + state.rects = { + reference: (0,_dom_utils_getCompositeRect_js__WEBPACK_IMPORTED_MODULE_9__["default"])(reference, (0,_dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_10__["default"])(popper), state.options.strategy === 'fixed'), + popper: (0,_dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_11__["default"])(popper) + }; // Modifiers have the ability to reset the current update cycle. The + // most common use case for this is the `flip` modifier changing the + // placement, which then needs to re-run all the modifiers, because the + // logic was previously ran for the previous placement and is therefore + // stale/incorrect + + state.reset = false; + state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier + // is filled with the initial data specified by the modifier. This means + // it doesn't persist and is fresh on each update. + // To ensure persistent data, use `${name}#persistent` + + state.orderedModifiers.forEach(function (modifier) { + return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); + }); + var __debug_loops__ = 0; + + for (var index = 0; index < state.orderedModifiers.length; index++) { + if (true) { + __debug_loops__ += 1; + + if (__debug_loops__ > 100) { + console.error(INFINITE_LOOP_ERROR); + break; + } + } + + if (state.reset === true) { + state.reset = false; + index = -1; + continue; + } + + var _state$orderedModifie = state.orderedModifiers[index], + fn = _state$orderedModifie.fn, + _state$orderedModifie2 = _state$orderedModifie.options, + _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, + name = _state$orderedModifie.name; + + if (typeof fn === 'function') { + state = fn({ + state: state, + options: _options, + name: name, + instance: instance + }) || state; + } + } + }, + // Async and optimistically optimized update – it will not be executed if + // not necessary (debounced to run at most once-per-tick) + update: (0,_utils_debounce_js__WEBPACK_IMPORTED_MODULE_12__["default"])(function () { + return new Promise(function (resolve) { + instance.forceUpdate(); + resolve(state); + }); + }), + destroy: function destroy() { + cleanupModifierEffects(); + isDestroyed = true; + } + }; + + if (!areValidElements(reference, popper)) { + if (true) { + console.error(INVALID_ELEMENT_ERROR); + } + + return instance; + } + + instance.setOptions(options).then(function (state) { + if (!isDestroyed && options.onFirstUpdate) { + options.onFirstUpdate(state); + } + }); // Modifiers have the ability to execute arbitrary code before the first + // update cycle runs. They will be executed in the same order as the update + // cycle. This is useful when a modifier adds some persistent data that + // other modifiers need to use, but the modifier is run after the dependent + // one. + + function runModifierEffects() { + state.orderedModifiers.forEach(function (_ref3) { + var name = _ref3.name, + _ref3$options = _ref3.options, + options = _ref3$options === void 0 ? {} : _ref3$options, + effect = _ref3.effect; + + if (typeof effect === 'function') { + var cleanupFn = effect({ + state: state, + name: name, + instance: instance, + options: options + }); + + var noopFn = function noopFn() {}; + + effectCleanupFns.push(cleanupFn || noopFn); + } + }); + } + + function cleanupModifierEffects() { + effectCleanupFns.forEach(function (fn) { + return fn(); + }); + effectCleanupFns = []; + } + + return instance; + }; +} +var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules + + + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/contains.js": +/*!*********************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/contains.js ***! + \*********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ contains; } +/* harmony export */ }); +/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); + +function contains(parent, child) { + var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method + + if (parent.contains(child)) { + return true; + } // then fallback to custom implementation with Shadow DOM support + else if (rootNode && (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isShadowRoot)(rootNode)) { + var next = child; + + do { + if (next && parent.isSameNode(next)) { + return true; + } // $FlowFixMe[prop-missing]: need a better way to handle this... + + + next = next.parentNode || next.host; + } while (next); + } // Give up, the result is false + + + return false; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js": +/*!**********************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js ***! + \**********************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getBoundingClientRect; } +/* harmony export */ }); +/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); +/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/math.js */ "../eyes/node_modules/@popperjs/core/lib/utils/math.js"); +/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getWindow.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js"); +/* harmony import */ var _isLayoutViewport_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./isLayoutViewport.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js"); + + + + +function getBoundingClientRect(element, includeScale, isFixedStrategy) { + if (includeScale === void 0) { + includeScale = false; + } + + if (isFixedStrategy === void 0) { + isFixedStrategy = false; + } + + var clientRect = element.getBoundingClientRect(); + var scaleX = 1; + var scaleY = 1; + + if (includeScale && (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element)) { + scaleX = element.offsetWidth > 0 ? (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_1__.round)(clientRect.width) / element.offsetWidth || 1 : 1; + scaleY = element.offsetHeight > 0 ? (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_1__.round)(clientRect.height) / element.offsetHeight || 1 : 1; + } + + var _ref = (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isElement)(element) ? (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_2__["default"])(element) : window, + visualViewport = _ref.visualViewport; + + var addVisualOffsets = !(0,_isLayoutViewport_js__WEBPACK_IMPORTED_MODULE_3__["default"])() && isFixedStrategy; + var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX; + var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY; + var width = clientRect.width / scaleX; + var height = clientRect.height / scaleY; + return { + width: width, + height: height, + top: y, + right: x + width, + bottom: y + height, + left: x, + x: x, + y: y + }; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js": +/*!****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js ***! + \****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getClippingRect; } +/* harmony export */ }); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); +/* harmony import */ var _getViewportRect_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getViewportRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js"); +/* harmony import */ var _getDocumentRect_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./getDocumentRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js"); +/* harmony import */ var _listScrollParents_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./listScrollParents.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js"); +/* harmony import */ var _getOffsetParent_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./getOffsetParent.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js"); +/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./getDocumentElement.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js"); +/* harmony import */ var _getComputedStyle_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./getComputedStyle.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js"); +/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); +/* harmony import */ var _getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getBoundingClientRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js"); +/* harmony import */ var _getParentNode_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./getParentNode.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js"); +/* harmony import */ var _contains_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./contains.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/contains.js"); +/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./getNodeName.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js"); +/* harmony import */ var _utils_rectToClientRect_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/rectToClientRect.js */ "../eyes/node_modules/@popperjs/core/lib/utils/rectToClientRect.js"); +/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../utils/math.js */ "../eyes/node_modules/@popperjs/core/lib/utils/math.js"); + + + + + + + + + + + + + + + +function getInnerBoundingClientRect(element, strategy) { + var rect = (0,_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element, false, strategy === 'fixed'); + rect.top = rect.top + element.clientTop; + rect.left = rect.left + element.clientLeft; + rect.bottom = rect.top + element.clientHeight; + rect.right = rect.left + element.clientWidth; + rect.width = element.clientWidth; + rect.height = element.clientHeight; + rect.x = rect.left; + rect.y = rect.top; + return rect; +} + +function getClientRectFromMixedType(element, clippingParent, strategy) { + return clippingParent === _enums_js__WEBPACK_IMPORTED_MODULE_1__.viewport ? (0,_utils_rectToClientRect_js__WEBPACK_IMPORTED_MODULE_2__["default"])((0,_getViewportRect_js__WEBPACK_IMPORTED_MODULE_3__["default"])(element, strategy)) : (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__.isElement)(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : (0,_utils_rectToClientRect_js__WEBPACK_IMPORTED_MODULE_2__["default"])((0,_getDocumentRect_js__WEBPACK_IMPORTED_MODULE_5__["default"])((0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_6__["default"])(element))); +} // A "clipping parent" is an overflowable container with the characteristic of +// clipping (or hiding) overflowing elements with a position different from +// `initial` + + +function getClippingParents(element) { + var clippingParents = (0,_listScrollParents_js__WEBPACK_IMPORTED_MODULE_7__["default"])((0,_getParentNode_js__WEBPACK_IMPORTED_MODULE_8__["default"])(element)); + var canEscapeClipping = ['absolute', 'fixed'].indexOf((0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_9__["default"])(element).position) >= 0; + var clipperElement = canEscapeClipping && (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(element) ? (0,_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_10__["default"])(element) : element; + + if (!(0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__.isElement)(clipperElement)) { + return []; + } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414 + + + return clippingParents.filter(function (clippingParent) { + return (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__.isElement)(clippingParent) && (0,_contains_js__WEBPACK_IMPORTED_MODULE_11__["default"])(clippingParent, clipperElement) && (0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_12__["default"])(clippingParent) !== 'body'; + }); +} // Gets the maximum area that the element is visible in due to any number of +// clipping parents + + +function getClippingRect(element, boundary, rootBoundary, strategy) { + var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary); + var clippingParents = [].concat(mainClippingParents, [rootBoundary]); + var firstClippingParent = clippingParents[0]; + var clippingRect = clippingParents.reduce(function (accRect, clippingParent) { + var rect = getClientRectFromMixedType(element, clippingParent, strategy); + accRect.top = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_13__.max)(rect.top, accRect.top); + accRect.right = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_13__.min)(rect.right, accRect.right); + accRect.bottom = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_13__.min)(rect.bottom, accRect.bottom); + accRect.left = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_13__.max)(rect.left, accRect.left); + return accRect; + }, getClientRectFromMixedType(element, firstClippingParent, strategy)); + clippingRect.width = clippingRect.right - clippingRect.left; + clippingRect.height = clippingRect.bottom - clippingRect.top; + clippingRect.x = clippingRect.left; + clippingRect.y = clippingRect.top; + return clippingRect; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js": +/*!*****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js ***! + \*****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getCompositeRect; } +/* harmony export */ }); +/* harmony import */ var _getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getBoundingClientRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js"); +/* harmony import */ var _getNodeScroll_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./getNodeScroll.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js"); +/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./getNodeName.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js"); +/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); +/* harmony import */ var _getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./getWindowScrollBarX.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js"); +/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getDocumentElement.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js"); +/* harmony import */ var _isScrollParent_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./isScrollParent.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js"); +/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/math.js */ "../eyes/node_modules/@popperjs/core/lib/utils/math.js"); + + + + + + + + + +function isElementScaled(element) { + var rect = element.getBoundingClientRect(); + var scaleX = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_0__.round)(rect.width) / element.offsetWidth || 1; + var scaleY = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_0__.round)(rect.height) / element.offsetHeight || 1; + return scaleX !== 1 || scaleY !== 1; +} // Returns the composite rect of an element relative to its offsetParent. +// Composite means it takes into account transforms as well as layout. + + +function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { + if (isFixed === void 0) { + isFixed = false; + } + + var isOffsetParentAnElement = (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isHTMLElement)(offsetParent); + var offsetParentIsScaled = (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isHTMLElement)(offsetParent) && isElementScaled(offsetParent); + var documentElement = (0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(offsetParent); + var rect = (0,_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_3__["default"])(elementOrVirtualElement, offsetParentIsScaled, isFixed); + var scroll = { + scrollLeft: 0, + scrollTop: 0 + }; + var offsets = { + x: 0, + y: 0 + }; + + if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { + if ((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_4__["default"])(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078 + (0,_isScrollParent_js__WEBPACK_IMPORTED_MODULE_5__["default"])(documentElement)) { + scroll = (0,_getNodeScroll_js__WEBPACK_IMPORTED_MODULE_6__["default"])(offsetParent); + } + + if ((0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isHTMLElement)(offsetParent)) { + offsets = (0,_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_3__["default"])(offsetParent, true); + offsets.x += offsetParent.clientLeft; + offsets.y += offsetParent.clientTop; + } else if (documentElement) { + offsets.x = (0,_getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_7__["default"])(documentElement); + } + } + + return { + x: rect.left + scroll.scrollLeft - offsets.x, + y: rect.top + scroll.scrollTop - offsets.y, + width: rect.width, + height: rect.height + }; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js": +/*!*****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js ***! + \*****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getComputedStyle; } +/* harmony export */ }); +/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getWindow.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js"); + +function getComputedStyle(element) { + return (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element).getComputedStyle(element); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js": +/*!*******************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js ***! + \*******************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getDocumentElement; } +/* harmony export */ }); +/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); + +function getDocumentElement(element) { + // $FlowFixMe[incompatible-return]: assume body is always available + return (((0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isElement)(element) ? element.ownerDocument : // $FlowFixMe[prop-missing] + element.document) || window.document).documentElement; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js": +/*!****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js ***! + \****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getDocumentRect; } +/* harmony export */ }); +/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getDocumentElement.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js"); +/* harmony import */ var _getComputedStyle_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./getComputedStyle.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js"); +/* harmony import */ var _getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getWindowScrollBarX.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js"); +/* harmony import */ var _getWindowScroll_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getWindowScroll.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js"); +/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/math.js */ "../eyes/node_modules/@popperjs/core/lib/utils/math.js"); + + + + + // Gets the entire size of the scrollable document area, even extending outside +// of the `` and `` rect bounds if horizontally scrollable + +function getDocumentRect(element) { + var _element$ownerDocumen; + + var html = (0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element); + var winScroll = (0,_getWindowScroll_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element); + var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; + var width = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_2__.max)(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); + var height = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_2__.max)(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); + var x = -winScroll.scrollLeft + (0,_getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_3__["default"])(element); + var y = -winScroll.scrollTop; + + if ((0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_4__["default"])(body || html).direction === 'rtl') { + x += (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_2__.max)(html.clientWidth, body ? body.clientWidth : 0) - width; + } + + return { + width: width, + height: height, + x: x, + y: y + }; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js": +/*!*********************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js ***! + \*********************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getHTMLElementScroll; } +/* harmony export */ }); +function getHTMLElementScroll(element) { + return { + scrollLeft: element.scrollLeft, + scrollTop: element.scrollTop + }; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js": +/*!**************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getLayoutRect; } +/* harmony export */ }); +/* harmony import */ var _getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getBoundingClientRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js"); + // Returns the layout rect of an element relative to its offsetParent. Layout +// means it doesn't take into account transforms. + +function getLayoutRect(element) { + var clientRect = (0,_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element); // Use the clientRect sizes if it's not been transformed. + // Fixes https://github.com/popperjs/popper-core/issues/1223 + + var width = element.offsetWidth; + var height = element.offsetHeight; + + if (Math.abs(clientRect.width - width) <= 1) { + width = clientRect.width; + } + + if (Math.abs(clientRect.height - height) <= 1) { + height = clientRect.height; + } + + return { + x: element.offsetLeft, + y: element.offsetTop, + width: width, + height: height + }; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js": +/*!************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js ***! + \************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getNodeName; } +/* harmony export */ }); +function getNodeName(element) { + return element ? (element.nodeName || '').toLowerCase() : null; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js": +/*!**************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getNodeScroll; } +/* harmony export */ }); +/* harmony import */ var _getWindowScroll_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getWindowScroll.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js"); +/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getWindow.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js"); +/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); +/* harmony import */ var _getHTMLElementScroll_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getHTMLElementScroll.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js"); + + + + +function getNodeScroll(node) { + if (node === (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node) || !(0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isHTMLElement)(node)) { + return (0,_getWindowScroll_js__WEBPACK_IMPORTED_MODULE_2__["default"])(node); + } else { + return (0,_getHTMLElementScroll_js__WEBPACK_IMPORTED_MODULE_3__["default"])(node); + } +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js": +/*!****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js ***! + \****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getOffsetParent; } +/* harmony export */ }); +/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./getWindow.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js"); +/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./getNodeName.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js"); +/* harmony import */ var _getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getComputedStyle.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js"); +/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); +/* harmony import */ var _isTableElement_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./isTableElement.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/isTableElement.js"); +/* harmony import */ var _getParentNode_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getParentNode.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js"); +/* harmony import */ var _utils_userAgent_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/userAgent.js */ "../eyes/node_modules/@popperjs/core/lib/utils/userAgent.js"); + + + + + + + + +function getTrueOffsetParent(element) { + if (!(0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element) || // https://github.com/popperjs/popper-core/issues/837 + (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element).position === 'fixed') { + return null; + } + + return element.offsetParent; +} // `.offsetParent` reports `null` for fixed elements, while absolute elements +// return the containing block + + +function getContainingBlock(element) { + var isFirefox = /firefox/i.test((0,_utils_userAgent_js__WEBPACK_IMPORTED_MODULE_2__["default"])()); + var isIE = /Trident/i.test((0,_utils_userAgent_js__WEBPACK_IMPORTED_MODULE_2__["default"])()); + + if (isIE && (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element)) { + // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport + var elementCss = (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element); + + if (elementCss.position === 'fixed') { + return null; + } + } + + var currentNode = (0,_getParentNode_js__WEBPACK_IMPORTED_MODULE_3__["default"])(element); + + if ((0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isShadowRoot)(currentNode)) { + currentNode = currentNode.host; + } + + while ((0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(currentNode) && ['html', 'body'].indexOf((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_4__["default"])(currentNode)) < 0) { + var css = (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__["default"])(currentNode); // This is non-exhaustive but covers the most common CSS properties that + // create a containing block. + // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block + + if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') { + return currentNode; + } else { + currentNode = currentNode.parentNode; + } + } + + return null; +} // Gets the closest ancestor positioned element. Handles some edge cases, +// such as table ancestors and cross browser bugs. + + +function getOffsetParent(element) { + var window = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_5__["default"])(element); + var offsetParent = getTrueOffsetParent(element); + + while (offsetParent && (0,_isTableElement_js__WEBPACK_IMPORTED_MODULE_6__["default"])(offsetParent) && (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__["default"])(offsetParent).position === 'static') { + offsetParent = getTrueOffsetParent(offsetParent); + } + + if (offsetParent && ((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_4__["default"])(offsetParent) === 'html' || (0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_4__["default"])(offsetParent) === 'body' && (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__["default"])(offsetParent).position === 'static')) { + return window; + } + + return offsetParent || getContainingBlock(element) || window; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js": +/*!**************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getParentNode; } +/* harmony export */ }); +/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getNodeName.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js"); +/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getDocumentElement.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js"); +/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); + + + +function getParentNode(element) { + if ((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element) === 'html') { + return element; + } + + return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle + // $FlowFixMe[incompatible-return] + // $FlowFixMe[prop-missing] + element.assignedSlot || // step into the shadow DOM of the parent of a slotted node + element.parentNode || ( // DOM Element detected + (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isShadowRoot)(element) ? element.host : null) || // ShadowRoot detected + // $FlowFixMe[incompatible-call]: HTMLElement is a Node + (0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(element) // fallback + + ); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js": +/*!****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js ***! + \****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getScrollParent; } +/* harmony export */ }); +/* harmony import */ var _getParentNode_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getParentNode.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js"); +/* harmony import */ var _isScrollParent_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./isScrollParent.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js"); +/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getNodeName.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js"); +/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); + + + + +function getScrollParent(node) { + if (['html', 'body', '#document'].indexOf((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node)) >= 0) { + // $FlowFixMe[incompatible-return]: assume body is always available + return node.ownerDocument.body; + } + + if ((0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isHTMLElement)(node) && (0,_isScrollParent_js__WEBPACK_IMPORTED_MODULE_2__["default"])(node)) { + return node; + } + + return getScrollParent((0,_getParentNode_js__WEBPACK_IMPORTED_MODULE_3__["default"])(node)); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js": +/*!****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js ***! + \****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getViewportRect; } +/* harmony export */ }); +/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getWindow.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js"); +/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getDocumentElement.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js"); +/* harmony import */ var _getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getWindowScrollBarX.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js"); +/* harmony import */ var _isLayoutViewport_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./isLayoutViewport.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js"); + + + + +function getViewportRect(element, strategy) { + var win = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element); + var html = (0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element); + var visualViewport = win.visualViewport; + var width = html.clientWidth; + var height = html.clientHeight; + var x = 0; + var y = 0; + + if (visualViewport) { + width = visualViewport.width; + height = visualViewport.height; + var layoutViewport = (0,_isLayoutViewport_js__WEBPACK_IMPORTED_MODULE_2__["default"])(); + + if (layoutViewport || !layoutViewport && strategy === 'fixed') { + x = visualViewport.offsetLeft; + y = visualViewport.offsetTop; + } + } + + return { + width: width, + height: height, + x: x + (0,_getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_3__["default"])(element), + y: y + }; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js": +/*!**********************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js ***! + \**********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getWindow; } +/* harmony export */ }); +function getWindow(node) { + if (node == null) { + return window; + } + + if (node.toString() !== '[object Window]') { + var ownerDocument = node.ownerDocument; + return ownerDocument ? ownerDocument.defaultView || window : window; + } + + return node; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js": +/*!****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js ***! + \****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getWindowScroll; } +/* harmony export */ }); +/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getWindow.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js"); + +function getWindowScroll(node) { + var win = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node); + var scrollLeft = win.pageXOffset; + var scrollTop = win.pageYOffset; + return { + scrollLeft: scrollLeft, + scrollTop: scrollTop + }; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js": +/*!********************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js ***! + \********************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getWindowScrollBarX; } +/* harmony export */ }); +/* harmony import */ var _getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getBoundingClientRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js"); +/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getDocumentElement.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js"); +/* harmony import */ var _getWindowScroll_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getWindowScroll.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js"); + + + +function getWindowScrollBarX(element) { + // If has a CSS width greater than the viewport, then this will be + // incorrect for RTL. + // Popper 1 is broken in this case and never had a bug report so let's assume + // it's not an issue. I don't think anyone ever specifies width on + // anyway. + // Browsers where the left scrollbar doesn't cause an issue report `0` for + // this (e.g. Edge 2019, IE11, Safari) + return (0,_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__["default"])((0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element)).left + (0,_getWindowScroll_js__WEBPACK_IMPORTED_MODULE_2__["default"])(element).scrollLeft; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js": +/*!***********************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js ***! + \***********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "isElement": function() { return /* binding */ isElement; }, +/* harmony export */ "isHTMLElement": function() { return /* binding */ isHTMLElement; }, +/* harmony export */ "isShadowRoot": function() { return /* binding */ isShadowRoot; } +/* harmony export */ }); +/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getWindow.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js"); + + +function isElement(node) { + var OwnElement = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node).Element; + return node instanceof OwnElement || node instanceof Element; +} + +function isHTMLElement(node) { + var OwnElement = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node).HTMLElement; + return node instanceof OwnElement || node instanceof HTMLElement; +} + +function isShadowRoot(node) { + // IE 11 has no ShadowRoot + if (typeof ShadowRoot === 'undefined') { + return false; + } + + var OwnElement = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node).ShadowRoot; + return node instanceof OwnElement || node instanceof ShadowRoot; +} + + + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js": +/*!*****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js ***! + \*****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ isLayoutViewport; } +/* harmony export */ }); +/* harmony import */ var _utils_userAgent_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/userAgent.js */ "../eyes/node_modules/@popperjs/core/lib/utils/userAgent.js"); + +function isLayoutViewport() { + return !/^((?!chrome|android).)*safari/i.test((0,_utils_userAgent_js__WEBPACK_IMPORTED_MODULE_0__["default"])()); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js": +/*!***************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js ***! + \***************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ isScrollParent; } +/* harmony export */ }); +/* harmony import */ var _getComputedStyle_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getComputedStyle.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js"); + +function isScrollParent(element) { + // Firefox wants us to check `-x` and `-y` variations as well + var _getComputedStyle = (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element), + overflow = _getComputedStyle.overflow, + overflowX = _getComputedStyle.overflowX, + overflowY = _getComputedStyle.overflowY; + + return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/isTableElement.js": +/*!***************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/isTableElement.js ***! + \***************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ isTableElement; } +/* harmony export */ }); +/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getNodeName.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js"); + +function isTableElement(element) { + return ['table', 'td', 'th'].indexOf((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element)) >= 0; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js": +/*!******************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js ***! + \******************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ listScrollParents; } +/* harmony export */ }); +/* harmony import */ var _getScrollParent_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getScrollParent.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js"); +/* harmony import */ var _getParentNode_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getParentNode.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js"); +/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getWindow.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js"); +/* harmony import */ var _isScrollParent_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./isScrollParent.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js"); + + + + +/* +given a DOM element, return the list of all scroll parents, up the list of ancesors +until we get to the top window object. This list is what we attach scroll listeners +to, because if any of these parent elements scroll, we'll need to re-calculate the +reference element's position. +*/ + +function listScrollParents(element, list) { + var _element$ownerDocumen; + + if (list === void 0) { + list = []; + } + + var scrollParent = (0,_getScrollParent_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element); + var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); + var win = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_1__["default"])(scrollParent); + var target = isBody ? [win].concat(win.visualViewport || [], (0,_isScrollParent_js__WEBPACK_IMPORTED_MODULE_2__["default"])(scrollParent) ? scrollParent : []) : scrollParent; + var updatedList = list.concat(target); + return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here + updatedList.concat(listScrollParents((0,_getParentNode_js__WEBPACK_IMPORTED_MODULE_3__["default"])(target))); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/enums.js": +/*!********************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/enums.js ***! + \********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "top": function() { return /* binding */ top; }, +/* harmony export */ "bottom": function() { return /* binding */ bottom; }, +/* harmony export */ "right": function() { return /* binding */ right; }, +/* harmony export */ "left": function() { return /* binding */ left; }, +/* harmony export */ "auto": function() { return /* binding */ auto; }, +/* harmony export */ "basePlacements": function() { return /* binding */ basePlacements; }, +/* harmony export */ "start": function() { return /* binding */ start; }, +/* harmony export */ "end": function() { return /* binding */ end; }, +/* harmony export */ "clippingParents": function() { return /* binding */ clippingParents; }, +/* harmony export */ "viewport": function() { return /* binding */ viewport; }, +/* harmony export */ "popper": function() { return /* binding */ popper; }, +/* harmony export */ "reference": function() { return /* binding */ reference; }, +/* harmony export */ "variationPlacements": function() { return /* binding */ variationPlacements; }, +/* harmony export */ "placements": function() { return /* binding */ placements; }, +/* harmony export */ "beforeRead": function() { return /* binding */ beforeRead; }, +/* harmony export */ "read": function() { return /* binding */ read; }, +/* harmony export */ "afterRead": function() { return /* binding */ afterRead; }, +/* harmony export */ "beforeMain": function() { return /* binding */ beforeMain; }, +/* harmony export */ "main": function() { return /* binding */ main; }, +/* harmony export */ "afterMain": function() { return /* binding */ afterMain; }, +/* harmony export */ "beforeWrite": function() { return /* binding */ beforeWrite; }, +/* harmony export */ "write": function() { return /* binding */ write; }, +/* harmony export */ "afterWrite": function() { return /* binding */ afterWrite; }, +/* harmony export */ "modifierPhases": function() { return /* binding */ modifierPhases; } +/* harmony export */ }); +var top = 'top'; +var bottom = 'bottom'; +var right = 'right'; +var left = 'left'; +var auto = 'auto'; +var basePlacements = [top, bottom, right, left]; +var start = 'start'; +var end = 'end'; +var clippingParents = 'clippingParents'; +var viewport = 'viewport'; +var popper = 'popper'; +var reference = 'reference'; +var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) { + return acc.concat([placement + "-" + start, placement + "-" + end]); +}, []); +var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) { + return acc.concat([placement, placement + "-" + start, placement + "-" + end]); +}, []); // modifiers that need to read the DOM + +var beforeRead = 'beforeRead'; +var read = 'read'; +var afterRead = 'afterRead'; // pure-logic modifiers + +var beforeMain = 'beforeMain'; +var main = 'main'; +var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state) + +var beforeWrite = 'beforeWrite'; +var write = 'write'; +var afterWrite = 'afterWrite'; +var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/modifiers/applyStyles.js": +/*!************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/modifiers/applyStyles.js ***! + \************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _dom_utils_getNodeName_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../dom-utils/getNodeName.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js"); +/* harmony import */ var _dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../dom-utils/instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); + + // This modifier takes the styles prepared by the `computeStyles` modifier +// and applies them to the HTMLElements such as popper and arrow + +function applyStyles(_ref) { + var state = _ref.state; + Object.keys(state.elements).forEach(function (name) { + var style = state.styles[name] || {}; + var attributes = state.attributes[name] || {}; + var element = state.elements[name]; // arrow is optional + virtual elements + + if (!(0,_dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element) || !(0,_dom_utils_getNodeName_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element)) { + return; + } // Flow doesn't support to extend this property, but it's the most + // effective way to apply styles to an HTMLElement + // $FlowFixMe[cannot-write] + + + Object.assign(element.style, style); + Object.keys(attributes).forEach(function (name) { + var value = attributes[name]; + + if (value === false) { + element.removeAttribute(name); + } else { + element.setAttribute(name, value === true ? '' : value); + } + }); + }); +} + +function effect(_ref2) { + var state = _ref2.state; + var initialStyles = { + popper: { + position: state.options.strategy, + left: '0', + top: '0', + margin: '0' + }, + arrow: { + position: 'absolute' + }, + reference: {} + }; + Object.assign(state.elements.popper.style, initialStyles.popper); + state.styles = initialStyles; + + if (state.elements.arrow) { + Object.assign(state.elements.arrow.style, initialStyles.arrow); + } + + return function () { + Object.keys(state.elements).forEach(function (name) { + var element = state.elements[name]; + var attributes = state.attributes[name] || {}; + var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them + + var style = styleProperties.reduce(function (style, property) { + style[property] = ''; + return style; + }, {}); // arrow is optional + virtual elements + + if (!(0,_dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element) || !(0,_dom_utils_getNodeName_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element)) { + return; + } + + Object.assign(element.style, style); + Object.keys(attributes).forEach(function (attribute) { + element.removeAttribute(attribute); + }); + }); + }; +} // eslint-disable-next-line import/no-unused-modules + + +/* harmony default export */ __webpack_exports__["default"] = ({ + name: 'applyStyles', + enabled: true, + phase: 'write', + fn: applyStyles, + effect: effect, + requires: ['computeStyles'] +}); + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/modifiers/arrow.js": +/*!******************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/modifiers/arrow.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/getBasePlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getBasePlacement.js"); +/* harmony import */ var _dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../dom-utils/getLayoutRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js"); +/* harmony import */ var _dom_utils_contains_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../dom-utils/contains.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/contains.js"); +/* harmony import */ var _dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../dom-utils/getOffsetParent.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js"); +/* harmony import */ var _utils_getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/getMainAxisFromPlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js"); +/* harmony import */ var _utils_within_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/within.js */ "../eyes/node_modules/@popperjs/core/lib/utils/within.js"); +/* harmony import */ var _utils_mergePaddingObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/mergePaddingObject.js */ "../eyes/node_modules/@popperjs/core/lib/utils/mergePaddingObject.js"); +/* harmony import */ var _utils_expandToHashMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/expandToHashMap.js */ "../eyes/node_modules/@popperjs/core/lib/utils/expandToHashMap.js"); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); +/* harmony import */ var _dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../dom-utils/instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); + + + + + + + + + + // eslint-disable-next-line import/no-unused-modules + +var toPaddingObject = function toPaddingObject(padding, state) { + padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, { + placement: state.placement + })) : padding; + return (0,_utils_mergePaddingObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(typeof padding !== 'number' ? padding : (0,_utils_expandToHashMap_js__WEBPACK_IMPORTED_MODULE_1__["default"])(padding, _enums_js__WEBPACK_IMPORTED_MODULE_2__.basePlacements)); +}; + +function arrow(_ref) { + var _state$modifiersData$; + + var state = _ref.state, + name = _ref.name, + options = _ref.options; + var arrowElement = state.elements.arrow; + var popperOffsets = state.modifiersData.popperOffsets; + var basePlacement = (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(state.placement); + var axis = (0,_utils_getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_4__["default"])(basePlacement); + var isVertical = [_enums_js__WEBPACK_IMPORTED_MODULE_2__.left, _enums_js__WEBPACK_IMPORTED_MODULE_2__.right].indexOf(basePlacement) >= 0; + var len = isVertical ? 'height' : 'width'; + + if (!arrowElement || !popperOffsets) { + return; + } + + var paddingObject = toPaddingObject(options.padding, state); + var arrowRect = (0,_dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_5__["default"])(arrowElement); + var minProp = axis === 'y' ? _enums_js__WEBPACK_IMPORTED_MODULE_2__.top : _enums_js__WEBPACK_IMPORTED_MODULE_2__.left; + var maxProp = axis === 'y' ? _enums_js__WEBPACK_IMPORTED_MODULE_2__.bottom : _enums_js__WEBPACK_IMPORTED_MODULE_2__.right; + var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len]; + var startDiff = popperOffsets[axis] - state.rects.reference[axis]; + var arrowOffsetParent = (0,_dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_6__["default"])(arrowElement); + var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; + var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is + // outside of the popper bounds + + var min = paddingObject[minProp]; + var max = clientSize - arrowRect[len] - paddingObject[maxProp]; + var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; + var offset = (0,_utils_within_js__WEBPACK_IMPORTED_MODULE_7__.within)(min, center, max); // Prevents breaking syntax highlighting... + + var axisProp = axis; + state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$); +} + +function effect(_ref2) { + var state = _ref2.state, + options = _ref2.options; + var _options$element = options.element, + arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element; + + if (arrowElement == null) { + return; + } // CSS selector + + + if (typeof arrowElement === 'string') { + arrowElement = state.elements.popper.querySelector(arrowElement); + + if (!arrowElement) { + return; + } + } + + if (true) { + if (!(0,_dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_8__.isHTMLElement)(arrowElement)) { + console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' ')); + } + } + + if (!(0,_dom_utils_contains_js__WEBPACK_IMPORTED_MODULE_9__["default"])(state.elements.popper, arrowElement)) { + if (true) { + console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', 'element.'].join(' ')); + } + + return; + } + + state.elements.arrow = arrowElement; +} // eslint-disable-next-line import/no-unused-modules + + +/* harmony default export */ __webpack_exports__["default"] = ({ + name: 'arrow', + enabled: true, + phase: 'main', + fn: arrow, + effect: effect, + requires: ['popperOffsets'], + requiresIfExists: ['preventOverflow'] +}); + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/modifiers/computeStyles.js": +/*!**************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/modifiers/computeStyles.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "mapToStyles": function() { return /* binding */ mapToStyles; } +/* harmony export */ }); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); +/* harmony import */ var _dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../dom-utils/getOffsetParent.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js"); +/* harmony import */ var _dom_utils_getWindow_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../dom-utils/getWindow.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js"); +/* harmony import */ var _dom_utils_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../dom-utils/getDocumentElement.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js"); +/* harmony import */ var _dom_utils_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../dom-utils/getComputedStyle.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js"); +/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/getBasePlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getBasePlacement.js"); +/* harmony import */ var _utils_getVariation_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/getVariation.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getVariation.js"); +/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/math.js */ "../eyes/node_modules/@popperjs/core/lib/utils/math.js"); + + + + + + + + // eslint-disable-next-line import/no-unused-modules + +var unsetSides = { + top: 'auto', + right: 'auto', + bottom: 'auto', + left: 'auto' +}; // Round the offsets to the nearest suitable subpixel based on the DPR. +// Zooming can change the DPR, but it seems to report a value that will +// cleanly divide the values into the appropriate subpixels. + +function roundOffsetsByDPR(_ref) { + var x = _ref.x, + y = _ref.y; + var win = window; + var dpr = win.devicePixelRatio || 1; + return { + x: (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_0__.round)(x * dpr) / dpr || 0, + y: (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_0__.round)(y * dpr) / dpr || 0 + }; +} + +function mapToStyles(_ref2) { + var _Object$assign2; + + var popper = _ref2.popper, + popperRect = _ref2.popperRect, + placement = _ref2.placement, + variation = _ref2.variation, + offsets = _ref2.offsets, + position = _ref2.position, + gpuAcceleration = _ref2.gpuAcceleration, + adaptive = _ref2.adaptive, + roundOffsets = _ref2.roundOffsets, + isFixed = _ref2.isFixed; + var _offsets$x = offsets.x, + x = _offsets$x === void 0 ? 0 : _offsets$x, + _offsets$y = offsets.y, + y = _offsets$y === void 0 ? 0 : _offsets$y; + + var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({ + x: x, + y: y + }) : { + x: x, + y: y + }; + + x = _ref3.x; + y = _ref3.y; + var hasX = offsets.hasOwnProperty('x'); + var hasY = offsets.hasOwnProperty('y'); + var sideX = _enums_js__WEBPACK_IMPORTED_MODULE_1__.left; + var sideY = _enums_js__WEBPACK_IMPORTED_MODULE_1__.top; + var win = window; + + if (adaptive) { + var offsetParent = (0,_dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_2__["default"])(popper); + var heightProp = 'clientHeight'; + var widthProp = 'clientWidth'; + + if (offsetParent === (0,_dom_utils_getWindow_js__WEBPACK_IMPORTED_MODULE_3__["default"])(popper)) { + offsetParent = (0,_dom_utils_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_4__["default"])(popper); + + if ((0,_dom_utils_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_5__["default"])(offsetParent).position !== 'static' && position === 'absolute') { + heightProp = 'scrollHeight'; + widthProp = 'scrollWidth'; + } + } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it + + + offsetParent = offsetParent; + + if (placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.top || (placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.left || placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.right) && variation === _enums_js__WEBPACK_IMPORTED_MODULE_1__.end) { + sideY = _enums_js__WEBPACK_IMPORTED_MODULE_1__.bottom; + var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing] + offsetParent[heightProp]; + y -= offsetY - popperRect.height; + y *= gpuAcceleration ? 1 : -1; + } + + if (placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.left || (placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.top || placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.bottom) && variation === _enums_js__WEBPACK_IMPORTED_MODULE_1__.end) { + sideX = _enums_js__WEBPACK_IMPORTED_MODULE_1__.right; + var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing] + offsetParent[widthProp]; + x -= offsetX - popperRect.width; + x *= gpuAcceleration ? 1 : -1; + } + } + + var commonStyles = Object.assign({ + position: position + }, adaptive && unsetSides); + + var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ + x: x, + y: y + }) : { + x: x, + y: y + }; + + x = _ref4.x; + y = _ref4.y; + + if (gpuAcceleration) { + var _Object$assign; + + return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); + } + + return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2)); +} + +function computeStyles(_ref5) { + var state = _ref5.state, + options = _ref5.options; + var _options$gpuAccelerat = options.gpuAcceleration, + gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, + _options$adaptive = options.adaptive, + adaptive = _options$adaptive === void 0 ? true : _options$adaptive, + _options$roundOffsets = options.roundOffsets, + roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; + + if (true) { + var transitionProperty = (0,_dom_utils_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_5__["default"])(state.elements.popper).transitionProperty || ''; + + if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) { + return transitionProperty.indexOf(property) >= 0; + })) { + console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: "transform", "top", "right", "bottom", "left".', '\n\n', 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\n\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' ')); + } + } + + var commonStyles = { + placement: (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_6__["default"])(state.placement), + variation: (0,_utils_getVariation_js__WEBPACK_IMPORTED_MODULE_7__["default"])(state.placement), + popper: state.elements.popper, + popperRect: state.rects.popper, + gpuAcceleration: gpuAcceleration, + isFixed: state.options.strategy === 'fixed' + }; + + if (state.modifiersData.popperOffsets != null) { + state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { + offsets: state.modifiersData.popperOffsets, + position: state.options.strategy, + adaptive: adaptive, + roundOffsets: roundOffsets + }))); + } + + if (state.modifiersData.arrow != null) { + state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { + offsets: state.modifiersData.arrow, + position: 'absolute', + adaptive: false, + roundOffsets: roundOffsets + }))); + } + + state.attributes.popper = Object.assign({}, state.attributes.popper, { + 'data-popper-placement': state.placement + }); +} // eslint-disable-next-line import/no-unused-modules + + +/* harmony default export */ __webpack_exports__["default"] = ({ + name: 'computeStyles', + enabled: true, + phase: 'beforeWrite', + fn: computeStyles, + data: {} +}); + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/modifiers/eventListeners.js": +/*!***************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/modifiers/eventListeners.js ***! + \***************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _dom_utils_getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../dom-utils/getWindow.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getWindow.js"); + // eslint-disable-next-line import/no-unused-modules + +var passive = { + passive: true +}; + +function effect(_ref) { + var state = _ref.state, + instance = _ref.instance, + options = _ref.options; + var _options$scroll = options.scroll, + scroll = _options$scroll === void 0 ? true : _options$scroll, + _options$resize = options.resize, + resize = _options$resize === void 0 ? true : _options$resize; + var window = (0,_dom_utils_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(state.elements.popper); + var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); + + if (scroll) { + scrollParents.forEach(function (scrollParent) { + scrollParent.addEventListener('scroll', instance.update, passive); + }); + } + + if (resize) { + window.addEventListener('resize', instance.update, passive); + } + + return function () { + if (scroll) { + scrollParents.forEach(function (scrollParent) { + scrollParent.removeEventListener('scroll', instance.update, passive); + }); + } + + if (resize) { + window.removeEventListener('resize', instance.update, passive); + } + }; +} // eslint-disable-next-line import/no-unused-modules + + +/* harmony default export */ __webpack_exports__["default"] = ({ + name: 'eventListeners', + enabled: true, + phase: 'write', + fn: function fn() {}, + effect: effect, + data: {} +}); + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/modifiers/flip.js": +/*!*****************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/modifiers/flip.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _utils_getOppositePlacement_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/getOppositePlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getOppositePlacement.js"); +/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/getBasePlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getBasePlacement.js"); +/* harmony import */ var _utils_getOppositeVariationPlacement_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/getOppositeVariationPlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js"); +/* harmony import */ var _utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/detectOverflow.js */ "../eyes/node_modules/@popperjs/core/lib/utils/detectOverflow.js"); +/* harmony import */ var _utils_computeAutoPlacement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/computeAutoPlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js"); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); +/* harmony import */ var _utils_getVariation_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/getVariation.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getVariation.js"); + + + + + + + // eslint-disable-next-line import/no-unused-modules + +function getExpandedFallbackPlacements(placement) { + if ((0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(placement) === _enums_js__WEBPACK_IMPORTED_MODULE_1__.auto) { + return []; + } + + var oppositePlacement = (0,_utils_getOppositePlacement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(placement); + return [(0,_utils_getOppositeVariationPlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(placement), oppositePlacement, (0,_utils_getOppositeVariationPlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(oppositePlacement)]; +} + +function flip(_ref) { + var state = _ref.state, + options = _ref.options, + name = _ref.name; + + if (state.modifiersData[name]._skip) { + return; + } + + var _options$mainAxis = options.mainAxis, + checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, + _options$altAxis = options.altAxis, + checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, + specifiedFallbackPlacements = options.fallbackPlacements, + padding = options.padding, + boundary = options.boundary, + rootBoundary = options.rootBoundary, + altBoundary = options.altBoundary, + _options$flipVariatio = options.flipVariations, + flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, + allowedAutoPlacements = options.allowedAutoPlacements; + var preferredPlacement = state.options.placement; + var basePlacement = (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(preferredPlacement); + var isBasePlacement = basePlacement === preferredPlacement; + var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [(0,_utils_getOppositePlacement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); + var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) { + return acc.concat((0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(placement) === _enums_js__WEBPACK_IMPORTED_MODULE_1__.auto ? (0,_utils_computeAutoPlacement_js__WEBPACK_IMPORTED_MODULE_4__["default"])(state, { + placement: placement, + boundary: boundary, + rootBoundary: rootBoundary, + padding: padding, + flipVariations: flipVariations, + allowedAutoPlacements: allowedAutoPlacements + }) : placement); + }, []); + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var checksMap = new Map(); + var makeFallbackChecks = true; + var firstFittingPlacement = placements[0]; + + for (var i = 0; i < placements.length; i++) { + var placement = placements[i]; + + var _basePlacement = (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(placement); + + var isStartVariation = (0,_utils_getVariation_js__WEBPACK_IMPORTED_MODULE_5__["default"])(placement) === _enums_js__WEBPACK_IMPORTED_MODULE_1__.start; + var isVertical = [_enums_js__WEBPACK_IMPORTED_MODULE_1__.top, _enums_js__WEBPACK_IMPORTED_MODULE_1__.bottom].indexOf(_basePlacement) >= 0; + var len = isVertical ? 'width' : 'height'; + var overflow = (0,_utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_6__["default"])(state, { + placement: placement, + boundary: boundary, + rootBoundary: rootBoundary, + altBoundary: altBoundary, + padding: padding + }); + var mainVariationSide = isVertical ? isStartVariation ? _enums_js__WEBPACK_IMPORTED_MODULE_1__.right : _enums_js__WEBPACK_IMPORTED_MODULE_1__.left : isStartVariation ? _enums_js__WEBPACK_IMPORTED_MODULE_1__.bottom : _enums_js__WEBPACK_IMPORTED_MODULE_1__.top; + + if (referenceRect[len] > popperRect[len]) { + mainVariationSide = (0,_utils_getOppositePlacement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(mainVariationSide); + } + + var altVariationSide = (0,_utils_getOppositePlacement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(mainVariationSide); + var checks = []; + + if (checkMainAxis) { + checks.push(overflow[_basePlacement] <= 0); + } + + if (checkAltAxis) { + checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); + } + + if (checks.every(function (check) { + return check; + })) { + firstFittingPlacement = placement; + makeFallbackChecks = false; + break; + } + + checksMap.set(placement, checks); + } + + if (makeFallbackChecks) { + // `2` may be desired in some cases – research later + var numberOfChecks = flipVariations ? 3 : 1; + + var _loop = function _loop(_i) { + var fittingPlacement = placements.find(function (placement) { + var checks = checksMap.get(placement); + + if (checks) { + return checks.slice(0, _i).every(function (check) { + return check; + }); + } + }); + + if (fittingPlacement) { + firstFittingPlacement = fittingPlacement; + return "break"; + } + }; + + for (var _i = numberOfChecks; _i > 0; _i--) { + var _ret = _loop(_i); + + if (_ret === "break") break; + } + } + + if (state.placement !== firstFittingPlacement) { + state.modifiersData[name]._skip = true; + state.placement = firstFittingPlacement; + state.reset = true; + } +} // eslint-disable-next-line import/no-unused-modules + + +/* harmony default export */ __webpack_exports__["default"] = ({ + name: 'flip', + enabled: true, + phase: 'main', + fn: flip, + requiresIfExists: ['offset'], + data: { + _skip: false + } +}); + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/modifiers/hide.js": +/*!*****************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/modifiers/hide.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); +/* harmony import */ var _utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/detectOverflow.js */ "../eyes/node_modules/@popperjs/core/lib/utils/detectOverflow.js"); + + + +function getSideOffsets(overflow, rect, preventedOffsets) { + if (preventedOffsets === void 0) { + preventedOffsets = { + x: 0, + y: 0 + }; + } + + return { + top: overflow.top - rect.height - preventedOffsets.y, + right: overflow.right - rect.width + preventedOffsets.x, + bottom: overflow.bottom - rect.height + preventedOffsets.y, + left: overflow.left - rect.width - preventedOffsets.x + }; +} + +function isAnySideFullyClipped(overflow) { + return [_enums_js__WEBPACK_IMPORTED_MODULE_0__.top, _enums_js__WEBPACK_IMPORTED_MODULE_0__.right, _enums_js__WEBPACK_IMPORTED_MODULE_0__.bottom, _enums_js__WEBPACK_IMPORTED_MODULE_0__.left].some(function (side) { + return overflow[side] >= 0; + }); +} + +function hide(_ref) { + var state = _ref.state, + name = _ref.name; + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var preventedOffsets = state.modifiersData.preventOverflow; + var referenceOverflow = (0,_utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_1__["default"])(state, { + elementContext: 'reference' + }); + var popperAltOverflow = (0,_utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_1__["default"])(state, { + altBoundary: true + }); + var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); + var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); + var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); + var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); + state.modifiersData[name] = { + referenceClippingOffsets: referenceClippingOffsets, + popperEscapeOffsets: popperEscapeOffsets, + isReferenceHidden: isReferenceHidden, + hasPopperEscaped: hasPopperEscaped + }; + state.attributes.popper = Object.assign({}, state.attributes.popper, { + 'data-popper-reference-hidden': isReferenceHidden, + 'data-popper-escaped': hasPopperEscaped + }); +} // eslint-disable-next-line import/no-unused-modules + + +/* harmony default export */ __webpack_exports__["default"] = ({ + name: 'hide', + enabled: true, + phase: 'main', + requiresIfExists: ['preventOverflow'], + fn: hide +}); + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/modifiers/index.js": +/*!******************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/modifiers/index.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "applyStyles": function() { return /* reexport safe */ _applyStyles_js__WEBPACK_IMPORTED_MODULE_0__["default"]; }, +/* harmony export */ "arrow": function() { return /* reexport safe */ _arrow_js__WEBPACK_IMPORTED_MODULE_1__["default"]; }, +/* harmony export */ "computeStyles": function() { return /* reexport safe */ _computeStyles_js__WEBPACK_IMPORTED_MODULE_2__["default"]; }, +/* harmony export */ "eventListeners": function() { return /* reexport safe */ _eventListeners_js__WEBPACK_IMPORTED_MODULE_3__["default"]; }, +/* harmony export */ "flip": function() { return /* reexport safe */ _flip_js__WEBPACK_IMPORTED_MODULE_4__["default"]; }, +/* harmony export */ "hide": function() { return /* reexport safe */ _hide_js__WEBPACK_IMPORTED_MODULE_5__["default"]; }, +/* harmony export */ "offset": function() { return /* reexport safe */ _offset_js__WEBPACK_IMPORTED_MODULE_6__["default"]; }, +/* harmony export */ "popperOffsets": function() { return /* reexport safe */ _popperOffsets_js__WEBPACK_IMPORTED_MODULE_7__["default"]; }, +/* harmony export */ "preventOverflow": function() { return /* reexport safe */ _preventOverflow_js__WEBPACK_IMPORTED_MODULE_8__["default"]; } +/* harmony export */ }); +/* harmony import */ var _applyStyles_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./applyStyles.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/applyStyles.js"); +/* harmony import */ var _arrow_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./arrow.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/arrow.js"); +/* harmony import */ var _computeStyles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./computeStyles.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/computeStyles.js"); +/* harmony import */ var _eventListeners_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./eventListeners.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/eventListeners.js"); +/* harmony import */ var _flip_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./flip.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/flip.js"); +/* harmony import */ var _hide_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./hide.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/hide.js"); +/* harmony import */ var _offset_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./offset.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/offset.js"); +/* harmony import */ var _popperOffsets_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./popperOffsets.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js"); +/* harmony import */ var _preventOverflow_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./preventOverflow.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/preventOverflow.js"); + + + + + + + + + + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/modifiers/offset.js": +/*!*******************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/modifiers/offset.js ***! + \*******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "distanceAndSkiddingToXY": function() { return /* binding */ distanceAndSkiddingToXY; } +/* harmony export */ }); +/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/getBasePlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getBasePlacement.js"); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); + + // eslint-disable-next-line import/no-unused-modules + +function distanceAndSkiddingToXY(placement, rects, offset) { + var basePlacement = (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(placement); + var invertDistance = [_enums_js__WEBPACK_IMPORTED_MODULE_1__.left, _enums_js__WEBPACK_IMPORTED_MODULE_1__.top].indexOf(basePlacement) >= 0 ? -1 : 1; + + var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, { + placement: placement + })) : offset, + skidding = _ref[0], + distance = _ref[1]; + + skidding = skidding || 0; + distance = (distance || 0) * invertDistance; + return [_enums_js__WEBPACK_IMPORTED_MODULE_1__.left, _enums_js__WEBPACK_IMPORTED_MODULE_1__.right].indexOf(basePlacement) >= 0 ? { + x: distance, + y: skidding + } : { + x: skidding, + y: distance + }; +} + +function offset(_ref2) { + var state = _ref2.state, + options = _ref2.options, + name = _ref2.name; + var _options$offset = options.offset, + offset = _options$offset === void 0 ? [0, 0] : _options$offset; + var data = _enums_js__WEBPACK_IMPORTED_MODULE_1__.placements.reduce(function (acc, placement) { + acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset); + return acc; + }, {}); + var _data$state$placement = data[state.placement], + x = _data$state$placement.x, + y = _data$state$placement.y; + + if (state.modifiersData.popperOffsets != null) { + state.modifiersData.popperOffsets.x += x; + state.modifiersData.popperOffsets.y += y; + } + + state.modifiersData[name] = data; +} // eslint-disable-next-line import/no-unused-modules + + +/* harmony default export */ __webpack_exports__["default"] = ({ + name: 'offset', + enabled: true, + phase: 'main', + requires: ['popperOffsets'], + fn: offset +}); + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js": +/*!**************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _utils_computeOffsets_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/computeOffsets.js */ "../eyes/node_modules/@popperjs/core/lib/utils/computeOffsets.js"); + + +function popperOffsets(_ref) { + var state = _ref.state, + name = _ref.name; + // Offsets are the actual position the popper needs to have to be + // properly positioned near its reference element + // This is the most basic placement, and will be adjusted by + // the modifiers in the next step + state.modifiersData[name] = (0,_utils_computeOffsets_js__WEBPACK_IMPORTED_MODULE_0__["default"])({ + reference: state.rects.reference, + element: state.rects.popper, + strategy: 'absolute', + placement: state.placement + }); +} // eslint-disable-next-line import/no-unused-modules + + +/* harmony default export */ __webpack_exports__["default"] = ({ + name: 'popperOffsets', + enabled: true, + phase: 'read', + fn: popperOffsets, + data: {} +}); + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/modifiers/preventOverflow.js": +/*!****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/modifiers/preventOverflow.js ***! + \****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); +/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/getBasePlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getBasePlacement.js"); +/* harmony import */ var _utils_getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/getMainAxisFromPlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js"); +/* harmony import */ var _utils_getAltAxis_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/getAltAxis.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getAltAxis.js"); +/* harmony import */ var _utils_within_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/within.js */ "../eyes/node_modules/@popperjs/core/lib/utils/within.js"); +/* harmony import */ var _dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../dom-utils/getLayoutRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js"); +/* harmony import */ var _dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../dom-utils/getOffsetParent.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js"); +/* harmony import */ var _utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/detectOverflow.js */ "../eyes/node_modules/@popperjs/core/lib/utils/detectOverflow.js"); +/* harmony import */ var _utils_getVariation_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/getVariation.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getVariation.js"); +/* harmony import */ var _utils_getFreshSideObject_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/getFreshSideObject.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getFreshSideObject.js"); +/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/math.js */ "../eyes/node_modules/@popperjs/core/lib/utils/math.js"); + + + + + + + + + + + + +function preventOverflow(_ref) { + var state = _ref.state, + options = _ref.options, + name = _ref.name; + var _options$mainAxis = options.mainAxis, + checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, + _options$altAxis = options.altAxis, + checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, + boundary = options.boundary, + rootBoundary = options.rootBoundary, + altBoundary = options.altBoundary, + padding = options.padding, + _options$tether = options.tether, + tether = _options$tether === void 0 ? true : _options$tether, + _options$tetherOffset = options.tetherOffset, + tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; + var overflow = (0,_utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(state, { + boundary: boundary, + rootBoundary: rootBoundary, + padding: padding, + altBoundary: altBoundary + }); + var basePlacement = (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_1__["default"])(state.placement); + var variation = (0,_utils_getVariation_js__WEBPACK_IMPORTED_MODULE_2__["default"])(state.placement); + var isBasePlacement = !variation; + var mainAxis = (0,_utils_getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(basePlacement); + var altAxis = (0,_utils_getAltAxis_js__WEBPACK_IMPORTED_MODULE_4__["default"])(mainAxis); + var popperOffsets = state.modifiersData.popperOffsets; + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, { + placement: state.placement + })) : tetherOffset; + var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? { + mainAxis: tetherOffsetValue, + altAxis: tetherOffsetValue + } : Object.assign({ + mainAxis: 0, + altAxis: 0 + }, tetherOffsetValue); + var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; + var data = { + x: 0, + y: 0 + }; + + if (!popperOffsets) { + return; + } + + if (checkMainAxis) { + var _offsetModifierState$; + + var mainSide = mainAxis === 'y' ? _enums_js__WEBPACK_IMPORTED_MODULE_5__.top : _enums_js__WEBPACK_IMPORTED_MODULE_5__.left; + var altSide = mainAxis === 'y' ? _enums_js__WEBPACK_IMPORTED_MODULE_5__.bottom : _enums_js__WEBPACK_IMPORTED_MODULE_5__.right; + var len = mainAxis === 'y' ? 'height' : 'width'; + var offset = popperOffsets[mainAxis]; + var min = offset + overflow[mainSide]; + var max = offset - overflow[altSide]; + var additive = tether ? -popperRect[len] / 2 : 0; + var minLen = variation === _enums_js__WEBPACK_IMPORTED_MODULE_5__.start ? referenceRect[len] : popperRect[len]; + var maxLen = variation === _enums_js__WEBPACK_IMPORTED_MODULE_5__.start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go + // outside the reference bounds + + var arrowElement = state.elements.arrow; + var arrowRect = tether && arrowElement ? (0,_dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_6__["default"])(arrowElement) : { + width: 0, + height: 0 + }; + var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : (0,_utils_getFreshSideObject_js__WEBPACK_IMPORTED_MODULE_7__["default"])(); + var arrowPaddingMin = arrowPaddingObject[mainSide]; + var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want + // to include its full size in the calculation. If the reference is small + // and near the edge of a boundary, the popper can overflow even if the + // reference is not overflowing as well (e.g. virtual elements with no + // width or height) + + var arrowLen = (0,_utils_within_js__WEBPACK_IMPORTED_MODULE_8__.within)(0, referenceRect[len], arrowRect[len]); + var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; + var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; + var arrowOffsetParent = state.elements.arrow && (0,_dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_9__["default"])(state.elements.arrow); + var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; + var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; + var tetherMin = offset + minOffset - offsetModifierValue - clientOffset; + var tetherMax = offset + maxOffset - offsetModifierValue; + var preventedOffset = (0,_utils_within_js__WEBPACK_IMPORTED_MODULE_8__.within)(tether ? (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_10__.min)(min, tetherMin) : min, offset, tether ? (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_10__.max)(max, tetherMax) : max); + popperOffsets[mainAxis] = preventedOffset; + data[mainAxis] = preventedOffset - offset; + } + + if (checkAltAxis) { + var _offsetModifierState$2; + + var _mainSide = mainAxis === 'x' ? _enums_js__WEBPACK_IMPORTED_MODULE_5__.top : _enums_js__WEBPACK_IMPORTED_MODULE_5__.left; + + var _altSide = mainAxis === 'x' ? _enums_js__WEBPACK_IMPORTED_MODULE_5__.bottom : _enums_js__WEBPACK_IMPORTED_MODULE_5__.right; + + var _offset = popperOffsets[altAxis]; + + var _len = altAxis === 'y' ? 'height' : 'width'; + + var _min = _offset + overflow[_mainSide]; + + var _max = _offset - overflow[_altSide]; + + var isOriginSide = [_enums_js__WEBPACK_IMPORTED_MODULE_5__.top, _enums_js__WEBPACK_IMPORTED_MODULE_5__.left].indexOf(basePlacement) !== -1; + + var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; + + var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; + + var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; + + var _preventedOffset = tether && isOriginSide ? (0,_utils_within_js__WEBPACK_IMPORTED_MODULE_8__.withinMaxClamp)(_tetherMin, _offset, _tetherMax) : (0,_utils_within_js__WEBPACK_IMPORTED_MODULE_8__.within)(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); + + popperOffsets[altAxis] = _preventedOffset; + data[altAxis] = _preventedOffset - _offset; + } + + state.modifiersData[name] = data; +} // eslint-disable-next-line import/no-unused-modules + + +/* harmony default export */ __webpack_exports__["default"] = ({ + name: 'preventOverflow', + enabled: true, + phase: 'main', + fn: preventOverflow, + requiresIfExists: ['offset'] +}); + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/popper-lite.js": +/*!**************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/popper-lite.js ***! + \**************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "createPopper": function() { return /* binding */ createPopper; }, +/* harmony export */ "popperGenerator": function() { return /* reexport safe */ _createPopper_js__WEBPACK_IMPORTED_MODULE_4__.popperGenerator; }, +/* harmony export */ "defaultModifiers": function() { return /* binding */ defaultModifiers; }, +/* harmony export */ "detectOverflow": function() { return /* reexport safe */ _createPopper_js__WEBPACK_IMPORTED_MODULE_5__["default"]; } +/* harmony export */ }); +/* harmony import */ var _createPopper_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./createPopper.js */ "../eyes/node_modules/@popperjs/core/lib/createPopper.js"); +/* harmony import */ var _createPopper_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./createPopper.js */ "../eyes/node_modules/@popperjs/core/lib/utils/detectOverflow.js"); +/* harmony import */ var _modifiers_eventListeners_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./modifiers/eventListeners.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/eventListeners.js"); +/* harmony import */ var _modifiers_popperOffsets_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modifiers/popperOffsets.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js"); +/* harmony import */ var _modifiers_computeStyles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modifiers/computeStyles.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/computeStyles.js"); +/* harmony import */ var _modifiers_applyStyles_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modifiers/applyStyles.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/applyStyles.js"); + + + + + +var defaultModifiers = [_modifiers_eventListeners_js__WEBPACK_IMPORTED_MODULE_0__["default"], _modifiers_popperOffsets_js__WEBPACK_IMPORTED_MODULE_1__["default"], _modifiers_computeStyles_js__WEBPACK_IMPORTED_MODULE_2__["default"], _modifiers_applyStyles_js__WEBPACK_IMPORTED_MODULE_3__["default"]]; +var createPopper = /*#__PURE__*/(0,_createPopper_js__WEBPACK_IMPORTED_MODULE_4__.popperGenerator)({ + defaultModifiers: defaultModifiers +}); // eslint-disable-next-line import/no-unused-modules + + + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/popper.js": +/*!*********************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/popper.js ***! + \*********************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "createPopper": function() { return /* binding */ createPopper; }, +/* harmony export */ "popperGenerator": function() { return /* reexport safe */ _createPopper_js__WEBPACK_IMPORTED_MODULE_9__.popperGenerator; }, +/* harmony export */ "defaultModifiers": function() { return /* binding */ defaultModifiers; }, +/* harmony export */ "detectOverflow": function() { return /* reexport safe */ _createPopper_js__WEBPACK_IMPORTED_MODULE_10__["default"]; }, +/* harmony export */ "createPopperLite": function() { return /* reexport safe */ _popper_lite_js__WEBPACK_IMPORTED_MODULE_11__.createPopper; }, +/* harmony export */ "applyStyles": function() { return /* reexport safe */ _modifiers_index_js__WEBPACK_IMPORTED_MODULE_12__.applyStyles; }, +/* harmony export */ "arrow": function() { return /* reexport safe */ _modifiers_index_js__WEBPACK_IMPORTED_MODULE_12__.arrow; }, +/* harmony export */ "computeStyles": function() { return /* reexport safe */ _modifiers_index_js__WEBPACK_IMPORTED_MODULE_12__.computeStyles; }, +/* harmony export */ "eventListeners": function() { return /* reexport safe */ _modifiers_index_js__WEBPACK_IMPORTED_MODULE_12__.eventListeners; }, +/* harmony export */ "flip": function() { return /* reexport safe */ _modifiers_index_js__WEBPACK_IMPORTED_MODULE_12__.flip; }, +/* harmony export */ "hide": function() { return /* reexport safe */ _modifiers_index_js__WEBPACK_IMPORTED_MODULE_12__.hide; }, +/* harmony export */ "offset": function() { return /* reexport safe */ _modifiers_index_js__WEBPACK_IMPORTED_MODULE_12__.offset; }, +/* harmony export */ "popperOffsets": function() { return /* reexport safe */ _modifiers_index_js__WEBPACK_IMPORTED_MODULE_12__.popperOffsets; }, +/* harmony export */ "preventOverflow": function() { return /* reexport safe */ _modifiers_index_js__WEBPACK_IMPORTED_MODULE_12__.preventOverflow; } +/* harmony export */ }); +/* harmony import */ var _createPopper_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./createPopper.js */ "../eyes/node_modules/@popperjs/core/lib/createPopper.js"); +/* harmony import */ var _createPopper_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./createPopper.js */ "../eyes/node_modules/@popperjs/core/lib/utils/detectOverflow.js"); +/* harmony import */ var _modifiers_eventListeners_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./modifiers/eventListeners.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/eventListeners.js"); +/* harmony import */ var _modifiers_popperOffsets_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modifiers/popperOffsets.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js"); +/* harmony import */ var _modifiers_computeStyles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modifiers/computeStyles.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/computeStyles.js"); +/* harmony import */ var _modifiers_applyStyles_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modifiers/applyStyles.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/applyStyles.js"); +/* harmony import */ var _modifiers_offset_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./modifiers/offset.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/offset.js"); +/* harmony import */ var _modifiers_flip_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./modifiers/flip.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/flip.js"); +/* harmony import */ var _modifiers_preventOverflow_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./modifiers/preventOverflow.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/preventOverflow.js"); +/* harmony import */ var _modifiers_arrow_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./modifiers/arrow.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/arrow.js"); +/* harmony import */ var _modifiers_hide_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./modifiers/hide.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/hide.js"); +/* harmony import */ var _popper_lite_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./popper-lite.js */ "../eyes/node_modules/@popperjs/core/lib/popper-lite.js"); +/* harmony import */ var _modifiers_index_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./modifiers/index.js */ "../eyes/node_modules/@popperjs/core/lib/modifiers/index.js"); + + + + + + + + + + +var defaultModifiers = [_modifiers_eventListeners_js__WEBPACK_IMPORTED_MODULE_0__["default"], _modifiers_popperOffsets_js__WEBPACK_IMPORTED_MODULE_1__["default"], _modifiers_computeStyles_js__WEBPACK_IMPORTED_MODULE_2__["default"], _modifiers_applyStyles_js__WEBPACK_IMPORTED_MODULE_3__["default"], _modifiers_offset_js__WEBPACK_IMPORTED_MODULE_4__["default"], _modifiers_flip_js__WEBPACK_IMPORTED_MODULE_5__["default"], _modifiers_preventOverflow_js__WEBPACK_IMPORTED_MODULE_6__["default"], _modifiers_arrow_js__WEBPACK_IMPORTED_MODULE_7__["default"], _modifiers_hide_js__WEBPACK_IMPORTED_MODULE_8__["default"]]; +var createPopper = /*#__PURE__*/(0,_createPopper_js__WEBPACK_IMPORTED_MODULE_9__.popperGenerator)({ + defaultModifiers: defaultModifiers +}); // eslint-disable-next-line import/no-unused-modules + + // eslint-disable-next-line import/no-unused-modules + + // eslint-disable-next-line import/no-unused-modules + + + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js": +/*!*****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js ***! + \*****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ computeAutoPlacement; } +/* harmony export */ }); +/* harmony import */ var _getVariation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getVariation.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getVariation.js"); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); +/* harmony import */ var _detectOverflow_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./detectOverflow.js */ "../eyes/node_modules/@popperjs/core/lib/utils/detectOverflow.js"); +/* harmony import */ var _getBasePlacement_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getBasePlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getBasePlacement.js"); + + + + +function computeAutoPlacement(state, options) { + if (options === void 0) { + options = {}; + } + + var _options = options, + placement = _options.placement, + boundary = _options.boundary, + rootBoundary = _options.rootBoundary, + padding = _options.padding, + flipVariations = _options.flipVariations, + _options$allowedAutoP = _options.allowedAutoPlacements, + allowedAutoPlacements = _options$allowedAutoP === void 0 ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.placements : _options$allowedAutoP; + var variation = (0,_getVariation_js__WEBPACK_IMPORTED_MODULE_1__["default"])(placement); + var placements = variation ? flipVariations ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.variationPlacements : _enums_js__WEBPACK_IMPORTED_MODULE_0__.variationPlacements.filter(function (placement) { + return (0,_getVariation_js__WEBPACK_IMPORTED_MODULE_1__["default"])(placement) === variation; + }) : _enums_js__WEBPACK_IMPORTED_MODULE_0__.basePlacements; + var allowedPlacements = placements.filter(function (placement) { + return allowedAutoPlacements.indexOf(placement) >= 0; + }); + + if (allowedPlacements.length === 0) { + allowedPlacements = placements; + + if (true) { + console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.'].join(' ')); + } + } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions... + + + var overflows = allowedPlacements.reduce(function (acc, placement) { + acc[placement] = (0,_detectOverflow_js__WEBPACK_IMPORTED_MODULE_2__["default"])(state, { + placement: placement, + boundary: boundary, + rootBoundary: rootBoundary, + padding: padding + })[(0,_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(placement)]; + return acc; + }, {}); + return Object.keys(overflows).sort(function (a, b) { + return overflows[a] - overflows[b]; + }); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/computeOffsets.js": +/*!***********************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/computeOffsets.js ***! + \***********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ computeOffsets; } +/* harmony export */ }); +/* harmony import */ var _getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getBasePlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getBasePlacement.js"); +/* harmony import */ var _getVariation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getVariation.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getVariation.js"); +/* harmony import */ var _getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getMainAxisFromPlacement.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js"); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); + + + + +function computeOffsets(_ref) { + var reference = _ref.reference, + element = _ref.element, + placement = _ref.placement; + var basePlacement = placement ? (0,_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(placement) : null; + var variation = placement ? (0,_getVariation_js__WEBPACK_IMPORTED_MODULE_1__["default"])(placement) : null; + var commonX = reference.x + reference.width / 2 - element.width / 2; + var commonY = reference.y + reference.height / 2 - element.height / 2; + var offsets; + + switch (basePlacement) { + case _enums_js__WEBPACK_IMPORTED_MODULE_2__.top: + offsets = { + x: commonX, + y: reference.y - element.height + }; + break; + + case _enums_js__WEBPACK_IMPORTED_MODULE_2__.bottom: + offsets = { + x: commonX, + y: reference.y + reference.height + }; + break; + + case _enums_js__WEBPACK_IMPORTED_MODULE_2__.right: + offsets = { + x: reference.x + reference.width, + y: commonY + }; + break; + + case _enums_js__WEBPACK_IMPORTED_MODULE_2__.left: + offsets = { + x: reference.x - element.width, + y: commonY + }; + break; + + default: + offsets = { + x: reference.x, + y: reference.y + }; + } + + var mainAxis = basePlacement ? (0,_getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(basePlacement) : null; + + if (mainAxis != null) { + var len = mainAxis === 'y' ? 'height' : 'width'; + + switch (variation) { + case _enums_js__WEBPACK_IMPORTED_MODULE_2__.start: + offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2); + break; + + case _enums_js__WEBPACK_IMPORTED_MODULE_2__.end: + offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2); + break; + + default: + } + } + + return offsets; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/debounce.js": +/*!*****************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/debounce.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ debounce; } +/* harmony export */ }); +function debounce(fn) { + var pending; + return function () { + if (!pending) { + pending = new Promise(function (resolve) { + Promise.resolve().then(function () { + pending = undefined; + resolve(fn()); + }); + }); + } + + return pending; + }; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/detectOverflow.js": +/*!***********************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/detectOverflow.js ***! + \***********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ detectOverflow; } +/* harmony export */ }); +/* harmony import */ var _dom_utils_getClippingRect_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../dom-utils/getClippingRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js"); +/* harmony import */ var _dom_utils_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../dom-utils/getDocumentElement.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js"); +/* harmony import */ var _dom_utils_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../dom-utils/getBoundingClientRect.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js"); +/* harmony import */ var _computeOffsets_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./computeOffsets.js */ "../eyes/node_modules/@popperjs/core/lib/utils/computeOffsets.js"); +/* harmony import */ var _rectToClientRect_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./rectToClientRect.js */ "../eyes/node_modules/@popperjs/core/lib/utils/rectToClientRect.js"); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); +/* harmony import */ var _dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../dom-utils/instanceOf.js */ "../eyes/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js"); +/* harmony import */ var _mergePaddingObject_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mergePaddingObject.js */ "../eyes/node_modules/@popperjs/core/lib/utils/mergePaddingObject.js"); +/* harmony import */ var _expandToHashMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./expandToHashMap.js */ "../eyes/node_modules/@popperjs/core/lib/utils/expandToHashMap.js"); + + + + + + + + + // eslint-disable-next-line import/no-unused-modules + +function detectOverflow(state, options) { + if (options === void 0) { + options = {}; + } + + var _options = options, + _options$placement = _options.placement, + placement = _options$placement === void 0 ? state.placement : _options$placement, + _options$strategy = _options.strategy, + strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, + _options$boundary = _options.boundary, + boundary = _options$boundary === void 0 ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.clippingParents : _options$boundary, + _options$rootBoundary = _options.rootBoundary, + rootBoundary = _options$rootBoundary === void 0 ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.viewport : _options$rootBoundary, + _options$elementConte = _options.elementContext, + elementContext = _options$elementConte === void 0 ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.popper : _options$elementConte, + _options$altBoundary = _options.altBoundary, + altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, + _options$padding = _options.padding, + padding = _options$padding === void 0 ? 0 : _options$padding; + var paddingObject = (0,_mergePaddingObject_js__WEBPACK_IMPORTED_MODULE_1__["default"])(typeof padding !== 'number' ? padding : (0,_expandToHashMap_js__WEBPACK_IMPORTED_MODULE_2__["default"])(padding, _enums_js__WEBPACK_IMPORTED_MODULE_0__.basePlacements)); + var altContext = elementContext === _enums_js__WEBPACK_IMPORTED_MODULE_0__.popper ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.reference : _enums_js__WEBPACK_IMPORTED_MODULE_0__.popper; + var popperRect = state.rects.popper; + var element = state.elements[altBoundary ? altContext : elementContext]; + var clippingClientRect = (0,_dom_utils_getClippingRect_js__WEBPACK_IMPORTED_MODULE_3__["default"])((0,_dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__.isElement)(element) ? element : element.contextElement || (0,_dom_utils_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_5__["default"])(state.elements.popper), boundary, rootBoundary, strategy); + var referenceClientRect = (0,_dom_utils_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_6__["default"])(state.elements.reference); + var popperOffsets = (0,_computeOffsets_js__WEBPACK_IMPORTED_MODULE_7__["default"])({ + reference: referenceClientRect, + element: popperRect, + strategy: 'absolute', + placement: placement + }); + var popperClientRect = (0,_rectToClientRect_js__WEBPACK_IMPORTED_MODULE_8__["default"])(Object.assign({}, popperRect, popperOffsets)); + var elementClientRect = elementContext === _enums_js__WEBPACK_IMPORTED_MODULE_0__.popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect + // 0 or negative = within the clipping rect + + var overflowOffsets = { + top: clippingClientRect.top - elementClientRect.top + paddingObject.top, + bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, + left: clippingClientRect.left - elementClientRect.left + paddingObject.left, + right: elementClientRect.right - clippingClientRect.right + paddingObject.right + }; + var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element + + if (elementContext === _enums_js__WEBPACK_IMPORTED_MODULE_0__.popper && offsetData) { + var offset = offsetData[placement]; + Object.keys(overflowOffsets).forEach(function (key) { + var multiply = [_enums_js__WEBPACK_IMPORTED_MODULE_0__.right, _enums_js__WEBPACK_IMPORTED_MODULE_0__.bottom].indexOf(key) >= 0 ? 1 : -1; + var axis = [_enums_js__WEBPACK_IMPORTED_MODULE_0__.top, _enums_js__WEBPACK_IMPORTED_MODULE_0__.bottom].indexOf(key) >= 0 ? 'y' : 'x'; + overflowOffsets[key] += offset[axis] * multiply; + }); + } + + return overflowOffsets; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/expandToHashMap.js": +/*!************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/expandToHashMap.js ***! + \************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ expandToHashMap; } +/* harmony export */ }); +function expandToHashMap(value, keys) { + return keys.reduce(function (hashMap, key) { + hashMap[key] = value; + return hashMap; + }, {}); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/format.js": +/*!***************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/format.js ***! + \***************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ format; } +/* harmony export */ }); +function format(str) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + return [].concat(args).reduce(function (p, c) { + return p.replace(/%s/, c); + }, str); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/getAltAxis.js": +/*!*******************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/getAltAxis.js ***! + \*******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getAltAxis; } +/* harmony export */ }); +function getAltAxis(axis) { + return axis === 'x' ? 'y' : 'x'; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/getBasePlacement.js": +/*!*************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/getBasePlacement.js ***! + \*************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getBasePlacement; } +/* harmony export */ }); + +function getBasePlacement(placement) { + return placement.split('-')[0]; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/getFreshSideObject.js": +/*!***************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/getFreshSideObject.js ***! + \***************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getFreshSideObject; } +/* harmony export */ }); +function getFreshSideObject() { + return { + top: 0, + right: 0, + bottom: 0, + left: 0 + }; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js": +/*!*********************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js ***! + \*********************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getMainAxisFromPlacement; } +/* harmony export */ }); +function getMainAxisFromPlacement(placement) { + return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y'; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/getOppositePlacement.js": +/*!*****************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/getOppositePlacement.js ***! + \*****************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getOppositePlacement; } +/* harmony export */ }); +var hash = { + left: 'right', + right: 'left', + bottom: 'top', + top: 'bottom' +}; +function getOppositePlacement(placement) { + return placement.replace(/left|right|bottom|top/g, function (matched) { + return hash[matched]; + }); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js": +/*!**************************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js ***! + \**************************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getOppositeVariationPlacement; } +/* harmony export */ }); +var hash = { + start: 'end', + end: 'start' +}; +function getOppositeVariationPlacement(placement) { + return placement.replace(/start|end/g, function (matched) { + return hash[matched]; + }); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/getVariation.js": +/*!*********************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/getVariation.js ***! + \*********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getVariation; } +/* harmony export */ }); +function getVariation(placement) { + return placement.split('-')[1]; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/math.js": +/*!*************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/math.js ***! + \*************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "max": function() { return /* binding */ max; }, +/* harmony export */ "min": function() { return /* binding */ min; }, +/* harmony export */ "round": function() { return /* binding */ round; } +/* harmony export */ }); +var max = Math.max; +var min = Math.min; +var round = Math.round; + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/mergeByName.js": +/*!********************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/mergeByName.js ***! + \********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ mergeByName; } +/* harmony export */ }); +function mergeByName(modifiers) { + var merged = modifiers.reduce(function (merged, current) { + var existing = merged[current.name]; + merged[current.name] = existing ? Object.assign({}, existing, current, { + options: Object.assign({}, existing.options, current.options), + data: Object.assign({}, existing.data, current.data) + }) : current; + return merged; + }, {}); // IE11 does not support Object.values + + return Object.keys(merged).map(function (key) { + return merged[key]; + }); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/mergePaddingObject.js": +/*!***************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/mergePaddingObject.js ***! + \***************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ mergePaddingObject; } +/* harmony export */ }); +/* harmony import */ var _getFreshSideObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getFreshSideObject.js */ "../eyes/node_modules/@popperjs/core/lib/utils/getFreshSideObject.js"); + +function mergePaddingObject(paddingObject) { + return Object.assign({}, (0,_getFreshSideObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(), paddingObject); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/orderModifiers.js": +/*!***********************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/orderModifiers.js ***! + \***********************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ orderModifiers; } +/* harmony export */ }); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); + // source: https://stackoverflow.com/questions/49875255 + +function order(modifiers) { + var map = new Map(); + var visited = new Set(); + var result = []; + modifiers.forEach(function (modifier) { + map.set(modifier.name, modifier); + }); // On visiting object, check for its dependencies and visit them recursively + + function sort(modifier) { + visited.add(modifier.name); + var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); + requires.forEach(function (dep) { + if (!visited.has(dep)) { + var depModifier = map.get(dep); + + if (depModifier) { + sort(depModifier); + } + } + }); + result.push(modifier); + } + + modifiers.forEach(function (modifier) { + if (!visited.has(modifier.name)) { + // check for visited object + sort(modifier); + } + }); + return result; +} + +function orderModifiers(modifiers) { + // order based on dependencies + var orderedModifiers = order(modifiers); // order based on phase + + return _enums_js__WEBPACK_IMPORTED_MODULE_0__.modifierPhases.reduce(function (acc, phase) { + return acc.concat(orderedModifiers.filter(function (modifier) { + return modifier.phase === phase; + })); + }, []); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/rectToClientRect.js": +/*!*************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/rectToClientRect.js ***! + \*************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ rectToClientRect; } +/* harmony export */ }); +function rectToClientRect(rect) { + return Object.assign({}, rect, { + left: rect.x, + top: rect.y, + right: rect.x + rect.width, + bottom: rect.y + rect.height + }); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/uniqueBy.js": +/*!*****************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/uniqueBy.js ***! + \*****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ uniqueBy; } +/* harmony export */ }); +function uniqueBy(arr, fn) { + var identifiers = new Set(); + return arr.filter(function (item) { + var identifier = fn(item); + + if (!identifiers.has(identifier)) { + identifiers.add(identifier); + return true; + } + }); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/userAgent.js": +/*!******************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/userAgent.js ***! + \******************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ getUAString; } +/* harmony export */ }); +function getUAString() { + var uaData = navigator.userAgentData; + + if (uaData != null && uaData.brands) { + return uaData.brands.map(function (item) { + return item.brand + "/" + item.version; + }).join(' '); + } + + return navigator.userAgent; +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/validateModifiers.js": +/*!**************************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/validateModifiers.js ***! + \**************************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ validateModifiers; } +/* harmony export */ }); +/* harmony import */ var _format_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./format.js */ "../eyes/node_modules/@popperjs/core/lib/utils/format.js"); +/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../enums.js */ "../eyes/node_modules/@popperjs/core/lib/enums.js"); + + +var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s'; +var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available'; +var VALID_PROPERTIES = ['name', 'enabled', 'phase', 'fn', 'effect', 'requires', 'options']; +function validateModifiers(modifiers) { + modifiers.forEach(function (modifier) { + [].concat(Object.keys(modifier), VALID_PROPERTIES) // IE11-compatible replacement for `new Set(iterable)` + .filter(function (value, index, self) { + return self.indexOf(value) === index; + }).forEach(function (key) { + switch (key) { + case 'name': + if (typeof modifier.name !== 'string') { + console.error((0,_format_js__WEBPACK_IMPORTED_MODULE_0__["default"])(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', "\"" + String(modifier.name) + "\"")); + } + + break; + + case 'enabled': + if (typeof modifier.enabled !== 'boolean') { + console.error((0,_format_js__WEBPACK_IMPORTED_MODULE_0__["default"])(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', "\"" + String(modifier.enabled) + "\"")); + } + + break; + + case 'phase': + if (_enums_js__WEBPACK_IMPORTED_MODULE_1__.modifierPhases.indexOf(modifier.phase) < 0) { + console.error((0,_format_js__WEBPACK_IMPORTED_MODULE_0__["default"])(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + _enums_js__WEBPACK_IMPORTED_MODULE_1__.modifierPhases.join(', '), "\"" + String(modifier.phase) + "\"")); + } + + break; + + case 'fn': + if (typeof modifier.fn !== 'function') { + console.error((0,_format_js__WEBPACK_IMPORTED_MODULE_0__["default"])(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', "\"" + String(modifier.fn) + "\"")); + } + + break; + + case 'effect': + if (modifier.effect != null && typeof modifier.effect !== 'function') { + console.error((0,_format_js__WEBPACK_IMPORTED_MODULE_0__["default"])(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', "\"" + String(modifier.fn) + "\"")); + } + + break; + + case 'requires': + if (modifier.requires != null && !Array.isArray(modifier.requires)) { + console.error((0,_format_js__WEBPACK_IMPORTED_MODULE_0__["default"])(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', "\"" + String(modifier.requires) + "\"")); + } + + break; + + case 'requiresIfExists': + if (!Array.isArray(modifier.requiresIfExists)) { + console.error((0,_format_js__WEBPACK_IMPORTED_MODULE_0__["default"])(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', "\"" + String(modifier.requiresIfExists) + "\"")); + } + + break; + + case 'options': + case 'data': + break; + + default: + console.error("PopperJS: an invalid property has been provided to the \"" + modifier.name + "\" modifier, valid properties are " + VALID_PROPERTIES.map(function (s) { + return "\"" + s + "\""; + }).join(', ') + "; but \"" + key + "\" was provided."); + } + + modifier.requires && modifier.requires.forEach(function (requirement) { + if (modifiers.find(function (mod) { + return mod.name === requirement; + }) == null) { + console.error((0,_format_js__WEBPACK_IMPORTED_MODULE_0__["default"])(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement)); + } + }); + }); + }); +} + +/***/ }), + +/***/ "../eyes/node_modules/@popperjs/core/lib/utils/within.js": +/*!***************************************************************!*\ + !*** ../eyes/node_modules/@popperjs/core/lib/utils/within.js ***! + \***************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "within": function() { return /* binding */ within; }, +/* harmony export */ "withinMaxClamp": function() { return /* binding */ withinMaxClamp; } +/* harmony export */ }); +/* harmony import */ var _math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.js */ "../eyes/node_modules/@popperjs/core/lib/utils/math.js"); + +function within(min, value, max) { + return (0,_math_js__WEBPACK_IMPORTED_MODULE_0__.max)(min, (0,_math_js__WEBPACK_IMPORTED_MODULE_0__.min)(value, max)); +} +function withinMaxClamp(min, value, max) { + var v = within(min, value, max); + return v > max ? max : v; +} + +/***/ }), + +/***/ "../eyes/node_modules/@tweenjs/tween.js/dist/tween.esm.js": +/*!****************************************************************!*\ + !*** ../eyes/node_modules/@tweenjs/tween.js/dist/tween.esm.js ***! + \****************************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Easing": function() { return /* binding */ Easing; }, +/* harmony export */ "Group": function() { return /* binding */ Group; }, +/* harmony export */ "Interpolation": function() { return /* binding */ Interpolation; }, +/* harmony export */ "Sequence": function() { return /* binding */ Sequence; }, +/* harmony export */ "Tween": function() { return /* binding */ Tween; }, +/* harmony export */ "VERSION": function() { return /* binding */ VERSION; }, +/* harmony export */ "add": function() { return /* binding */ add; }, +/* harmony export */ "getAll": function() { return /* binding */ getAll; }, +/* harmony export */ "nextId": function() { return /* binding */ nextId; }, +/* harmony export */ "now": function() { return /* binding */ now$1; }, +/* harmony export */ "remove": function() { return /* binding */ remove; }, +/* harmony export */ "removeAll": function() { return /* binding */ removeAll; }, +/* harmony export */ "update": function() { return /* binding */ update; } +/* harmony export */ }); +/** + * The Ease class provides a collection of easing functions for use with tween.js. + */ +var Easing = { + Linear: { + None: function (amount) { + return amount; + }, + }, + Quadratic: { + In: function (amount) { + return amount * amount; + }, + Out: function (amount) { + return amount * (2 - amount); + }, + InOut: function (amount) { + if ((amount *= 2) < 1) { + return 0.5 * amount * amount; + } + return -0.5 * (--amount * (amount - 2) - 1); + }, + }, + Cubic: { + In: function (amount) { + return amount * amount * amount; + }, + Out: function (amount) { + return --amount * amount * amount + 1; + }, + InOut: function (amount) { + if ((amount *= 2) < 1) { + return 0.5 * amount * amount * amount; + } + return 0.5 * ((amount -= 2) * amount * amount + 2); + }, + }, + Quartic: { + In: function (amount) { + return amount * amount * amount * amount; + }, + Out: function (amount) { + return 1 - --amount * amount * amount * amount; + }, + InOut: function (amount) { + if ((amount *= 2) < 1) { + return 0.5 * amount * amount * amount * amount; + } + return -0.5 * ((amount -= 2) * amount * amount * amount - 2); + }, + }, + Quintic: { + In: function (amount) { + return amount * amount * amount * amount * amount; + }, + Out: function (amount) { + return --amount * amount * amount * amount * amount + 1; + }, + InOut: function (amount) { + if ((amount *= 2) < 1) { + return 0.5 * amount * amount * amount * amount * amount; + } + return 0.5 * ((amount -= 2) * amount * amount * amount * amount + 2); + }, + }, + Sinusoidal: { + In: function (amount) { + return 1 - Math.cos((amount * Math.PI) / 2); + }, + Out: function (amount) { + return Math.sin((amount * Math.PI) / 2); + }, + InOut: function (amount) { + return 0.5 * (1 - Math.cos(Math.PI * amount)); + }, + }, + Exponential: { + In: function (amount) { + return amount === 0 ? 0 : Math.pow(1024, amount - 1); + }, + Out: function (amount) { + return amount === 1 ? 1 : 1 - Math.pow(2, -10 * amount); + }, + InOut: function (amount) { + if (amount === 0) { + return 0; + } + if (amount === 1) { + return 1; + } + if ((amount *= 2) < 1) { + return 0.5 * Math.pow(1024, amount - 1); + } + return 0.5 * (-Math.pow(2, -10 * (amount - 1)) + 2); + }, + }, + Circular: { + In: function (amount) { + return 1 - Math.sqrt(1 - amount * amount); + }, + Out: function (amount) { + return Math.sqrt(1 - --amount * amount); + }, + InOut: function (amount) { + if ((amount *= 2) < 1) { + return -0.5 * (Math.sqrt(1 - amount * amount) - 1); + } + return 0.5 * (Math.sqrt(1 - (amount -= 2) * amount) + 1); + }, + }, + Elastic: { + In: function (amount) { + if (amount === 0) { + return 0; + } + if (amount === 1) { + return 1; + } + return -Math.pow(2, 10 * (amount - 1)) * Math.sin((amount - 1.1) * 5 * Math.PI); + }, + Out: function (amount) { + if (amount === 0) { + return 0; + } + if (amount === 1) { + return 1; + } + return Math.pow(2, -10 * amount) * Math.sin((amount - 0.1) * 5 * Math.PI) + 1; + }, + InOut: function (amount) { + if (amount === 0) { + return 0; + } + if (amount === 1) { + return 1; + } + amount *= 2; + if (amount < 1) { + return -0.5 * Math.pow(2, 10 * (amount - 1)) * Math.sin((amount - 1.1) * 5 * Math.PI); + } + return 0.5 * Math.pow(2, -10 * (amount - 1)) * Math.sin((amount - 1.1) * 5 * Math.PI) + 1; + }, + }, + Back: { + In: function (amount) { + var s = 1.70158; + return amount * amount * ((s + 1) * amount - s); + }, + Out: function (amount) { + var s = 1.70158; + return --amount * amount * ((s + 1) * amount + s) + 1; + }, + InOut: function (amount) { + var s = 1.70158 * 1.525; + if ((amount *= 2) < 1) { + return 0.5 * (amount * amount * ((s + 1) * amount - s)); + } + return 0.5 * ((amount -= 2) * amount * ((s + 1) * amount + s) + 2); + }, + }, + Bounce: { + In: function (amount) { + return 1 - Easing.Bounce.Out(1 - amount); + }, + Out: function (amount) { + if (amount < 1 / 2.75) { + return 7.5625 * amount * amount; + } + else if (amount < 2 / 2.75) { + return 7.5625 * (amount -= 1.5 / 2.75) * amount + 0.75; + } + else if (amount < 2.5 / 2.75) { + return 7.5625 * (amount -= 2.25 / 2.75) * amount + 0.9375; + } + else { + return 7.5625 * (amount -= 2.625 / 2.75) * amount + 0.984375; + } + }, + InOut: function (amount) { + if (amount < 0.5) { + return Easing.Bounce.In(amount * 2) * 0.5; + } + return Easing.Bounce.Out(amount * 2 - 1) * 0.5 + 0.5; + }, + }, +}; + +var now; +// Include a performance.now polyfill. +// In node.js, use process.hrtime. +// eslint-disable-next-line +// @ts-ignore +if (typeof self === 'undefined' && typeof process !== 'undefined' && process.hrtime) { + now = function () { + // eslint-disable-next-line + // @ts-ignore + var time = process.hrtime(); + // Convert [seconds, nanoseconds] to milliseconds. + return time[0] * 1000 + time[1] / 1000000; + }; +} +// In a browser, use self.performance.now if it is available. +else if (typeof self !== 'undefined' && self.performance !== undefined && self.performance.now !== undefined) { + // This must be bound, because directly assigning this function + // leads to an invocation exception in Chrome. + now = self.performance.now.bind(self.performance); +} +// Use Date.now if it is available. +else if (Date.now !== undefined) { + now = Date.now; +} +// Otherwise, use 'new Date().getTime()'. +else { + now = function () { + return new Date().getTime(); + }; +} +var now$1 = now; + +/** + * Controlling groups of tweens + * + * Using the TWEEN singleton to manage your tweens can cause issues in large apps with many components. + * In these cases, you may want to create your own smaller groups of tween + */ +var Group = /** @class */ (function () { + function Group() { + this._tweens = {}; + this._tweensAddedDuringUpdate = {}; + } + Group.prototype.getAll = function () { + var _this = this; + return Object.keys(this._tweens).map(function (tweenId) { + return _this._tweens[tweenId]; + }); + }; + Group.prototype.removeAll = function () { + this._tweens = {}; + }; + Group.prototype.add = function (tween) { + this._tweens[tween.getId()] = tween; + this._tweensAddedDuringUpdate[tween.getId()] = tween; + }; + Group.prototype.remove = function (tween) { + delete this._tweens[tween.getId()]; + delete this._tweensAddedDuringUpdate[tween.getId()]; + }; + Group.prototype.update = function (time, preserve) { + if (time === void 0) { time = now$1(); } + if (preserve === void 0) { preserve = false; } + var tweenIds = Object.keys(this._tweens); + if (tweenIds.length === 0) { + return false; + } + // Tweens are updated in "batches". If you add a new tween during an + // update, then the new tween will be updated in the next batch. + // If you remove a tween during an update, it may or may not be updated. + // However, if the removed tween was added during the current batch, + // then it will not be updated. + while (tweenIds.length > 0) { + this._tweensAddedDuringUpdate = {}; + for (var i = 0; i < tweenIds.length; i++) { + var tween = this._tweens[tweenIds[i]]; + var autoStart = !preserve; + if (tween && tween.update(time, autoStart) === false && !preserve) { + delete this._tweens[tweenIds[i]]; + } + } + tweenIds = Object.keys(this._tweensAddedDuringUpdate); + } + return true; + }; + return Group; +}()); + +/** + * + */ +var Interpolation = { + Linear: function (v, k) { + var m = v.length - 1; + var f = m * k; + var i = Math.floor(f); + var fn = Interpolation.Utils.Linear; + if (k < 0) { + return fn(v[0], v[1], f); + } + if (k > 1) { + return fn(v[m], v[m - 1], m - f); + } + return fn(v[i], v[i + 1 > m ? m : i + 1], f - i); + }, + Bezier: function (v, k) { + var b = 0; + var n = v.length - 1; + var pw = Math.pow; + var bn = Interpolation.Utils.Bernstein; + for (var i = 0; i <= n; i++) { + b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i); + } + return b; + }, + CatmullRom: function (v, k) { + var m = v.length - 1; + var f = m * k; + var i = Math.floor(f); + var fn = Interpolation.Utils.CatmullRom; + if (v[0] === v[m]) { + if (k < 0) { + i = Math.floor((f = m * (1 + k))); + } + return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i); + } + else { + if (k < 0) { + return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]); + } + if (k > 1) { + return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]); + } + return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i); + } + }, + Utils: { + Linear: function (p0, p1, t) { + return (p1 - p0) * t + p0; + }, + Bernstein: function (n, i) { + var fc = Interpolation.Utils.Factorial; + return fc(n) / fc(i) / fc(n - i); + }, + Factorial: (function () { + var a = [1]; + return function (n) { + var s = 1; + if (a[n]) { + return a[n]; + } + for (var i = n; i > 1; i--) { + s *= i; + } + a[n] = s; + return s; + }; + })(), + CatmullRom: function (p0, p1, p2, p3, t) { + var v0 = (p2 - p0) * 0.5; + var v1 = (p3 - p1) * 0.5; + var t2 = t * t; + var t3 = t * t2; + return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; + }, + }, +}; + +/** + * Utils + */ +var Sequence = /** @class */ (function () { + function Sequence() { + } + Sequence.nextId = function () { + return Sequence._nextId++; + }; + Sequence._nextId = 0; + return Sequence; +}()); + +var mainGroup = new Group(); + +/** + * Tween.js - Licensed under the MIT license + * https://github.com/tweenjs/tween.js + * ---------------------------------------------- + * + * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors. + * Thank you all, you're awesome! + */ +var Tween = /** @class */ (function () { + function Tween(_object, _group) { + if (_group === void 0) { _group = mainGroup; } + this._object = _object; + this._group = _group; + this._isPaused = false; + this._pauseStart = 0; + this._valuesStart = {}; + this._valuesEnd = {}; + this._valuesStartRepeat = {}; + this._duration = 1000; + this._initialRepeat = 0; + this._repeat = 0; + this._yoyo = false; + this._isPlaying = false; + this._reversed = false; + this._delayTime = 0; + this._startTime = 0; + this._easingFunction = Easing.Linear.None; + this._interpolationFunction = Interpolation.Linear; + this._chainedTweens = []; + this._onStartCallbackFired = false; + this._id = Sequence.nextId(); + this._isChainStopped = false; + this._goToEnd = false; + } + Tween.prototype.getId = function () { + return this._id; + }; + Tween.prototype.isPlaying = function () { + return this._isPlaying; + }; + Tween.prototype.isPaused = function () { + return this._isPaused; + }; + Tween.prototype.to = function (properties, duration) { + // TODO? restore this, then update the 07_dynamic_to example to set fox + // tween's to on each update. That way the behavior is opt-in (there's + // currently no opt-out). + // for (const prop in properties) this._valuesEnd[prop] = properties[prop] + this._valuesEnd = Object.create(properties); + if (duration !== undefined) { + this._duration = duration; + } + return this; + }; + Tween.prototype.duration = function (d) { + this._duration = d; + return this; + }; + Tween.prototype.start = function (time) { + if (this._isPlaying) { + return this; + } + // eslint-disable-next-line + this._group && this._group.add(this); + this._repeat = this._initialRepeat; + if (this._reversed) { + // If we were reversed (f.e. using the yoyo feature) then we need to + // flip the tween direction back to forward. + this._reversed = false; + for (var property in this._valuesStartRepeat) { + this._swapEndStartRepeatValues(property); + this._valuesStart[property] = this._valuesStartRepeat[property]; + } + } + this._isPlaying = true; + this._isPaused = false; + this._onStartCallbackFired = false; + this._isChainStopped = false; + this._startTime = time !== undefined ? (typeof time === 'string' ? now$1() + parseFloat(time) : time) : now$1(); + this._startTime += this._delayTime; + this._setupProperties(this._object, this._valuesStart, this._valuesEnd, this._valuesStartRepeat); + return this; + }; + Tween.prototype._setupProperties = function (_object, _valuesStart, _valuesEnd, _valuesStartRepeat) { + for (var property in _valuesEnd) { + var startValue = _object[property]; + var startValueIsArray = Array.isArray(startValue); + var propType = startValueIsArray ? 'array' : typeof startValue; + var isInterpolationList = !startValueIsArray && Array.isArray(_valuesEnd[property]); + // If `to()` specifies a property that doesn't exist in the source object, + // we should not set that property in the object + if (propType === 'undefined' || propType === 'function') { + continue; + } + // Check if an Array was provided as property value + if (isInterpolationList) { + var endValues = _valuesEnd[property]; + if (endValues.length === 0) { + continue; + } + // handle an array of relative values + endValues = endValues.map(this._handleRelativeValue.bind(this, startValue)); + // Create a local copy of the Array with the start value at the front + _valuesEnd[property] = [startValue].concat(endValues); + } + // handle the deepness of the values + if ((propType === 'object' || startValueIsArray) && startValue && !isInterpolationList) { + _valuesStart[property] = startValueIsArray ? [] : {}; + // eslint-disable-next-line + for (var prop in startValue) { + // eslint-disable-next-line + // @ts-ignore FIXME? + _valuesStart[property][prop] = startValue[prop]; + } + _valuesStartRepeat[property] = startValueIsArray ? [] : {}; // TODO? repeat nested values? And yoyo? And array values? + // eslint-disable-next-line + // @ts-ignore FIXME? + this._setupProperties(startValue, _valuesStart[property], _valuesEnd[property], _valuesStartRepeat[property]); + } + else { + // Save the starting value, but only once. + if (typeof _valuesStart[property] === 'undefined') { + _valuesStart[property] = startValue; + } + if (!startValueIsArray) { + // eslint-disable-next-line + // @ts-ignore FIXME? + _valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings + } + if (isInterpolationList) { + // eslint-disable-next-line + // @ts-ignore FIXME? + _valuesStartRepeat[property] = _valuesEnd[property].slice().reverse(); + } + else { + _valuesStartRepeat[property] = _valuesStart[property] || 0; + } + } + } + }; + Tween.prototype.stop = function () { + if (!this._isChainStopped) { + this._isChainStopped = true; + this.stopChainedTweens(); + } + if (!this._isPlaying) { + return this; + } + // eslint-disable-next-line + this._group && this._group.remove(this); + this._isPlaying = false; + this._isPaused = false; + if (this._onStopCallback) { + this._onStopCallback(this._object); + } + return this; + }; + Tween.prototype.end = function () { + this._goToEnd = true; + this.update(Infinity); + return this; + }; + Tween.prototype.pause = function (time) { + if (time === void 0) { time = now$1(); } + if (this._isPaused || !this._isPlaying) { + return this; + } + this._isPaused = true; + this._pauseStart = time; + // eslint-disable-next-line + this._group && this._group.remove(this); + return this; + }; + Tween.prototype.resume = function (time) { + if (time === void 0) { time = now$1(); } + if (!this._isPaused || !this._isPlaying) { + return this; + } + this._isPaused = false; + this._startTime += time - this._pauseStart; + this._pauseStart = 0; + // eslint-disable-next-line + this._group && this._group.add(this); + return this; + }; + Tween.prototype.stopChainedTweens = function () { + for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { + this._chainedTweens[i].stop(); + } + return this; + }; + Tween.prototype.group = function (group) { + this._group = group; + return this; + }; + Tween.prototype.delay = function (amount) { + this._delayTime = amount; + return this; + }; + Tween.prototype.repeat = function (times) { + this._initialRepeat = times; + this._repeat = times; + return this; + }; + Tween.prototype.repeatDelay = function (amount) { + this._repeatDelayTime = amount; + return this; + }; + Tween.prototype.yoyo = function (yoyo) { + this._yoyo = yoyo; + return this; + }; + Tween.prototype.easing = function (easingFunction) { + this._easingFunction = easingFunction; + return this; + }; + Tween.prototype.interpolation = function (interpolationFunction) { + this._interpolationFunction = interpolationFunction; + return this; + }; + Tween.prototype.chain = function () { + var tweens = []; + for (var _i = 0; _i < arguments.length; _i++) { + tweens[_i] = arguments[_i]; + } + this._chainedTweens = tweens; + return this; + }; + Tween.prototype.onStart = function (callback) { + this._onStartCallback = callback; + return this; + }; + Tween.prototype.onUpdate = function (callback) { + this._onUpdateCallback = callback; + return this; + }; + Tween.prototype.onRepeat = function (callback) { + this._onRepeatCallback = callback; + return this; + }; + Tween.prototype.onComplete = function (callback) { + this._onCompleteCallback = callback; + return this; + }; + Tween.prototype.onStop = function (callback) { + this._onStopCallback = callback; + return this; + }; + /** + * @returns true if the tween is still playing after the update, false + * otherwise (calling update on a paused tween still returns true because + * it is still playing, just paused). + */ + Tween.prototype.update = function (time, autoStart) { + if (time === void 0) { time = now$1(); } + if (autoStart === void 0) { autoStart = true; } + if (this._isPaused) + return true; + var property; + var elapsed; + var endTime = this._startTime + this._duration; + if (!this._goToEnd && !this._isPlaying) { + if (time > endTime) + return false; + if (autoStart) + this.start(time); + } + this._goToEnd = false; + if (time < this._startTime) { + return true; + } + if (this._onStartCallbackFired === false) { + if (this._onStartCallback) { + this._onStartCallback(this._object); + } + this._onStartCallbackFired = true; + } + elapsed = (time - this._startTime) / this._duration; + elapsed = this._duration === 0 || elapsed > 1 ? 1 : elapsed; + var value = this._easingFunction(elapsed); + // properties transformations + this._updateProperties(this._object, this._valuesStart, this._valuesEnd, value); + if (this._onUpdateCallback) { + this._onUpdateCallback(this._object, elapsed); + } + if (elapsed === 1) { + if (this._repeat > 0) { + if (isFinite(this._repeat)) { + this._repeat--; + } + // Reassign starting values, restart by making startTime = now + for (property in this._valuesStartRepeat) { + if (!this._yoyo && typeof this._valuesEnd[property] === 'string') { + this._valuesStartRepeat[property] = + // eslint-disable-next-line + // @ts-ignore FIXME? + this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property]); + } + if (this._yoyo) { + this._swapEndStartRepeatValues(property); + } + this._valuesStart[property] = this._valuesStartRepeat[property]; + } + if (this._yoyo) { + this._reversed = !this._reversed; + } + if (this._repeatDelayTime !== undefined) { + this._startTime = time + this._repeatDelayTime; + } + else { + this._startTime = time + this._delayTime; + } + if (this._onRepeatCallback) { + this._onRepeatCallback(this._object); + } + return true; + } + else { + if (this._onCompleteCallback) { + this._onCompleteCallback(this._object); + } + for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { + // Make the chained tweens start exactly at the time they should, + // even if the `update()` method was called way past the duration of the tween + this._chainedTweens[i].start(this._startTime + this._duration); + } + this._isPlaying = false; + return false; + } + } + return true; + }; + Tween.prototype._updateProperties = function (_object, _valuesStart, _valuesEnd, value) { + for (var property in _valuesEnd) { + // Don't update properties that do not exist in the source object + if (_valuesStart[property] === undefined) { + continue; + } + var start = _valuesStart[property] || 0; + var end = _valuesEnd[property]; + var startIsArray = Array.isArray(_object[property]); + var endIsArray = Array.isArray(end); + var isInterpolationList = !startIsArray && endIsArray; + if (isInterpolationList) { + _object[property] = this._interpolationFunction(end, value); + } + else if (typeof end === 'object' && end) { + // eslint-disable-next-line + // @ts-ignore FIXME? + this._updateProperties(_object[property], start, end, value); + } + else { + // Parses relative end values with start as base (e.g.: +10, -3) + end = this._handleRelativeValue(start, end); + // Protect against non numeric properties. + if (typeof end === 'number') { + // eslint-disable-next-line + // @ts-ignore FIXME? + _object[property] = start + (end - start) * value; + } + } + } + }; + Tween.prototype._handleRelativeValue = function (start, end) { + if (typeof end !== 'string') { + return end; + } + if (end.charAt(0) === '+' || end.charAt(0) === '-') { + return start + parseFloat(end); + } + else { + return parseFloat(end); + } + }; + Tween.prototype._swapEndStartRepeatValues = function (property) { + var tmp = this._valuesStartRepeat[property]; + var endValue = this._valuesEnd[property]; + if (typeof endValue === 'string') { + this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(endValue); + } + else { + this._valuesStartRepeat[property] = this._valuesEnd[property]; + } + this._valuesEnd[property] = tmp; + }; + return Tween; +}()); + +var VERSION = '18.6.4'; + +/** + * Tween.js - Licensed under the MIT license + * https://github.com/tweenjs/tween.js + * ---------------------------------------------- + * + * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors. + * Thank you all, you're awesome! + */ +var nextId = Sequence.nextId; +/** + * Controlling groups of tweens + * + * Using the TWEEN singleton to manage your tweens can cause issues in large apps with many components. + * In these cases, you may want to create your own smaller groups of tweens. + */ +var TWEEN = mainGroup; +// This is the best way to export things in a way that's compatible with both ES +// Modules and CommonJS, without build hacks, and so as not to break the +// existing API. +// https://github.com/rollup/rollup/issues/1961#issuecomment-423037881 +var getAll = TWEEN.getAll.bind(TWEEN); +var removeAll = TWEEN.removeAll.bind(TWEEN); +var add = TWEEN.add.bind(TWEEN); +var remove = TWEEN.remove.bind(TWEEN); +var update = TWEEN.update.bind(TWEEN); +var exports = { + Easing: Easing, + Group: Group, + Interpolation: Interpolation, + now: now$1, + Sequence: Sequence, + nextId: nextId, + Tween: Tween, + VERSION: VERSION, + getAll: getAll, + removeAll: removeAll, + add: add, + remove: remove, + update: update, +}; + +/* harmony default export */ __webpack_exports__["default"] = (exports); + + + +/***/ }), + +/***/ "../eyes/node_modules/deepmerge/dist/cjs.js": +/*!**************************************************!*\ + !*** ../eyes/node_modules/deepmerge/dist/cjs.js ***! + \**************************************************/ +/***/ (function(module) { + +"use strict"; + + +var isMergeableObject = function isMergeableObject(value) { + return isNonNullObject(value) + && !isSpecial(value) +}; + +function isNonNullObject(value) { + return !!value && typeof value === 'object' +} + +function isSpecial(value) { + var stringValue = Object.prototype.toString.call(value); + + return stringValue === '[object RegExp]' + || stringValue === '[object Date]' + || isReactElement(value) +} + +// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25 +var canUseSymbol = typeof Symbol === 'function' && Symbol.for; +var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7; + +function isReactElement(value) { + return value.$$typeof === REACT_ELEMENT_TYPE +} + +function emptyTarget(val) { + return Array.isArray(val) ? [] : {} +} + +function cloneUnlessOtherwiseSpecified(value, options) { + return (options.clone !== false && options.isMergeableObject(value)) + ? deepmerge(emptyTarget(value), value, options) + : value +} + +function defaultArrayMerge(target, source, options) { + return target.concat(source).map(function(element) { + return cloneUnlessOtherwiseSpecified(element, options) + }) +} + +function getMergeFunction(key, options) { + if (!options.customMerge) { + return deepmerge + } + var customMerge = options.customMerge(key); + return typeof customMerge === 'function' ? customMerge : deepmerge +} + +function getEnumerableOwnPropertySymbols(target) { + return Object.getOwnPropertySymbols + ? Object.getOwnPropertySymbols(target).filter(function(symbol) { + return target.propertyIsEnumerable(symbol) + }) + : [] +} + +function getKeys(target) { + return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target)) +} + +function propertyIsOnObject(object, property) { + try { + return property in object + } catch(_) { + return false + } +} + +// Protects from prototype poisoning and unexpected merging up the prototype chain. +function propertyIsUnsafe(target, key) { + return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet, + && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain, + && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable. +} + +function mergeObject(target, source, options) { + var destination = {}; + if (options.isMergeableObject(target)) { + getKeys(target).forEach(function(key) { + destination[key] = cloneUnlessOtherwiseSpecified(target[key], options); + }); + } + getKeys(source).forEach(function(key) { + if (propertyIsUnsafe(target, key)) { + return + } + + if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) { + destination[key] = getMergeFunction(key, options)(target[key], source[key], options); + } else { + destination[key] = cloneUnlessOtherwiseSpecified(source[key], options); + } + }); + return destination +} + +function deepmerge(target, source, options) { + options = options || {}; + options.arrayMerge = options.arrayMerge || defaultArrayMerge; + options.isMergeableObject = options.isMergeableObject || isMergeableObject; + // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge() + // implementations can use it. The caller may not replace it. + options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified; + + var sourceIsArray = Array.isArray(source); + var targetIsArray = Array.isArray(target); + var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray; + + if (!sourceAndTargetTypesMatch) { + return cloneUnlessOtherwiseSpecified(source, options) + } else if (sourceIsArray) { + return options.arrayMerge(target, source, options) + } else { + return mergeObject(target, source, options) + } +} + +deepmerge.all = function deepmergeAll(array, options) { + if (!Array.isArray(array)) { + throw new Error('first argument should be an array') + } + + return array.reduce(function(prev, next) { + return deepmerge(prev, next, options) + }, {}) +}; + +var deepmerge_1 = deepmerge; + +module.exports = deepmerge_1; + + +/***/ }), + +/***/ "../eyes/node_modules/fuse.js/dist/fuse.esm.js": +/*!*****************************************************!*\ + !*** ../eyes/node_modules/fuse.js/dist/fuse.esm.js ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": function() { return /* binding */ Fuse; } +/* harmony export */ }); +/** + * Fuse.js v6.6.2 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2022 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +function isArray(value) { + return !Array.isArray + ? getTag(value) === '[object Array]' + : Array.isArray(value) +} + +// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js +const INFINITY = 1 / 0; +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value + } + let result = value + ''; + return result == '0' && 1 / value == -INFINITY ? '-0' : result +} + +function toString(value) { + return value == null ? '' : baseToString(value) +} + +function isString(value) { + return typeof value === 'string' +} + +function isNumber(value) { + return typeof value === 'number' +} + +// Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js +function isBoolean(value) { + return ( + value === true || + value === false || + (isObjectLike(value) && getTag(value) == '[object Boolean]') + ) +} + +function isObject(value) { + return typeof value === 'object' +} + +// Checks if `value` is object-like. +function isObjectLike(value) { + return isObject(value) && value !== null +} + +function isDefined(value) { + return value !== undefined && value !== null +} + +function isBlank(value) { + return !value.trim().length +} + +// Gets the `toStringTag` of `value`. +// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js +function getTag(value) { + return value == null + ? value === undefined + ? '[object Undefined]' + : '[object Null]' + : Object.prototype.toString.call(value) +} + +const EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available'; + +const INCORRECT_INDEX_TYPE = "Incorrect 'index' type"; + +const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) => + `Invalid value for key ${key}`; + +const PATTERN_LENGTH_TOO_LARGE = (max) => + `Pattern length exceeds max of ${max}.`; + +const MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`; + +const INVALID_KEY_WEIGHT_VALUE = (key) => + `Property 'weight' in key '${key}' must be a positive integer`; + +const hasOwn = Object.prototype.hasOwnProperty; + +class KeyStore { + constructor(keys) { + this._keys = []; + this._keyMap = {}; + + let totalWeight = 0; + + keys.forEach((key) => { + let obj = createKey(key); + + totalWeight += obj.weight; + + this._keys.push(obj); + this._keyMap[obj.id] = obj; + + totalWeight += obj.weight; + }); + + // Normalize weights so that their sum is equal to 1 + this._keys.forEach((key) => { + key.weight /= totalWeight; + }); + } + get(keyId) { + return this._keyMap[keyId] + } + keys() { + return this._keys + } + toJSON() { + return JSON.stringify(this._keys) + } +} + +function createKey(key) { + let path = null; + let id = null; + let src = null; + let weight = 1; + let getFn = null; + + if (isString(key) || isArray(key)) { + src = key; + path = createKeyPath(key); + id = createKeyId(key); + } else { + if (!hasOwn.call(key, 'name')) { + throw new Error(MISSING_KEY_PROPERTY('name')) + } + + const name = key.name; + src = name; + + if (hasOwn.call(key, 'weight')) { + weight = key.weight; + + if (weight <= 0) { + throw new Error(INVALID_KEY_WEIGHT_VALUE(name)) + } + } + + path = createKeyPath(name); + id = createKeyId(name); + getFn = key.getFn; + } + + return { path, id, weight, src, getFn } +} + +function createKeyPath(key) { + return isArray(key) ? key : key.split('.') +} + +function createKeyId(key) { + return isArray(key) ? key.join('.') : key +} + +function get(obj, path) { + let list = []; + let arr = false; + + const deepGet = (obj, path, index) => { + if (!isDefined(obj)) { + return + } + if (!path[index]) { + // If there's no path left, we've arrived at the object we care about. + list.push(obj); + } else { + let key = path[index]; + + const value = obj[key]; + + if (!isDefined(value)) { + return + } + + // If we're at the last value in the path, and if it's a string/number/bool, + // add it to the list + if ( + index === path.length - 1 && + (isString(value) || isNumber(value) || isBoolean(value)) + ) { + list.push(toString(value)); + } else if (isArray(value)) { + arr = true; + // Search each item in the array. + for (let i = 0, len = value.length; i < len; i += 1) { + deepGet(value[i], path, index + 1); + } + } else if (path.length) { + // An object. Recurse further. + deepGet(value, path, index + 1); + } + } + }; + + // Backwards compatibility (since path used to be a string) + deepGet(obj, isString(path) ? path.split('.') : path, 0); + + return arr ? list : list[0] +} + +const MatchOptions = { + // Whether the matches should be included in the result set. When `true`, each record in the result + // set will include the indices of the matched characters. + // These can consequently be used for highlighting purposes. + includeMatches: false, + // When `true`, the matching function will continue to the end of a search pattern even if + // a perfect match has already been located in the string. + findAllMatches: false, + // Minimum number of characters that must be matched before a result is considered a match + minMatchCharLength: 1 +}; + +const BasicOptions = { + // When `true`, the algorithm continues searching to the end of the input even if a perfect + // match is found before the end of the same input. + isCaseSensitive: false, + // When true, the matching function will continue to the end of a search pattern even if + includeScore: false, + // List of properties that will be searched. This also supports nested properties. + keys: [], + // Whether to sort the result list, by score + shouldSort: true, + // Default sort function: sort by ascending score, ascending index + sortFn: (a, b) => + a.score === b.score ? (a.idx < b.idx ? -1 : 1) : a.score < b.score ? -1 : 1 +}; + +const FuzzyOptions = { + // Approximately where in the text is the pattern expected to be found? + location: 0, + // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match + // (of both letters and location), a threshold of '1.0' would match anything. + threshold: 0.6, + // Determines how close the match must be to the fuzzy location (specified above). + // An exact letter match which is 'distance' characters away from the fuzzy location + // would score as a complete mismatch. A distance of '0' requires the match be at + // the exact location specified, a threshold of '1000' would require a perfect match + // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold. + distance: 100 +}; + +const AdvancedOptions = { + // When `true`, it enables the use of unix-like search commands + useExtendedSearch: false, + // The get function to use when fetching an object's properties. + // The default will search nested paths *ie foo.bar.baz* + getFn: get, + // When `true`, search will ignore `location` and `distance`, so it won't matter + // where in the string the pattern appears. + // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score + ignoreLocation: false, + // When `true`, the calculation for the relevance score (used for sorting) will + // ignore the field-length norm. + // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm + ignoreFieldNorm: false, + // The weight to determine how much field length norm effects scoring. + fieldNormWeight: 1 +}; + +var Config = { + ...BasicOptions, + ...MatchOptions, + ...FuzzyOptions, + ...AdvancedOptions +}; + +const SPACE = /[^ ]+/g; + +// Field-length norm: the shorter the field, the higher the weight. +// Set to 3 decimals to reduce index size. +function norm(weight = 1, mantissa = 3) { + const cache = new Map(); + const m = Math.pow(10, mantissa); + + return { + get(value) { + const numTokens = value.match(SPACE).length; + + if (cache.has(numTokens)) { + return cache.get(numTokens) + } + + // Default function is 1/sqrt(x), weight makes that variable + const norm = 1 / Math.pow(numTokens, 0.5 * weight); + + // In place of `toFixed(mantissa)`, for faster computation + const n = parseFloat(Math.round(norm * m) / m); + + cache.set(numTokens, n); + + return n + }, + clear() { + cache.clear(); + } + } +} + +class FuseIndex { + constructor({ + getFn = Config.getFn, + fieldNormWeight = Config.fieldNormWeight + } = {}) { + this.norm = norm(fieldNormWeight, 3); + this.getFn = getFn; + this.isCreated = false; + + this.setIndexRecords(); + } + setSources(docs = []) { + this.docs = docs; + } + setIndexRecords(records = []) { + this.records = records; + } + setKeys(keys = []) { + this.keys = keys; + this._keysMap = {}; + keys.forEach((key, idx) => { + this._keysMap[key.id] = idx; + }); + } + create() { + if (this.isCreated || !this.docs.length) { + return + } + + this.isCreated = true; + + // List is Array + if (isString(this.docs[0])) { + this.docs.forEach((doc, docIndex) => { + this._addString(doc, docIndex); + }); + } else { + // List is Array + this.docs.forEach((doc, docIndex) => { + this._addObject(doc, docIndex); + }); + } + + this.norm.clear(); + } + // Adds a doc to the end of the index + add(doc) { + const idx = this.size(); + + if (isString(doc)) { + this._addString(doc, idx); + } else { + this._addObject(doc, idx); + } + } + // Removes the doc at the specified index of the index + removeAt(idx) { + this.records.splice(idx, 1); + + // Change ref index of every subsquent doc + for (let i = idx, len = this.size(); i < len; i += 1) { + this.records[i].i -= 1; + } + } + getValueForItemAtKeyId(item, keyId) { + return item[this._keysMap[keyId]] + } + size() { + return this.records.length + } + _addString(doc, docIndex) { + if (!isDefined(doc) || isBlank(doc)) { + return + } + + let record = { + v: doc, + i: docIndex, + n: this.norm.get(doc) + }; + + this.records.push(record); + } + _addObject(doc, docIndex) { + let record = { i: docIndex, $: {} }; + + // Iterate over every key (i.e, path), and fetch the value at that key + this.keys.forEach((key, keyIndex) => { + let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path); + + if (!isDefined(value)) { + return + } + + if (isArray(value)) { + let subRecords = []; + const stack = [{ nestedArrIndex: -1, value }]; + + while (stack.length) { + const { nestedArrIndex, value } = stack.pop(); + + if (!isDefined(value)) { + continue + } + + if (isString(value) && !isBlank(value)) { + let subRecord = { + v: value, + i: nestedArrIndex, + n: this.norm.get(value) + }; + + subRecords.push(subRecord); + } else if (isArray(value)) { + value.forEach((item, k) => { + stack.push({ + nestedArrIndex: k, + value: item + }); + }); + } else ; + } + record.$[keyIndex] = subRecords; + } else if (isString(value) && !isBlank(value)) { + let subRecord = { + v: value, + n: this.norm.get(value) + }; + + record.$[keyIndex] = subRecord; + } + }); + + this.records.push(record); + } + toJSON() { + return { + keys: this.keys, + records: this.records + } + } +} + +function createIndex( + keys, + docs, + { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {} +) { + const myIndex = new FuseIndex({ getFn, fieldNormWeight }); + myIndex.setKeys(keys.map(createKey)); + myIndex.setSources(docs); + myIndex.create(); + return myIndex +} + +function parseIndex( + data, + { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {} +) { + const { keys, records } = data; + const myIndex = new FuseIndex({ getFn, fieldNormWeight }); + myIndex.setKeys(keys); + myIndex.setIndexRecords(records); + return myIndex +} + +function computeScore$1( + pattern, + { + errors = 0, + currentLocation = 0, + expectedLocation = 0, + distance = Config.distance, + ignoreLocation = Config.ignoreLocation + } = {} +) { + const accuracy = errors / pattern.length; + + if (ignoreLocation) { + return accuracy + } + + const proximity = Math.abs(expectedLocation - currentLocation); + + if (!distance) { + // Dodge divide by zero error. + return proximity ? 1.0 : accuracy + } + + return accuracy + proximity / distance +} + +function convertMaskToIndices( + matchmask = [], + minMatchCharLength = Config.minMatchCharLength +) { + let indices = []; + let start = -1; + let end = -1; + let i = 0; + + for (let len = matchmask.length; i < len; i += 1) { + let match = matchmask[i]; + if (match && start === -1) { + start = i; + } else if (!match && start !== -1) { + end = i - 1; + if (end - start + 1 >= minMatchCharLength) { + indices.push([start, end]); + } + start = -1; + } + } + + // (i-1 - start) + 1 => i - start + if (matchmask[i - 1] && i - start >= minMatchCharLength) { + indices.push([start, i - 1]); + } + + return indices +} + +// Machine word size +const MAX_BITS = 32; + +function search( + text, + pattern, + patternAlphabet, + { + location = Config.location, + distance = Config.distance, + threshold = Config.threshold, + findAllMatches = Config.findAllMatches, + minMatchCharLength = Config.minMatchCharLength, + includeMatches = Config.includeMatches, + ignoreLocation = Config.ignoreLocation + } = {} +) { + if (pattern.length > MAX_BITS) { + throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS)) + } + + const patternLen = pattern.length; + // Set starting location at beginning text and initialize the alphabet. + const textLen = text.length; + // Handle the case when location > text.length + const expectedLocation = Math.max(0, Math.min(location, textLen)); + // Highest score beyond which we give up. + let currentThreshold = threshold; + // Is there a nearby exact match? (speedup) + let bestLocation = expectedLocation; + + // Performance: only computer matches when the minMatchCharLength > 1 + // OR if `includeMatches` is true. + const computeMatches = minMatchCharLength > 1 || includeMatches; + // A mask of the matches, used for building the indices + const matchMask = computeMatches ? Array(textLen) : []; + + let index; + + // Get all exact matches, here for speed up + while ((index = text.indexOf(pattern, bestLocation)) > -1) { + let score = computeScore$1(pattern, { + currentLocation: index, + expectedLocation, + distance, + ignoreLocation + }); + + currentThreshold = Math.min(score, currentThreshold); + bestLocation = index + patternLen; + + if (computeMatches) { + let i = 0; + while (i < patternLen) { + matchMask[index + i] = 1; + i += 1; + } + } + } + + // Reset the best location + bestLocation = -1; + + let lastBitArr = []; + let finalScore = 1; + let binMax = patternLen + textLen; + + const mask = 1 << (patternLen - 1); + + for (let i = 0; i < patternLen; i += 1) { + // Scan for the best match; each iteration allows for one more error. + // Run a binary search to determine how far from the match location we can stray + // at this error level. + let binMin = 0; + let binMid = binMax; + + while (binMin < binMid) { + const score = computeScore$1(pattern, { + errors: i, + currentLocation: expectedLocation + binMid, + expectedLocation, + distance, + ignoreLocation + }); + + if (score <= currentThreshold) { + binMin = binMid; + } else { + binMax = binMid; + } + + binMid = Math.floor((binMax - binMin) / 2 + binMin); + } + + // Use the result from this iteration as the maximum for the next. + binMax = binMid; + + let start = Math.max(1, expectedLocation - binMid + 1); + let finish = findAllMatches + ? textLen + : Math.min(expectedLocation + binMid, textLen) + patternLen; + + // Initialize the bit array + let bitArr = Array(finish + 2); + + bitArr[finish + 1] = (1 << i) - 1; + + for (let j = finish; j >= start; j -= 1) { + let currentLocation = j - 1; + let charMatch = patternAlphabet[text.charAt(currentLocation)]; + + if (computeMatches) { + // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`) + matchMask[currentLocation] = +!!charMatch; + } + + // First pass: exact match + bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch; + + // Subsequent passes: fuzzy match + if (i) { + bitArr[j] |= + ((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1 | lastBitArr[j + 1]; + } + + if (bitArr[j] & mask) { + finalScore = computeScore$1(pattern, { + errors: i, + currentLocation, + expectedLocation, + distance, + ignoreLocation + }); + + // This match will almost certainly be better than any existing match. + // But check anyway. + if (finalScore <= currentThreshold) { + // Indeed it is + currentThreshold = finalScore; + bestLocation = currentLocation; + + // Already passed `loc`, downhill from here on in. + if (bestLocation <= expectedLocation) { + break + } + + // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`. + start = Math.max(1, 2 * expectedLocation - bestLocation); + } + } + } + + // No hope for a (better) match at greater error levels. + const score = computeScore$1(pattern, { + errors: i + 1, + currentLocation: expectedLocation, + expectedLocation, + distance, + ignoreLocation + }); + + if (score > currentThreshold) { + break + } + + lastBitArr = bitArr; + } + + const result = { + isMatch: bestLocation >= 0, + // Count exact matches (those with a score of 0) to be "almost" exact + score: Math.max(0.001, finalScore) + }; + + if (computeMatches) { + const indices = convertMaskToIndices(matchMask, minMatchCharLength); + if (!indices.length) { + result.isMatch = false; + } else if (includeMatches) { + result.indices = indices; + } + } + + return result +} + +function createPatternAlphabet(pattern) { + let mask = {}; + + for (let i = 0, len = pattern.length; i < len; i += 1) { + const char = pattern.charAt(i); + mask[char] = (mask[char] || 0) | (1 << (len - i - 1)); + } + + return mask +} + +class BitapSearch { + constructor( + pattern, + { + location = Config.location, + threshold = Config.threshold, + distance = Config.distance, + includeMatches = Config.includeMatches, + findAllMatches = Config.findAllMatches, + minMatchCharLength = Config.minMatchCharLength, + isCaseSensitive = Config.isCaseSensitive, + ignoreLocation = Config.ignoreLocation + } = {} + ) { + this.options = { + location, + threshold, + distance, + includeMatches, + findAllMatches, + minMatchCharLength, + isCaseSensitive, + ignoreLocation + }; + + this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase(); + + this.chunks = []; + + if (!this.pattern.length) { + return + } + + const addChunk = (pattern, startIndex) => { + this.chunks.push({ + pattern, + alphabet: createPatternAlphabet(pattern), + startIndex + }); + }; + + const len = this.pattern.length; + + if (len > MAX_BITS) { + let i = 0; + const remainder = len % MAX_BITS; + const end = len - remainder; + + while (i < end) { + addChunk(this.pattern.substr(i, MAX_BITS), i); + i += MAX_BITS; + } + + if (remainder) { + const startIndex = len - MAX_BITS; + addChunk(this.pattern.substr(startIndex), startIndex); + } + } else { + addChunk(this.pattern, 0); + } + } + + searchIn(text) { + const { isCaseSensitive, includeMatches } = this.options; + + if (!isCaseSensitive) { + text = text.toLowerCase(); + } + + // Exact match + if (this.pattern === text) { + let result = { + isMatch: true, + score: 0 + }; + + if (includeMatches) { + result.indices = [[0, text.length - 1]]; + } + + return result + } + + // Otherwise, use Bitap algorithm + const { + location, + distance, + threshold, + findAllMatches, + minMatchCharLength, + ignoreLocation + } = this.options; + + let allIndices = []; + let totalScore = 0; + let hasMatches = false; + + this.chunks.forEach(({ pattern, alphabet, startIndex }) => { + const { isMatch, score, indices } = search(text, pattern, alphabet, { + location: location + startIndex, + distance, + threshold, + findAllMatches, + minMatchCharLength, + includeMatches, + ignoreLocation + }); + + if (isMatch) { + hasMatches = true; + } + + totalScore += score; + + if (isMatch && indices) { + allIndices = [...allIndices, ...indices]; + } + }); + + let result = { + isMatch: hasMatches, + score: hasMatches ? totalScore / this.chunks.length : 1 + }; + + if (hasMatches && includeMatches) { + result.indices = allIndices; + } + + return result + } +} + +class BaseMatch { + constructor(pattern) { + this.pattern = pattern; + } + static isMultiMatch(pattern) { + return getMatch(pattern, this.multiRegex) + } + static isSingleMatch(pattern) { + return getMatch(pattern, this.singleRegex) + } + search(/*text*/) {} +} + +function getMatch(pattern, exp) { + const matches = pattern.match(exp); + return matches ? matches[1] : null +} + +// Token: 'file + +class ExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'exact' + } + static get multiRegex() { + return /^="(.*)"$/ + } + static get singleRegex() { + return /^=(.*)$/ + } + search(text) { + const isMatch = text === this.pattern; + + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [0, this.pattern.length - 1] + } + } +} + +// Token: !fire + +class InverseExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'inverse-exact' + } + static get multiRegex() { + return /^!"(.*)"$/ + } + static get singleRegex() { + return /^!(.*)$/ + } + search(text) { + const index = text.indexOf(this.pattern); + const isMatch = index === -1; + + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [0, text.length - 1] + } + } +} + +// Token: ^file + +class PrefixExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'prefix-exact' + } + static get multiRegex() { + return /^\^"(.*)"$/ + } + static get singleRegex() { + return /^\^(.*)$/ + } + search(text) { + const isMatch = text.startsWith(this.pattern); + + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [0, this.pattern.length - 1] + } + } +} + +// Token: !^fire + +class InversePrefixExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'inverse-prefix-exact' + } + static get multiRegex() { + return /^!\^"(.*)"$/ + } + static get singleRegex() { + return /^!\^(.*)$/ + } + search(text) { + const isMatch = !text.startsWith(this.pattern); + + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [0, text.length - 1] + } + } +} + +// Token: .file$ + +class SuffixExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'suffix-exact' + } + static get multiRegex() { + return /^"(.*)"\$$/ + } + static get singleRegex() { + return /^(.*)\$$/ + } + search(text) { + const isMatch = text.endsWith(this.pattern); + + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [text.length - this.pattern.length, text.length - 1] + } + } +} + +// Token: !.file$ + +class InverseSuffixExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'inverse-suffix-exact' + } + static get multiRegex() { + return /^!"(.*)"\$$/ + } + static get singleRegex() { + return /^!(.*)\$$/ + } + search(text) { + const isMatch = !text.endsWith(this.pattern); + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [0, text.length - 1] + } + } +} + +class FuzzyMatch extends BaseMatch { + constructor( + pattern, + { + location = Config.location, + threshold = Config.threshold, + distance = Config.distance, + includeMatches = Config.includeMatches, + findAllMatches = Config.findAllMatches, + minMatchCharLength = Config.minMatchCharLength, + isCaseSensitive = Config.isCaseSensitive, + ignoreLocation = Config.ignoreLocation + } = {} + ) { + super(pattern); + this._bitapSearch = new BitapSearch(pattern, { + location, + threshold, + distance, + includeMatches, + findAllMatches, + minMatchCharLength, + isCaseSensitive, + ignoreLocation + }); + } + static get type() { + return 'fuzzy' + } + static get multiRegex() { + return /^"(.*)"$/ + } + static get singleRegex() { + return /^(.*)$/ + } + search(text) { + return this._bitapSearch.searchIn(text) + } +} + +// Token: 'file + +class IncludeMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'include' + } + static get multiRegex() { + return /^'"(.*)"$/ + } + static get singleRegex() { + return /^'(.*)$/ + } + search(text) { + let location = 0; + let index; + + const indices = []; + const patternLen = this.pattern.length; + + // Get all exact matches + while ((index = text.indexOf(this.pattern, location)) > -1) { + location = index + patternLen; + indices.push([index, location - 1]); + } + + const isMatch = !!indices.length; + + return { + isMatch, + score: isMatch ? 0 : 1, + indices + } + } +} + +// ❗Order is important. DO NOT CHANGE. +const searchers = [ + ExactMatch, + IncludeMatch, + PrefixExactMatch, + InversePrefixExactMatch, + InverseSuffixExactMatch, + SuffixExactMatch, + InverseExactMatch, + FuzzyMatch +]; + +const searchersLen = searchers.length; + +// Regex to split by spaces, but keep anything in quotes together +const SPACE_RE = / +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/; +const OR_TOKEN = '|'; + +// Return a 2D array representation of the query, for simpler parsing. +// Example: +// "^core go$ | rb$ | py$ xy$" => [["^core", "go$"], ["rb$"], ["py$", "xy$"]] +function parseQuery(pattern, options = {}) { + return pattern.split(OR_TOKEN).map((item) => { + let query = item + .trim() + .split(SPACE_RE) + .filter((item) => item && !!item.trim()); + + let results = []; + for (let i = 0, len = query.length; i < len; i += 1) { + const queryItem = query[i]; + + // 1. Handle multiple query match (i.e, once that are quoted, like `"hello world"`) + let found = false; + let idx = -1; + while (!found && ++idx < searchersLen) { + const searcher = searchers[idx]; + let token = searcher.isMultiMatch(queryItem); + if (token) { + results.push(new searcher(token, options)); + found = true; + } + } + + if (found) { + continue + } + + // 2. Handle single query matches (i.e, once that are *not* quoted) + idx = -1; + while (++idx < searchersLen) { + const searcher = searchers[idx]; + let token = searcher.isSingleMatch(queryItem); + if (token) { + results.push(new searcher(token, options)); + break + } + } + } + + return results + }) +} + +// These extended matchers can return an array of matches, as opposed +// to a singl match +const MultiMatchSet = new Set([FuzzyMatch.type, IncludeMatch.type]); + +/** + * Command-like searching + * ====================== + * + * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`, + * search in a given text. + * + * Search syntax: + * + * | Token | Match type | Description | + * | ----------- | -------------------------- | -------------------------------------- | + * | `jscript` | fuzzy-match | Items that fuzzy match `jscript` | + * | `=scheme` | exact-match | Items that are `scheme` | + * | `'python` | include-match | Items that include `python` | + * | `!ruby` | inverse-exact-match | Items that do not include `ruby` | + * | `^java` | prefix-exact-match | Items that start with `java` | + * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` | + * | `.js$` | suffix-exact-match | Items that end with `.js` | + * | `!.go$` | inverse-suffix-exact-match | Items that do not end with `.go` | + * + * A single pipe character acts as an OR operator. For example, the following + * query matches entries that start with `core` and end with either`go`, `rb`, + * or`py`. + * + * ``` + * ^core go$ | rb$ | py$ + * ``` + */ +class ExtendedSearch { + constructor( + pattern, + { + isCaseSensitive = Config.isCaseSensitive, + includeMatches = Config.includeMatches, + minMatchCharLength = Config.minMatchCharLength, + ignoreLocation = Config.ignoreLocation, + findAllMatches = Config.findAllMatches, + location = Config.location, + threshold = Config.threshold, + distance = Config.distance + } = {} + ) { + this.query = null; + this.options = { + isCaseSensitive, + includeMatches, + minMatchCharLength, + findAllMatches, + ignoreLocation, + location, + threshold, + distance + }; + + this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase(); + this.query = parseQuery(this.pattern, this.options); + } + + static condition(_, options) { + return options.useExtendedSearch + } + + searchIn(text) { + const query = this.query; + + if (!query) { + return { + isMatch: false, + score: 1 + } + } + + const { includeMatches, isCaseSensitive } = this.options; + + text = isCaseSensitive ? text : text.toLowerCase(); + + let numMatches = 0; + let allIndices = []; + let totalScore = 0; + + // ORs + for (let i = 0, qLen = query.length; i < qLen; i += 1) { + const searchers = query[i]; + + // Reset indices + allIndices.length = 0; + numMatches = 0; + + // ANDs + for (let j = 0, pLen = searchers.length; j < pLen; j += 1) { + const searcher = searchers[j]; + const { isMatch, indices, score } = searcher.search(text); + + if (isMatch) { + numMatches += 1; + totalScore += score; + if (includeMatches) { + const type = searcher.constructor.type; + if (MultiMatchSet.has(type)) { + allIndices = [...allIndices, ...indices]; + } else { + allIndices.push(indices); + } + } + } else { + totalScore = 0; + numMatches = 0; + allIndices.length = 0; + break + } + } + + // OR condition, so if TRUE, return + if (numMatches) { + let result = { + isMatch: true, + score: totalScore / numMatches + }; + + if (includeMatches) { + result.indices = allIndices; + } + + return result + } + } + + // Nothing was matched + return { + isMatch: false, + score: 1 + } + } +} + +const registeredSearchers = []; + +function register(...args) { + registeredSearchers.push(...args); +} + +function createSearcher(pattern, options) { + for (let i = 0, len = registeredSearchers.length; i < len; i += 1) { + let searcherClass = registeredSearchers[i]; + if (searcherClass.condition(pattern, options)) { + return new searcherClass(pattern, options) + } + } + + return new BitapSearch(pattern, options) +} + +const LogicalOperator = { + AND: '$and', + OR: '$or' +}; + +const KeyType = { + PATH: '$path', + PATTERN: '$val' +}; + +const isExpression = (query) => + !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]); + +const isPath = (query) => !!query[KeyType.PATH]; + +const isLeaf = (query) => + !isArray(query) && isObject(query) && !isExpression(query); + +const convertToExplicit = (query) => ({ + [LogicalOperator.AND]: Object.keys(query).map((key) => ({ + [key]: query[key] + })) +}); + +// When `auto` is `true`, the parse function will infer and initialize and add +// the appropriate `Searcher` instance +function parse(query, options, { auto = true } = {}) { + const next = (query) => { + let keys = Object.keys(query); + + const isQueryPath = isPath(query); + + if (!isQueryPath && keys.length > 1 && !isExpression(query)) { + return next(convertToExplicit(query)) + } + + if (isLeaf(query)) { + const key = isQueryPath ? query[KeyType.PATH] : keys[0]; + + const pattern = isQueryPath ? query[KeyType.PATTERN] : query[key]; + + if (!isString(pattern)) { + throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key)) + } + + const obj = { + keyId: createKeyId(key), + pattern + }; + + if (auto) { + obj.searcher = createSearcher(pattern, options); + } + + return obj + } + + let node = { + children: [], + operator: keys[0] + }; + + keys.forEach((key) => { + const value = query[key]; + + if (isArray(value)) { + value.forEach((item) => { + node.children.push(next(item)); + }); + } + }); + + return node + }; + + if (!isExpression(query)) { + query = convertToExplicit(query); + } + + return next(query) +} + +// Practical scoring function +function computeScore( + results, + { ignoreFieldNorm = Config.ignoreFieldNorm } +) { + results.forEach((result) => { + let totalScore = 1; + + result.matches.forEach(({ key, norm, score }) => { + const weight = key ? key.weight : null; + + totalScore *= Math.pow( + score === 0 && weight ? Number.EPSILON : score, + (weight || 1) * (ignoreFieldNorm ? 1 : norm) + ); + }); + + result.score = totalScore; + }); +} + +function transformMatches(result, data) { + const matches = result.matches; + data.matches = []; + + if (!isDefined(matches)) { + return + } + + matches.forEach((match) => { + if (!isDefined(match.indices) || !match.indices.length) { + return + } + + const { indices, value } = match; + + let obj = { + indices, + value + }; + + if (match.key) { + obj.key = match.key.src; + } + + if (match.idx > -1) { + obj.refIndex = match.idx; + } + + data.matches.push(obj); + }); +} + +function transformScore(result, data) { + data.score = result.score; +} + +function format( + results, + docs, + { + includeMatches = Config.includeMatches, + includeScore = Config.includeScore + } = {} +) { + const transformers = []; + + if (includeMatches) transformers.push(transformMatches); + if (includeScore) transformers.push(transformScore); + + return results.map((result) => { + const { idx } = result; + + const data = { + item: docs[idx], + refIndex: idx + }; + + if (transformers.length) { + transformers.forEach((transformer) => { + transformer(result, data); + }); + } + + return data + }) +} + +class Fuse { + constructor(docs, options = {}, index) { + this.options = { ...Config, ...options }; + + if ( + this.options.useExtendedSearch && + !true + ) {} + + this._keyStore = new KeyStore(this.options.keys); + + this.setCollection(docs, index); + } + + setCollection(docs, index) { + this._docs = docs; + + if (index && !(index instanceof FuseIndex)) { + throw new Error(INCORRECT_INDEX_TYPE) + } + + this._myIndex = + index || + createIndex(this.options.keys, this._docs, { + getFn: this.options.getFn, + fieldNormWeight: this.options.fieldNormWeight + }); + } + + add(doc) { + if (!isDefined(doc)) { + return + } + + this._docs.push(doc); + this._myIndex.add(doc); + } + + remove(predicate = (/* doc, idx */) => false) { + const results = []; + + for (let i = 0, len = this._docs.length; i < len; i += 1) { + const doc = this._docs[i]; + if (predicate(doc, i)) { + this.removeAt(i); + i -= 1; + len -= 1; + + results.push(doc); + } + } + + return results + } + + removeAt(idx) { + this._docs.splice(idx, 1); + this._myIndex.removeAt(idx); + } + + getIndex() { + return this._myIndex + } + + search(query, { limit = -1 } = {}) { + const { + includeMatches, + includeScore, + shouldSort, + sortFn, + ignoreFieldNorm + } = this.options; + + let results = isString(query) + ? isString(this._docs[0]) + ? this._searchStringList(query) + : this._searchObjectList(query) + : this._searchLogical(query); + + computeScore(results, { ignoreFieldNorm }); + + if (shouldSort) { + results.sort(sortFn); + } + + if (isNumber(limit) && limit > -1) { + results = results.slice(0, limit); + } + + return format(results, this._docs, { + includeMatches, + includeScore + }) + } + + _searchStringList(query) { + const searcher = createSearcher(query, this.options); + const { records } = this._myIndex; + const results = []; + + // Iterate over every string in the index + records.forEach(({ v: text, i: idx, n: norm }) => { + if (!isDefined(text)) { + return + } + + const { isMatch, score, indices } = searcher.searchIn(text); + + if (isMatch) { + results.push({ + item: text, + idx, + matches: [{ score, value: text, norm, indices }] + }); + } + }); + + return results + } + + _searchLogical(query) { + + const expression = parse(query, this.options); + + const evaluate = (node, item, idx) => { + if (!node.children) { + const { keyId, searcher } = node; + + const matches = this._findMatches({ + key: this._keyStore.get(keyId), + value: this._myIndex.getValueForItemAtKeyId(item, keyId), + searcher + }); + + if (matches && matches.length) { + return [ + { + idx, + item, + matches + } + ] + } + + return [] + } + + const res = []; + for (let i = 0, len = node.children.length; i < len; i += 1) { + const child = node.children[i]; + const result = evaluate(child, item, idx); + if (result.length) { + res.push(...result); + } else if (node.operator === LogicalOperator.AND) { + return [] + } + } + return res + }; + + const records = this._myIndex.records; + const resultMap = {}; + const results = []; + + records.forEach(({ $: item, i: idx }) => { + if (isDefined(item)) { + let expResults = evaluate(expression, item, idx); + + if (expResults.length) { + // Dedupe when adding + if (!resultMap[idx]) { + resultMap[idx] = { idx, item, matches: [] }; + results.push(resultMap[idx]); + } + expResults.forEach(({ matches }) => { + resultMap[idx].matches.push(...matches); + }); + } + } + }); + + return results + } + + _searchObjectList(query) { + const searcher = createSearcher(query, this.options); + const { keys, records } = this._myIndex; + const results = []; + + // List is Array + records.forEach(({ $: item, i: idx }) => { + if (!isDefined(item)) { + return + } + + let matches = []; + + // Iterate over every key (i.e, path), and fetch the value at that key + keys.forEach((key, keyIndex) => { + matches.push( + ...this._findMatches({ + key, + value: item[keyIndex], + searcher + }) + ); + }); + + if (matches.length) { + results.push({ + idx, + item, + matches + }); + } + }); + + return results + } + _findMatches({ key, value, searcher }) { + if (!isDefined(value)) { + return [] + } + + let matches = []; + + if (isArray(value)) { + value.forEach(({ v: text, i: idx, n: norm }) => { + if (!isDefined(text)) { + return + } + + const { isMatch, score, indices } = searcher.searchIn(text); + + if (isMatch) { + matches.push({ + score, + key, + value: text, + idx, + norm, + indices + }); + } + }); + } else { + const { v: text, n: norm } = value; + + const { isMatch, score, indices } = searcher.searchIn(text); + + if (isMatch) { + matches.push({ score, key, value: text, norm, indices }); + } + } + + return matches + } +} + +Fuse.version = '6.6.2'; +Fuse.createIndex = createIndex; +Fuse.parseIndex = parseIndex; +Fuse.config = Config; + +{ + Fuse.parseQuery = parse; +} + +{ + register(ExtendedSearch); +} + + + + +/***/ }), + +/***/ "../eyes/node_modules/lodash.debounce/index.js": +/*!*****************************************************!*\ + !*** ../eyes/node_modules/lodash.debounce/index.js ***! + \*****************************************************/ +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** Used to match leading and trailing whitespace. */ +var reTrim = /^\s+|\s+$/g; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof __webpack_require__.g == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return root.Date.now(); +}; + +/** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ +function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + result = wait - timeSinceLastCall; + + return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +module.exports = debounce; + + +/***/ }), + +/***/ "../eyes/node_modules/lodash.throttle/index.js": +/*!*****************************************************!*\ + !*** ../eyes/node_modules/lodash.throttle/index.js ***! + \*****************************************************/ +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** Used to match leading and trailing whitespace. */ +var reTrim = /^\s+|\s+$/g; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof __webpack_require__.g == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return root.Date.now(); +}; + +/** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ +function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + result = wait - timeSinceLastCall; + + return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; +} + +/** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide `options` to indicate whether `func` + * should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the throttled function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=true] + * Specify invoking on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ +function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +module.exports = throttle; + + +/***/ }), + +/***/ "../eyes/node_modules/moment-timezone/index.js": +/*!*****************************************************!*\ + !*** ../eyes/node_modules/moment-timezone/index.js ***! + \*****************************************************/ +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +var moment = module.exports = __webpack_require__(/*! ./moment-timezone */ "../eyes/node_modules/moment-timezone/moment-timezone.js"); +moment.tz.load(__webpack_require__(/*! ./data/packed/latest.json */ "../eyes/node_modules/moment-timezone/data/packed/latest.json")); + + +/***/ }), + +/***/ "../eyes/node_modules/moment-timezone/moment-timezone.js": +/*!***************************************************************!*\ + !*** ../eyes/node_modules/moment-timezone/moment-timezone.js ***! + \***************************************************************/ +/***/ (function(module, exports, __webpack_require__) { + +var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;//! moment-timezone.js +//! version : 0.5.33 +//! Copyright (c) JS Foundation and other contributors +//! license : MIT +//! github.com/moment/moment-timezone + +(function (root, factory) { + "use strict"; + + /*global define*/ + if ( true && module.exports) { + module.exports = factory(__webpack_require__(/*! moment */ "../eyes/node_modules/moment/moment.js")); // Node + } else if (true) { + !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! moment */ "../eyes/node_modules/moment/moment.js")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), + __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? + (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD + } else {} +}(this, function (moment) { + "use strict"; + + // Resolves es6 module loading issue + if (moment.version === undefined && moment.default) { + moment = moment.default; + } + + // Do not load moment-timezone a second time. + // if (moment.tz !== undefined) { + // logError('Moment Timezone ' + moment.tz.version + ' was already loaded ' + (moment.tz.dataVersion ? 'with data from ' : 'without any data') + moment.tz.dataVersion); + // return moment; + // } + + var VERSION = "0.5.33", + zones = {}, + links = {}, + countries = {}, + names = {}, + guesses = {}, + cachedGuess; + + if (!moment || typeof moment.version !== 'string') { + logError('Moment Timezone requires Moment.js. See https://momentjs.com/timezone/docs/#/use-it/browser/'); + } + + var momentVersion = moment.version.split('.'), + major = +momentVersion[0], + minor = +momentVersion[1]; + + // Moment.js version check + if (major < 2 || (major === 2 && minor < 6)) { + logError('Moment Timezone requires Moment.js >= 2.6.0. You are using Moment.js ' + moment.version + '. See momentjs.com'); + } + + /************************************ + Unpacking + ************************************/ + + function charCodeToInt(charCode) { + if (charCode > 96) { + return charCode - 87; + } else if (charCode > 64) { + return charCode - 29; + } + return charCode - 48; + } + + function unpackBase60(string) { + var i = 0, + parts = string.split('.'), + whole = parts[0], + fractional = parts[1] || '', + multiplier = 1, + num, + out = 0, + sign = 1; + + // handle negative numbers + if (string.charCodeAt(0) === 45) { + i = 1; + sign = -1; + } + + // handle digits before the decimal + for (i; i < whole.length; i++) { + num = charCodeToInt(whole.charCodeAt(i)); + out = 60 * out + num; + } + + // handle digits after the decimal + for (i = 0; i < fractional.length; i++) { + multiplier = multiplier / 60; + num = charCodeToInt(fractional.charCodeAt(i)); + out += num * multiplier; + } + + return out * sign; + } + + function arrayToInt (array) { + for (var i = 0; i < array.length; i++) { + array[i] = unpackBase60(array[i]); + } + } + + function intToUntil (array, length) { + for (var i = 0; i < length; i++) { + array[i] = Math.round((array[i - 1] || 0) + (array[i] * 60000)); // minutes to milliseconds + } + + array[length - 1] = Infinity; + } + + function mapIndices (source, indices) { + var out = [], i; + + for (i = 0; i < indices.length; i++) { + out[i] = source[indices[i]]; + } + + return out; + } + + function unpack (string) { + var data = string.split('|'), + offsets = data[2].split(' '), + indices = data[3].split(''), + untils = data[4].split(' '); + + arrayToInt(offsets); + arrayToInt(indices); + arrayToInt(untils); + + intToUntil(untils, indices.length); + + return { + name : data[0], + abbrs : mapIndices(data[1].split(' '), indices), + offsets : mapIndices(offsets, indices), + untils : untils, + population : data[5] | 0 + }; + } + + /************************************ + Zone object + ************************************/ + + function Zone (packedString) { + if (packedString) { + this._set(unpack(packedString)); + } + } + + Zone.prototype = { + _set : function (unpacked) { + this.name = unpacked.name; + this.abbrs = unpacked.abbrs; + this.untils = unpacked.untils; + this.offsets = unpacked.offsets; + this.population = unpacked.population; + }, + + _index : function (timestamp) { + var target = +timestamp, + untils = this.untils, + i; + + for (i = 0; i < untils.length; i++) { + if (target < untils[i]) { + return i; + } + } + }, + + countries : function () { + var zone_name = this.name; + return Object.keys(countries).filter(function (country_code) { + return countries[country_code].zones.indexOf(zone_name) !== -1; + }); + }, + + parse : function (timestamp) { + var target = +timestamp, + offsets = this.offsets, + untils = this.untils, + max = untils.length - 1, + offset, offsetNext, offsetPrev, i; + + for (i = 0; i < max; i++) { + offset = offsets[i]; + offsetNext = offsets[i + 1]; + offsetPrev = offsets[i ? i - 1 : i]; + + if (offset < offsetNext && tz.moveAmbiguousForward) { + offset = offsetNext; + } else if (offset > offsetPrev && tz.moveInvalidForward) { + offset = offsetPrev; + } + + if (target < untils[i] - (offset * 60000)) { + return offsets[i]; + } + } + + return offsets[max]; + }, + + abbr : function (mom) { + return this.abbrs[this._index(mom)]; + }, + + offset : function (mom) { + logError("zone.offset has been deprecated in favor of zone.utcOffset"); + return this.offsets[this._index(mom)]; + }, + + utcOffset : function (mom) { + return this.offsets[this._index(mom)]; + } + }; + + /************************************ + Country object + ************************************/ + + function Country (country_name, zone_names) { + this.name = country_name; + this.zones = zone_names; + } + + /************************************ + Current Timezone + ************************************/ + + function OffsetAt(at) { + var timeString = at.toTimeString(); + var abbr = timeString.match(/\([a-z ]+\)/i); + if (abbr && abbr[0]) { + // 17:56:31 GMT-0600 (CST) + // 17:56:31 GMT-0600 (Central Standard Time) + abbr = abbr[0].match(/[A-Z]/g); + abbr = abbr ? abbr.join('') : undefined; + } else { + // 17:56:31 CST + // 17:56:31 GMT+0800 (台北標準時間) + abbr = timeString.match(/[A-Z]{3,5}/g); + abbr = abbr ? abbr[0] : undefined; + } + + if (abbr === 'GMT') { + abbr = undefined; + } + + this.at = +at; + this.abbr = abbr; + this.offset = at.getTimezoneOffset(); + } + + function ZoneScore(zone) { + this.zone = zone; + this.offsetScore = 0; + this.abbrScore = 0; + } + + ZoneScore.prototype.scoreOffsetAt = function (offsetAt) { + this.offsetScore += Math.abs(this.zone.utcOffset(offsetAt.at) - offsetAt.offset); + if (this.zone.abbr(offsetAt.at).replace(/[^A-Z]/g, '') !== offsetAt.abbr) { + this.abbrScore++; + } + }; + + function findChange(low, high) { + var mid, diff; + + while ((diff = ((high.at - low.at) / 12e4 | 0) * 6e4)) { + mid = new OffsetAt(new Date(low.at + diff)); + if (mid.offset === low.offset) { + low = mid; + } else { + high = mid; + } + } + + return low; + } + + function userOffsets() { + var startYear = new Date().getFullYear() - 2, + last = new OffsetAt(new Date(startYear, 0, 1)), + offsets = [last], + change, next, i; + + for (i = 1; i < 48; i++) { + next = new OffsetAt(new Date(startYear, i, 1)); + if (next.offset !== last.offset) { + change = findChange(last, next); + offsets.push(change); + offsets.push(new OffsetAt(new Date(change.at + 6e4))); + } + last = next; + } + + for (i = 0; i < 4; i++) { + offsets.push(new OffsetAt(new Date(startYear + i, 0, 1))); + offsets.push(new OffsetAt(new Date(startYear + i, 6, 1))); + } + + return offsets; + } + + function sortZoneScores (a, b) { + if (a.offsetScore !== b.offsetScore) { + return a.offsetScore - b.offsetScore; + } + if (a.abbrScore !== b.abbrScore) { + return a.abbrScore - b.abbrScore; + } + if (a.zone.population !== b.zone.population) { + return b.zone.population - a.zone.population; + } + return b.zone.name.localeCompare(a.zone.name); + } + + function addToGuesses (name, offsets) { + var i, offset; + arrayToInt(offsets); + for (i = 0; i < offsets.length; i++) { + offset = offsets[i]; + guesses[offset] = guesses[offset] || {}; + guesses[offset][name] = true; + } + } + + function guessesForUserOffsets (offsets) { + var offsetsLength = offsets.length, + filteredGuesses = {}, + out = [], + i, j, guessesOffset; + + for (i = 0; i < offsetsLength; i++) { + guessesOffset = guesses[offsets[i].offset] || {}; + for (j in guessesOffset) { + if (guessesOffset.hasOwnProperty(j)) { + filteredGuesses[j] = true; + } + } + } + + for (i in filteredGuesses) { + if (filteredGuesses.hasOwnProperty(i)) { + out.push(names[i]); + } + } + + return out; + } + + function rebuildGuess () { + + // use Intl API when available and returning valid time zone + try { + var intlName = Intl.DateTimeFormat().resolvedOptions().timeZone; + if (intlName && intlName.length > 3) { + var name = names[normalizeName(intlName)]; + if (name) { + return name; + } + logError("Moment Timezone found " + intlName + " from the Intl api, but did not have that data loaded."); + } + } catch (e) { + // Intl unavailable, fall back to manual guessing. + } + + var offsets = userOffsets(), + offsetsLength = offsets.length, + guesses = guessesForUserOffsets(offsets), + zoneScores = [], + zoneScore, i, j; + + for (i = 0; i < guesses.length; i++) { + zoneScore = new ZoneScore(getZone(guesses[i]), offsetsLength); + for (j = 0; j < offsetsLength; j++) { + zoneScore.scoreOffsetAt(offsets[j]); + } + zoneScores.push(zoneScore); + } + + zoneScores.sort(sortZoneScores); + + return zoneScores.length > 0 ? zoneScores[0].zone.name : undefined; + } + + function guess (ignoreCache) { + if (!cachedGuess || ignoreCache) { + cachedGuess = rebuildGuess(); + } + return cachedGuess; + } + + /************************************ + Global Methods + ************************************/ + + function normalizeName (name) { + return (name || '').toLowerCase().replace(/\//g, '_'); + } + + function addZone (packed) { + var i, name, split, normalized; + + if (typeof packed === "string") { + packed = [packed]; + } + + for (i = 0; i < packed.length; i++) { + split = packed[i].split('|'); + name = split[0]; + normalized = normalizeName(name); + zones[normalized] = packed[i]; + names[normalized] = name; + addToGuesses(normalized, split[2].split(' ')); + } + } + + function getZone (name, caller) { + + name = normalizeName(name); + + var zone = zones[name]; + var link; + + if (zone instanceof Zone) { + return zone; + } + + if (typeof zone === 'string') { + zone = new Zone(zone); + zones[name] = zone; + return zone; + } + + // Pass getZone to prevent recursion more than 1 level deep + if (links[name] && caller !== getZone && (link = getZone(links[name], getZone))) { + zone = zones[name] = new Zone(); + zone._set(link); + zone.name = names[name]; + return zone; + } + + return null; + } + + function getNames () { + var i, out = []; + + for (i in names) { + if (names.hasOwnProperty(i) && (zones[i] || zones[links[i]]) && names[i]) { + out.push(names[i]); + } + } + + return out.sort(); + } + + function getCountryNames () { + return Object.keys(countries); + } + + function addLink (aliases) { + var i, alias, normal0, normal1; + + if (typeof aliases === "string") { + aliases = [aliases]; + } + + for (i = 0; i < aliases.length; i++) { + alias = aliases[i].split('|'); + + normal0 = normalizeName(alias[0]); + normal1 = normalizeName(alias[1]); + + links[normal0] = normal1; + names[normal0] = alias[0]; + + links[normal1] = normal0; + names[normal1] = alias[1]; + } + } + + function addCountries (data) { + var i, country_code, country_zones, split; + if (!data || !data.length) return; + for (i = 0; i < data.length; i++) { + split = data[i].split('|'); + country_code = split[0].toUpperCase(); + country_zones = split[1].split(' '); + countries[country_code] = new Country( + country_code, + country_zones + ); + } + } + + function getCountry (name) { + name = name.toUpperCase(); + return countries[name] || null; + } + + function zonesForCountry(country, with_offset) { + country = getCountry(country); + + if (!country) return null; + + var zones = country.zones.sort(); + + if (with_offset) { + return zones.map(function (zone_name) { + var zone = getZone(zone_name); + return { + name: zone_name, + offset: zone.utcOffset(new Date()) + }; + }); + } + + return zones; + } + + function loadData (data) { + addZone(data.zones); + addLink(data.links); + addCountries(data.countries); + tz.dataVersion = data.version; + } + + function zoneExists (name) { + if (!zoneExists.didShowError) { + zoneExists.didShowError = true; + logError("moment.tz.zoneExists('" + name + "') has been deprecated in favor of !moment.tz.zone('" + name + "')"); + } + return !!getZone(name); + } + + function needsOffset (m) { + var isUnixTimestamp = (m._f === 'X' || m._f === 'x'); + return !!(m._a && (m._tzm === undefined) && !isUnixTimestamp); + } + + function logError (message) { + if (typeof console !== 'undefined' && typeof console.error === 'function') { + console.error(message); + } + } + + /************************************ + moment.tz namespace + ************************************/ + + function tz (input) { + var args = Array.prototype.slice.call(arguments, 0, -1), + name = arguments[arguments.length - 1], + zone = getZone(name), + out = moment.utc.apply(null, args); + + if (zone && !moment.isMoment(input) && needsOffset(out)) { + out.add(zone.parse(out), 'minutes'); + } + + out.tz(name); + + return out; + } + + tz.version = VERSION; + tz.dataVersion = ''; + tz._zones = zones; + tz._links = links; + tz._names = names; + tz._countries = countries; + tz.add = addZone; + tz.link = addLink; + tz.load = loadData; + tz.zone = getZone; + tz.zoneExists = zoneExists; // deprecated in 0.1.0 + tz.guess = guess; + tz.names = getNames; + tz.Zone = Zone; + tz.unpack = unpack; + tz.unpackBase60 = unpackBase60; + tz.needsOffset = needsOffset; + tz.moveInvalidForward = true; + tz.moveAmbiguousForward = false; + tz.countries = getCountryNames; + tz.zonesForCountry = zonesForCountry; + + /************************************ + Interface with Moment.js + ************************************/ + + var fn = moment.fn; + + moment.tz = tz; + + moment.defaultZone = null; + + moment.updateOffset = function (mom, keepTime) { + var zone = moment.defaultZone, + offset; + + if (mom._z === undefined) { + if (zone && needsOffset(mom) && !mom._isUTC) { + mom._d = moment.utc(mom._a)._d; + mom.utc().add(zone.parse(mom), 'minutes'); + } + mom._z = zone; + } + if (mom._z) { + offset = mom._z.utcOffset(mom); + if (Math.abs(offset) < 16) { + offset = offset / 60; + } + if (mom.utcOffset !== undefined) { + var z = mom._z; + mom.utcOffset(-offset, keepTime); + mom._z = z; + } else { + mom.zone(offset, keepTime); + } + } + }; + + fn.tz = function (name, keepTime) { + if (name) { + if (typeof name !== 'string') { + throw new Error('Time zone name must be a string, got ' + name + ' [' + typeof name + ']'); + } + this._z = getZone(name); + if (this._z) { + moment.updateOffset(this, keepTime); + } else { + logError("Moment Timezone has no data for " + name + ". See http://momentjs.com/timezone/docs/#/data-loading/."); + } + return this; + } + if (this._z) { return this._z.name; } + }; + + function abbrWrap (old) { + return function () { + if (this._z) { return this._z.abbr(this); } + return old.call(this); + }; + } + + function resetZoneWrap (old) { + return function () { + this._z = null; + return old.apply(this, arguments); + }; + } + + function resetZoneWrap2 (old) { + return function () { + if (arguments.length > 0) this._z = null; + return old.apply(this, arguments); + }; + } + + fn.zoneName = abbrWrap(fn.zoneName); + fn.zoneAbbr = abbrWrap(fn.zoneAbbr); + fn.utc = resetZoneWrap(fn.utc); + fn.local = resetZoneWrap(fn.local); + fn.utcOffset = resetZoneWrap2(fn.utcOffset); + + moment.tz.setDefault = function(name) { + if (major < 2 || (major === 2 && minor < 9)) { + logError('Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js ' + moment.version + '.'); + } + moment.defaultZone = name ? getZone(name) : null; + return moment; + }; + + // Cloning a moment should include the _z property. + var momentProperties = moment.momentProperties; + if (Object.prototype.toString.call(momentProperties) === '[object Array]') { + // moment 2.8.1+ + momentProperties.push('_z'); + momentProperties.push('_a'); + } else if (momentProperties) { + // moment 2.7.0 + momentProperties._z = null; + } + + // INJECT DATA + + return moment; +})); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/af.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/af.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Afrikaans [af] +//! author : Werner Mollentze : https://github.com/wernerm + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var af = moment.defineLocale('af', { + months: 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'), + weekdays: 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split( + '_' + ), + weekdaysShort: 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'), + weekdaysMin: 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'), + meridiemParse: /vm|nm/i, + isPM: function (input) { + return /^nm$/i.test(input); + }, + meridiem: function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'vm' : 'VM'; + } else { + return isLower ? 'nm' : 'NM'; + } + }, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Vandag om] LT', + nextDay: '[Môre om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[Gister om] LT', + lastWeek: '[Laas] dddd [om] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'oor %s', + past: '%s gelede', + s: "'n paar sekondes", + ss: '%d sekondes', + m: "'n minuut", + mm: '%d minute', + h: "'n uur", + hh: '%d ure', + d: "'n dag", + dd: '%d dae', + M: "'n maand", + MM: '%d maande', + y: "'n jaar", + yy: '%d jaar', + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal: function (number) { + return ( + number + + (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de') + ); // Thanks to Joris Röling : https://github.com/jjupiter + }, + week: { + dow: 1, // Maandag is die eerste dag van die week. + doy: 4, // Die week wat die 4de Januarie bevat is die eerste week van die jaar. + }, + }); + + return af; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ar-dz.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ar-dz.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Arabic (Algeria) [ar-dz] +//! author : Amine Roukh: https://github.com/Amine27 +//! author : Abdel Said: https://github.com/abdelsaid +//! author : Ahmed Elkhatib +//! author : forabi https://github.com/forabi +//! author : Noureddine LOUAHEDJ : https://github.com/noureddinem + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var pluralForm = function (n) { + return n === 0 + ? 0 + : n === 1 + ? 1 + : n === 2 + ? 2 + : n % 100 >= 3 && n % 100 <= 10 + ? 3 + : n % 100 >= 11 + ? 4 + : 5; + }, + plurals = { + s: [ + 'أقل من ثانية', + 'ثانية واحدة', + ['ثانيتان', 'ثانيتين'], + '%d ثوان', + '%d ثانية', + '%d ثانية', + ], + m: [ + 'أقل من دقيقة', + 'دقيقة واحدة', + ['دقيقتان', 'دقيقتين'], + '%d دقائق', + '%d دقيقة', + '%d دقيقة', + ], + h: [ + 'أقل من ساعة', + 'ساعة واحدة', + ['ساعتان', 'ساعتين'], + '%d ساعات', + '%d ساعة', + '%d ساعة', + ], + d: [ + 'أقل من يوم', + 'يوم واحد', + ['يومان', 'يومين'], + '%d أيام', + '%d يومًا', + '%d يوم', + ], + M: [ + 'أقل من شهر', + 'شهر واحد', + ['شهران', 'شهرين'], + '%d أشهر', + '%d شهرا', + '%d شهر', + ], + y: [ + 'أقل من عام', + 'عام واحد', + ['عامان', 'عامين'], + '%d أعوام', + '%d عامًا', + '%d عام', + ], + }, + pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; + }, + months = [ + 'جانفي', + 'فيفري', + 'مارس', + 'أفريل', + 'ماي', + 'جوان', + 'جويلية', + 'أوت', + 'سبتمبر', + 'أكتوبر', + 'نوفمبر', + 'ديسمبر', + ]; + + var arDz = moment.defineLocale('ar-dz', { + months: months, + monthsShort: months, + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'D/\u200FM/\u200FYYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + meridiemParse: /ص|م/, + isPM: function (input) { + return 'م' === input; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar: { + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'بعد %s', + past: 'منذ %s', + s: pluralize('s'), + ss: pluralize('s'), + m: pluralize('m'), + mm: pluralize('m'), + h: pluralize('h'), + hh: pluralize('h'), + d: pluralize('d'), + dd: pluralize('d'), + M: pluralize('M'), + MM: pluralize('M'), + y: pluralize('y'), + yy: pluralize('y'), + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return arDz; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ar-kw.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ar-kw.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Arabic (Kuwait) [ar-kw] +//! author : Nusret Parlak: https://github.com/nusretparlak + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var arKw = moment.defineLocale('ar-kw', { + months: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split( + '_' + ), + monthsShort: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split( + '_' + ), + weekdays: 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'في %s', + past: 'منذ %s', + s: 'ثوان', + ss: '%d ثانية', + m: 'دقيقة', + mm: '%d دقائق', + h: 'ساعة', + hh: '%d ساعات', + d: 'يوم', + dd: '%d أيام', + M: 'شهر', + MM: '%d أشهر', + y: 'سنة', + yy: '%d سنوات', + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 12, // The week that contains Jan 12th is the first week of the year. + }, + }); + + return arKw; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ar-ly.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ar-ly.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Arabic (Lybia) [ar-ly] +//! author : Ali Hmer: https://github.com/kikoanis + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '1', + 2: '2', + 3: '3', + 4: '4', + 5: '5', + 6: '6', + 7: '7', + 8: '8', + 9: '9', + 0: '0', + }, + pluralForm = function (n) { + return n === 0 + ? 0 + : n === 1 + ? 1 + : n === 2 + ? 2 + : n % 100 >= 3 && n % 100 <= 10 + ? 3 + : n % 100 >= 11 + ? 4 + : 5; + }, + plurals = { + s: [ + 'أقل من ثانية', + 'ثانية واحدة', + ['ثانيتان', 'ثانيتين'], + '%d ثوان', + '%d ثانية', + '%d ثانية', + ], + m: [ + 'أقل من دقيقة', + 'دقيقة واحدة', + ['دقيقتان', 'دقيقتين'], + '%d دقائق', + '%d دقيقة', + '%d دقيقة', + ], + h: [ + 'أقل من ساعة', + 'ساعة واحدة', + ['ساعتان', 'ساعتين'], + '%d ساعات', + '%d ساعة', + '%d ساعة', + ], + d: [ + 'أقل من يوم', + 'يوم واحد', + ['يومان', 'يومين'], + '%d أيام', + '%d يومًا', + '%d يوم', + ], + M: [ + 'أقل من شهر', + 'شهر واحد', + ['شهران', 'شهرين'], + '%d أشهر', + '%d شهرا', + '%d شهر', + ], + y: [ + 'أقل من عام', + 'عام واحد', + ['عامان', 'عامين'], + '%d أعوام', + '%d عامًا', + '%d عام', + ], + }, + pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; + }, + months = [ + 'يناير', + 'فبراير', + 'مارس', + 'أبريل', + 'مايو', + 'يونيو', + 'يوليو', + 'أغسطس', + 'سبتمبر', + 'أكتوبر', + 'نوفمبر', + 'ديسمبر', + ]; + + var arLy = moment.defineLocale('ar-ly', { + months: months, + monthsShort: months, + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'D/\u200FM/\u200FYYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + meridiemParse: /ص|م/, + isPM: function (input) { + return 'م' === input; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar: { + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'بعد %s', + past: 'منذ %s', + s: pluralize('s'), + ss: pluralize('s'), + m: pluralize('m'), + mm: pluralize('m'), + h: pluralize('h'), + hh: pluralize('h'), + d: pluralize('d'), + dd: pluralize('d'), + M: pluralize('M'), + MM: pluralize('M'), + y: pluralize('y'), + yy: pluralize('y'), + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string + .replace(/\d/g, function (match) { + return symbolMap[match]; + }) + .replace(/,/g, '،'); + }, + week: { + dow: 6, // Saturday is the first day of the week. + doy: 12, // The week that contains Jan 12th is the first week of the year. + }, + }); + + return arLy; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ar-ma.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ar-ma.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Arabic (Morocco) [ar-ma] +//! author : ElFadili Yassine : https://github.com/ElFadiliY +//! author : Abdel Said : https://github.com/abdelsaid + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var arMa = moment.defineLocale('ar-ma', { + months: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split( + '_' + ), + monthsShort: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split( + '_' + ), + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'في %s', + past: 'منذ %s', + s: 'ثوان', + ss: '%d ثانية', + m: 'دقيقة', + mm: '%d دقائق', + h: 'ساعة', + hh: '%d ساعات', + d: 'يوم', + dd: '%d أيام', + M: 'شهر', + MM: '%d أشهر', + y: 'سنة', + yy: '%d سنوات', + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return arMa; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ar-sa.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ar-sa.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Arabic (Saudi Arabia) [ar-sa] +//! author : Suhail Alkowaileet : https://github.com/xsoh + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '١', + 2: '٢', + 3: '٣', + 4: '٤', + 5: '٥', + 6: '٦', + 7: '٧', + 8: '٨', + 9: '٩', + 0: '٠', + }, + numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0', + }; + + var arSa = moment.defineLocale('ar-sa', { + months: 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split( + '_' + ), + monthsShort: 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split( + '_' + ), + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + meridiemParse: /ص|م/, + isPM: function (input) { + return 'م' === input; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar: { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'في %s', + past: 'منذ %s', + s: 'ثوان', + ss: '%d ثانية', + m: 'دقيقة', + mm: '%d دقائق', + h: 'ساعة', + hh: '%d ساعات', + d: 'يوم', + dd: '%d أيام', + M: 'شهر', + MM: '%d أشهر', + y: 'سنة', + yy: '%d سنوات', + }, + preparse: function (string) { + return string + .replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return numberMap[match]; + }) + .replace(/،/g, ','); + }, + postformat: function (string) { + return string + .replace(/\d/g, function (match) { + return symbolMap[match]; + }) + .replace(/,/g, '،'); + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return arSa; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ar-tn.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ar-tn.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Arabic (Tunisia) [ar-tn] +//! author : Nader Toukabri : https://github.com/naderio + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var arTn = moment.defineLocale('ar-tn', { + months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split( + '_' + ), + monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split( + '_' + ), + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'في %s', + past: 'منذ %s', + s: 'ثوان', + ss: '%d ثانية', + m: 'دقيقة', + mm: '%d دقائق', + h: 'ساعة', + hh: '%d ساعات', + d: 'يوم', + dd: '%d أيام', + M: 'شهر', + MM: '%d أشهر', + y: 'سنة', + yy: '%d سنوات', + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return arTn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ar.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ar.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Arabic [ar] +//! author : Abdel Said: https://github.com/abdelsaid +//! author : Ahmed Elkhatib +//! author : forabi https://github.com/forabi + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '١', + 2: '٢', + 3: '٣', + 4: '٤', + 5: '٥', + 6: '٦', + 7: '٧', + 8: '٨', + 9: '٩', + 0: '٠', + }, + numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0', + }, + pluralForm = function (n) { + return n === 0 + ? 0 + : n === 1 + ? 1 + : n === 2 + ? 2 + : n % 100 >= 3 && n % 100 <= 10 + ? 3 + : n % 100 >= 11 + ? 4 + : 5; + }, + plurals = { + s: [ + 'أقل من ثانية', + 'ثانية واحدة', + ['ثانيتان', 'ثانيتين'], + '%d ثوان', + '%d ثانية', + '%d ثانية', + ], + m: [ + 'أقل من دقيقة', + 'دقيقة واحدة', + ['دقيقتان', 'دقيقتين'], + '%d دقائق', + '%d دقيقة', + '%d دقيقة', + ], + h: [ + 'أقل من ساعة', + 'ساعة واحدة', + ['ساعتان', 'ساعتين'], + '%d ساعات', + '%d ساعة', + '%d ساعة', + ], + d: [ + 'أقل من يوم', + 'يوم واحد', + ['يومان', 'يومين'], + '%d أيام', + '%d يومًا', + '%d يوم', + ], + M: [ + 'أقل من شهر', + 'شهر واحد', + ['شهران', 'شهرين'], + '%d أشهر', + '%d شهرا', + '%d شهر', + ], + y: [ + 'أقل من عام', + 'عام واحد', + ['عامان', 'عامين'], + '%d أعوام', + '%d عامًا', + '%d عام', + ], + }, + pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; + }, + months = [ + 'يناير', + 'فبراير', + 'مارس', + 'أبريل', + 'مايو', + 'يونيو', + 'يوليو', + 'أغسطس', + 'سبتمبر', + 'أكتوبر', + 'نوفمبر', + 'ديسمبر', + ]; + + var ar = moment.defineLocale('ar', { + months: months, + monthsShort: months, + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'D/\u200FM/\u200FYYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + meridiemParse: /ص|م/, + isPM: function (input) { + return 'م' === input; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar: { + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'بعد %s', + past: 'منذ %s', + s: pluralize('s'), + ss: pluralize('s'), + m: pluralize('m'), + mm: pluralize('m'), + h: pluralize('h'), + hh: pluralize('h'), + d: pluralize('d'), + dd: pluralize('d'), + M: pluralize('M'), + MM: pluralize('M'), + y: pluralize('y'), + yy: pluralize('y'), + }, + preparse: function (string) { + return string + .replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return numberMap[match]; + }) + .replace(/،/g, ','); + }, + postformat: function (string) { + return string + .replace(/\d/g, function (match) { + return symbolMap[match]; + }) + .replace(/,/g, '،'); + }, + week: { + dow: 6, // Saturday is the first day of the week. + doy: 12, // The week that contains Jan 12th is the first week of the year. + }, + }); + + return ar; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/az.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/az.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Azerbaijani [az] +//! author : topchiyev : https://github.com/topchiyev + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var suffixes = { + 1: '-inci', + 5: '-inci', + 8: '-inci', + 70: '-inci', + 80: '-inci', + 2: '-nci', + 7: '-nci', + 20: '-nci', + 50: '-nci', + 3: '-üncü', + 4: '-üncü', + 100: '-üncü', + 6: '-ncı', + 9: '-uncu', + 10: '-uncu', + 30: '-uncu', + 60: '-ıncı', + 90: '-ıncı', + }; + + var az = moment.defineLocale('az', { + months: 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split( + '_' + ), + monthsShort: 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'), + weekdays: 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split( + '_' + ), + weekdaysShort: 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'), + weekdaysMin: 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[bugün saat] LT', + nextDay: '[sabah saat] LT', + nextWeek: '[gələn həftə] dddd [saat] LT', + lastDay: '[dünən] LT', + lastWeek: '[keçən həftə] dddd [saat] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s sonra', + past: '%s əvvəl', + s: 'bir neçə saniyə', + ss: '%d saniyə', + m: 'bir dəqiqə', + mm: '%d dəqiqə', + h: 'bir saat', + hh: '%d saat', + d: 'bir gün', + dd: '%d gün', + M: 'bir ay', + MM: '%d ay', + y: 'bir il', + yy: '%d il', + }, + meridiemParse: /gecə|səhər|gündüz|axşam/, + isPM: function (input) { + return /^(gündüz|axşam)$/.test(input); + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'gecə'; + } else if (hour < 12) { + return 'səhər'; + } else if (hour < 17) { + return 'gündüz'; + } else { + return 'axşam'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/, + ordinal: function (number) { + if (number === 0) { + // special case for zero + return number + '-ıncı'; + } + var a = number % 10, + b = (number % 100) - a, + c = number >= 100 ? 100 : null; + return number + (suffixes[a] || suffixes[b] || suffixes[c]); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return az; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/be.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/be.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Belarusian [be] +//! author : Dmitry Demidov : https://github.com/demidov91 +//! author: Praleska: http://praleska.pro/ +//! Author : Menelion Elensúle : https://github.com/Oire + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 + ? forms[0] + : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) + ? forms[1] + : forms[2]; + } + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + ss: withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', + mm: withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін', + hh: withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін', + dd: 'дзень_дні_дзён', + MM: 'месяц_месяцы_месяцаў', + yy: 'год_гады_гадоў', + }; + if (key === 'm') { + return withoutSuffix ? 'хвіліна' : 'хвіліну'; + } else if (key === 'h') { + return withoutSuffix ? 'гадзіна' : 'гадзіну'; + } else { + return number + ' ' + plural(format[key], +number); + } + } + + var be = moment.defineLocale('be', { + months: { + format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split( + '_' + ), + standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split( + '_' + ), + }, + monthsShort: 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split( + '_' + ), + weekdays: { + format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split( + '_' + ), + standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split( + '_' + ), + isFormat: /\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/, + }, + weekdaysShort: 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + weekdaysMin: 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY г.', + LLL: 'D MMMM YYYY г., HH:mm', + LLLL: 'dddd, D MMMM YYYY г., HH:mm', + }, + calendar: { + sameDay: '[Сёння ў] LT', + nextDay: '[Заўтра ў] LT', + lastDay: '[Учора ў] LT', + nextWeek: function () { + return '[У] dddd [ў] LT'; + }, + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return '[У мінулую] dddd [ў] LT'; + case 1: + case 2: + case 4: + return '[У мінулы] dddd [ў] LT'; + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'праз %s', + past: '%s таму', + s: 'некалькі секунд', + m: relativeTimeWithPlural, + mm: relativeTimeWithPlural, + h: relativeTimeWithPlural, + hh: relativeTimeWithPlural, + d: 'дзень', + dd: relativeTimeWithPlural, + M: 'месяц', + MM: relativeTimeWithPlural, + y: 'год', + yy: relativeTimeWithPlural, + }, + meridiemParse: /ночы|раніцы|дня|вечара/, + isPM: function (input) { + return /^(дня|вечара)$/.test(input); + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'ночы'; + } else if (hour < 12) { + return 'раніцы'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечара'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(і|ы|га)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return (number % 10 === 2 || number % 10 === 3) && + number % 100 !== 12 && + number % 100 !== 13 + ? number + '-і' + : number + '-ы'; + case 'D': + return number + '-га'; + default: + return number; + } + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return be; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/bg.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/bg.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Bulgarian [bg] +//! author : Krasen Borisov : https://github.com/kraz + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var bg = moment.defineLocale('bg', { + months: 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split( + '_' + ), + monthsShort: 'яну_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'), + weekdays: 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split( + '_' + ), + weekdaysShort: 'нед_пон_вто_сря_чет_пет_съб'.split('_'), + weekdaysMin: 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'D.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY H:mm', + LLLL: 'dddd, D MMMM YYYY H:mm', + }, + calendar: { + sameDay: '[Днес в] LT', + nextDay: '[Утре в] LT', + nextWeek: 'dddd [в] LT', + lastDay: '[Вчера в] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[Миналата] dddd [в] LT'; + case 1: + case 2: + case 4: + case 5: + return '[Миналия] dddd [в] LT'; + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'след %s', + past: 'преди %s', + s: 'няколко секунди', + ss: '%d секунди', + m: 'минута', + mm: '%d минути', + h: 'час', + hh: '%d часа', + d: 'ден', + dd: '%d дена', + w: 'седмица', + ww: '%d седмици', + M: 'месец', + MM: '%d месеца', + y: 'година', + yy: '%d години', + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, + ordinal: function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return bg; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/bm.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/bm.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Bambara [bm] +//! author : Estelle Comment : https://github.com/estellecomment + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var bm = moment.defineLocale('bm', { + months: 'Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo'.split( + '_' + ), + monthsShort: 'Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des'.split('_'), + weekdays: 'Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri'.split('_'), + weekdaysShort: 'Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib'.split('_'), + weekdaysMin: 'Ka_Nt_Ta_Ar_Al_Ju_Si'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'MMMM [tile] D [san] YYYY', + LLL: 'MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm', + LLLL: 'dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm', + }, + calendar: { + sameDay: '[Bi lɛrɛ] LT', + nextDay: '[Sini lɛrɛ] LT', + nextWeek: 'dddd [don lɛrɛ] LT', + lastDay: '[Kunu lɛrɛ] LT', + lastWeek: 'dddd [tɛmɛnen lɛrɛ] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s kɔnɔ', + past: 'a bɛ %s bɔ', + s: 'sanga dama dama', + ss: 'sekondi %d', + m: 'miniti kelen', + mm: 'miniti %d', + h: 'lɛrɛ kelen', + hh: 'lɛrɛ %d', + d: 'tile kelen', + dd: 'tile %d', + M: 'kalo kelen', + MM: 'kalo %d', + y: 'san kelen', + yy: 'san %d', + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return bm; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/bn-bd.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/bn-bd.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Bengali (Bangladesh) [bn-bd] +//! author : Asraf Hossain Patoary : https://github.com/ashwoolford + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '১', + 2: '২', + 3: '৩', + 4: '৪', + 5: '৫', + 6: '৬', + 7: '৭', + 8: '৮', + 9: '৯', + 0: '০', + }, + numberMap = { + '১': '1', + '২': '2', + '৩': '3', + '৪': '4', + '৫': '5', + '৬': '6', + '৭': '7', + '৮': '8', + '৯': '9', + '০': '0', + }; + + var bnBd = moment.defineLocale('bn-bd', { + months: 'জানুয়ারি_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split( + '_' + ), + monthsShort: 'জানু_ফেব্রু_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্ট_অক্টো_নভে_ডিসে'.split( + '_' + ), + weekdays: 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split( + '_' + ), + weekdaysShort: 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'), + weekdaysMin: 'রবি_সোম_মঙ্গল_বুধ_বৃহ_শুক্র_শনি'.split('_'), + longDateFormat: { + LT: 'A h:mm সময়', + LTS: 'A h:mm:ss সময়', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm সময়', + LLLL: 'dddd, D MMMM YYYY, A h:mm সময়', + }, + calendar: { + sameDay: '[আজ] LT', + nextDay: '[আগামীকাল] LT', + nextWeek: 'dddd, LT', + lastDay: '[গতকাল] LT', + lastWeek: '[গত] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s পরে', + past: '%s আগে', + s: 'কয়েক সেকেন্ড', + ss: '%d সেকেন্ড', + m: 'এক মিনিট', + mm: '%d মিনিট', + h: 'এক ঘন্টা', + hh: '%d ঘন্টা', + d: 'এক দিন', + dd: '%d দিন', + M: 'এক মাস', + MM: '%d মাস', + y: 'এক বছর', + yy: '%d বছর', + }, + preparse: function (string) { + return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + + meridiemParse: /রাত|ভোর|সকাল|দুপুর|বিকাল|সন্ধ্যা|রাত/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'রাত') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ভোর') { + return hour; + } else if (meridiem === 'সকাল') { + return hour; + } else if (meridiem === 'দুপুর') { + return hour >= 3 ? hour : hour + 12; + } else if (meridiem === 'বিকাল') { + return hour + 12; + } else if (meridiem === 'সন্ধ্যা') { + return hour + 12; + } + }, + + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'রাত'; + } else if (hour < 6) { + return 'ভোর'; + } else if (hour < 12) { + return 'সকাল'; + } else if (hour < 15) { + return 'দুপুর'; + } else if (hour < 18) { + return 'বিকাল'; + } else if (hour < 20) { + return 'সন্ধ্যা'; + } else { + return 'রাত'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return bnBd; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/bn.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/bn.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Bengali [bn] +//! author : Kaushik Gandhi : https://github.com/kaushikgandhi + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '১', + 2: '২', + 3: '৩', + 4: '৪', + 5: '৫', + 6: '৬', + 7: '৭', + 8: '৮', + 9: '৯', + 0: '০', + }, + numberMap = { + '১': '1', + '২': '2', + '৩': '3', + '৪': '4', + '৫': '5', + '৬': '6', + '৭': '7', + '৮': '8', + '৯': '9', + '০': '0', + }; + + var bn = moment.defineLocale('bn', { + months: 'জানুয়ারি_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split( + '_' + ), + monthsShort: 'জানু_ফেব্রু_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্ট_অক্টো_নভে_ডিসে'.split( + '_' + ), + weekdays: 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split( + '_' + ), + weekdaysShort: 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'), + weekdaysMin: 'রবি_সোম_মঙ্গল_বুধ_বৃহ_শুক্র_শনি'.split('_'), + longDateFormat: { + LT: 'A h:mm সময়', + LTS: 'A h:mm:ss সময়', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm সময়', + LLLL: 'dddd, D MMMM YYYY, A h:mm সময়', + }, + calendar: { + sameDay: '[আজ] LT', + nextDay: '[আগামীকাল] LT', + nextWeek: 'dddd, LT', + lastDay: '[গতকাল] LT', + lastWeek: '[গত] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s পরে', + past: '%s আগে', + s: 'কয়েক সেকেন্ড', + ss: '%d সেকেন্ড', + m: 'এক মিনিট', + mm: '%d মিনিট', + h: 'এক ঘন্টা', + hh: '%d ঘন্টা', + d: 'এক দিন', + dd: '%d দিন', + M: 'এক মাস', + MM: '%d মাস', + y: 'এক বছর', + yy: '%d বছর', + }, + preparse: function (string) { + return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ( + (meridiem === 'রাত' && hour >= 4) || + (meridiem === 'দুপুর' && hour < 5) || + meridiem === 'বিকাল' + ) { + return hour + 12; + } else { + return hour; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'রাত'; + } else if (hour < 10) { + return 'সকাল'; + } else if (hour < 17) { + return 'দুপুর'; + } else if (hour < 20) { + return 'বিকাল'; + } else { + return 'রাত'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return bn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/bo.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/bo.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Tibetan [bo] +//! author : Thupten N. Chakrishar : https://github.com/vajradog + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '༡', + 2: '༢', + 3: '༣', + 4: '༤', + 5: '༥', + 6: '༦', + 7: '༧', + 8: '༨', + 9: '༩', + 0: '༠', + }, + numberMap = { + '༡': '1', + '༢': '2', + '༣': '3', + '༤': '4', + '༥': '5', + '༦': '6', + '༧': '7', + '༨': '8', + '༩': '9', + '༠': '0', + }; + + var bo = moment.defineLocale('bo', { + months: 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split( + '_' + ), + monthsShort: 'ཟླ་1_ཟླ་2_ཟླ་3_ཟླ་4_ཟླ་5_ཟླ་6_ཟླ་7_ཟླ་8_ཟླ་9_ཟླ་10_ཟླ་11_ཟླ་12'.split( + '_' + ), + monthsShortRegex: /^(ཟླ་\d{1,2})/, + monthsParseExact: true, + weekdays: 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split( + '_' + ), + weekdaysShort: 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split( + '_' + ), + weekdaysMin: 'ཉི_ཟླ_མིག_ལྷག_ཕུར_སངས_སྤེན'.split('_'), + longDateFormat: { + LT: 'A h:mm', + LTS: 'A h:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm', + LLLL: 'dddd, D MMMM YYYY, A h:mm', + }, + calendar: { + sameDay: '[དི་རིང] LT', + nextDay: '[སང་ཉིན] LT', + nextWeek: '[བདུན་ཕྲག་རྗེས་མ], LT', + lastDay: '[ཁ་སང] LT', + lastWeek: '[བདུན་ཕྲག་མཐའ་མ] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s ལ་', + past: '%s སྔན་ལ', + s: 'ལམ་སང', + ss: '%d སྐར་ཆ།', + m: 'སྐར་མ་གཅིག', + mm: '%d སྐར་མ', + h: 'ཆུ་ཚོད་གཅིག', + hh: '%d ཆུ་ཚོད', + d: 'ཉིན་གཅིག', + dd: '%d ཉིན་', + M: 'ཟླ་བ་གཅིག', + MM: '%d ཟླ་བ', + y: 'ལོ་གཅིག', + yy: '%d ལོ', + }, + preparse: function (string) { + return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ( + (meridiem === 'མཚན་མོ' && hour >= 4) || + (meridiem === 'ཉིན་གུང' && hour < 5) || + meridiem === 'དགོང་དག' + ) { + return hour + 12; + } else { + return hour; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'མཚན་མོ'; + } else if (hour < 10) { + return 'ཞོགས་ཀས'; + } else if (hour < 17) { + return 'ཉིན་གུང'; + } else if (hour < 20) { + return 'དགོང་དག'; + } else { + return 'མཚན་མོ'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return bo; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/br.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/br.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Breton [br] +//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function relativeTimeWithMutation(number, withoutSuffix, key) { + var format = { + mm: 'munutenn', + MM: 'miz', + dd: 'devezh', + }; + return number + ' ' + mutation(format[key], number); + } + function specialMutationForYears(number) { + switch (lastNumber(number)) { + case 1: + case 3: + case 4: + case 5: + case 9: + return number + ' bloaz'; + default: + return number + ' vloaz'; + } + } + function lastNumber(number) { + if (number > 9) { + return lastNumber(number % 10); + } + return number; + } + function mutation(text, number) { + if (number === 2) { + return softMutation(text); + } + return text; + } + function softMutation(text) { + var mutationTable = { + m: 'v', + b: 'v', + d: 'z', + }; + if (mutationTable[text.charAt(0)] === undefined) { + return text; + } + return mutationTable[text.charAt(0)] + text.substring(1); + } + + var monthsParse = [ + /^gen/i, + /^c[ʼ\']hwe/i, + /^meu/i, + /^ebr/i, + /^mae/i, + /^(mez|eve)/i, + /^gou/i, + /^eos/i, + /^gwe/i, + /^her/i, + /^du/i, + /^ker/i, + ], + monthsRegex = /^(genver|c[ʼ\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu|gen|c[ʼ\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i, + monthsStrictRegex = /^(genver|c[ʼ\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu)/i, + monthsShortStrictRegex = /^(gen|c[ʼ\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i, + fullWeekdaysParse = [ + /^sul/i, + /^lun/i, + /^meurzh/i, + /^merc[ʼ\']her/i, + /^yaou/i, + /^gwener/i, + /^sadorn/i, + ], + shortWeekdaysParse = [ + /^Sul/i, + /^Lun/i, + /^Meu/i, + /^Mer/i, + /^Yao/i, + /^Gwe/i, + /^Sad/i, + ], + minWeekdaysParse = [ + /^Su/i, + /^Lu/i, + /^Me([^r]|$)/i, + /^Mer/i, + /^Ya/i, + /^Gw/i, + /^Sa/i, + ]; + + var br = moment.defineLocale('br', { + months: 'Genver_Cʼhwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split( + '_' + ), + monthsShort: 'Gen_Cʼhwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'), + weekdays: 'Sul_Lun_Meurzh_Mercʼher_Yaou_Gwener_Sadorn'.split('_'), + weekdaysShort: 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'), + weekdaysMin: 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'), + weekdaysParse: minWeekdaysParse, + fullWeekdaysParse: fullWeekdaysParse, + shortWeekdaysParse: shortWeekdaysParse, + minWeekdaysParse: minWeekdaysParse, + + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: monthsStrictRegex, + monthsShortStrictRegex: monthsShortStrictRegex, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D [a viz] MMMM YYYY', + LLL: 'D [a viz] MMMM YYYY HH:mm', + LLLL: 'dddd, D [a viz] MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Hiziv da] LT', + nextDay: '[Warcʼhoazh da] LT', + nextWeek: 'dddd [da] LT', + lastDay: '[Decʼh da] LT', + lastWeek: 'dddd [paset da] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'a-benn %s', + past: '%s ʼzo', + s: 'un nebeud segondennoù', + ss: '%d eilenn', + m: 'ur vunutenn', + mm: relativeTimeWithMutation, + h: 'un eur', + hh: '%d eur', + d: 'un devezh', + dd: relativeTimeWithMutation, + M: 'ur miz', + MM: relativeTimeWithMutation, + y: 'ur bloaz', + yy: specialMutationForYears, + }, + dayOfMonthOrdinalParse: /\d{1,2}(añ|vet)/, + ordinal: function (number) { + var output = number === 1 ? 'añ' : 'vet'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + meridiemParse: /a.m.|g.m./, // goude merenn | a-raok merenn + isPM: function (token) { + return token === 'g.m.'; + }, + meridiem: function (hour, minute, isLower) { + return hour < 12 ? 'a.m.' : 'g.m.'; + }, + }); + + return br; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/bs.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/bs.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Bosnian [bs] +//! author : Nedim Cholich : https://github.com/frontyard +//! based on (hr) translation by Bojan Marković + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + if (number === 1) { + result += 'sekunda'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sekunde'; + } else { + result += 'sekundi'; + } + return result; + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } + } + + var bs = moment.defineLocale('bs', { + months: 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split( + '_' + ), + monthsShort: 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split( + '_' + ), + weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm', + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sutra u] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay: '[jučer u] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + return '[prošlu] dddd [u] LT'; + case 6: + return '[prošle] [subote] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prošli] dddd [u] LT'; + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'za %s', + past: 'prije %s', + s: 'par sekundi', + ss: translate, + m: translate, + mm: translate, + h: translate, + hh: translate, + d: 'dan', + dd: translate, + M: 'mjesec', + MM: translate, + y: 'godinu', + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return bs; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ca.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ca.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Catalan [ca] +//! author : Juan G. Hurtado : https://github.com/juanghurtado + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var ca = moment.defineLocale('ca', { + months: { + standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split( + '_' + ), + format: "de gener_de febrer_de març_d'abril_de maig_de juny_de juliol_d'agost_de setembre_d'octubre_de novembre_de desembre".split( + '_' + ), + isFormat: /D[oD]?(\s)+MMMM/, + }, + monthsShort: 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split( + '_' + ), + weekdaysShort: 'dg._dl._dt._dc._dj._dv._ds.'.split('_'), + weekdaysMin: 'dg_dl_dt_dc_dj_dv_ds'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM [de] YYYY', + ll: 'D MMM YYYY', + LLL: 'D MMMM [de] YYYY [a les] H:mm', + lll: 'D MMM YYYY, H:mm', + LLLL: 'dddd D MMMM [de] YYYY [a les] H:mm', + llll: 'ddd D MMM YYYY, H:mm', + }, + calendar: { + sameDay: function () { + return '[avui a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT'; + }, + nextDay: function () { + return '[demà a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT'; + }, + nextWeek: function () { + return 'dddd [a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT'; + }, + lastDay: function () { + return '[ahir a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT'; + }, + lastWeek: function () { + return ( + '[el] dddd [passat a ' + + (this.hours() !== 1 ? 'les' : 'la') + + '] LT' + ); + }, + sameElse: 'L', + }, + relativeTime: { + future: "d'aquí %s", + past: 'fa %s', + s: 'uns segons', + ss: '%d segons', + m: 'un minut', + mm: '%d minuts', + h: 'una hora', + hh: '%d hores', + d: 'un dia', + dd: '%d dies', + M: 'un mes', + MM: '%d mesos', + y: 'un any', + yy: '%d anys', + }, + dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/, + ordinal: function (number, period) { + var output = + number === 1 + ? 'r' + : number === 2 + ? 'n' + : number === 3 + ? 'r' + : number === 4 + ? 't' + : 'è'; + if (period === 'w' || period === 'W') { + output = 'a'; + } + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return ca; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/cs.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/cs.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Czech [cs] +//! author : petrbela : https://github.com/petrbela + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split( + '_' + ), + monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'), + monthsParse = [ + /^led/i, + /^úno/i, + /^bře/i, + /^dub/i, + /^kvě/i, + /^(čvn|červen$|června)/i, + /^(čvc|červenec|července)/i, + /^srp/i, + /^zář/i, + /^říj/i, + /^lis/i, + /^pro/i, + ], + // NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched. + // Otherwise parser matches '1. červenec' as '1. červen' + 'ec'. + monthsRegex = /^(leden|únor|březen|duben|květen|červenec|července|červen|června|srpen|září|říjen|listopad|prosinec|led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i; + + function plural(n) { + return n > 1 && n < 5 && ~~(n / 10) !== 1; + } + function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return withoutSuffix || isFuture ? 'pár sekund' : 'pár sekundami'; + case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'sekundy' : 'sekund'); + } else { + return result + 'sekundami'; + } + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minuta' : isFuture ? 'minutu' : 'minutou'; + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'minuty' : 'minut'); + } else { + return result + 'minutami'; + } + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : isFuture ? 'hodinu' : 'hodinou'; + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'hodiny' : 'hodin'); + } else { + return result + 'hodinami'; + } + case 'd': // a day / in a day / a day ago + return withoutSuffix || isFuture ? 'den' : 'dnem'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'dny' : 'dní'); + } else { + return result + 'dny'; + } + case 'M': // a month / in a month / a month ago + return withoutSuffix || isFuture ? 'měsíc' : 'měsícem'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'měsíce' : 'měsíců'); + } else { + return result + 'měsíci'; + } + case 'y': // a year / in a year / a year ago + return withoutSuffix || isFuture ? 'rok' : 'rokem'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'roky' : 'let'); + } else { + return result + 'lety'; + } + } + } + + var cs = moment.defineLocale('cs', { + months: months, + monthsShort: monthsShort, + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + // NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched. + // Otherwise parser matches '1. červenec' as '1. červen' + 'ec'. + monthsStrictRegex: /^(leden|ledna|února|únor|březen|března|duben|dubna|květen|května|červenec|července|červen|června|srpen|srpna|září|říjen|října|listopadu|listopad|prosinec|prosince)/i, + monthsShortStrictRegex: /^(led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays: 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'), + weekdaysShort: 'ne_po_út_st_čt_pá_so'.split('_'), + weekdaysMin: 'ne_po_út_st_čt_pá_so'.split('_'), + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd D. MMMM YYYY H:mm', + l: 'D. M. YYYY', + }, + calendar: { + sameDay: '[dnes v] LT', + nextDay: '[zítra v] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v neděli v] LT'; + case 1: + case 2: + return '[v] dddd [v] LT'; + case 3: + return '[ve středu v] LT'; + case 4: + return '[ve čtvrtek v] LT'; + case 5: + return '[v pátek v] LT'; + case 6: + return '[v sobotu v] LT'; + } + }, + lastDay: '[včera v] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulou neděli v] LT'; + case 1: + case 2: + return '[minulé] dddd [v] LT'; + case 3: + return '[minulou středu v] LT'; + case 4: + case 5: + return '[minulý] dddd [v] LT'; + case 6: + return '[minulou sobotu v] LT'; + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'za %s', + past: 'před %s', + s: translate, + ss: translate, + m: translate, + mm: translate, + h: translate, + hh: translate, + d: translate, + dd: translate, + M: translate, + MM: translate, + y: translate, + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return cs; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/cv.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/cv.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Chuvash [cv] +//! author : Anatoly Mironov : https://github.com/mirontoli + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var cv = moment.defineLocale('cv', { + months: 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split( + '_' + ), + monthsShort: 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'), + weekdays: 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split( + '_' + ), + weekdaysShort: 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'), + weekdaysMin: 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD-MM-YYYY', + LL: 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]', + LLL: 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm', + LLLL: 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm', + }, + calendar: { + sameDay: '[Паян] LT [сехетре]', + nextDay: '[Ыран] LT [сехетре]', + lastDay: '[Ӗнер] LT [сехетре]', + nextWeek: '[Ҫитес] dddd LT [сехетре]', + lastWeek: '[Иртнӗ] dddd LT [сехетре]', + sameElse: 'L', + }, + relativeTime: { + future: function (output) { + var affix = /сехет$/i.exec(output) + ? 'рен' + : /ҫул$/i.exec(output) + ? 'тан' + : 'ран'; + return output + affix; + }, + past: '%s каялла', + s: 'пӗр-ик ҫеккунт', + ss: '%d ҫеккунт', + m: 'пӗр минут', + mm: '%d минут', + h: 'пӗр сехет', + hh: '%d сехет', + d: 'пӗр кун', + dd: '%d кун', + M: 'пӗр уйӑх', + MM: '%d уйӑх', + y: 'пӗр ҫул', + yy: '%d ҫул', + }, + dayOfMonthOrdinalParse: /\d{1,2}-мӗш/, + ordinal: '%d-мӗш', + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return cv; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/cy.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/cy.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Welsh [cy] +//! author : Robert Allen : https://github.com/robgallen +//! author : https://github.com/ryangreaves + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var cy = moment.defineLocale('cy', { + months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split( + '_' + ), + monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split( + '_' + ), + weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split( + '_' + ), + weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'), + weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'), + weekdaysParseExact: true, + // time formats are the same as en-gb + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Heddiw am] LT', + nextDay: '[Yfory am] LT', + nextWeek: 'dddd [am] LT', + lastDay: '[Ddoe am] LT', + lastWeek: 'dddd [diwethaf am] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'mewn %s', + past: '%s yn ôl', + s: 'ychydig eiliadau', + ss: '%d eiliad', + m: 'munud', + mm: '%d munud', + h: 'awr', + hh: '%d awr', + d: 'diwrnod', + dd: '%d diwrnod', + M: 'mis', + MM: '%d mis', + y: 'blwyddyn', + yy: '%d flynedd', + }, + dayOfMonthOrdinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/, + // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh + ordinal: function (number) { + var b = number, + output = '', + lookup = [ + '', + 'af', + 'il', + 'ydd', + 'ydd', + 'ed', + 'ed', + 'ed', + 'fed', + 'fed', + 'fed', // 1af to 10fed + 'eg', + 'fed', + 'eg', + 'eg', + 'fed', + 'eg', + 'eg', + 'fed', + 'eg', + 'fed', // 11eg to 20fed + ]; + if (b > 20) { + if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) { + output = 'fed'; // not 30ain, 70ain or 90ain + } else { + output = 'ain'; + } + } else if (b > 0) { + output = lookup[b]; + } + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return cy; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/da.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/da.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Danish [da] +//! author : Ulrik Nielsen : https://github.com/mrbase + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var da = moment.defineLocale('da', { + months: 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split( + '_' + ), + monthsShort: 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays: 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort: 'søn_man_tir_ons_tor_fre_lør'.split('_'), + weekdaysMin: 'sø_ma_ti_on_to_fr_lø'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY HH:mm', + LLLL: 'dddd [d.] D. MMMM YYYY [kl.] HH:mm', + }, + calendar: { + sameDay: '[i dag kl.] LT', + nextDay: '[i morgen kl.] LT', + nextWeek: 'på dddd [kl.] LT', + lastDay: '[i går kl.] LT', + lastWeek: '[i] dddd[s kl.] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'om %s', + past: '%s siden', + s: 'få sekunder', + ss: '%d sekunder', + m: 'et minut', + mm: '%d minutter', + h: 'en time', + hh: '%d timer', + d: 'en dag', + dd: '%d dage', + M: 'en måned', + MM: '%d måneder', + y: 'et år', + yy: '%d år', + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return da; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/de-at.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/de-at.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : German (Austria) [de-at] +//! author : lluchs : https://github.com/lluchs +//! author: Menelion Elensúle: https://github.com/Oire +//! author : Martin Groller : https://github.com/MadMG +//! author : Mikolaj Dadela : https://github.com/mik01aj + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + m: ['eine Minute', 'einer Minute'], + h: ['eine Stunde', 'einer Stunde'], + d: ['ein Tag', 'einem Tag'], + dd: [number + ' Tage', number + ' Tagen'], + w: ['eine Woche', 'einer Woche'], + M: ['ein Monat', 'einem Monat'], + MM: [number + ' Monate', number + ' Monaten'], + y: ['ein Jahr', 'einem Jahr'], + yy: [number + ' Jahre', number + ' Jahren'], + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + var deAt = moment.defineLocale('de-at', { + months: 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split( + '_' + ), + monthsShort: 'Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split( + '_' + ), + weekdaysShort: 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY HH:mm', + LLLL: 'dddd, D. MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]', + }, + relativeTime: { + future: 'in %s', + past: 'vor %s', + s: 'ein paar Sekunden', + ss: '%d Sekunden', + m: processRelativeTime, + mm: '%d Minuten', + h: processRelativeTime, + hh: '%d Stunden', + d: processRelativeTime, + dd: processRelativeTime, + w: processRelativeTime, + ww: '%d Wochen', + M: processRelativeTime, + MM: processRelativeTime, + y: processRelativeTime, + yy: processRelativeTime, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return deAt; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/de-ch.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/de-ch.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : German (Switzerland) [de-ch] +//! author : sschueller : https://github.com/sschueller + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + m: ['eine Minute', 'einer Minute'], + h: ['eine Stunde', 'einer Stunde'], + d: ['ein Tag', 'einem Tag'], + dd: [number + ' Tage', number + ' Tagen'], + w: ['eine Woche', 'einer Woche'], + M: ['ein Monat', 'einem Monat'], + MM: [number + ' Monate', number + ' Monaten'], + y: ['ein Jahr', 'einem Jahr'], + yy: [number + ' Jahre', number + ' Jahren'], + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + var deCh = moment.defineLocale('de-ch', { + months: 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split( + '_' + ), + monthsShort: 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split( + '_' + ), + weekdaysShort: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY HH:mm', + LLLL: 'dddd, D. MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]', + }, + relativeTime: { + future: 'in %s', + past: 'vor %s', + s: 'ein paar Sekunden', + ss: '%d Sekunden', + m: processRelativeTime, + mm: '%d Minuten', + h: processRelativeTime, + hh: '%d Stunden', + d: processRelativeTime, + dd: processRelativeTime, + w: processRelativeTime, + ww: '%d Wochen', + M: processRelativeTime, + MM: processRelativeTime, + y: processRelativeTime, + yy: processRelativeTime, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return deCh; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/de.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/de.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : German [de] +//! author : lluchs : https://github.com/lluchs +//! author: Menelion Elensúle: https://github.com/Oire +//! author : Mikolaj Dadela : https://github.com/mik01aj + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + m: ['eine Minute', 'einer Minute'], + h: ['eine Stunde', 'einer Stunde'], + d: ['ein Tag', 'einem Tag'], + dd: [number + ' Tage', number + ' Tagen'], + w: ['eine Woche', 'einer Woche'], + M: ['ein Monat', 'einem Monat'], + MM: [number + ' Monate', number + ' Monaten'], + y: ['ein Jahr', 'einem Jahr'], + yy: [number + ' Jahre', number + ' Jahren'], + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + var de = moment.defineLocale('de', { + months: 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split( + '_' + ), + monthsShort: 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split( + '_' + ), + weekdaysShort: 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY HH:mm', + LLLL: 'dddd, D. MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]', + }, + relativeTime: { + future: 'in %s', + past: 'vor %s', + s: 'ein paar Sekunden', + ss: '%d Sekunden', + m: processRelativeTime, + mm: '%d Minuten', + h: processRelativeTime, + hh: '%d Stunden', + d: processRelativeTime, + dd: processRelativeTime, + w: processRelativeTime, + ww: '%d Wochen', + M: processRelativeTime, + MM: processRelativeTime, + y: processRelativeTime, + yy: processRelativeTime, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return de; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/dv.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/dv.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Maldivian [dv] +//! author : Jawish Hameed : https://github.com/jawish + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var months = [ + 'ޖެނުއަރީ', + 'ފެބްރުއަރީ', + 'މާރިޗު', + 'އޭޕްރީލު', + 'މޭ', + 'ޖޫން', + 'ޖުލައި', + 'އޯގަސްޓު', + 'ސެޕްޓެމްބަރު', + 'އޮކްޓޯބަރު', + 'ނޮވެމްބަރު', + 'ޑިސެމްބަރު', + ], + weekdays = [ + 'އާދިއްތަ', + 'ހޯމަ', + 'އަންގާރަ', + 'ބުދަ', + 'ބުރާސްފަތި', + 'ހުކުރު', + 'ހޮނިހިރު', + ]; + + var dv = moment.defineLocale('dv', { + months: months, + monthsShort: months, + weekdays: weekdays, + weekdaysShort: weekdays, + weekdaysMin: 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'D/M/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + meridiemParse: /މކ|މފ/, + isPM: function (input) { + return 'މފ' === input; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'މކ'; + } else { + return 'މފ'; + } + }, + calendar: { + sameDay: '[މިއަދު] LT', + nextDay: '[މާދަމާ] LT', + nextWeek: 'dddd LT', + lastDay: '[އިއްޔެ] LT', + lastWeek: '[ފާއިތުވި] dddd LT', + sameElse: 'L', + }, + relativeTime: { + future: 'ތެރޭގައި %s', + past: 'ކުރިން %s', + s: 'ސިކުންތުކޮޅެއް', + ss: 'd% ސިކުންތު', + m: 'މިނިޓެއް', + mm: 'މިނިޓު %d', + h: 'ގަޑިއިރެއް', + hh: 'ގަޑިއިރު %d', + d: 'ދުވަހެއް', + dd: 'ދުވަސް %d', + M: 'މަހެއް', + MM: 'މަސް %d', + y: 'އަހަރެއް', + yy: 'އަހަރު %d', + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week: { + dow: 7, // Sunday is the first day of the week. + doy: 12, // The week that contains Jan 12th is the first week of the year. + }, + }); + + return dv; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/el.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/el.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Greek [el] +//! author : Aggelos Karalias : https://github.com/mehiel + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function isFunction(input) { + return ( + (typeof Function !== 'undefined' && input instanceof Function) || + Object.prototype.toString.call(input) === '[object Function]' + ); + } + + var el = moment.defineLocale('el', { + monthsNominativeEl: 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split( + '_' + ), + monthsGenitiveEl: 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split( + '_' + ), + months: function (momentToFormat, format) { + if (!momentToFormat) { + return this._monthsNominativeEl; + } else if ( + typeof format === 'string' && + /D/.test(format.substring(0, format.indexOf('MMMM'))) + ) { + // if there is a day number before 'MMMM' + return this._monthsGenitiveEl[momentToFormat.month()]; + } else { + return this._monthsNominativeEl[momentToFormat.month()]; + } + }, + monthsShort: 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'), + weekdays: 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split( + '_' + ), + weekdaysShort: 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'), + weekdaysMin: 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'), + meridiem: function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'μμ' : 'ΜΜ'; + } else { + return isLower ? 'πμ' : 'ΠΜ'; + } + }, + isPM: function (input) { + return (input + '').toLowerCase()[0] === 'μ'; + }, + meridiemParse: /[ΠΜ]\.?Μ?\.?/i, + longDateFormat: { + LT: 'h:mm A', + LTS: 'h:mm:ss A', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY h:mm A', + LLLL: 'dddd, D MMMM YYYY h:mm A', + }, + calendarEl: { + sameDay: '[Σήμερα {}] LT', + nextDay: '[Αύριο {}] LT', + nextWeek: 'dddd [{}] LT', + lastDay: '[Χθες {}] LT', + lastWeek: function () { + switch (this.day()) { + case 6: + return '[το προηγούμενο] dddd [{}] LT'; + default: + return '[την προηγούμενη] dddd [{}] LT'; + } + }, + sameElse: 'L', + }, + calendar: function (key, mom) { + var output = this._calendarEl[key], + hours = mom && mom.hours(); + if (isFunction(output)) { + output = output.apply(mom); + } + return output.replace('{}', hours % 12 === 1 ? 'στη' : 'στις'); + }, + relativeTime: { + future: 'σε %s', + past: '%s πριν', + s: 'λίγα δευτερόλεπτα', + ss: '%d δευτερόλεπτα', + m: 'ένα λεπτό', + mm: '%d λεπτά', + h: 'μία ώρα', + hh: '%d ώρες', + d: 'μία μέρα', + dd: '%d μέρες', + M: 'ένας μήνας', + MM: '%d μήνες', + y: 'ένας χρόνος', + yy: '%d χρόνια', + }, + dayOfMonthOrdinalParse: /\d{1,2}η/, + ordinal: '%dη', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4st is the first week of the year. + }, + }); + + return el; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/en-au.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/en-au.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : English (Australia) [en-au] +//! author : Jared Morse : https://github.com/jarcoal + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var enAu = moment.defineLocale('en-au', { + months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( + '_' + ), + weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat: { + LT: 'h:mm A', + LTS: 'h:mm:ss A', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY h:mm A', + LLLL: 'dddd, D MMMM YYYY h:mm A', + }, + calendar: { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'dddd [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: '[Last] dddd [at] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'in %s', + past: '%s ago', + s: 'a few seconds', + ss: '%d seconds', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years', + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return enAu; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/en-ca.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/en-ca.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : English (Canada) [en-ca] +//! author : Jonathan Abourbih : https://github.com/jonbca + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var enCa = moment.defineLocale('en-ca', { + months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( + '_' + ), + weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat: { + LT: 'h:mm A', + LTS: 'h:mm:ss A', + L: 'YYYY-MM-DD', + LL: 'MMMM D, YYYY', + LLL: 'MMMM D, YYYY h:mm A', + LLLL: 'dddd, MMMM D, YYYY h:mm A', + }, + calendar: { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'dddd [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: '[Last] dddd [at] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'in %s', + past: '%s ago', + s: 'a few seconds', + ss: '%d seconds', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years', + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + }); + + return enCa; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/en-gb.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/en-gb.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : English (United Kingdom) [en-gb] +//! author : Chris Gedrim : https://github.com/chrisgedrim + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var enGb = moment.defineLocale('en-gb', { + months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( + '_' + ), + weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'dddd [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: '[Last] dddd [at] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'in %s', + past: '%s ago', + s: 'a few seconds', + ss: '%d seconds', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years', + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return enGb; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/en-ie.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/en-ie.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : English (Ireland) [en-ie] +//! author : Chris Cartlidge : https://github.com/chriscartlidge + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var enIe = moment.defineLocale('en-ie', { + months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( + '_' + ), + weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'dddd [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: '[Last] dddd [at] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'in %s', + past: '%s ago', + s: 'a few seconds', + ss: '%d seconds', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years', + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return enIe; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/en-il.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/en-il.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : English (Israel) [en-il] +//! author : Chris Gedrim : https://github.com/chrisgedrim + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var enIl = moment.defineLocale('en-il', { + months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( + '_' + ), + weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'dddd [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: '[Last] dddd [at] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'in %s', + past: '%s ago', + s: 'a few seconds', + ss: '%d seconds', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years', + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + }); + + return enIl; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/en-in.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/en-in.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : English (India) [en-in] +//! author : Jatin Agrawal : https://github.com/jatinag22 + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var enIn = moment.defineLocale('en-in', { + months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( + '_' + ), + weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat: { + LT: 'h:mm A', + LTS: 'h:mm:ss A', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY h:mm A', + LLLL: 'dddd, D MMMM YYYY h:mm A', + }, + calendar: { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'dddd [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: '[Last] dddd [at] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'in %s', + past: '%s ago', + s: 'a few seconds', + ss: '%d seconds', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years', + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 1st is the first week of the year. + }, + }); + + return enIn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/en-nz.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/en-nz.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : English (New Zealand) [en-nz] +//! author : Luke McGregor : https://github.com/lukemcgregor + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var enNz = moment.defineLocale('en-nz', { + months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( + '_' + ), + weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat: { + LT: 'h:mm A', + LTS: 'h:mm:ss A', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY h:mm A', + LLLL: 'dddd, D MMMM YYYY h:mm A', + }, + calendar: { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'dddd [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: '[Last] dddd [at] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'in %s', + past: '%s ago', + s: 'a few seconds', + ss: '%d seconds', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years', + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return enNz; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/en-sg.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/en-sg.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : English (Singapore) [en-sg] +//! author : Matthew Castrillon-Madrigal : https://github.com/techdimension + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var enSg = moment.defineLocale('en-sg', { + months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( + '_' + ), + weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'dddd [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: '[Last] dddd [at] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'in %s', + past: '%s ago', + s: 'a few seconds', + ss: '%d seconds', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years', + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return enSg; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/eo.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/eo.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Esperanto [eo] +//! author : Colin Dean : https://github.com/colindean +//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia +//! comment : miestasmia corrected the translation by colindean +//! comment : Vivakvo corrected the translation by colindean and miestasmia + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var eo = moment.defineLocale('eo', { + months: 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split( + '_' + ), + monthsShort: 'jan_feb_mart_apr_maj_jun_jul_aŭg_sept_okt_nov_dec'.split('_'), + weekdays: 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'), + weekdaysShort: 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'), + weekdaysMin: 'di_lu_ma_me_ĵa_ve_sa'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY-MM-DD', + LL: '[la] D[-an de] MMMM, YYYY', + LLL: '[la] D[-an de] MMMM, YYYY HH:mm', + LLLL: 'dddd[n], [la] D[-an de] MMMM, YYYY HH:mm', + llll: 'ddd, [la] D[-an de] MMM, YYYY HH:mm', + }, + meridiemParse: /[ap]\.t\.m/i, + isPM: function (input) { + return input.charAt(0).toLowerCase() === 'p'; + }, + meridiem: function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'p.t.m.' : 'P.T.M.'; + } else { + return isLower ? 'a.t.m.' : 'A.T.M.'; + } + }, + calendar: { + sameDay: '[Hodiaŭ je] LT', + nextDay: '[Morgaŭ je] LT', + nextWeek: 'dddd[n je] LT', + lastDay: '[Hieraŭ je] LT', + lastWeek: '[pasintan] dddd[n je] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'post %s', + past: 'antaŭ %s', + s: 'kelkaj sekundoj', + ss: '%d sekundoj', + m: 'unu minuto', + mm: '%d minutoj', + h: 'unu horo', + hh: '%d horoj', + d: 'unu tago', //ne 'diurno', ĉar estas uzita por proksimumo + dd: '%d tagoj', + M: 'unu monato', + MM: '%d monatoj', + y: 'unu jaro', + yy: '%d jaroj', + }, + dayOfMonthOrdinalParse: /\d{1,2}a/, + ordinal: '%da', + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return eo; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/es-do.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/es-do.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Spanish (Dominican Republic) [es-do] + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split( + '_' + ), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'), + monthsParse = [ + /^ene/i, + /^feb/i, + /^mar/i, + /^abr/i, + /^may/i, + /^jun/i, + /^jul/i, + /^ago/i, + /^sep/i, + /^oct/i, + /^nov/i, + /^dic/i, + ], + monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + + var esDo = moment.defineLocale('es-do', { + months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split( + '_' + ), + monthsShort: function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'h:mm A', + LTS: 'h:mm:ss A', + L: 'DD/MM/YYYY', + LL: 'D [de] MMMM [de] YYYY', + LLL: 'D [de] MMMM [de] YYYY h:mm A', + LLLL: 'dddd, D [de] MMMM [de] YYYY h:mm A', + }, + calendar: { + sameDay: function () { + return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + nextDay: function () { + return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + nextWeek: function () { + return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + lastDay: function () { + return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + lastWeek: function () { + return ( + '[el] dddd [pasado a la' + + (this.hours() !== 1 ? 's' : '') + + '] LT' + ); + }, + sameElse: 'L', + }, + relativeTime: { + future: 'en %s', + past: 'hace %s', + s: 'unos segundos', + ss: '%d segundos', + m: 'un minuto', + mm: '%d minutos', + h: 'una hora', + hh: '%d horas', + d: 'un día', + dd: '%d días', + w: 'una semana', + ww: '%d semanas', + M: 'un mes', + MM: '%d meses', + y: 'un año', + yy: '%d años', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return esDo; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/es-mx.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/es-mx.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Spanish (Mexico) [es-mx] +//! author : JC Franco : https://github.com/jcfranco + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split( + '_' + ), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'), + monthsParse = [ + /^ene/i, + /^feb/i, + /^mar/i, + /^abr/i, + /^may/i, + /^jun/i, + /^jul/i, + /^ago/i, + /^sep/i, + /^oct/i, + /^nov/i, + /^dic/i, + ], + monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + + var esMx = moment.defineLocale('es-mx', { + months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split( + '_' + ), + monthsShort: function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D [de] MMMM [de] YYYY', + LLL: 'D [de] MMMM [de] YYYY H:mm', + LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm', + }, + calendar: { + sameDay: function () { + return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + nextDay: function () { + return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + nextWeek: function () { + return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + lastDay: function () { + return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + lastWeek: function () { + return ( + '[el] dddd [pasado a la' + + (this.hours() !== 1 ? 's' : '') + + '] LT' + ); + }, + sameElse: 'L', + }, + relativeTime: { + future: 'en %s', + past: 'hace %s', + s: 'unos segundos', + ss: '%d segundos', + m: 'un minuto', + mm: '%d minutos', + h: 'una hora', + hh: '%d horas', + d: 'un día', + dd: '%d días', + w: 'una semana', + ww: '%d semanas', + M: 'un mes', + MM: '%d meses', + y: 'un año', + yy: '%d años', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week: { + dow: 0, // Sunday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + invalidDate: 'Fecha inválida', + }); + + return esMx; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/es-us.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/es-us.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Spanish (United States) [es-us] +//! author : bustta : https://github.com/bustta +//! author : chrisrodz : https://github.com/chrisrodz + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split( + '_' + ), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'), + monthsParse = [ + /^ene/i, + /^feb/i, + /^mar/i, + /^abr/i, + /^may/i, + /^jun/i, + /^jul/i, + /^ago/i, + /^sep/i, + /^oct/i, + /^nov/i, + /^dic/i, + ], + monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + + var esUs = moment.defineLocale('es-us', { + months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split( + '_' + ), + monthsShort: function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'h:mm A', + LTS: 'h:mm:ss A', + L: 'MM/DD/YYYY', + LL: 'D [de] MMMM [de] YYYY', + LLL: 'D [de] MMMM [de] YYYY h:mm A', + LLLL: 'dddd, D [de] MMMM [de] YYYY h:mm A', + }, + calendar: { + sameDay: function () { + return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + nextDay: function () { + return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + nextWeek: function () { + return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + lastDay: function () { + return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + lastWeek: function () { + return ( + '[el] dddd [pasado a la' + + (this.hours() !== 1 ? 's' : '') + + '] LT' + ); + }, + sameElse: 'L', + }, + relativeTime: { + future: 'en %s', + past: 'hace %s', + s: 'unos segundos', + ss: '%d segundos', + m: 'un minuto', + mm: '%d minutos', + h: 'una hora', + hh: '%d horas', + d: 'un día', + dd: '%d días', + w: 'una semana', + ww: '%d semanas', + M: 'un mes', + MM: '%d meses', + y: 'un año', + yy: '%d años', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return esUs; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/es.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/es.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Spanish [es] +//! author : Julio Napurí : https://github.com/julionc + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split( + '_' + ), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'), + monthsParse = [ + /^ene/i, + /^feb/i, + /^mar/i, + /^abr/i, + /^may/i, + /^jun/i, + /^jul/i, + /^ago/i, + /^sep/i, + /^oct/i, + /^nov/i, + /^dic/i, + ], + monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + + var es = moment.defineLocale('es', { + months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split( + '_' + ), + monthsShort: function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D [de] MMMM [de] YYYY', + LLL: 'D [de] MMMM [de] YYYY H:mm', + LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm', + }, + calendar: { + sameDay: function () { + return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + nextDay: function () { + return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + nextWeek: function () { + return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + lastDay: function () { + return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT'; + }, + lastWeek: function () { + return ( + '[el] dddd [pasado a la' + + (this.hours() !== 1 ? 's' : '') + + '] LT' + ); + }, + sameElse: 'L', + }, + relativeTime: { + future: 'en %s', + past: 'hace %s', + s: 'unos segundos', + ss: '%d segundos', + m: 'un minuto', + mm: '%d minutos', + h: 'una hora', + hh: '%d horas', + d: 'un día', + dd: '%d días', + w: 'una semana', + ww: '%d semanas', + M: 'un mes', + MM: '%d meses', + y: 'un año', + yy: '%d años', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + invalidDate: 'Fecha inválida', + }); + + return es; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/et.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/et.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Estonian [et] +//! author : Henry Kehlmann : https://github.com/madhenry +//! improvements : Illimar Tambek : https://github.com/ragulka + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + s: ['mõne sekundi', 'mõni sekund', 'paar sekundit'], + ss: [number + 'sekundi', number + 'sekundit'], + m: ['ühe minuti', 'üks minut'], + mm: [number + ' minuti', number + ' minutit'], + h: ['ühe tunni', 'tund aega', 'üks tund'], + hh: [number + ' tunni', number + ' tundi'], + d: ['ühe päeva', 'üks päev'], + M: ['kuu aja', 'kuu aega', 'üks kuu'], + MM: [number + ' kuu', number + ' kuud'], + y: ['ühe aasta', 'aasta', 'üks aasta'], + yy: [number + ' aasta', number + ' aastat'], + }; + if (withoutSuffix) { + return format[key][2] ? format[key][2] : format[key][1]; + } + return isFuture ? format[key][0] : format[key][1]; + } + + var et = moment.defineLocale('et', { + months: 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split( + '_' + ), + monthsShort: 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split( + '_' + ), + weekdays: 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split( + '_' + ), + weekdaysShort: 'P_E_T_K_N_R_L'.split('_'), + weekdaysMin: 'P_E_T_K_N_R_L'.split('_'), + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm', + }, + calendar: { + sameDay: '[Täna,] LT', + nextDay: '[Homme,] LT', + nextWeek: '[Järgmine] dddd LT', + lastDay: '[Eile,] LT', + lastWeek: '[Eelmine] dddd LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s pärast', + past: '%s tagasi', + s: processRelativeTime, + ss: processRelativeTime, + m: processRelativeTime, + mm: processRelativeTime, + h: processRelativeTime, + hh: processRelativeTime, + d: processRelativeTime, + dd: '%d päeva', + M: processRelativeTime, + MM: processRelativeTime, + y: processRelativeTime, + yy: processRelativeTime, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return et; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/eu.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/eu.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Basque [eu] +//! author : Eneko Illarramendi : https://github.com/eillarra + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var eu = moment.defineLocale('eu', { + months: 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split( + '_' + ), + monthsShort: 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split( + '_' + ), + weekdaysShort: 'ig._al._ar._az._og._ol._lr.'.split('_'), + weekdaysMin: 'ig_al_ar_az_og_ol_lr'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY-MM-DD', + LL: 'YYYY[ko] MMMM[ren] D[a]', + LLL: 'YYYY[ko] MMMM[ren] D[a] HH:mm', + LLLL: 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm', + l: 'YYYY-M-D', + ll: 'YYYY[ko] MMM D[a]', + lll: 'YYYY[ko] MMM D[a] HH:mm', + llll: 'ddd, YYYY[ko] MMM D[a] HH:mm', + }, + calendar: { + sameDay: '[gaur] LT[etan]', + nextDay: '[bihar] LT[etan]', + nextWeek: 'dddd LT[etan]', + lastDay: '[atzo] LT[etan]', + lastWeek: '[aurreko] dddd LT[etan]', + sameElse: 'L', + }, + relativeTime: { + future: '%s barru', + past: 'duela %s', + s: 'segundo batzuk', + ss: '%d segundo', + m: 'minutu bat', + mm: '%d minutu', + h: 'ordu bat', + hh: '%d ordu', + d: 'egun bat', + dd: '%d egun', + M: 'hilabete bat', + MM: '%d hilabete', + y: 'urte bat', + yy: '%d urte', + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return eu; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/fa.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/fa.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Persian [fa] +//! author : Ebrahim Byagowi : https://github.com/ebraminio + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '۱', + 2: '۲', + 3: '۳', + 4: '۴', + 5: '۵', + 6: '۶', + 7: '۷', + 8: '۸', + 9: '۹', + 0: '۰', + }, + numberMap = { + '۱': '1', + '۲': '2', + '۳': '3', + '۴': '4', + '۵': '5', + '۶': '6', + '۷': '7', + '۸': '8', + '۹': '9', + '۰': '0', + }; + + var fa = moment.defineLocale('fa', { + months: 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split( + '_' + ), + monthsShort: 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split( + '_' + ), + weekdays: 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split( + '_' + ), + weekdaysShort: 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split( + '_' + ), + weekdaysMin: 'ی_د_س_چ_پ_ج_ش'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + meridiemParse: /قبل از ظهر|بعد از ظهر/, + isPM: function (input) { + return /بعد از ظهر/.test(input); + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'قبل از ظهر'; + } else { + return 'بعد از ظهر'; + } + }, + calendar: { + sameDay: '[امروز ساعت] LT', + nextDay: '[فردا ساعت] LT', + nextWeek: 'dddd [ساعت] LT', + lastDay: '[دیروز ساعت] LT', + lastWeek: 'dddd [پیش] [ساعت] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'در %s', + past: '%s پیش', + s: 'چند ثانیه', + ss: '%d ثانیه', + m: 'یک دقیقه', + mm: '%d دقیقه', + h: 'یک ساعت', + hh: '%d ساعت', + d: 'یک روز', + dd: '%d روز', + M: 'یک ماه', + MM: '%d ماه', + y: 'یک سال', + yy: '%d سال', + }, + preparse: function (string) { + return string + .replace(/[۰-۹]/g, function (match) { + return numberMap[match]; + }) + .replace(/،/g, ','); + }, + postformat: function (string) { + return string + .replace(/\d/g, function (match) { + return symbolMap[match]; + }) + .replace(/,/g, '،'); + }, + dayOfMonthOrdinalParse: /\d{1,2}م/, + ordinal: '%dم', + week: { + dow: 6, // Saturday is the first day of the week. + doy: 12, // The week that contains Jan 12th is the first week of the year. + }, + }); + + return fa; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/fi.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/fi.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Finnish [fi] +//! author : Tarmo Aidantausta : https://github.com/bleadof + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split( + ' ' + ), + numbersFuture = [ + 'nolla', + 'yhden', + 'kahden', + 'kolmen', + 'neljän', + 'viiden', + 'kuuden', + numbersPast[7], + numbersPast[8], + numbersPast[9], + ]; + function translate(number, withoutSuffix, key, isFuture) { + var result = ''; + switch (key) { + case 's': + return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; + case 'ss': + result = isFuture ? 'sekunnin' : 'sekuntia'; + break; + case 'm': + return isFuture ? 'minuutin' : 'minuutti'; + case 'mm': + result = isFuture ? 'minuutin' : 'minuuttia'; + break; + case 'h': + return isFuture ? 'tunnin' : 'tunti'; + case 'hh': + result = isFuture ? 'tunnin' : 'tuntia'; + break; + case 'd': + return isFuture ? 'päivän' : 'päivä'; + case 'dd': + result = isFuture ? 'päivän' : 'päivää'; + break; + case 'M': + return isFuture ? 'kuukauden' : 'kuukausi'; + case 'MM': + result = isFuture ? 'kuukauden' : 'kuukautta'; + break; + case 'y': + return isFuture ? 'vuoden' : 'vuosi'; + case 'yy': + result = isFuture ? 'vuoden' : 'vuotta'; + break; + } + result = verbalNumber(number, isFuture) + ' ' + result; + return result; + } + function verbalNumber(number, isFuture) { + return number < 10 + ? isFuture + ? numbersFuture[number] + : numbersPast[number] + : number; + } + + var fi = moment.defineLocale('fi', { + months: 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split( + '_' + ), + monthsShort: 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split( + '_' + ), + weekdays: 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split( + '_' + ), + weekdaysShort: 'su_ma_ti_ke_to_pe_la'.split('_'), + weekdaysMin: 'su_ma_ti_ke_to_pe_la'.split('_'), + longDateFormat: { + LT: 'HH.mm', + LTS: 'HH.mm.ss', + L: 'DD.MM.YYYY', + LL: 'Do MMMM[ta] YYYY', + LLL: 'Do MMMM[ta] YYYY, [klo] HH.mm', + LLLL: 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm', + l: 'D.M.YYYY', + ll: 'Do MMM YYYY', + lll: 'Do MMM YYYY, [klo] HH.mm', + llll: 'ddd, Do MMM YYYY, [klo] HH.mm', + }, + calendar: { + sameDay: '[tänään] [klo] LT', + nextDay: '[huomenna] [klo] LT', + nextWeek: 'dddd [klo] LT', + lastDay: '[eilen] [klo] LT', + lastWeek: '[viime] dddd[na] [klo] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s päästä', + past: '%s sitten', + s: translate, + ss: translate, + m: translate, + mm: translate, + h: translate, + hh: translate, + d: translate, + dd: translate, + M: translate, + MM: translate, + y: translate, + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return fi; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/fil.js": +/*!*************************************************!*\ + !*** ../eyes/node_modules/moment/locale/fil.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Filipino [fil] +//! author : Dan Hagman : https://github.com/hagmandan +//! author : Matthew Co : https://github.com/matthewdeeco + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var fil = moment.defineLocale('fil', { + months: 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split( + '_' + ), + monthsShort: 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'), + weekdays: 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split( + '_' + ), + weekdaysShort: 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'), + weekdaysMin: 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'MM/D/YYYY', + LL: 'MMMM D, YYYY', + LLL: 'MMMM D, YYYY HH:mm', + LLLL: 'dddd, MMMM DD, YYYY HH:mm', + }, + calendar: { + sameDay: 'LT [ngayong araw]', + nextDay: '[Bukas ng] LT', + nextWeek: 'LT [sa susunod na] dddd', + lastDay: 'LT [kahapon]', + lastWeek: 'LT [noong nakaraang] dddd', + sameElse: 'L', + }, + relativeTime: { + future: 'sa loob ng %s', + past: '%s ang nakalipas', + s: 'ilang segundo', + ss: '%d segundo', + m: 'isang minuto', + mm: '%d minuto', + h: 'isang oras', + hh: '%d oras', + d: 'isang araw', + dd: '%d araw', + M: 'isang buwan', + MM: '%d buwan', + y: 'isang taon', + yy: '%d taon', + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal: function (number) { + return number; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return fil; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/fo.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/fo.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Faroese [fo] +//! author : Ragnar Johannesen : https://github.com/ragnar123 +//! author : Kristian Sakarisson : https://github.com/sakarisson + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var fo = moment.defineLocale('fo', { + months: 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split( + '_' + ), + monthsShort: 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays: 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split( + '_' + ), + weekdaysShort: 'sun_mán_týs_mik_hós_frí_ley'.split('_'), + weekdaysMin: 'su_má_tý_mi_hó_fr_le'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D. MMMM, YYYY HH:mm', + }, + calendar: { + sameDay: '[Í dag kl.] LT', + nextDay: '[Í morgin kl.] LT', + nextWeek: 'dddd [kl.] LT', + lastDay: '[Í gjár kl.] LT', + lastWeek: '[síðstu] dddd [kl] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'um %s', + past: '%s síðani', + s: 'fá sekund', + ss: '%d sekundir', + m: 'ein minuttur', + mm: '%d minuttir', + h: 'ein tími', + hh: '%d tímar', + d: 'ein dagur', + dd: '%d dagar', + M: 'ein mánaður', + MM: '%d mánaðir', + y: 'eitt ár', + yy: '%d ár', + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return fo; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/fr-ca.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/fr-ca.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : French (Canada) [fr-ca] +//! author : Jonathan Abourbih : https://github.com/jonbca + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var frCa = moment.defineLocale('fr-ca', { + months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split( + '_' + ), + monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY-MM-DD', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Aujourd’hui à] LT', + nextDay: '[Demain à] LT', + nextWeek: 'dddd [à] LT', + lastDay: '[Hier à] LT', + lastWeek: 'dddd [dernier à] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'dans %s', + past: 'il y a %s', + s: 'quelques secondes', + ss: '%d secondes', + m: 'une minute', + mm: '%d minutes', + h: 'une heure', + hh: '%d heures', + d: 'un jour', + dd: '%d jours', + M: 'un mois', + MM: '%d mois', + y: 'un an', + yy: '%d ans', + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, + ordinal: function (number, period) { + switch (period) { + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'D': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); + + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + }, + }); + + return frCa; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/fr-ch.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/fr-ch.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : French (Switzerland) [fr-ch] +//! author : Gaspard Bucher : https://github.com/gaspard + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var frCh = moment.defineLocale('fr-ch', { + months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split( + '_' + ), + monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Aujourd’hui à] LT', + nextDay: '[Demain à] LT', + nextWeek: 'dddd [à] LT', + lastDay: '[Hier à] LT', + lastWeek: 'dddd [dernier à] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'dans %s', + past: 'il y a %s', + s: 'quelques secondes', + ss: '%d secondes', + m: 'une minute', + mm: '%d minutes', + h: 'une heure', + hh: '%d heures', + d: 'un jour', + dd: '%d jours', + M: 'un mois', + MM: '%d mois', + y: 'un an', + yy: '%d ans', + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, + ordinal: function (number, period) { + switch (period) { + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'D': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); + + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return frCh; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/fr.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/fr.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : French [fr] +//! author : John Fischer : https://github.com/jfroffice + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var monthsStrictRegex = /^(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i, + monthsShortStrictRegex = /(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?)/i, + monthsRegex = /(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?|janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i, + monthsParse = [ + /^janv/i, + /^févr/i, + /^mars/i, + /^avr/i, + /^mai/i, + /^juin/i, + /^juil/i, + /^août/i, + /^sept/i, + /^oct/i, + /^nov/i, + /^déc/i, + ]; + + var fr = moment.defineLocale('fr', { + months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split( + '_' + ), + monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split( + '_' + ), + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: monthsStrictRegex, + monthsShortStrictRegex: monthsShortStrictRegex, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Aujourd’hui à] LT', + nextDay: '[Demain à] LT', + nextWeek: 'dddd [à] LT', + lastDay: '[Hier à] LT', + lastWeek: 'dddd [dernier à] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'dans %s', + past: 'il y a %s', + s: 'quelques secondes', + ss: '%d secondes', + m: 'une minute', + mm: '%d minutes', + h: 'une heure', + hh: '%d heures', + d: 'un jour', + dd: '%d jours', + w: 'une semaine', + ww: '%d semaines', + M: 'un mois', + MM: '%d mois', + y: 'un an', + yy: '%d ans', + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|)/, + ordinal: function (number, period) { + switch (period) { + // TODO: Return 'e' when day of month > 1. Move this case inside + // block for masculine words below. + // See https://github.com/moment/moment/issues/3375 + case 'D': + return number + (number === 1 ? 'er' : ''); + + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); + + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return fr; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/fy.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/fy.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Frisian [fy] +//! author : Robin van der Vliet : https://github.com/robin0van0der0v + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split( + '_' + ), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split( + '_' + ); + + var fy = moment.defineLocale('fy', { + months: 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split( + '_' + ), + monthsShort: function (m, format) { + if (!m) { + return monthsShortWithDots; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + monthsParseExact: true, + weekdays: 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split( + '_' + ), + weekdaysShort: 'si._mo._ti._wo._to._fr._so.'.split('_'), + weekdaysMin: 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD-MM-YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[hjoed om] LT', + nextDay: '[moarn om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[juster om] LT', + lastWeek: '[ôfrûne] dddd [om] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'oer %s', + past: '%s lyn', + s: 'in pear sekonden', + ss: '%d sekonden', + m: 'ien minút', + mm: '%d minuten', + h: 'ien oere', + hh: '%d oeren', + d: 'ien dei', + dd: '%d dagen', + M: 'ien moanne', + MM: '%d moannen', + y: 'ien jier', + yy: '%d jierren', + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal: function (number) { + return ( + number + + (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de') + ); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return fy; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ga.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ga.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Irish or Irish Gaelic [ga] +//! author : André Silva : https://github.com/askpt + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var months = [ + 'Eanáir', + 'Feabhra', + 'Márta', + 'Aibreán', + 'Bealtaine', + 'Meitheamh', + 'Iúil', + 'Lúnasa', + 'Meán Fómhair', + 'Deireadh Fómhair', + 'Samhain', + 'Nollaig', + ], + monthsShort = [ + 'Ean', + 'Feabh', + 'Márt', + 'Aib', + 'Beal', + 'Meith', + 'Iúil', + 'Lún', + 'M.F.', + 'D.F.', + 'Samh', + 'Noll', + ], + weekdays = [ + 'Dé Domhnaigh', + 'Dé Luain', + 'Dé Máirt', + 'Dé Céadaoin', + 'Déardaoin', + 'Dé hAoine', + 'Dé Sathairn', + ], + weekdaysShort = ['Domh', 'Luan', 'Máirt', 'Céad', 'Déar', 'Aoine', 'Sath'], + weekdaysMin = ['Do', 'Lu', 'Má', 'Cé', 'Dé', 'A', 'Sa']; + + var ga = moment.defineLocale('ga', { + months: months, + monthsShort: monthsShort, + monthsParseExact: true, + weekdays: weekdays, + weekdaysShort: weekdaysShort, + weekdaysMin: weekdaysMin, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Inniu ag] LT', + nextDay: '[Amárach ag] LT', + nextWeek: 'dddd [ag] LT', + lastDay: '[Inné ag] LT', + lastWeek: 'dddd [seo caite] [ag] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'i %s', + past: '%s ó shin', + s: 'cúpla soicind', + ss: '%d soicind', + m: 'nóiméad', + mm: '%d nóiméad', + h: 'uair an chloig', + hh: '%d uair an chloig', + d: 'lá', + dd: '%d lá', + M: 'mí', + MM: '%d míonna', + y: 'bliain', + yy: '%d bliain', + }, + dayOfMonthOrdinalParse: /\d{1,2}(d|na|mh)/, + ordinal: function (number) { + var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return ga; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/gd.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/gd.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Scottish Gaelic [gd] +//! author : Jon Ashdown : https://github.com/jonashdown + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var months = [ + 'Am Faoilleach', + 'An Gearran', + 'Am Màrt', + 'An Giblean', + 'An Cèitean', + 'An t-Ògmhios', + 'An t-Iuchar', + 'An Lùnastal', + 'An t-Sultain', + 'An Dàmhair', + 'An t-Samhain', + 'An Dùbhlachd', + ], + monthsShort = [ + 'Faoi', + 'Gear', + 'Màrt', + 'Gibl', + 'Cèit', + 'Ògmh', + 'Iuch', + 'Lùn', + 'Sult', + 'Dàmh', + 'Samh', + 'Dùbh', + ], + weekdays = [ + 'Didòmhnaich', + 'Diluain', + 'Dimàirt', + 'Diciadain', + 'Diardaoin', + 'Dihaoine', + 'Disathairne', + ], + weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'], + weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa']; + + var gd = moment.defineLocale('gd', { + months: months, + monthsShort: monthsShort, + monthsParseExact: true, + weekdays: weekdays, + weekdaysShort: weekdaysShort, + weekdaysMin: weekdaysMin, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[An-diugh aig] LT', + nextDay: '[A-màireach aig] LT', + nextWeek: 'dddd [aig] LT', + lastDay: '[An-dè aig] LT', + lastWeek: 'dddd [seo chaidh] [aig] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'ann an %s', + past: 'bho chionn %s', + s: 'beagan diogan', + ss: '%d diogan', + m: 'mionaid', + mm: '%d mionaidean', + h: 'uair', + hh: '%d uairean', + d: 'latha', + dd: '%d latha', + M: 'mìos', + MM: '%d mìosan', + y: 'bliadhna', + yy: '%d bliadhna', + }, + dayOfMonthOrdinalParse: /\d{1,2}(d|na|mh)/, + ordinal: function (number) { + var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return gd; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/gl.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/gl.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Galician [gl] +//! author : Juan G. Hurtado : https://github.com/juanghurtado + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var gl = moment.defineLocale('gl', { + months: 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split( + '_' + ), + monthsShort: 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'), + weekdaysShort: 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'), + weekdaysMin: 'do_lu_ma_mé_xo_ve_sá'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D [de] MMMM [de] YYYY', + LLL: 'D [de] MMMM [de] YYYY H:mm', + LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm', + }, + calendar: { + sameDay: function () { + return '[hoxe ' + (this.hours() !== 1 ? 'ás' : 'á') + '] LT'; + }, + nextDay: function () { + return '[mañá ' + (this.hours() !== 1 ? 'ás' : 'á') + '] LT'; + }, + nextWeek: function () { + return 'dddd [' + (this.hours() !== 1 ? 'ás' : 'a') + '] LT'; + }, + lastDay: function () { + return '[onte ' + (this.hours() !== 1 ? 'á' : 'a') + '] LT'; + }, + lastWeek: function () { + return ( + '[o] dddd [pasado ' + (this.hours() !== 1 ? 'ás' : 'a') + '] LT' + ); + }, + sameElse: 'L', + }, + relativeTime: { + future: function (str) { + if (str.indexOf('un') === 0) { + return 'n' + str; + } + return 'en ' + str; + }, + past: 'hai %s', + s: 'uns segundos', + ss: '%d segundos', + m: 'un minuto', + mm: '%d minutos', + h: 'unha hora', + hh: '%d horas', + d: 'un día', + dd: '%d días', + M: 'un mes', + MM: '%d meses', + y: 'un ano', + yy: '%d anos', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return gl; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/gom-deva.js": +/*!******************************************************!*\ + !*** ../eyes/node_modules/moment/locale/gom-deva.js ***! + \******************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Konkani Devanagari script [gom-deva] +//! author : The Discoverer : https://github.com/WikiDiscoverer + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + s: ['थोडया सॅकंडांनी', 'थोडे सॅकंड'], + ss: [number + ' सॅकंडांनी', number + ' सॅकंड'], + m: ['एका मिणटान', 'एक मिनूट'], + mm: [number + ' मिणटांनी', number + ' मिणटां'], + h: ['एका वरान', 'एक वर'], + hh: [number + ' वरांनी', number + ' वरां'], + d: ['एका दिसान', 'एक दीस'], + dd: [number + ' दिसांनी', number + ' दीस'], + M: ['एका म्हयन्यान', 'एक म्हयनो'], + MM: [number + ' म्हयन्यानी', number + ' म्हयने'], + y: ['एका वर्सान', 'एक वर्स'], + yy: [number + ' वर्सांनी', number + ' वर्सां'], + }; + return isFuture ? format[key][0] : format[key][1]; + } + + var gomDeva = moment.defineLocale('gom-deva', { + months: { + standalone: 'जानेवारी_फेब्रुवारी_मार्च_एप्रील_मे_जून_जुलय_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split( + '_' + ), + format: 'जानेवारीच्या_फेब्रुवारीच्या_मार्चाच्या_एप्रीलाच्या_मेयाच्या_जूनाच्या_जुलयाच्या_ऑगस्टाच्या_सप्टेंबराच्या_ऑक्टोबराच्या_नोव्हेंबराच्या_डिसेंबराच्या'.split( + '_' + ), + isFormat: /MMMM(\s)+D[oD]?/, + }, + monthsShort: 'जाने._फेब्रु._मार्च_एप्री._मे_जून_जुल._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'आयतार_सोमार_मंगळार_बुधवार_बिरेस्तार_सुक्रार_शेनवार'.split('_'), + weekdaysShort: 'आयत._सोम._मंगळ._बुध._ब्रेस्त._सुक्र._शेन.'.split('_'), + weekdaysMin: 'आ_सो_मं_बु_ब्रे_सु_शे'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'A h:mm [वाजतां]', + LTS: 'A h:mm:ss [वाजतां]', + L: 'DD-MM-YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY A h:mm [वाजतां]', + LLLL: 'dddd, MMMM Do, YYYY, A h:mm [वाजतां]', + llll: 'ddd, D MMM YYYY, A h:mm [वाजतां]', + }, + calendar: { + sameDay: '[आयज] LT', + nextDay: '[फाल्यां] LT', + nextWeek: '[फुडलो] dddd[,] LT', + lastDay: '[काल] LT', + lastWeek: '[फाटलो] dddd[,] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s', + past: '%s आदीं', + s: processRelativeTime, + ss: processRelativeTime, + m: processRelativeTime, + mm: processRelativeTime, + h: processRelativeTime, + hh: processRelativeTime, + d: processRelativeTime, + dd: processRelativeTime, + M: processRelativeTime, + MM: processRelativeTime, + y: processRelativeTime, + yy: processRelativeTime, + }, + dayOfMonthOrdinalParse: /\d{1,2}(वेर)/, + ordinal: function (number, period) { + switch (period) { + // the ordinal 'वेर' only applies to day of the month + case 'D': + return number + 'वेर'; + default: + case 'M': + case 'Q': + case 'DDD': + case 'd': + case 'w': + case 'W': + return number; + } + }, + week: { + dow: 0, // Sunday is the first day of the week + doy: 3, // The week that contains Jan 4th is the first week of the year (7 + 0 - 4) + }, + meridiemParse: /राती|सकाळीं|दनपारां|सांजे/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'राती') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सकाळीं') { + return hour; + } else if (meridiem === 'दनपारां') { + return hour > 12 ? hour : hour + 12; + } else if (meridiem === 'सांजे') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'राती'; + } else if (hour < 12) { + return 'सकाळीं'; + } else if (hour < 16) { + return 'दनपारां'; + } else if (hour < 20) { + return 'सांजे'; + } else { + return 'राती'; + } + }, + }); + + return gomDeva; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/gom-latn.js": +/*!******************************************************!*\ + !*** ../eyes/node_modules/moment/locale/gom-latn.js ***! + \******************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Konkani Latin script [gom-latn] +//! author : The Discoverer : https://github.com/WikiDiscoverer + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + s: ['thoddea sekondamni', 'thodde sekond'], + ss: [number + ' sekondamni', number + ' sekond'], + m: ['eka mintan', 'ek minut'], + mm: [number + ' mintamni', number + ' mintam'], + h: ['eka voran', 'ek vor'], + hh: [number + ' voramni', number + ' voram'], + d: ['eka disan', 'ek dis'], + dd: [number + ' disamni', number + ' dis'], + M: ['eka mhoinean', 'ek mhoino'], + MM: [number + ' mhoineamni', number + ' mhoine'], + y: ['eka vorsan', 'ek voros'], + yy: [number + ' vorsamni', number + ' vorsam'], + }; + return isFuture ? format[key][0] : format[key][1]; + } + + var gomLatn = moment.defineLocale('gom-latn', { + months: { + standalone: 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split( + '_' + ), + format: 'Janerachea_Febrerachea_Marsachea_Abrilachea_Maiachea_Junachea_Julaiachea_Agostachea_Setembrachea_Otubrachea_Novembrachea_Dezembrachea'.split( + '_' + ), + isFormat: /MMMM(\s)+D[oD]?/, + }, + monthsShort: 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split( + '_' + ), + monthsParseExact: true, + weekdays: "Aitar_Somar_Mongllar_Budhvar_Birestar_Sukrar_Son'var".split('_'), + weekdaysShort: 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'), + weekdaysMin: 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'A h:mm [vazta]', + LTS: 'A h:mm:ss [vazta]', + L: 'DD-MM-YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY A h:mm [vazta]', + LLLL: 'dddd, MMMM Do, YYYY, A h:mm [vazta]', + llll: 'ddd, D MMM YYYY, A h:mm [vazta]', + }, + calendar: { + sameDay: '[Aiz] LT', + nextDay: '[Faleam] LT', + nextWeek: '[Fuddlo] dddd[,] LT', + lastDay: '[Kal] LT', + lastWeek: '[Fattlo] dddd[,] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s', + past: '%s adim', + s: processRelativeTime, + ss: processRelativeTime, + m: processRelativeTime, + mm: processRelativeTime, + h: processRelativeTime, + hh: processRelativeTime, + d: processRelativeTime, + dd: processRelativeTime, + M: processRelativeTime, + MM: processRelativeTime, + y: processRelativeTime, + yy: processRelativeTime, + }, + dayOfMonthOrdinalParse: /\d{1,2}(er)/, + ordinal: function (number, period) { + switch (period) { + // the ordinal 'er' only applies to day of the month + case 'D': + return number + 'er'; + default: + case 'M': + case 'Q': + case 'DDD': + case 'd': + case 'w': + case 'W': + return number; + } + }, + week: { + dow: 0, // Sunday is the first day of the week + doy: 3, // The week that contains Jan 4th is the first week of the year (7 + 0 - 4) + }, + meridiemParse: /rati|sokallim|donparam|sanje/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'rati') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'sokallim') { + return hour; + } else if (meridiem === 'donparam') { + return hour > 12 ? hour : hour + 12; + } else if (meridiem === 'sanje') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'rati'; + } else if (hour < 12) { + return 'sokallim'; + } else if (hour < 16) { + return 'donparam'; + } else if (hour < 20) { + return 'sanje'; + } else { + return 'rati'; + } + }, + }); + + return gomLatn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/gu.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/gu.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Gujarati [gu] +//! author : Kaushik Thanki : https://github.com/Kaushik1987 + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '૧', + 2: '૨', + 3: '૩', + 4: '૪', + 5: '૫', + 6: '૬', + 7: '૭', + 8: '૮', + 9: '૯', + 0: '૦', + }, + numberMap = { + '૧': '1', + '૨': '2', + '૩': '3', + '૪': '4', + '૫': '5', + '૬': '6', + '૭': '7', + '૮': '8', + '૯': '9', + '૦': '0', + }; + + var gu = moment.defineLocale('gu', { + months: 'જાન્યુઆરી_ફેબ્રુઆરી_માર્ચ_એપ્રિલ_મે_જૂન_જુલાઈ_ઑગસ્ટ_સપ્ટેમ્બર_ઑક્ટ્બર_નવેમ્બર_ડિસેમ્બર'.split( + '_' + ), + monthsShort: 'જાન્યુ._ફેબ્રુ._માર્ચ_એપ્રિ._મે_જૂન_જુલા._ઑગ._સપ્ટે._ઑક્ટ્._નવે._ડિસે.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'રવિવાર_સોમવાર_મંગળવાર_બુધ્વાર_ગુરુવાર_શુક્રવાર_શનિવાર'.split( + '_' + ), + weekdaysShort: 'રવિ_સોમ_મંગળ_બુધ્_ગુરુ_શુક્ર_શનિ'.split('_'), + weekdaysMin: 'ર_સો_મં_બુ_ગુ_શુ_શ'.split('_'), + longDateFormat: { + LT: 'A h:mm વાગ્યે', + LTS: 'A h:mm:ss વાગ્યે', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm વાગ્યે', + LLLL: 'dddd, D MMMM YYYY, A h:mm વાગ્યે', + }, + calendar: { + sameDay: '[આજ] LT', + nextDay: '[કાલે] LT', + nextWeek: 'dddd, LT', + lastDay: '[ગઇકાલે] LT', + lastWeek: '[પાછલા] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s મા', + past: '%s પહેલા', + s: 'અમુક પળો', + ss: '%d સેકંડ', + m: 'એક મિનિટ', + mm: '%d મિનિટ', + h: 'એક કલાક', + hh: '%d કલાક', + d: 'એક દિવસ', + dd: '%d દિવસ', + M: 'એક મહિનો', + MM: '%d મહિનો', + y: 'એક વર્ષ', + yy: '%d વર્ષ', + }, + preparse: function (string) { + return string.replace(/[૧૨૩૪૫૬૭૮૯૦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // Gujarati notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Gujarati. + meridiemParse: /રાત|બપોર|સવાર|સાંજ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'રાત') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'સવાર') { + return hour; + } else if (meridiem === 'બપોર') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'સાંજ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'રાત'; + } else if (hour < 10) { + return 'સવાર'; + } else if (hour < 17) { + return 'બપોર'; + } else if (hour < 20) { + return 'સાંજ'; + } else { + return 'રાત'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return gu; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/he.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/he.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Hebrew [he] +//! author : Tomer Cohen : https://github.com/tomer +//! author : Moshe Simantov : https://github.com/DevelopmentIL +//! author : Tal Ater : https://github.com/TalAter + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var he = moment.defineLocale('he', { + months: 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split( + '_' + ), + monthsShort: 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split( + '_' + ), + weekdays: 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'), + weekdaysShort: 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'), + weekdaysMin: 'א_ב_ג_ד_ה_ו_ש'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D [ב]MMMM YYYY', + LLL: 'D [ב]MMMM YYYY HH:mm', + LLLL: 'dddd, D [ב]MMMM YYYY HH:mm', + l: 'D/M/YYYY', + ll: 'D MMM YYYY', + lll: 'D MMM YYYY HH:mm', + llll: 'ddd, D MMM YYYY HH:mm', + }, + calendar: { + sameDay: '[היום ב־]LT', + nextDay: '[מחר ב־]LT', + nextWeek: 'dddd [בשעה] LT', + lastDay: '[אתמול ב־]LT', + lastWeek: '[ביום] dddd [האחרון בשעה] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'בעוד %s', + past: 'לפני %s', + s: 'מספר שניות', + ss: '%d שניות', + m: 'דקה', + mm: '%d דקות', + h: 'שעה', + hh: function (number) { + if (number === 2) { + return 'שעתיים'; + } + return number + ' שעות'; + }, + d: 'יום', + dd: function (number) { + if (number === 2) { + return 'יומיים'; + } + return number + ' ימים'; + }, + M: 'חודש', + MM: function (number) { + if (number === 2) { + return 'חודשיים'; + } + return number + ' חודשים'; + }, + y: 'שנה', + yy: function (number) { + if (number === 2) { + return 'שנתיים'; + } else if (number % 10 === 0 && number !== 10) { + return number + ' שנה'; + } + return number + ' שנים'; + }, + }, + meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i, + isPM: function (input) { + return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input); + }, + meridiem: function (hour, minute, isLower) { + if (hour < 5) { + return 'לפנות בוקר'; + } else if (hour < 10) { + return 'בבוקר'; + } else if (hour < 12) { + return isLower ? 'לפנה"צ' : 'לפני הצהריים'; + } else if (hour < 18) { + return isLower ? 'אחה"צ' : 'אחרי הצהריים'; + } else { + return 'בערב'; + } + }, + }); + + return he; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/hi.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/hi.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Hindi [hi] +//! author : Mayank Singhal : https://github.com/mayanksinghal + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '१', + 2: '२', + 3: '३', + 4: '४', + 5: '५', + 6: '६', + 7: '७', + 8: '८', + 9: '९', + 0: '०', + }, + numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0', + }, + monthsParse = [ + /^जन/i, + /^फ़र|फर/i, + /^मार्च/i, + /^अप्रै/i, + /^मई/i, + /^जून/i, + /^जुल/i, + /^अग/i, + /^सितं|सित/i, + /^अक्टू/i, + /^नव|नवं/i, + /^दिसं|दिस/i, + ], + shortMonthsParse = [ + /^जन/i, + /^फ़र/i, + /^मार्च/i, + /^अप्रै/i, + /^मई/i, + /^जून/i, + /^जुल/i, + /^अग/i, + /^सित/i, + /^अक्टू/i, + /^नव/i, + /^दिस/i, + ]; + + var hi = moment.defineLocale('hi', { + months: { + format: 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split( + '_' + ), + standalone: 'जनवरी_फरवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितंबर_अक्टूबर_नवंबर_दिसंबर'.split( + '_' + ), + }, + monthsShort: 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split( + '_' + ), + weekdays: 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort: 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin: 'र_सो_मं_बु_गु_शु_श'.split('_'), + longDateFormat: { + LT: 'A h:mm बजे', + LTS: 'A h:mm:ss बजे', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm बजे', + LLLL: 'dddd, D MMMM YYYY, A h:mm बजे', + }, + + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: shortMonthsParse, + + monthsRegex: /^(जनवरी|जन\.?|फ़रवरी|फरवरी|फ़र\.?|मार्च?|अप्रैल|अप्रै\.?|मई?|जून?|जुलाई|जुल\.?|अगस्त|अग\.?|सितम्बर|सितंबर|सित\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर|नव\.?|दिसम्बर|दिसंबर|दिस\.?)/i, + + monthsShortRegex: /^(जनवरी|जन\.?|फ़रवरी|फरवरी|फ़र\.?|मार्च?|अप्रैल|अप्रै\.?|मई?|जून?|जुलाई|जुल\.?|अगस्त|अग\.?|सितम्बर|सितंबर|सित\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर|नव\.?|दिसम्बर|दिसंबर|दिस\.?)/i, + + monthsStrictRegex: /^(जनवरी?|फ़रवरी|फरवरी?|मार्च?|अप्रैल?|मई?|जून?|जुलाई?|अगस्त?|सितम्बर|सितंबर|सित?\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर?|दिसम्बर|दिसंबर?)/i, + + monthsShortStrictRegex: /^(जन\.?|फ़र\.?|मार्च?|अप्रै\.?|मई?|जून?|जुल\.?|अग\.?|सित\.?|अक्टू\.?|नव\.?|दिस\.?)/i, + + calendar: { + sameDay: '[आज] LT', + nextDay: '[कल] LT', + nextWeek: 'dddd, LT', + lastDay: '[कल] LT', + lastWeek: '[पिछले] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s में', + past: '%s पहले', + s: 'कुछ ही क्षण', + ss: '%d सेकंड', + m: 'एक मिनट', + mm: '%d मिनट', + h: 'एक घंटा', + hh: '%d घंटे', + d: 'एक दिन', + dd: '%d दिन', + M: 'एक महीने', + MM: '%d महीने', + y: 'एक वर्ष', + yy: '%d वर्ष', + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // Hindi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi. + meridiemParse: /रात|सुबह|दोपहर|शाम/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सुबह') { + return hour; + } else if (meridiem === 'दोपहर') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'शाम') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'रात'; + } else if (hour < 10) { + return 'सुबह'; + } else if (hour < 17) { + return 'दोपहर'; + } else if (hour < 20) { + return 'शाम'; + } else { + return 'रात'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return hi; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/hr.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/hr.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Croatian [hr] +//! author : Bojan Marković : https://github.com/bmarkovic + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + if (number === 1) { + result += 'sekunda'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sekunde'; + } else { + result += 'sekundi'; + } + return result; + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } + } + + var hr = moment.defineLocale('hr', { + months: { + format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split( + '_' + ), + standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split( + '_' + ), + }, + monthsShort: 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split( + '_' + ), + weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'Do MMMM YYYY', + LLL: 'Do MMMM YYYY H:mm', + LLLL: 'dddd, Do MMMM YYYY H:mm', + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sutra u] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay: '[jučer u] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[prošlu] [nedjelju] [u] LT'; + case 3: + return '[prošlu] [srijedu] [u] LT'; + case 6: + return '[prošle] [subote] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prošli] dddd [u] LT'; + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'za %s', + past: 'prije %s', + s: 'par sekundi', + ss: translate, + m: translate, + mm: translate, + h: translate, + hh: translate, + d: 'dan', + dd: translate, + M: 'mjesec', + MM: translate, + y: 'godinu', + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return hr; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/hu.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/hu.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Hungarian [hu] +//! author : Adam Brunner : https://github.com/adambrunner +//! author : Peter Viszt : https://github.com/passatgt + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split( + ' ' + ); + function translate(number, withoutSuffix, key, isFuture) { + var num = number; + switch (key) { + case 's': + return isFuture || withoutSuffix + ? 'néhány másodperc' + : 'néhány másodperce'; + case 'ss': + return num + (isFuture || withoutSuffix) + ? ' másodperc' + : ' másodperce'; + case 'm': + return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'mm': + return num + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'h': + return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'hh': + return num + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'd': + return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'dd': + return num + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'M': + return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'MM': + return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'y': + return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve'); + case 'yy': + return num + (isFuture || withoutSuffix ? ' év' : ' éve'); + } + return ''; + } + function week(isFuture) { + return ( + (isFuture ? '' : '[múlt] ') + + '[' + + weekEndings[this.day()] + + '] LT[-kor]' + ); + } + + var hu = moment.defineLocale('hu', { + months: 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split( + '_' + ), + monthsShort: 'jan._feb._márc._ápr._máj._jún._júl._aug._szept._okt._nov._dec.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'), + weekdaysShort: 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'), + weekdaysMin: 'v_h_k_sze_cs_p_szo'.split('_'), + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'YYYY.MM.DD.', + LL: 'YYYY. MMMM D.', + LLL: 'YYYY. MMMM D. H:mm', + LLLL: 'YYYY. MMMM D., dddd H:mm', + }, + meridiemParse: /de|du/i, + isPM: function (input) { + return input.charAt(1).toLowerCase() === 'u'; + }, + meridiem: function (hours, minutes, isLower) { + if (hours < 12) { + return isLower === true ? 'de' : 'DE'; + } else { + return isLower === true ? 'du' : 'DU'; + } + }, + calendar: { + sameDay: '[ma] LT[-kor]', + nextDay: '[holnap] LT[-kor]', + nextWeek: function () { + return week.call(this, true); + }, + lastDay: '[tegnap] LT[-kor]', + lastWeek: function () { + return week.call(this, false); + }, + sameElse: 'L', + }, + relativeTime: { + future: '%s múlva', + past: '%s', + s: translate, + ss: translate, + m: translate, + mm: translate, + h: translate, + hh: translate, + d: translate, + dd: translate, + M: translate, + MM: translate, + y: translate, + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return hu; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/hy-am.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/hy-am.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Armenian [hy-am] +//! author : Armendarabyan : https://github.com/armendarabyan + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var hyAm = moment.defineLocale('hy-am', { + months: { + format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split( + '_' + ), + standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split( + '_' + ), + }, + monthsShort: 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'), + weekdays: 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split( + '_' + ), + weekdaysShort: 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + weekdaysMin: 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY թ.', + LLL: 'D MMMM YYYY թ., HH:mm', + LLLL: 'dddd, D MMMM YYYY թ., HH:mm', + }, + calendar: { + sameDay: '[այսօր] LT', + nextDay: '[վաղը] LT', + lastDay: '[երեկ] LT', + nextWeek: function () { + return 'dddd [օրը ժամը] LT'; + }, + lastWeek: function () { + return '[անցած] dddd [օրը ժամը] LT'; + }, + sameElse: 'L', + }, + relativeTime: { + future: '%s հետո', + past: '%s առաջ', + s: 'մի քանի վայրկյան', + ss: '%d վայրկյան', + m: 'րոպե', + mm: '%d րոպե', + h: 'ժամ', + hh: '%d ժամ', + d: 'օր', + dd: '%d օր', + M: 'ամիս', + MM: '%d ամիս', + y: 'տարի', + yy: '%d տարի', + }, + meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/, + isPM: function (input) { + return /^(ցերեկվա|երեկոյան)$/.test(input); + }, + meridiem: function (hour) { + if (hour < 4) { + return 'գիշերվա'; + } else if (hour < 12) { + return 'առավոտվա'; + } else if (hour < 17) { + return 'ցերեկվա'; + } else { + return 'երեկոյան'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/, + ordinal: function (number, period) { + switch (period) { + case 'DDD': + case 'w': + case 'W': + case 'DDDo': + if (number === 1) { + return number + '-ին'; + } + return number + '-րդ'; + default: + return number; + } + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return hyAm; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/id.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/id.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Indonesian [id] +//! author : Mohammad Satrio Utomo : https://github.com/tyok +//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var id = moment.defineLocale('id', { + months: 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des'.split('_'), + weekdays: 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'), + weekdaysShort: 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'), + weekdaysMin: 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat: { + LT: 'HH.mm', + LTS: 'HH.mm.ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY [pukul] HH.mm', + LLLL: 'dddd, D MMMM YYYY [pukul] HH.mm', + }, + meridiemParse: /pagi|siang|sore|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'siang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sore' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem: function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'siang'; + } else if (hours < 19) { + return 'sore'; + } else { + return 'malam'; + } + }, + calendar: { + sameDay: '[Hari ini pukul] LT', + nextDay: '[Besok pukul] LT', + nextWeek: 'dddd [pukul] LT', + lastDay: '[Kemarin pukul] LT', + lastWeek: 'dddd [lalu pukul] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'dalam %s', + past: '%s yang lalu', + s: 'beberapa detik', + ss: '%d detik', + m: 'semenit', + mm: '%d menit', + h: 'sejam', + hh: '%d jam', + d: 'sehari', + dd: '%d hari', + M: 'sebulan', + MM: '%d bulan', + y: 'setahun', + yy: '%d tahun', + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return id; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/is.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/is.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Icelandic [is] +//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function plural(n) { + if (n % 100 === 11) { + return true; + } else if (n % 10 === 1) { + return false; + } + return true; + } + function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': + return withoutSuffix || isFuture + ? 'nokkrar sekúndur' + : 'nokkrum sekúndum'; + case 'ss': + if (plural(number)) { + return ( + result + + (withoutSuffix || isFuture ? 'sekúndur' : 'sekúndum') + ); + } + return result + 'sekúnda'; + case 'm': + return withoutSuffix ? 'mínúta' : 'mínútu'; + case 'mm': + if (plural(number)) { + return ( + result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum') + ); + } else if (withoutSuffix) { + return result + 'mínúta'; + } + return result + 'mínútu'; + case 'hh': + if (plural(number)) { + return ( + result + + (withoutSuffix || isFuture + ? 'klukkustundir' + : 'klukkustundum') + ); + } + return result + 'klukkustund'; + case 'd': + if (withoutSuffix) { + return 'dagur'; + } + return isFuture ? 'dag' : 'degi'; + case 'dd': + if (plural(number)) { + if (withoutSuffix) { + return result + 'dagar'; + } + return result + (isFuture ? 'daga' : 'dögum'); + } else if (withoutSuffix) { + return result + 'dagur'; + } + return result + (isFuture ? 'dag' : 'degi'); + case 'M': + if (withoutSuffix) { + return 'mánuður'; + } + return isFuture ? 'mánuð' : 'mánuði'; + case 'MM': + if (plural(number)) { + if (withoutSuffix) { + return result + 'mánuðir'; + } + return result + (isFuture ? 'mánuði' : 'mánuðum'); + } else if (withoutSuffix) { + return result + 'mánuður'; + } + return result + (isFuture ? 'mánuð' : 'mánuði'); + case 'y': + return withoutSuffix || isFuture ? 'ár' : 'ári'; + case 'yy': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'ár' : 'árum'); + } + return result + (withoutSuffix || isFuture ? 'ár' : 'ári'); + } + } + + var is = moment.defineLocale('is', { + months: 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split( + '_' + ), + monthsShort: 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'), + weekdays: 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split( + '_' + ), + weekdaysShort: 'sun_mán_þri_mið_fim_fös_lau'.split('_'), + weekdaysMin: 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'), + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY [kl.] H:mm', + LLLL: 'dddd, D. MMMM YYYY [kl.] H:mm', + }, + calendar: { + sameDay: '[í dag kl.] LT', + nextDay: '[á morgun kl.] LT', + nextWeek: 'dddd [kl.] LT', + lastDay: '[í gær kl.] LT', + lastWeek: '[síðasta] dddd [kl.] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'eftir %s', + past: 'fyrir %s síðan', + s: translate, + ss: translate, + m: translate, + mm: translate, + h: 'klukkustund', + hh: translate, + d: translate, + dd: translate, + M: translate, + MM: translate, + y: translate, + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return is; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/it-ch.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/it-ch.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Italian (Switzerland) [it-ch] +//! author : xfh : https://github.com/xfh + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var itCh = moment.defineLocale('it-ch', { + months: 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split( + '_' + ), + monthsShort: 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), + weekdays: 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split( + '_' + ), + weekdaysShort: 'dom_lun_mar_mer_gio_ven_sab'.split('_'), + weekdaysMin: 'do_lu_ma_me_gi_ve_sa'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Oggi alle] LT', + nextDay: '[Domani alle] LT', + nextWeek: 'dddd [alle] LT', + lastDay: '[Ieri alle] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[la scorsa] dddd [alle] LT'; + default: + return '[lo scorso] dddd [alle] LT'; + } + }, + sameElse: 'L', + }, + relativeTime: { + future: function (s) { + return (/^[0-9].+$/.test(s) ? 'tra' : 'in') + ' ' + s; + }, + past: '%s fa', + s: 'alcuni secondi', + ss: '%d secondi', + m: 'un minuto', + mm: '%d minuti', + h: "un'ora", + hh: '%d ore', + d: 'un giorno', + dd: '%d giorni', + M: 'un mese', + MM: '%d mesi', + y: 'un anno', + yy: '%d anni', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return itCh; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/it.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/it.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Italian [it] +//! author : Lorenzo : https://github.com/aliem +//! author: Mattia Larentis: https://github.com/nostalgiaz +//! author: Marco : https://github.com/Manfre98 + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var it = moment.defineLocale('it', { + months: 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split( + '_' + ), + monthsShort: 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), + weekdays: 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split( + '_' + ), + weekdaysShort: 'dom_lun_mar_mer_gio_ven_sab'.split('_'), + weekdaysMin: 'do_lu_ma_me_gi_ve_sa'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: function () { + return ( + '[Oggi a' + + (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") + + ']LT' + ); + }, + nextDay: function () { + return ( + '[Domani a' + + (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") + + ']LT' + ); + }, + nextWeek: function () { + return ( + 'dddd [a' + + (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") + + ']LT' + ); + }, + lastDay: function () { + return ( + '[Ieri a' + + (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") + + ']LT' + ); + }, + lastWeek: function () { + switch (this.day()) { + case 0: + return ( + '[La scorsa] dddd [a' + + (this.hours() > 1 + ? 'lle ' + : this.hours() === 0 + ? ' ' + : "ll'") + + ']LT' + ); + default: + return ( + '[Lo scorso] dddd [a' + + (this.hours() > 1 + ? 'lle ' + : this.hours() === 0 + ? ' ' + : "ll'") + + ']LT' + ); + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'tra %s', + past: '%s fa', + s: 'alcuni secondi', + ss: '%d secondi', + m: 'un minuto', + mm: '%d minuti', + h: "un'ora", + hh: '%d ore', + d: 'un giorno', + dd: '%d giorni', + w: 'una settimana', + ww: '%d settimane', + M: 'un mese', + MM: '%d mesi', + y: 'un anno', + yy: '%d anni', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return it; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ja.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ja.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Japanese [ja] +//! author : LI Long : https://github.com/baryon + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var ja = moment.defineLocale('ja', { + eras: [ + { + since: '2019-05-01', + offset: 1, + name: '令和', + narrow: '㋿', + abbr: 'R', + }, + { + since: '1989-01-08', + until: '2019-04-30', + offset: 1, + name: '平成', + narrow: '㍻', + abbr: 'H', + }, + { + since: '1926-12-25', + until: '1989-01-07', + offset: 1, + name: '昭和', + narrow: '㍼', + abbr: 'S', + }, + { + since: '1912-07-30', + until: '1926-12-24', + offset: 1, + name: '大正', + narrow: '㍽', + abbr: 'T', + }, + { + since: '1873-01-01', + until: '1912-07-29', + offset: 6, + name: '明治', + narrow: '㍾', + abbr: 'M', + }, + { + since: '0001-01-01', + until: '1873-12-31', + offset: 1, + name: '西暦', + narrow: 'AD', + abbr: 'AD', + }, + { + since: '0000-12-31', + until: -Infinity, + offset: 1, + name: '紀元前', + narrow: 'BC', + abbr: 'BC', + }, + ], + eraYearOrdinalRegex: /(元|\d+)年/, + eraYearOrdinalParse: function (input, match) { + return match[1] === '元' ? 1 : parseInt(match[1] || input, 10); + }, + months: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split( + '_' + ), + weekdays: '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'), + weekdaysShort: '日_月_火_水_木_金_土'.split('_'), + weekdaysMin: '日_月_火_水_木_金_土'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY/MM/DD', + LL: 'YYYY年M月D日', + LLL: 'YYYY年M月D日 HH:mm', + LLLL: 'YYYY年M月D日 dddd HH:mm', + l: 'YYYY/MM/DD', + ll: 'YYYY年M月D日', + lll: 'YYYY年M月D日 HH:mm', + llll: 'YYYY年M月D日(ddd) HH:mm', + }, + meridiemParse: /午前|午後/i, + isPM: function (input) { + return input === '午後'; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return '午前'; + } else { + return '午後'; + } + }, + calendar: { + sameDay: '[今日] LT', + nextDay: '[明日] LT', + nextWeek: function (now) { + if (now.week() !== this.week()) { + return '[来週]dddd LT'; + } else { + return 'dddd LT'; + } + }, + lastDay: '[昨日] LT', + lastWeek: function (now) { + if (this.week() !== now.week()) { + return '[先週]dddd LT'; + } else { + return 'dddd LT'; + } + }, + sameElse: 'L', + }, + dayOfMonthOrdinalParse: /\d{1,2}日/, + ordinal: function (number, period) { + switch (period) { + case 'y': + return number === 1 ? '元年' : number + '年'; + case 'd': + case 'D': + case 'DDD': + return number + '日'; + default: + return number; + } + }, + relativeTime: { + future: '%s後', + past: '%s前', + s: '数秒', + ss: '%d秒', + m: '1分', + mm: '%d分', + h: '1時間', + hh: '%d時間', + d: '1日', + dd: '%d日', + M: '1ヶ月', + MM: '%dヶ月', + y: '1年', + yy: '%d年', + }, + }); + + return ja; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/jv.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/jv.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Javanese [jv] +//! author : Rony Lantip : https://github.com/lantip +//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var jv = moment.defineLocale('jv', { + months: 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'), + weekdays: 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'), + weekdaysShort: 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'), + weekdaysMin: 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'), + longDateFormat: { + LT: 'HH.mm', + LTS: 'HH.mm.ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY [pukul] HH.mm', + LLLL: 'dddd, D MMMM YYYY [pukul] HH.mm', + }, + meridiemParse: /enjing|siyang|sonten|ndalu/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'enjing') { + return hour; + } else if (meridiem === 'siyang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sonten' || meridiem === 'ndalu') { + return hour + 12; + } + }, + meridiem: function (hours, minutes, isLower) { + if (hours < 11) { + return 'enjing'; + } else if (hours < 15) { + return 'siyang'; + } else if (hours < 19) { + return 'sonten'; + } else { + return 'ndalu'; + } + }, + calendar: { + sameDay: '[Dinten puniko pukul] LT', + nextDay: '[Mbenjang pukul] LT', + nextWeek: 'dddd [pukul] LT', + lastDay: '[Kala wingi pukul] LT', + lastWeek: 'dddd [kepengker pukul] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'wonten ing %s', + past: '%s ingkang kepengker', + s: 'sawetawis detik', + ss: '%d detik', + m: 'setunggal menit', + mm: '%d menit', + h: 'setunggal jam', + hh: '%d jam', + d: 'sedinten', + dd: '%d dinten', + M: 'sewulan', + MM: '%d wulan', + y: 'setaun', + yy: '%d taun', + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return jv; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ka.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ka.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Georgian [ka] +//! author : Irakli Janiashvili : https://github.com/IrakliJani + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var ka = moment.defineLocale('ka', { + months: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split( + '_' + ), + monthsShort: 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'), + weekdays: { + standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split( + '_' + ), + format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split( + '_' + ), + isFormat: /(წინა|შემდეგ)/, + }, + weekdaysShort: 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'), + weekdaysMin: 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[დღეს] LT[-ზე]', + nextDay: '[ხვალ] LT[-ზე]', + lastDay: '[გუშინ] LT[-ზე]', + nextWeek: '[შემდეგ] dddd LT[-ზე]', + lastWeek: '[წინა] dddd LT-ზე', + sameElse: 'L', + }, + relativeTime: { + future: function (s) { + return s.replace(/(წამ|წუთ|საათ|წელ|დღ|თვ)(ი|ე)/, function ( + $0, + $1, + $2 + ) { + return $2 === 'ი' ? $1 + 'ში' : $1 + $2 + 'ში'; + }); + }, + past: function (s) { + if (/(წამი|წუთი|საათი|დღე|თვე)/.test(s)) { + return s.replace(/(ი|ე)$/, 'ის წინ'); + } + if (/წელი/.test(s)) { + return s.replace(/წელი$/, 'წლის წინ'); + } + return s; + }, + s: 'რამდენიმე წამი', + ss: '%d წამი', + m: 'წუთი', + mm: '%d წუთი', + h: 'საათი', + hh: '%d საათი', + d: 'დღე', + dd: '%d დღე', + M: 'თვე', + MM: '%d თვე', + y: 'წელი', + yy: '%d წელი', + }, + dayOfMonthOrdinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/, + ordinal: function (number) { + if (number === 0) { + return number; + } + if (number === 1) { + return number + '-ლი'; + } + if ( + number < 20 || + (number <= 100 && number % 20 === 0) || + number % 100 === 0 + ) { + return 'მე-' + number; + } + return number + '-ე'; + }, + week: { + dow: 1, + doy: 7, + }, + }); + + return ka; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/kk.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/kk.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Kazakh [kk] +//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var suffixes = { + 0: '-ші', + 1: '-ші', + 2: '-ші', + 3: '-ші', + 4: '-ші', + 5: '-ші', + 6: '-шы', + 7: '-ші', + 8: '-ші', + 9: '-шы', + 10: '-шы', + 20: '-шы', + 30: '-шы', + 40: '-шы', + 50: '-ші', + 60: '-шы', + 70: '-ші', + 80: '-ші', + 90: '-шы', + 100: '-ші', + }; + + var kk = moment.defineLocale('kk', { + months: 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split( + '_' + ), + monthsShort: 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'), + weekdays: 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split( + '_' + ), + weekdaysShort: 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'), + weekdaysMin: 'жк_дй_сй_ср_бй_жм_сн'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Бүгін сағат] LT', + nextDay: '[Ертең сағат] LT', + nextWeek: 'dddd [сағат] LT', + lastDay: '[Кеше сағат] LT', + lastWeek: '[Өткен аптаның] dddd [сағат] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s ішінде', + past: '%s бұрын', + s: 'бірнеше секунд', + ss: '%d секунд', + m: 'бір минут', + mm: '%d минут', + h: 'бір сағат', + hh: '%d сағат', + d: 'бір күн', + dd: '%d күн', + M: 'бір ай', + MM: '%d ай', + y: 'бір жыл', + yy: '%d жыл', + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ші|шы)/, + ordinal: function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes[number] || suffixes[a] || suffixes[b]); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return kk; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/km.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/km.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Cambodian [km] +//! author : Kruy Vanna : https://github.com/kruyvanna + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '១', + 2: '២', + 3: '៣', + 4: '៤', + 5: '៥', + 6: '៦', + 7: '៧', + 8: '៨', + 9: '៩', + 0: '០', + }, + numberMap = { + '១': '1', + '២': '2', + '៣': '3', + '៤': '4', + '៥': '5', + '៦': '6', + '៧': '7', + '៨': '8', + '៩': '9', + '០': '0', + }; + + var km = moment.defineLocale('km', { + months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( + '_' + ), + monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( + '_' + ), + weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), + weekdaysShort: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), + weekdaysMin: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + meridiemParse: /ព្រឹក|ល្ងាច/, + isPM: function (input) { + return input === 'ល្ងាច'; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ព្រឹក'; + } else { + return 'ល្ងាច'; + } + }, + calendar: { + sameDay: '[ថ្ងៃនេះ ម៉ោង] LT', + nextDay: '[ស្អែក ម៉ោង] LT', + nextWeek: 'dddd [ម៉ោង] LT', + lastDay: '[ម្សិលមិញ ម៉ោង] LT', + lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%sទៀត', + past: '%sមុន', + s: 'ប៉ុន្មានវិនាទី', + ss: '%d វិនាទី', + m: 'មួយនាទី', + mm: '%d នាទី', + h: 'មួយម៉ោង', + hh: '%d ម៉ោង', + d: 'មួយថ្ងៃ', + dd: '%d ថ្ងៃ', + M: 'មួយខែ', + MM: '%d ខែ', + y: 'មួយឆ្នាំ', + yy: '%d ឆ្នាំ', + }, + dayOfMonthOrdinalParse: /ទី\d{1,2}/, + ordinal: 'ទី%d', + preparse: function (string) { + return string.replace(/[១២៣៤៥៦៧៨៩០]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return km; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/kn.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/kn.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Kannada [kn] +//! author : Rajeev Naik : https://github.com/rajeevnaikte + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '೧', + 2: '೨', + 3: '೩', + 4: '೪', + 5: '೫', + 6: '೬', + 7: '೭', + 8: '೮', + 9: '೯', + 0: '೦', + }, + numberMap = { + '೧': '1', + '೨': '2', + '೩': '3', + '೪': '4', + '೫': '5', + '೬': '6', + '೭': '7', + '೮': '8', + '೯': '9', + '೦': '0', + }; + + var kn = moment.defineLocale('kn', { + months: 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split( + '_' + ), + monthsShort: 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂ_ಅಕ್ಟೋ_ನವೆಂ_ಡಿಸೆಂ'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split( + '_' + ), + weekdaysShort: 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'), + weekdaysMin: 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'), + longDateFormat: { + LT: 'A h:mm', + LTS: 'A h:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm', + LLLL: 'dddd, D MMMM YYYY, A h:mm', + }, + calendar: { + sameDay: '[ಇಂದು] LT', + nextDay: '[ನಾಳೆ] LT', + nextWeek: 'dddd, LT', + lastDay: '[ನಿನ್ನೆ] LT', + lastWeek: '[ಕೊನೆಯ] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s ನಂತರ', + past: '%s ಹಿಂದೆ', + s: 'ಕೆಲವು ಕ್ಷಣಗಳು', + ss: '%d ಸೆಕೆಂಡುಗಳು', + m: 'ಒಂದು ನಿಮಿಷ', + mm: '%d ನಿಮಿಷ', + h: 'ಒಂದು ಗಂಟೆ', + hh: '%d ಗಂಟೆ', + d: 'ಒಂದು ದಿನ', + dd: '%d ದಿನ', + M: 'ಒಂದು ತಿಂಗಳು', + MM: '%d ತಿಂಗಳು', + y: 'ಒಂದು ವರ್ಷ', + yy: '%d ವರ್ಷ', + }, + preparse: function (string) { + return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ರಾತ್ರಿ') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') { + return hour; + } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'ಸಂಜೆ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'ರಾತ್ರಿ'; + } else if (hour < 10) { + return 'ಬೆಳಿಗ್ಗೆ'; + } else if (hour < 17) { + return 'ಮಧ್ಯಾಹ್ನ'; + } else if (hour < 20) { + return 'ಸಂಜೆ'; + } else { + return 'ರಾತ್ರಿ'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}(ನೇ)/, + ordinal: function (number) { + return number + 'ನೇ'; + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return kn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ko.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ko.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Korean [ko] +//! author : Kyungwook, Park : https://github.com/kyungw00k +//! author : Jeeeyul Lee + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var ko = moment.defineLocale('ko', { + months: '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + monthsShort: '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split( + '_' + ), + weekdays: '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'), + weekdaysShort: '일_월_화_수_목_금_토'.split('_'), + weekdaysMin: '일_월_화_수_목_금_토'.split('_'), + longDateFormat: { + LT: 'A h:mm', + LTS: 'A h:mm:ss', + L: 'YYYY.MM.DD.', + LL: 'YYYY년 MMMM D일', + LLL: 'YYYY년 MMMM D일 A h:mm', + LLLL: 'YYYY년 MMMM D일 dddd A h:mm', + l: 'YYYY.MM.DD.', + ll: 'YYYY년 MMMM D일', + lll: 'YYYY년 MMMM D일 A h:mm', + llll: 'YYYY년 MMMM D일 dddd A h:mm', + }, + calendar: { + sameDay: '오늘 LT', + nextDay: '내일 LT', + nextWeek: 'dddd LT', + lastDay: '어제 LT', + lastWeek: '지난주 dddd LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s 후', + past: '%s 전', + s: '몇 초', + ss: '%d초', + m: '1분', + mm: '%d분', + h: '한 시간', + hh: '%d시간', + d: '하루', + dd: '%d일', + M: '한 달', + MM: '%d달', + y: '일 년', + yy: '%d년', + }, + dayOfMonthOrdinalParse: /\d{1,2}(일|월|주)/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '일'; + case 'M': + return number + '월'; + case 'w': + case 'W': + return number + '주'; + default: + return number; + } + }, + meridiemParse: /오전|오후/, + isPM: function (token) { + return token === '오후'; + }, + meridiem: function (hour, minute, isUpper) { + return hour < 12 ? '오전' : '오후'; + }, + }); + + return ko; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ku.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ku.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Kurdish [ku] +//! author : Shahram Mebashar : https://github.com/ShahramMebashar + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '١', + 2: '٢', + 3: '٣', + 4: '٤', + 5: '٥', + 6: '٦', + 7: '٧', + 8: '٨', + 9: '٩', + 0: '٠', + }, + numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0', + }, + months = [ + 'کانونی دووەم', + 'شوبات', + 'ئازار', + 'نیسان', + 'ئایار', + 'حوزەیران', + 'تەمموز', + 'ئاب', + 'ئەیلوول', + 'تشرینی یەكەم', + 'تشرینی دووەم', + 'كانونی یەکەم', + ]; + + var ku = moment.defineLocale('ku', { + months: months, + monthsShort: months, + weekdays: 'یه‌كشه‌ممه‌_دووشه‌ممه‌_سێشه‌ممه‌_چوارشه‌ممه‌_پێنجشه‌ممه‌_هه‌ینی_شه‌ممه‌'.split( + '_' + ), + weekdaysShort: 'یه‌كشه‌م_دووشه‌م_سێشه‌م_چوارشه‌م_پێنجشه‌م_هه‌ینی_شه‌ممه‌'.split( + '_' + ), + weekdaysMin: 'ی_د_س_چ_پ_ه_ش'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + meridiemParse: /ئێواره‌|به‌یانی/, + isPM: function (input) { + return /ئێواره‌/.test(input); + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'به‌یانی'; + } else { + return 'ئێواره‌'; + } + }, + calendar: { + sameDay: '[ئه‌مرۆ كاتژمێر] LT', + nextDay: '[به‌یانی كاتژمێر] LT', + nextWeek: 'dddd [كاتژمێر] LT', + lastDay: '[دوێنێ كاتژمێر] LT', + lastWeek: 'dddd [كاتژمێر] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'له‌ %s', + past: '%s', + s: 'چه‌ند چركه‌یه‌ك', + ss: 'چركه‌ %d', + m: 'یه‌ك خوله‌ك', + mm: '%d خوله‌ك', + h: 'یه‌ك كاتژمێر', + hh: '%d كاتژمێر', + d: 'یه‌ك ڕۆژ', + dd: '%d ڕۆژ', + M: 'یه‌ك مانگ', + MM: '%d مانگ', + y: 'یه‌ك ساڵ', + yy: '%d ساڵ', + }, + preparse: function (string) { + return string + .replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return numberMap[match]; + }) + .replace(/،/g, ','); + }, + postformat: function (string) { + return string + .replace(/\d/g, function (match) { + return symbolMap[match]; + }) + .replace(/,/g, '،'); + }, + week: { + dow: 6, // Saturday is the first day of the week. + doy: 12, // The week that contains Jan 12th is the first week of the year. + }, + }); + + return ku; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ky.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ky.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Kyrgyz [ky] +//! author : Chyngyz Arystan uulu : https://github.com/chyngyz + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var suffixes = { + 0: '-чү', + 1: '-чи', + 2: '-чи', + 3: '-чү', + 4: '-чү', + 5: '-чи', + 6: '-чы', + 7: '-чи', + 8: '-чи', + 9: '-чу', + 10: '-чу', + 20: '-чы', + 30: '-чу', + 40: '-чы', + 50: '-чү', + 60: '-чы', + 70: '-чи', + 80: '-чи', + 90: '-чу', + 100: '-чү', + }; + + var ky = moment.defineLocale('ky', { + months: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split( + '_' + ), + monthsShort: 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split( + '_' + ), + weekdays: 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split( + '_' + ), + weekdaysShort: 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'), + weekdaysMin: 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Бүгүн саат] LT', + nextDay: '[Эртең саат] LT', + nextWeek: 'dddd [саат] LT', + lastDay: '[Кечээ саат] LT', + lastWeek: '[Өткөн аптанын] dddd [күнү] [саат] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s ичинде', + past: '%s мурун', + s: 'бирнече секунд', + ss: '%d секунд', + m: 'бир мүнөт', + mm: '%d мүнөт', + h: 'бир саат', + hh: '%d саат', + d: 'бир күн', + dd: '%d күн', + M: 'бир ай', + MM: '%d ай', + y: 'бир жыл', + yy: '%d жыл', + }, + dayOfMonthOrdinalParse: /\d{1,2}-(чи|чы|чү|чу)/, + ordinal: function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes[number] || suffixes[a] || suffixes[b]); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return ky; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/lb.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/lb.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Luxembourgish [lb] +//! author : mweimerskirch : https://github.com/mweimerskirch +//! author : David Raison : https://github.com/kwisatz + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + m: ['eng Minutt', 'enger Minutt'], + h: ['eng Stonn', 'enger Stonn'], + d: ['een Dag', 'engem Dag'], + M: ['ee Mount', 'engem Mount'], + y: ['ee Joer', 'engem Joer'], + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + function processFutureTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return 'a ' + string; + } + return 'an ' + string; + } + function processPastTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return 'viru ' + string; + } + return 'virun ' + string; + } + /** + * Returns true if the word before the given number loses the '-n' ending. + * e.g. 'an 10 Deeg' but 'a 5 Deeg' + * + * @param number {integer} + * @returns {boolean} + */ + function eifelerRegelAppliesToNumber(number) { + number = parseInt(number, 10); + if (isNaN(number)) { + return false; + } + if (number < 0) { + // Negative Number --> always true + return true; + } else if (number < 10) { + // Only 1 digit + if (4 <= number && number <= 7) { + return true; + } + return false; + } else if (number < 100) { + // 2 digits + var lastDigit = number % 10, + firstDigit = number / 10; + if (lastDigit === 0) { + return eifelerRegelAppliesToNumber(firstDigit); + } + return eifelerRegelAppliesToNumber(lastDigit); + } else if (number < 10000) { + // 3 or 4 digits --> recursively check first digit + while (number >= 10) { + number = number / 10; + } + return eifelerRegelAppliesToNumber(number); + } else { + // Anything larger than 4 digits: recursively check first n-3 digits + number = number / 1000; + return eifelerRegelAppliesToNumber(number); + } + } + + var lb = moment.defineLocale('lb', { + months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split( + '_' + ), + monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split( + '_' + ), + weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'), + weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm [Auer]', + LTS: 'H:mm:ss [Auer]', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm [Auer]', + LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]', + }, + calendar: { + sameDay: '[Haut um] LT', + sameElse: 'L', + nextDay: '[Muer um] LT', + nextWeek: 'dddd [um] LT', + lastDay: '[Gëschter um] LT', + lastWeek: function () { + // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule + switch (this.day()) { + case 2: + case 4: + return '[Leschten] dddd [um] LT'; + default: + return '[Leschte] dddd [um] LT'; + } + }, + }, + relativeTime: { + future: processFutureTime, + past: processPastTime, + s: 'e puer Sekonnen', + ss: '%d Sekonnen', + m: processRelativeTime, + mm: '%d Minutten', + h: processRelativeTime, + hh: '%d Stonnen', + d: processRelativeTime, + dd: '%d Deeg', + M: processRelativeTime, + MM: '%d Méint', + y: processRelativeTime, + yy: '%d Joer', + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return lb; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/lo.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/lo.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Lao [lo] +//! author : Ryan Hart : https://github.com/ryanhart2 + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var lo = moment.defineLocale('lo', { + months: 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split( + '_' + ), + monthsShort: 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split( + '_' + ), + weekdays: 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysShort: 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysMin: 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'ວັນdddd D MMMM YYYY HH:mm', + }, + meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/, + isPM: function (input) { + return input === 'ຕອນແລງ'; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ຕອນເຊົ້າ'; + } else { + return 'ຕອນແລງ'; + } + }, + calendar: { + sameDay: '[ມື້ນີ້ເວລາ] LT', + nextDay: '[ມື້ອື່ນເວລາ] LT', + nextWeek: '[ວັນ]dddd[ໜ້າເວລາ] LT', + lastDay: '[ມື້ວານນີ້ເວລາ] LT', + lastWeek: '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'ອີກ %s', + past: '%sຜ່ານມາ', + s: 'ບໍ່ເທົ່າໃດວິນາທີ', + ss: '%d ວິນາທີ', + m: '1 ນາທີ', + mm: '%d ນາທີ', + h: '1 ຊົ່ວໂມງ', + hh: '%d ຊົ່ວໂມງ', + d: '1 ມື້', + dd: '%d ມື້', + M: '1 ເດືອນ', + MM: '%d ເດືອນ', + y: '1 ປີ', + yy: '%d ປີ', + }, + dayOfMonthOrdinalParse: /(ທີ່)\d{1,2}/, + ordinal: function (number) { + return 'ທີ່' + number; + }, + }); + + return lo; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/lt.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/lt.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Lithuanian [lt] +//! author : Mindaugas Mozūras : https://github.com/mmozuras + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var units = { + ss: 'sekundė_sekundžių_sekundes', + m: 'minutė_minutės_minutę', + mm: 'minutės_minučių_minutes', + h: 'valanda_valandos_valandą', + hh: 'valandos_valandų_valandas', + d: 'diena_dienos_dieną', + dd: 'dienos_dienų_dienas', + M: 'mėnuo_mėnesio_mėnesį', + MM: 'mėnesiai_mėnesių_mėnesius', + y: 'metai_metų_metus', + yy: 'metai_metų_metus', + }; + function translateSeconds(number, withoutSuffix, key, isFuture) { + if (withoutSuffix) { + return 'kelios sekundės'; + } else { + return isFuture ? 'kelių sekundžių' : 'kelias sekundes'; + } + } + function translateSingular(number, withoutSuffix, key, isFuture) { + return withoutSuffix + ? forms(key)[0] + : isFuture + ? forms(key)[1] + : forms(key)[2]; + } + function special(number) { + return number % 10 === 0 || (number > 10 && number < 20); + } + function forms(key) { + return units[key].split('_'); + } + function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + if (number === 1) { + return ( + result + translateSingular(number, withoutSuffix, key[0], isFuture) + ); + } else if (withoutSuffix) { + return result + (special(number) ? forms(key)[1] : forms(key)[0]); + } else { + if (isFuture) { + return result + forms(key)[1]; + } else { + return result + (special(number) ? forms(key)[1] : forms(key)[2]); + } + } + } + var lt = moment.defineLocale('lt', { + months: { + format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split( + '_' + ), + standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split( + '_' + ), + isFormat: /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/, + }, + monthsShort: 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'), + weekdays: { + format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split( + '_' + ), + standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split( + '_' + ), + isFormat: /dddd HH:mm/, + }, + weekdaysShort: 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'), + weekdaysMin: 'S_P_A_T_K_Pn_Š'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY-MM-DD', + LL: 'YYYY [m.] MMMM D [d.]', + LLL: 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + LLLL: 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]', + l: 'YYYY-MM-DD', + ll: 'YYYY [m.] MMMM D [d.]', + lll: 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + llll: 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]', + }, + calendar: { + sameDay: '[Šiandien] LT', + nextDay: '[Rytoj] LT', + nextWeek: 'dddd LT', + lastDay: '[Vakar] LT', + lastWeek: '[Praėjusį] dddd LT', + sameElse: 'L', + }, + relativeTime: { + future: 'po %s', + past: 'prieš %s', + s: translateSeconds, + ss: translate, + m: translateSingular, + mm: translate, + h: translateSingular, + hh: translate, + d: translateSingular, + dd: translate, + M: translateSingular, + MM: translate, + y: translateSingular, + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}-oji/, + ordinal: function (number) { + return number + '-oji'; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return lt; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/lv.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/lv.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Latvian [lv] +//! author : Kristaps Karlsons : https://github.com/skakri +//! author : Jānis Elmeris : https://github.com/JanisE + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var units = { + ss: 'sekundes_sekundēm_sekunde_sekundes'.split('_'), + m: 'minūtes_minūtēm_minūte_minūtes'.split('_'), + mm: 'minūtes_minūtēm_minūte_minūtes'.split('_'), + h: 'stundas_stundām_stunda_stundas'.split('_'), + hh: 'stundas_stundām_stunda_stundas'.split('_'), + d: 'dienas_dienām_diena_dienas'.split('_'), + dd: 'dienas_dienām_diena_dienas'.split('_'), + M: 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + MM: 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + y: 'gada_gadiem_gads_gadi'.split('_'), + yy: 'gada_gadiem_gads_gadi'.split('_'), + }; + /** + * @param withoutSuffix boolean true = a length of time; false = before/after a period of time. + */ + function format(forms, number, withoutSuffix) { + if (withoutSuffix) { + // E.g. "21 minūte", "3 minūtes". + return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3]; + } else { + // E.g. "21 minūtes" as in "pēc 21 minūtes". + // E.g. "3 minūtēm" as in "pēc 3 minūtēm". + return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1]; + } + } + function relativeTimeWithPlural(number, withoutSuffix, key) { + return number + ' ' + format(units[key], number, withoutSuffix); + } + function relativeTimeWithSingular(number, withoutSuffix, key) { + return format(units[key], number, withoutSuffix); + } + function relativeSeconds(number, withoutSuffix) { + return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm'; + } + + var lv = moment.defineLocale('lv', { + months: 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split( + '_' + ), + monthsShort: 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'), + weekdays: 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split( + '_' + ), + weekdaysShort: 'Sv_P_O_T_C_Pk_S'.split('_'), + weekdaysMin: 'Sv_P_O_T_C_Pk_S'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY.', + LL: 'YYYY. [gada] D. MMMM', + LLL: 'YYYY. [gada] D. MMMM, HH:mm', + LLLL: 'YYYY. [gada] D. MMMM, dddd, HH:mm', + }, + calendar: { + sameDay: '[Šodien pulksten] LT', + nextDay: '[Rīt pulksten] LT', + nextWeek: 'dddd [pulksten] LT', + lastDay: '[Vakar pulksten] LT', + lastWeek: '[Pagājušā] dddd [pulksten] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'pēc %s', + past: 'pirms %s', + s: relativeSeconds, + ss: relativeTimeWithPlural, + m: relativeTimeWithSingular, + mm: relativeTimeWithPlural, + h: relativeTimeWithSingular, + hh: relativeTimeWithPlural, + d: relativeTimeWithSingular, + dd: relativeTimeWithPlural, + M: relativeTimeWithSingular, + MM: relativeTimeWithPlural, + y: relativeTimeWithSingular, + yy: relativeTimeWithPlural, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return lv; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/me.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/me.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Montenegrin [me] +//! author : Miodrag Nikač : https://github.com/miodragnikac + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var translator = { + words: { + //Different grammatical cases + ss: ['sekund', 'sekunda', 'sekundi'], + m: ['jedan minut', 'jednog minuta'], + mm: ['minut', 'minuta', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mjesec', 'mjeseca', 'mjeseci'], + yy: ['godina', 'godine', 'godina'], + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 + ? wordKey[0] + : number >= 2 && number <= 4 + ? wordKey[1] + : wordKey[2]; + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return ( + number + + ' ' + + translator.correctGrammaticalCase(number, wordKey) + ); + } + }, + }; + + var me = moment.defineLocale('me', { + months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split( + '_' + ), + monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split( + '_' + ), + weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm', + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sjutra u] LT', + + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay: '[juče u] LT', + lastWeek: function () { + var lastWeekDays = [ + '[prošle] [nedjelje] [u] LT', + '[prošlog] [ponedjeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srijede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT', + ]; + return lastWeekDays[this.day()]; + }, + sameElse: 'L', + }, + relativeTime: { + future: 'za %s', + past: 'prije %s', + s: 'nekoliko sekundi', + ss: translator.translate, + m: translator.translate, + mm: translator.translate, + h: translator.translate, + hh: translator.translate, + d: 'dan', + dd: translator.translate, + M: 'mjesec', + MM: translator.translate, + y: 'godinu', + yy: translator.translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return me; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/mi.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/mi.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Maori [mi] +//! author : John Corrigan : https://github.com/johnideal + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var mi = moment.defineLocale('mi', { + months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split( + '_' + ), + monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split( + '_' + ), + monthsRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsShortRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsShortStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i, + weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'), + weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), + weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY [i] HH:mm', + LLLL: 'dddd, D MMMM YYYY [i] HH:mm', + }, + calendar: { + sameDay: '[i teie mahana, i] LT', + nextDay: '[apopo i] LT', + nextWeek: 'dddd [i] LT', + lastDay: '[inanahi i] LT', + lastWeek: 'dddd [whakamutunga i] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'i roto i %s', + past: '%s i mua', + s: 'te hēkona ruarua', + ss: '%d hēkona', + m: 'he meneti', + mm: '%d meneti', + h: 'te haora', + hh: '%d haora', + d: 'he ra', + dd: '%d ra', + M: 'he marama', + MM: '%d marama', + y: 'he tau', + yy: '%d tau', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return mi; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/mk.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/mk.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Macedonian [mk] +//! author : Borislav Mickov : https://github.com/B0k0 +//! author : Sashko Todorov : https://github.com/bkyceh + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var mk = moment.defineLocale('mk', { + months: 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split( + '_' + ), + monthsShort: 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'), + weekdays: 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split( + '_' + ), + weekdaysShort: 'нед_пон_вто_сре_чет_пет_саб'.split('_'), + weekdaysMin: 'нe_пo_вт_ср_че_пе_сa'.split('_'), + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'D.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY H:mm', + LLLL: 'dddd, D MMMM YYYY H:mm', + }, + calendar: { + sameDay: '[Денес во] LT', + nextDay: '[Утре во] LT', + nextWeek: '[Во] dddd [во] LT', + lastDay: '[Вчера во] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[Изминатата] dddd [во] LT'; + case 1: + case 2: + case 4: + case 5: + return '[Изминатиот] dddd [во] LT'; + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'за %s', + past: 'пред %s', + s: 'неколку секунди', + ss: '%d секунди', + m: 'една минута', + mm: '%d минути', + h: 'еден час', + hh: '%d часа', + d: 'еден ден', + dd: '%d дена', + M: 'еден месец', + MM: '%d месеци', + y: 'една година', + yy: '%d години', + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, + ordinal: function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return mk; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ml.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ml.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Malayalam [ml] +//! author : Floyd Pink : https://github.com/floydpink + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var ml = moment.defineLocale('ml', { + months: 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split( + '_' + ), + monthsShort: 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split( + '_' + ), + weekdaysShort: 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'), + weekdaysMin: 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'), + longDateFormat: { + LT: 'A h:mm -നു', + LTS: 'A h:mm:ss -നു', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm -നു', + LLLL: 'dddd, D MMMM YYYY, A h:mm -നു', + }, + calendar: { + sameDay: '[ഇന്ന്] LT', + nextDay: '[നാളെ] LT', + nextWeek: 'dddd, LT', + lastDay: '[ഇന്നലെ] LT', + lastWeek: '[കഴിഞ്ഞ] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s കഴിഞ്ഞ്', + past: '%s മുൻപ്', + s: 'അൽപ നിമിഷങ്ങൾ', + ss: '%d സെക്കൻഡ്', + m: 'ഒരു മിനിറ്റ്', + mm: '%d മിനിറ്റ്', + h: 'ഒരു മണിക്കൂർ', + hh: '%d മണിക്കൂർ', + d: 'ഒരു ദിവസം', + dd: '%d ദിവസം', + M: 'ഒരു മാസം', + MM: '%d മാസം', + y: 'ഒരു വർഷം', + yy: '%d വർഷം', + }, + meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ( + (meridiem === 'രാത്രി' && hour >= 4) || + meridiem === 'ഉച്ച കഴിഞ്ഞ്' || + meridiem === 'വൈകുന്നേരം' + ) { + return hour + 12; + } else { + return hour; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'രാത്രി'; + } else if (hour < 12) { + return 'രാവിലെ'; + } else if (hour < 17) { + return 'ഉച്ച കഴിഞ്ഞ്'; + } else if (hour < 20) { + return 'വൈകുന്നേരം'; + } else { + return 'രാത്രി'; + } + }, + }); + + return ml; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/mn.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/mn.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Mongolian [mn] +//! author : Javkhlantugs Nyamdorj : https://github.com/javkhaanj7 + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function translate(number, withoutSuffix, key, isFuture) { + switch (key) { + case 's': + return withoutSuffix ? 'хэдхэн секунд' : 'хэдхэн секундын'; + case 'ss': + return number + (withoutSuffix ? ' секунд' : ' секундын'); + case 'm': + case 'mm': + return number + (withoutSuffix ? ' минут' : ' минутын'); + case 'h': + case 'hh': + return number + (withoutSuffix ? ' цаг' : ' цагийн'); + case 'd': + case 'dd': + return number + (withoutSuffix ? ' өдөр' : ' өдрийн'); + case 'M': + case 'MM': + return number + (withoutSuffix ? ' сар' : ' сарын'); + case 'y': + case 'yy': + return number + (withoutSuffix ? ' жил' : ' жилийн'); + default: + return number; + } + } + + var mn = moment.defineLocale('mn', { + months: 'Нэгдүгээр сар_Хоёрдугаар сар_Гуравдугаар сар_Дөрөвдүгээр сар_Тавдугаар сар_Зургадугаар сар_Долдугаар сар_Наймдугаар сар_Есдүгээр сар_Аравдугаар сар_Арван нэгдүгээр сар_Арван хоёрдугаар сар'.split( + '_' + ), + monthsShort: '1 сар_2 сар_3 сар_4 сар_5 сар_6 сар_7 сар_8 сар_9 сар_10 сар_11 сар_12 сар'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'Ням_Даваа_Мягмар_Лхагва_Пүрэв_Баасан_Бямба'.split('_'), + weekdaysShort: 'Ням_Дав_Мяг_Лха_Пүр_Баа_Бям'.split('_'), + weekdaysMin: 'Ня_Да_Мя_Лх_Пү_Ба_Бя'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY-MM-DD', + LL: 'YYYY оны MMMMын D', + LLL: 'YYYY оны MMMMын D HH:mm', + LLLL: 'dddd, YYYY оны MMMMын D HH:mm', + }, + meridiemParse: /ҮӨ|ҮХ/i, + isPM: function (input) { + return input === 'ҮХ'; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ҮӨ'; + } else { + return 'ҮХ'; + } + }, + calendar: { + sameDay: '[Өнөөдөр] LT', + nextDay: '[Маргааш] LT', + nextWeek: '[Ирэх] dddd LT', + lastDay: '[Өчигдөр] LT', + lastWeek: '[Өнгөрсөн] dddd LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s дараа', + past: '%s өмнө', + s: translate, + ss: translate, + m: translate, + mm: translate, + h: translate, + hh: translate, + d: translate, + dd: translate, + M: translate, + MM: translate, + y: translate, + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2} өдөр/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + ' өдөр'; + default: + return number; + } + }, + }); + + return mn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/mr.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/mr.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Marathi [mr] +//! author : Harshad Kale : https://github.com/kalehv +//! author : Vivek Athalye : https://github.com/vnathalye + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '१', + 2: '२', + 3: '३', + 4: '४', + 5: '५', + 6: '६', + 7: '७', + 8: '८', + 9: '९', + 0: '०', + }, + numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0', + }; + + function relativeTimeMr(number, withoutSuffix, string, isFuture) { + var output = ''; + if (withoutSuffix) { + switch (string) { + case 's': + output = 'काही सेकंद'; + break; + case 'ss': + output = '%d सेकंद'; + break; + case 'm': + output = 'एक मिनिट'; + break; + case 'mm': + output = '%d मिनिटे'; + break; + case 'h': + output = 'एक तास'; + break; + case 'hh': + output = '%d तास'; + break; + case 'd': + output = 'एक दिवस'; + break; + case 'dd': + output = '%d दिवस'; + break; + case 'M': + output = 'एक महिना'; + break; + case 'MM': + output = '%d महिने'; + break; + case 'y': + output = 'एक वर्ष'; + break; + case 'yy': + output = '%d वर्षे'; + break; + } + } else { + switch (string) { + case 's': + output = 'काही सेकंदां'; + break; + case 'ss': + output = '%d सेकंदां'; + break; + case 'm': + output = 'एका मिनिटा'; + break; + case 'mm': + output = '%d मिनिटां'; + break; + case 'h': + output = 'एका तासा'; + break; + case 'hh': + output = '%d तासां'; + break; + case 'd': + output = 'एका दिवसा'; + break; + case 'dd': + output = '%d दिवसां'; + break; + case 'M': + output = 'एका महिन्या'; + break; + case 'MM': + output = '%d महिन्यां'; + break; + case 'y': + output = 'एका वर्षा'; + break; + case 'yy': + output = '%d वर्षां'; + break; + } + } + return output.replace(/%d/i, number); + } + + var mr = moment.defineLocale('mr', { + months: 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split( + '_' + ), + monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort: 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin: 'र_सो_मं_बु_गु_शु_श'.split('_'), + longDateFormat: { + LT: 'A h:mm वाजता', + LTS: 'A h:mm:ss वाजता', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm वाजता', + LLLL: 'dddd, D MMMM YYYY, A h:mm वाजता', + }, + calendar: { + sameDay: '[आज] LT', + nextDay: '[उद्या] LT', + nextWeek: 'dddd, LT', + lastDay: '[काल] LT', + lastWeek: '[मागील] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%sमध्ये', + past: '%sपूर्वी', + s: relativeTimeMr, + ss: relativeTimeMr, + m: relativeTimeMr, + mm: relativeTimeMr, + h: relativeTimeMr, + hh: relativeTimeMr, + d: relativeTimeMr, + dd: relativeTimeMr, + M: relativeTimeMr, + MM: relativeTimeMr, + y: relativeTimeMr, + yy: relativeTimeMr, + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /पहाटे|सकाळी|दुपारी|सायंकाळी|रात्री/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'पहाटे' || meridiem === 'सकाळी') { + return hour; + } else if ( + meridiem === 'दुपारी' || + meridiem === 'सायंकाळी' || + meridiem === 'रात्री' + ) { + return hour >= 12 ? hour : hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour >= 0 && hour < 6) { + return 'पहाटे'; + } else if (hour < 12) { + return 'सकाळी'; + } else if (hour < 17) { + return 'दुपारी'; + } else if (hour < 20) { + return 'सायंकाळी'; + } else { + return 'रात्री'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return mr; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ms-my.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ms-my.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Malay [ms-my] +//! note : DEPRECATED, the correct one is [ms] +//! author : Weldan Jamili : https://github.com/weldan + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var msMy = moment.defineLocale('ms-my', { + months: 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays: 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort: 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin: 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat: { + LT: 'HH.mm', + LTS: 'HH.mm.ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY [pukul] HH.mm', + LLLL: 'dddd, D MMMM YYYY [pukul] HH.mm', + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem: function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } + }, + calendar: { + sameDay: '[Hari ini pukul] LT', + nextDay: '[Esok pukul] LT', + nextWeek: 'dddd [pukul] LT', + lastDay: '[Kelmarin pukul] LT', + lastWeek: 'dddd [lepas pukul] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'dalam %s', + past: '%s yang lepas', + s: 'beberapa saat', + ss: '%d saat', + m: 'seminit', + mm: '%d minit', + h: 'sejam', + hh: '%d jam', + d: 'sehari', + dd: '%d hari', + M: 'sebulan', + MM: '%d bulan', + y: 'setahun', + yy: '%d tahun', + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return msMy; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ms.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ms.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Malay [ms] +//! author : Weldan Jamili : https://github.com/weldan + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var ms = moment.defineLocale('ms', { + months: 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays: 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort: 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin: 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat: { + LT: 'HH.mm', + LTS: 'HH.mm.ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY [pukul] HH.mm', + LLLL: 'dddd, D MMMM YYYY [pukul] HH.mm', + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem: function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } + }, + calendar: { + sameDay: '[Hari ini pukul] LT', + nextDay: '[Esok pukul] LT', + nextWeek: 'dddd [pukul] LT', + lastDay: '[Kelmarin pukul] LT', + lastWeek: 'dddd [lepas pukul] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'dalam %s', + past: '%s yang lepas', + s: 'beberapa saat', + ss: '%d saat', + m: 'seminit', + mm: '%d minit', + h: 'sejam', + hh: '%d jam', + d: 'sehari', + dd: '%d hari', + M: 'sebulan', + MM: '%d bulan', + y: 'setahun', + yy: '%d tahun', + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return ms; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/mt.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/mt.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Maltese (Malta) [mt] +//! author : Alessandro Maruccia : https://github.com/alesma + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var mt = moment.defineLocale('mt', { + months: 'Jannar_Frar_Marzu_April_Mejju_Ġunju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Diċembru'.split( + '_' + ), + monthsShort: 'Jan_Fra_Mar_Apr_Mej_Ġun_Lul_Aww_Set_Ott_Nov_Diċ'.split('_'), + weekdays: 'Il-Ħadd_It-Tnejn_It-Tlieta_L-Erbgħa_Il-Ħamis_Il-Ġimgħa_Is-Sibt'.split( + '_' + ), + weekdaysShort: 'Ħad_Tne_Tli_Erb_Ħam_Ġim_Sib'.split('_'), + weekdaysMin: 'Ħa_Tn_Tl_Er_Ħa_Ġi_Si'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Illum fil-]LT', + nextDay: '[Għada fil-]LT', + nextWeek: 'dddd [fil-]LT', + lastDay: '[Il-bieraħ fil-]LT', + lastWeek: 'dddd [li għadda] [fil-]LT', + sameElse: 'L', + }, + relativeTime: { + future: 'f’ %s', + past: '%s ilu', + s: 'ftit sekondi', + ss: '%d sekondi', + m: 'minuta', + mm: '%d minuti', + h: 'siegħa', + hh: '%d siegħat', + d: 'ġurnata', + dd: '%d ġranet', + M: 'xahar', + MM: '%d xhur', + y: 'sena', + yy: '%d sni', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return mt; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/my.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/my.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Burmese [my] +//! author : Squar team, mysquar.com +//! author : David Rossellat : https://github.com/gholadr +//! author : Tin Aung Lin : https://github.com/thanyawzinmin + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '၁', + 2: '၂', + 3: '၃', + 4: '၄', + 5: '၅', + 6: '၆', + 7: '၇', + 8: '၈', + 9: '၉', + 0: '၀', + }, + numberMap = { + '၁': '1', + '၂': '2', + '၃': '3', + '၄': '4', + '၅': '5', + '၆': '6', + '၇': '7', + '၈': '8', + '၉': '9', + '၀': '0', + }; + + var my = moment.defineLocale('my', { + months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split( + '_' + ), + monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'), + weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split( + '_' + ), + weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[ယနေ.] LT [မှာ]', + nextDay: '[မနက်ဖြန်] LT [မှာ]', + nextWeek: 'dddd LT [မှာ]', + lastDay: '[မနေ.က] LT [မှာ]', + lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]', + sameElse: 'L', + }, + relativeTime: { + future: 'လာမည့် %s မှာ', + past: 'လွန်ခဲ့သော %s က', + s: 'စက္ကန်.အနည်းငယ်', + ss: '%d စက္ကန့်', + m: 'တစ်မိနစ်', + mm: '%d မိနစ်', + h: 'တစ်နာရီ', + hh: '%d နာရီ', + d: 'တစ်ရက်', + dd: '%d ရက်', + M: 'တစ်လ', + MM: '%d လ', + y: 'တစ်နှစ်', + yy: '%d နှစ်', + }, + preparse: function (string) { + return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return my; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/nb.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/nb.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Norwegian Bokmål [nb] +//! authors : Espen Hovlandsdal : https://github.com/rexxars +//! Sigurd Gartmann : https://github.com/sigurdga +//! Stephen Ramthun : https://github.com/stephenramthun + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var nb = moment.defineLocale('nb', { + months: 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split( + '_' + ), + monthsShort: 'jan._feb._mars_apr._mai_juni_juli_aug._sep._okt._nov._des.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort: 'sø._ma._ti._on._to._fr._lø.'.split('_'), + weekdaysMin: 'sø_ma_ti_on_to_fr_lø'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY [kl.] HH:mm', + LLLL: 'dddd D. MMMM YYYY [kl.] HH:mm', + }, + calendar: { + sameDay: '[i dag kl.] LT', + nextDay: '[i morgen kl.] LT', + nextWeek: 'dddd [kl.] LT', + lastDay: '[i går kl.] LT', + lastWeek: '[forrige] dddd [kl.] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'om %s', + past: '%s siden', + s: 'noen sekunder', + ss: '%d sekunder', + m: 'ett minutt', + mm: '%d minutter', + h: 'en time', + hh: '%d timer', + d: 'en dag', + dd: '%d dager', + w: 'en uke', + ww: '%d uker', + M: 'en måned', + MM: '%d måneder', + y: 'ett år', + yy: '%d år', + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return nb; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ne.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ne.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Nepalese [ne] +//! author : suvash : https://github.com/suvash + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '१', + 2: '२', + 3: '३', + 4: '४', + 5: '५', + 6: '६', + 7: '७', + 8: '८', + 9: '९', + 0: '०', + }, + numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0', + }; + + var ne = moment.defineLocale('ne', { + months: 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split( + '_' + ), + monthsShort: 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split( + '_' + ), + weekdaysShort: 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'), + weekdaysMin: 'आ._सो._मं._बु._बि._शु._श.'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'Aको h:mm बजे', + LTS: 'Aको h:mm:ss बजे', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, Aको h:mm बजे', + LLLL: 'dddd, D MMMM YYYY, Aको h:mm बजे', + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /राति|बिहान|दिउँसो|साँझ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'राति') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'बिहान') { + return hour; + } else if (meridiem === 'दिउँसो') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'साँझ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 3) { + return 'राति'; + } else if (hour < 12) { + return 'बिहान'; + } else if (hour < 16) { + return 'दिउँसो'; + } else if (hour < 20) { + return 'साँझ'; + } else { + return 'राति'; + } + }, + calendar: { + sameDay: '[आज] LT', + nextDay: '[भोलि] LT', + nextWeek: '[आउँदो] dddd[,] LT', + lastDay: '[हिजो] LT', + lastWeek: '[गएको] dddd[,] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%sमा', + past: '%s अगाडि', + s: 'केही क्षण', + ss: '%d सेकेण्ड', + m: 'एक मिनेट', + mm: '%d मिनेट', + h: 'एक घण्टा', + hh: '%d घण्टा', + d: 'एक दिन', + dd: '%d दिन', + M: 'एक महिना', + MM: '%d महिना', + y: 'एक बर्ष', + yy: '%d बर्ष', + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return ne; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/nl-be.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/nl-be.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Dutch (Belgium) [nl-be] +//! author : Joris Röling : https://github.com/jorisroling +//! author : Jacob Middag : https://github.com/middagj + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split( + '_' + ), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split( + '_' + ), + monthsParse = [ + /^jan/i, + /^feb/i, + /^maart|mrt.?$/i, + /^apr/i, + /^mei$/i, + /^jun[i.]?$/i, + /^jul[i.]?$/i, + /^aug/i, + /^sep/i, + /^okt/i, + /^nov/i, + /^dec/i, + ], + monthsRegex = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; + + var nlBe = moment.defineLocale('nl-be', { + months: 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split( + '_' + ), + monthsShort: function (m, format) { + if (!m) { + return monthsShortWithDots; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i, + monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, + + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + + weekdays: 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split( + '_' + ), + weekdaysShort: 'zo._ma._di._wo._do._vr._za.'.split('_'), + weekdaysMin: 'zo_ma_di_wo_do_vr_za'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[vandaag om] LT', + nextDay: '[morgen om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[gisteren om] LT', + lastWeek: '[afgelopen] dddd [om] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'over %s', + past: '%s geleden', + s: 'een paar seconden', + ss: '%d seconden', + m: 'één minuut', + mm: '%d minuten', + h: 'één uur', + hh: '%d uur', + d: 'één dag', + dd: '%d dagen', + M: 'één maand', + MM: '%d maanden', + y: 'één jaar', + yy: '%d jaar', + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal: function (number) { + return ( + number + + (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de') + ); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return nlBe; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/nl.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/nl.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Dutch [nl] +//! author : Joris Röling : https://github.com/jorisroling +//! author : Jacob Middag : https://github.com/middagj + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split( + '_' + ), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split( + '_' + ), + monthsParse = [ + /^jan/i, + /^feb/i, + /^maart|mrt.?$/i, + /^apr/i, + /^mei$/i, + /^jun[i.]?$/i, + /^jul[i.]?$/i, + /^aug/i, + /^sep/i, + /^okt/i, + /^nov/i, + /^dec/i, + ], + monthsRegex = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; + + var nl = moment.defineLocale('nl', { + months: 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split( + '_' + ), + monthsShort: function (m, format) { + if (!m) { + return monthsShortWithDots; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i, + monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, + + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + + weekdays: 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split( + '_' + ), + weekdaysShort: 'zo._ma._di._wo._do._vr._za.'.split('_'), + weekdaysMin: 'zo_ma_di_wo_do_vr_za'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD-MM-YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[vandaag om] LT', + nextDay: '[morgen om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[gisteren om] LT', + lastWeek: '[afgelopen] dddd [om] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'over %s', + past: '%s geleden', + s: 'een paar seconden', + ss: '%d seconden', + m: 'één minuut', + mm: '%d minuten', + h: 'één uur', + hh: '%d uur', + d: 'één dag', + dd: '%d dagen', + w: 'één week', + ww: '%d weken', + M: 'één maand', + MM: '%d maanden', + y: 'één jaar', + yy: '%d jaar', + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal: function (number) { + return ( + number + + (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de') + ); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return nl; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/nn.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/nn.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Nynorsk [nn] +//! authors : https://github.com/mechuwind +//! Stephen Ramthun : https://github.com/stephenramthun + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var nn = moment.defineLocale('nn', { + months: 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split( + '_' + ), + monthsShort: 'jan._feb._mars_apr._mai_juni_juli_aug._sep._okt._nov._des.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'), + weekdaysShort: 'su._må._ty._on._to._fr._lau.'.split('_'), + weekdaysMin: 'su_må_ty_on_to_fr_la'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY [kl.] H:mm', + LLLL: 'dddd D. MMMM YYYY [kl.] HH:mm', + }, + calendar: { + sameDay: '[I dag klokka] LT', + nextDay: '[I morgon klokka] LT', + nextWeek: 'dddd [klokka] LT', + lastDay: '[I går klokka] LT', + lastWeek: '[Føregåande] dddd [klokka] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'om %s', + past: '%s sidan', + s: 'nokre sekund', + ss: '%d sekund', + m: 'eit minutt', + mm: '%d minutt', + h: 'ein time', + hh: '%d timar', + d: 'ein dag', + dd: '%d dagar', + w: 'ei veke', + ww: '%d veker', + M: 'ein månad', + MM: '%d månader', + y: 'eit år', + yy: '%d år', + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return nn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/oc-lnc.js": +/*!****************************************************!*\ + !*** ../eyes/node_modules/moment/locale/oc-lnc.js ***! + \****************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Occitan, lengadocian dialecte [oc-lnc] +//! author : Quentin PAGÈS : https://github.com/Quenty31 + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var ocLnc = moment.defineLocale('oc-lnc', { + months: { + standalone: 'genièr_febrièr_març_abril_mai_junh_julhet_agost_setembre_octòbre_novembre_decembre'.split( + '_' + ), + format: "de genièr_de febrièr_de març_d'abril_de mai_de junh_de julhet_d'agost_de setembre_d'octòbre_de novembre_de decembre".split( + '_' + ), + isFormat: /D[oD]?(\s)+MMMM/, + }, + monthsShort: 'gen._febr._març_abr._mai_junh_julh._ago._set._oct._nov._dec.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'dimenge_diluns_dimars_dimècres_dijòus_divendres_dissabte'.split( + '_' + ), + weekdaysShort: 'dg._dl._dm._dc._dj._dv._ds.'.split('_'), + weekdaysMin: 'dg_dl_dm_dc_dj_dv_ds'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM [de] YYYY', + ll: 'D MMM YYYY', + LLL: 'D MMMM [de] YYYY [a] H:mm', + lll: 'D MMM YYYY, H:mm', + LLLL: 'dddd D MMMM [de] YYYY [a] H:mm', + llll: 'ddd D MMM YYYY, H:mm', + }, + calendar: { + sameDay: '[uèi a] LT', + nextDay: '[deman a] LT', + nextWeek: 'dddd [a] LT', + lastDay: '[ièr a] LT', + lastWeek: 'dddd [passat a] LT', + sameElse: 'L', + }, + relativeTime: { + future: "d'aquí %s", + past: 'fa %s', + s: 'unas segondas', + ss: '%d segondas', + m: 'una minuta', + mm: '%d minutas', + h: 'una ora', + hh: '%d oras', + d: 'un jorn', + dd: '%d jorns', + M: 'un mes', + MM: '%d meses', + y: 'un an', + yy: '%d ans', + }, + dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/, + ordinal: function (number, period) { + var output = + number === 1 + ? 'r' + : number === 2 + ? 'n' + : number === 3 + ? 'r' + : number === 4 + ? 't' + : 'è'; + if (period === 'w' || period === 'W') { + output = 'a'; + } + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, + }, + }); + + return ocLnc; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/pa-in.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/pa-in.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Punjabi (India) [pa-in] +//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '੧', + 2: '੨', + 3: '੩', + 4: '੪', + 5: '੫', + 6: '੬', + 7: '੭', + 8: '੮', + 9: '੯', + 0: '੦', + }, + numberMap = { + '੧': '1', + '੨': '2', + '੩': '3', + '੪': '4', + '੫': '5', + '੬': '6', + '੭': '7', + '੮': '8', + '੯': '9', + '੦': '0', + }; + + var paIn = moment.defineLocale('pa-in', { + // There are months name as per Nanakshahi Calendar but they are not used as rigidly in modern Punjabi. + months: 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split( + '_' + ), + monthsShort: 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split( + '_' + ), + weekdays: 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split( + '_' + ), + weekdaysShort: 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), + weekdaysMin: 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), + longDateFormat: { + LT: 'A h:mm ਵਜੇ', + LTS: 'A h:mm:ss ਵਜੇ', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm ਵਜੇ', + LLLL: 'dddd, D MMMM YYYY, A h:mm ਵਜੇ', + }, + calendar: { + sameDay: '[ਅਜ] LT', + nextDay: '[ਕਲ] LT', + nextWeek: '[ਅਗਲਾ] dddd, LT', + lastDay: '[ਕਲ] LT', + lastWeek: '[ਪਿਛਲੇ] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s ਵਿੱਚ', + past: '%s ਪਿਛਲੇ', + s: 'ਕੁਝ ਸਕਿੰਟ', + ss: '%d ਸਕਿੰਟ', + m: 'ਇਕ ਮਿੰਟ', + mm: '%d ਮਿੰਟ', + h: 'ਇੱਕ ਘੰਟਾ', + hh: '%d ਘੰਟੇ', + d: 'ਇੱਕ ਦਿਨ', + dd: '%d ਦਿਨ', + M: 'ਇੱਕ ਮਹੀਨਾ', + MM: '%d ਮਹੀਨੇ', + y: 'ਇੱਕ ਸਾਲ', + yy: '%d ਸਾਲ', + }, + preparse: function (string) { + return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // Punjabi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi. + meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ਰਾਤ') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ਸਵੇਰ') { + return hour; + } else if (meridiem === 'ਦੁਪਹਿਰ') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'ਸ਼ਾਮ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'ਰਾਤ'; + } else if (hour < 10) { + return 'ਸਵੇਰ'; + } else if (hour < 17) { + return 'ਦੁਪਹਿਰ'; + } else if (hour < 20) { + return 'ਸ਼ਾਮ'; + } else { + return 'ਰਾਤ'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return paIn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/pl.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/pl.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Polish [pl] +//! author : Rafal Hirsz : https://github.com/evoL + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split( + '_' + ), + monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split( + '_' + ), + monthsParse = [ + /^sty/i, + /^lut/i, + /^mar/i, + /^kwi/i, + /^maj/i, + /^cze/i, + /^lip/i, + /^sie/i, + /^wrz/i, + /^paź/i, + /^lis/i, + /^gru/i, + ]; + function plural(n) { + return n % 10 < 5 && n % 10 > 1 && ~~(n / 10) % 10 !== 1; + } + function translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + return result + (plural(number) ? 'sekundy' : 'sekund'); + case 'm': + return withoutSuffix ? 'minuta' : 'minutę'; + case 'mm': + return result + (plural(number) ? 'minuty' : 'minut'); + case 'h': + return withoutSuffix ? 'godzina' : 'godzinę'; + case 'hh': + return result + (plural(number) ? 'godziny' : 'godzin'); + case 'ww': + return result + (plural(number) ? 'tygodnie' : 'tygodni'); + case 'MM': + return result + (plural(number) ? 'miesiące' : 'miesięcy'); + case 'yy': + return result + (plural(number) ? 'lata' : 'lat'); + } + } + + var pl = moment.defineLocale('pl', { + months: function (momentToFormat, format) { + if (!momentToFormat) { + return monthsNominative; + } else if (/D MMMM/.test(format)) { + return monthsSubjective[momentToFormat.month()]; + } else { + return monthsNominative[momentToFormat.month()]; + } + }, + monthsShort: 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'), + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays: 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split( + '_' + ), + weekdaysShort: 'ndz_pon_wt_śr_czw_pt_sob'.split('_'), + weekdaysMin: 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Dziś o] LT', + nextDay: '[Jutro o] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[W niedzielę o] LT'; + + case 2: + return '[We wtorek o] LT'; + + case 3: + return '[W środę o] LT'; + + case 6: + return '[W sobotę o] LT'; + + default: + return '[W] dddd [o] LT'; + } + }, + lastDay: '[Wczoraj o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[W zeszłą niedzielę o] LT'; + case 3: + return '[W zeszłą środę o] LT'; + case 6: + return '[W zeszłą sobotę o] LT'; + default: + return '[W zeszły] dddd [o] LT'; + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'za %s', + past: '%s temu', + s: 'kilka sekund', + ss: translate, + m: translate, + mm: translate, + h: translate, + hh: translate, + d: '1 dzień', + dd: '%d dni', + w: 'tydzień', + ww: translate, + M: 'miesiąc', + MM: translate, + y: 'rok', + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return pl; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/pt-br.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/pt-br.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Portuguese (Brazil) [pt-br] +//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var ptBr = moment.defineLocale('pt-br', { + months: 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split( + '_' + ), + monthsShort: 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'), + weekdays: 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split( + '_' + ), + weekdaysShort: 'dom_seg_ter_qua_qui_sex_sáb'.split('_'), + weekdaysMin: 'do_2ª_3ª_4ª_5ª_6ª_sá'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D [de] MMMM [de] YYYY', + LLL: 'D [de] MMMM [de] YYYY [às] HH:mm', + LLLL: 'dddd, D [de] MMMM [de] YYYY [às] HH:mm', + }, + calendar: { + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return this.day() === 0 || this.day() === 6 + ? '[Último] dddd [às] LT' // Saturday + Sunday + : '[Última] dddd [às] LT'; // Monday - Friday + }, + sameElse: 'L', + }, + relativeTime: { + future: 'em %s', + past: 'há %s', + s: 'poucos segundos', + ss: '%d segundos', + m: 'um minuto', + mm: '%d minutos', + h: 'uma hora', + hh: '%d horas', + d: 'um dia', + dd: '%d dias', + M: 'um mês', + MM: '%d meses', + y: 'um ano', + yy: '%d anos', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + invalidDate: 'Data inválida', + }); + + return ptBr; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/pt.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/pt.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Portuguese [pt] +//! author : Jefferson : https://github.com/jalex79 + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var pt = moment.defineLocale('pt', { + months: 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split( + '_' + ), + monthsShort: 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'), + weekdays: 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split( + '_' + ), + weekdaysShort: 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin: 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D [de] MMMM [de] YYYY', + LLL: 'D [de] MMMM [de] YYYY HH:mm', + LLLL: 'dddd, D [de] MMMM [de] YYYY HH:mm', + }, + calendar: { + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return this.day() === 0 || this.day() === 6 + ? '[Último] dddd [às] LT' // Saturday + Sunday + : '[Última] dddd [às] LT'; // Monday - Friday + }, + sameElse: 'L', + }, + relativeTime: { + future: 'em %s', + past: 'há %s', + s: 'segundos', + ss: '%d segundos', + m: 'um minuto', + mm: '%d minutos', + h: 'uma hora', + hh: '%d horas', + d: 'um dia', + dd: '%d dias', + w: 'uma semana', + ww: '%d semanas', + M: 'um mês', + MM: '%d meses', + y: 'um ano', + yy: '%d anos', + }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return pt; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ro.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ro.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Romanian [ro] +//! author : Vlad Gurdiga : https://github.com/gurdiga +//! author : Valentin Agachi : https://github.com/avaly +//! author : Emanuel Cepoi : https://github.com/cepem + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + ss: 'secunde', + mm: 'minute', + hh: 'ore', + dd: 'zile', + ww: 'săptămâni', + MM: 'luni', + yy: 'ani', + }, + separator = ' '; + if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) { + separator = ' de '; + } + return number + separator + format[key]; + } + + var ro = moment.defineLocale('ro', { + months: 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split( + '_' + ), + monthsShort: 'ian._feb._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'), + weekdaysShort: 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'), + weekdaysMin: 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'), + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY H:mm', + LLLL: 'dddd, D MMMM YYYY H:mm', + }, + calendar: { + sameDay: '[azi la] LT', + nextDay: '[mâine la] LT', + nextWeek: 'dddd [la] LT', + lastDay: '[ieri la] LT', + lastWeek: '[fosta] dddd [la] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'peste %s', + past: '%s în urmă', + s: 'câteva secunde', + ss: relativeTimeWithPlural, + m: 'un minut', + mm: relativeTimeWithPlural, + h: 'o oră', + hh: relativeTimeWithPlural, + d: 'o zi', + dd: relativeTimeWithPlural, + w: 'o săptămână', + ww: relativeTimeWithPlural, + M: 'o lună', + MM: relativeTimeWithPlural, + y: 'un an', + yy: relativeTimeWithPlural, + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return ro; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ru.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ru.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Russian [ru] +//! author : Viktorminator : https://github.com/Viktorminator +//! author : Menelion Elensúle : https://github.com/Oire +//! author : Коренберг Марк : https://github.com/socketpair + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 + ? forms[0] + : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) + ? forms[1] + : forms[2]; + } + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + ss: withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', + mm: withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут', + hh: 'час_часа_часов', + dd: 'день_дня_дней', + ww: 'неделя_недели_недель', + MM: 'месяц_месяца_месяцев', + yy: 'год_года_лет', + }; + if (key === 'm') { + return withoutSuffix ? 'минута' : 'минуту'; + } else { + return number + ' ' + plural(format[key], +number); + } + } + var monthsParse = [ + /^янв/i, + /^фев/i, + /^мар/i, + /^апр/i, + /^ма[йя]/i, + /^июн/i, + /^июл/i, + /^авг/i, + /^сен/i, + /^окт/i, + /^ноя/i, + /^дек/i, + ]; + + // http://new.gramota.ru/spravka/rules/139-prop : § 103 + // Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637 + // CLDR data: http://www.unicode.org/cldr/charts/28/summary/ru.html#1753 + var ru = moment.defineLocale('ru', { + months: { + format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split( + '_' + ), + standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split( + '_' + ), + }, + monthsShort: { + // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку? + format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split( + '_' + ), + standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split( + '_' + ), + }, + weekdays: { + standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split( + '_' + ), + format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split( + '_' + ), + isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?] ?dddd/, + }, + weekdaysShort: 'вс_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin: 'вс_пн_вт_ср_чт_пт_сб'.split('_'), + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + + // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки + monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, + + // копия предыдущего + monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, + + // полные названия с падежами + monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i, + + // Выражение, которое соответствует только сокращённым формам + monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY г.', + LLL: 'D MMMM YYYY г., H:mm', + LLLL: 'dddd, D MMMM YYYY г., H:mm', + }, + calendar: { + sameDay: '[Сегодня, в] LT', + nextDay: '[Завтра, в] LT', + lastDay: '[Вчера, в] LT', + nextWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В следующее] dddd, [в] LT'; + case 1: + case 2: + case 4: + return '[В следующий] dddd, [в] LT'; + case 3: + case 5: + case 6: + return '[В следующую] dddd, [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd, [в] LT'; + } else { + return '[В] dddd, [в] LT'; + } + } + }, + lastWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В прошлое] dddd, [в] LT'; + case 1: + case 2: + case 4: + return '[В прошлый] dddd, [в] LT'; + case 3: + case 5: + case 6: + return '[В прошлую] dddd, [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd, [в] LT'; + } else { + return '[В] dddd, [в] LT'; + } + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'через %s', + past: '%s назад', + s: 'несколько секунд', + ss: relativeTimeWithPlural, + m: relativeTimeWithPlural, + mm: relativeTimeWithPlural, + h: 'час', + hh: relativeTimeWithPlural, + d: 'день', + dd: relativeTimeWithPlural, + w: 'неделя', + ww: relativeTimeWithPlural, + M: 'месяц', + MM: relativeTimeWithPlural, + y: 'год', + yy: relativeTimeWithPlural, + }, + meridiemParse: /ночи|утра|дня|вечера/i, + isPM: function (input) { + return /^(дня|вечера)$/.test(input); + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'ночи'; + } else if (hour < 12) { + return 'утра'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечера'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + return number + '-й'; + case 'D': + return number + '-го'; + case 'w': + case 'W': + return number + '-я'; + default: + return number; + } + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return ru; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/sd.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/sd.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Sindhi [sd] +//! author : Narain Sagar : https://github.com/narainsagar + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var months = [ + 'جنوري', + 'فيبروري', + 'مارچ', + 'اپريل', + 'مئي', + 'جون', + 'جولاءِ', + 'آگسٽ', + 'سيپٽمبر', + 'آڪٽوبر', + 'نومبر', + 'ڊسمبر', + ], + days = ['آچر', 'سومر', 'اڱارو', 'اربع', 'خميس', 'جمع', 'ڇنڇر']; + + var sd = moment.defineLocale('sd', { + months: months, + monthsShort: months, + weekdays: days, + weekdaysShort: days, + weekdaysMin: days, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd، D MMMM YYYY HH:mm', + }, + meridiemParse: /صبح|شام/, + isPM: function (input) { + return 'شام' === input; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'صبح'; + } + return 'شام'; + }, + calendar: { + sameDay: '[اڄ] LT', + nextDay: '[سڀاڻي] LT', + nextWeek: 'dddd [اڳين هفتي تي] LT', + lastDay: '[ڪالهه] LT', + lastWeek: '[گزريل هفتي] dddd [تي] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s پوء', + past: '%s اڳ', + s: 'چند سيڪنڊ', + ss: '%d سيڪنڊ', + m: 'هڪ منٽ', + mm: '%d منٽ', + h: 'هڪ ڪلاڪ', + hh: '%d ڪلاڪ', + d: 'هڪ ڏينهن', + dd: '%d ڏينهن', + M: 'هڪ مهينو', + MM: '%d مهينا', + y: 'هڪ سال', + yy: '%d سال', + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return sd; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/se.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/se.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Northern Sami [se] +//! authors : Bård Rolstad Henriksen : https://github.com/karamell + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var se = moment.defineLocale('se', { + months: 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split( + '_' + ), + monthsShort: 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split( + '_' + ), + weekdays: 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split( + '_' + ), + weekdaysShort: 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'), + weekdaysMin: 's_v_m_g_d_b_L'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'MMMM D. [b.] YYYY', + LLL: 'MMMM D. [b.] YYYY [ti.] HH:mm', + LLLL: 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm', + }, + calendar: { + sameDay: '[otne ti] LT', + nextDay: '[ihttin ti] LT', + nextWeek: 'dddd [ti] LT', + lastDay: '[ikte ti] LT', + lastWeek: '[ovddit] dddd [ti] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s geažes', + past: 'maŋit %s', + s: 'moadde sekunddat', + ss: '%d sekunddat', + m: 'okta minuhta', + mm: '%d minuhtat', + h: 'okta diimmu', + hh: '%d diimmut', + d: 'okta beaivi', + dd: '%d beaivvit', + M: 'okta mánnu', + MM: '%d mánut', + y: 'okta jahki', + yy: '%d jagit', + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return se; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/si.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/si.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Sinhalese [si] +//! author : Sampath Sitinamaluwa : https://github.com/sampathsris + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + /*jshint -W100*/ + var si = moment.defineLocale('si', { + months: 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split( + '_' + ), + monthsShort: 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split( + '_' + ), + weekdays: 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split( + '_' + ), + weekdaysShort: 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'), + weekdaysMin: 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'a h:mm', + LTS: 'a h:mm:ss', + L: 'YYYY/MM/DD', + LL: 'YYYY MMMM D', + LLL: 'YYYY MMMM D, a h:mm', + LLLL: 'YYYY MMMM D [වැනි] dddd, a h:mm:ss', + }, + calendar: { + sameDay: '[අද] LT[ට]', + nextDay: '[හෙට] LT[ට]', + nextWeek: 'dddd LT[ට]', + lastDay: '[ඊයේ] LT[ට]', + lastWeek: '[පසුගිය] dddd LT[ට]', + sameElse: 'L', + }, + relativeTime: { + future: '%sකින්', + past: '%sකට පෙර', + s: 'තත්පර කිහිපය', + ss: 'තත්පර %d', + m: 'මිනිත්තුව', + mm: 'මිනිත්තු %d', + h: 'පැය', + hh: 'පැය %d', + d: 'දිනය', + dd: 'දින %d', + M: 'මාසය', + MM: 'මාස %d', + y: 'වසර', + yy: 'වසර %d', + }, + dayOfMonthOrdinalParse: /\d{1,2} වැනි/, + ordinal: function (number) { + return number + ' වැනි'; + }, + meridiemParse: /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./, + isPM: function (input) { + return input === 'ප.ව.' || input === 'පස් වරු'; + }, + meridiem: function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'ප.ව.' : 'පස් වරු'; + } else { + return isLower ? 'පෙ.ව.' : 'පෙර වරු'; + } + }, + }); + + return si; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/sk.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/sk.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Slovak [sk] +//! author : Martin Minka : https://github.com/k2s +//! based on work of petrbela : https://github.com/petrbela + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split( + '_' + ), + monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_'); + function plural(n) { + return n > 1 && n < 5; + } + function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return withoutSuffix || isFuture ? 'pár sekúnd' : 'pár sekundami'; + case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'sekundy' : 'sekúnd'); + } else { + return result + 'sekundami'; + } + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minúta' : isFuture ? 'minútu' : 'minútou'; + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'minúty' : 'minút'); + } else { + return result + 'minútami'; + } + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : isFuture ? 'hodinu' : 'hodinou'; + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'hodiny' : 'hodín'); + } else { + return result + 'hodinami'; + } + case 'd': // a day / in a day / a day ago + return withoutSuffix || isFuture ? 'deň' : 'dňom'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'dni' : 'dní'); + } else { + return result + 'dňami'; + } + case 'M': // a month / in a month / a month ago + return withoutSuffix || isFuture ? 'mesiac' : 'mesiacom'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'mesiace' : 'mesiacov'); + } else { + return result + 'mesiacmi'; + } + case 'y': // a year / in a year / a year ago + return withoutSuffix || isFuture ? 'rok' : 'rokom'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'roky' : 'rokov'); + } else { + return result + 'rokmi'; + } + } + } + + var sk = moment.defineLocale('sk', { + months: months, + monthsShort: monthsShort, + weekdays: 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'), + weekdaysShort: 'ne_po_ut_st_št_pi_so'.split('_'), + weekdaysMin: 'ne_po_ut_st_št_pi_so'.split('_'), + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd D. MMMM YYYY H:mm', + }, + calendar: { + sameDay: '[dnes o] LT', + nextDay: '[zajtra o] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v nedeľu o] LT'; + case 1: + case 2: + return '[v] dddd [o] LT'; + case 3: + return '[v stredu o] LT'; + case 4: + return '[vo štvrtok o] LT'; + case 5: + return '[v piatok o] LT'; + case 6: + return '[v sobotu o] LT'; + } + }, + lastDay: '[včera o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulú nedeľu o] LT'; + case 1: + case 2: + return '[minulý] dddd [o] LT'; + case 3: + return '[minulú stredu o] LT'; + case 4: + case 5: + return '[minulý] dddd [o] LT'; + case 6: + return '[minulú sobotu o] LT'; + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'za %s', + past: 'pred %s', + s: translate, + ss: translate, + m: translate, + mm: translate, + h: translate, + hh: translate, + d: translate, + dd: translate, + M: translate, + MM: translate, + y: translate, + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return sk; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/sl.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/sl.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Slovenian [sl] +//! author : Robert Sedovšek : https://github.com/sedovsek + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': + return withoutSuffix || isFuture + ? 'nekaj sekund' + : 'nekaj sekundami'; + case 'ss': + if (number === 1) { + result += withoutSuffix ? 'sekundo' : 'sekundi'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'sekundi' : 'sekundah'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'sekunde' : 'sekundah'; + } else { + result += 'sekund'; + } + return result; + case 'm': + return withoutSuffix ? 'ena minuta' : 'eno minuto'; + case 'mm': + if (number === 1) { + result += withoutSuffix ? 'minuta' : 'minuto'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'minuti' : 'minutama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'minute' : 'minutami'; + } else { + result += withoutSuffix || isFuture ? 'minut' : 'minutami'; + } + return result; + case 'h': + return withoutSuffix ? 'ena ura' : 'eno uro'; + case 'hh': + if (number === 1) { + result += withoutSuffix ? 'ura' : 'uro'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'uri' : 'urama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'ure' : 'urami'; + } else { + result += withoutSuffix || isFuture ? 'ur' : 'urami'; + } + return result; + case 'd': + return withoutSuffix || isFuture ? 'en dan' : 'enim dnem'; + case 'dd': + if (number === 1) { + result += withoutSuffix || isFuture ? 'dan' : 'dnem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'dni' : 'dnevoma'; + } else { + result += withoutSuffix || isFuture ? 'dni' : 'dnevi'; + } + return result; + case 'M': + return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem'; + case 'MM': + if (number === 1) { + result += withoutSuffix || isFuture ? 'mesec' : 'mesecem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'meseca' : 'mesecema'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'mesece' : 'meseci'; + } else { + result += withoutSuffix || isFuture ? 'mesecev' : 'meseci'; + } + return result; + case 'y': + return withoutSuffix || isFuture ? 'eno leto' : 'enim letom'; + case 'yy': + if (number === 1) { + result += withoutSuffix || isFuture ? 'leto' : 'letom'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'leti' : 'letoma'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'leta' : 'leti'; + } else { + result += withoutSuffix || isFuture ? 'let' : 'leti'; + } + return result; + } + } + + var sl = moment.defineLocale('sl', { + months: 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split( + '_' + ), + monthsShort: 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), + weekdaysShort: 'ned._pon._tor._sre._čet._pet._sob.'.split('_'), + weekdaysMin: 'ne_po_to_sr_če_pe_so'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD. MM. YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm', + }, + calendar: { + sameDay: '[danes ob] LT', + nextDay: '[jutri ob] LT', + + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v] [nedeljo] [ob] LT'; + case 3: + return '[v] [sredo] [ob] LT'; + case 6: + return '[v] [soboto] [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[v] dddd [ob] LT'; + } + }, + lastDay: '[včeraj ob] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[prejšnjo] [nedeljo] [ob] LT'; + case 3: + return '[prejšnjo] [sredo] [ob] LT'; + case 6: + return '[prejšnjo] [soboto] [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prejšnji] dddd [ob] LT'; + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'čez %s', + past: 'pred %s', + s: processRelativeTime, + ss: processRelativeTime, + m: processRelativeTime, + mm: processRelativeTime, + h: processRelativeTime, + hh: processRelativeTime, + d: processRelativeTime, + dd: processRelativeTime, + M: processRelativeTime, + MM: processRelativeTime, + y: processRelativeTime, + yy: processRelativeTime, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return sl; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/sq.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/sq.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Albanian [sq] +//! author : Flakërim Ismani : https://github.com/flakerimi +//! author : Menelion Elensúle : https://github.com/Oire +//! author : Oerd Cukalla : https://github.com/oerd + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var sq = moment.defineLocale('sq', { + months: 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split( + '_' + ), + monthsShort: 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'), + weekdays: 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split( + '_' + ), + weekdaysShort: 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'), + weekdaysMin: 'D_H_Ma_Më_E_P_Sh'.split('_'), + weekdaysParseExact: true, + meridiemParse: /PD|MD/, + isPM: function (input) { + return input.charAt(0) === 'M'; + }, + meridiem: function (hours, minutes, isLower) { + return hours < 12 ? 'PD' : 'MD'; + }, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Sot në] LT', + nextDay: '[Nesër në] LT', + nextWeek: 'dddd [në] LT', + lastDay: '[Dje në] LT', + lastWeek: 'dddd [e kaluar në] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'në %s', + past: '%s më parë', + s: 'disa sekonda', + ss: '%d sekonda', + m: 'një minutë', + mm: '%d minuta', + h: 'një orë', + hh: '%d orë', + d: 'një ditë', + dd: '%d ditë', + M: 'një muaj', + MM: '%d muaj', + y: 'një vit', + yy: '%d vite', + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return sq; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/sr-cyrl.js": +/*!*****************************************************!*\ + !*** ../eyes/node_modules/moment/locale/sr-cyrl.js ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Serbian Cyrillic [sr-cyrl] +//! author : Milan Janačković : https://github.com/milan-j +//! author : Stefan Crnjaković : https://github.com/crnjakovic + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var translator = { + words: { + //Different grammatical cases + ss: ['секунда', 'секунде', 'секунди'], + m: ['један минут', 'једне минуте'], + mm: ['минут', 'минуте', 'минута'], + h: ['један сат', 'једног сата'], + hh: ['сат', 'сата', 'сати'], + dd: ['дан', 'дана', 'дана'], + MM: ['месец', 'месеца', 'месеци'], + yy: ['година', 'године', 'година'], + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 + ? wordKey[0] + : number >= 2 && number <= 4 + ? wordKey[1] + : wordKey[2]; + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return ( + number + + ' ' + + translator.correctGrammaticalCase(number, wordKey) + ); + } + }, + }; + + var srCyrl = moment.defineLocale('sr-cyrl', { + months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split( + '_' + ), + monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'), + weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'), + weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'D. M. YYYY.', + LL: 'D. MMMM YYYY.', + LLL: 'D. MMMM YYYY. H:mm', + LLLL: 'dddd, D. MMMM YYYY. H:mm', + }, + calendar: { + sameDay: '[данас у] LT', + nextDay: '[сутра у] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[у] [недељу] [у] LT'; + case 3: + return '[у] [среду] [у] LT'; + case 6: + return '[у] [суботу] [у] LT'; + case 1: + case 2: + case 4: + case 5: + return '[у] dddd [у] LT'; + } + }, + lastDay: '[јуче у] LT', + lastWeek: function () { + var lastWeekDays = [ + '[прошле] [недеље] [у] LT', + '[прошлог] [понедељка] [у] LT', + '[прошлог] [уторка] [у] LT', + '[прошле] [среде] [у] LT', + '[прошлог] [четвртка] [у] LT', + '[прошлог] [петка] [у] LT', + '[прошле] [суботе] [у] LT', + ]; + return lastWeekDays[this.day()]; + }, + sameElse: 'L', + }, + relativeTime: { + future: 'за %s', + past: 'пре %s', + s: 'неколико секунди', + ss: translator.translate, + m: translator.translate, + mm: translator.translate, + h: translator.translate, + hh: translator.translate, + d: 'дан', + dd: translator.translate, + M: 'месец', + MM: translator.translate, + y: 'годину', + yy: translator.translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 1st is the first week of the year. + }, + }); + + return srCyrl; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/sr.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/sr.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Serbian [sr] +//! author : Milan Janačković : https://github.com/milan-j +//! author : Stefan Crnjaković : https://github.com/crnjakovic + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var translator = { + words: { + //Different grammatical cases + ss: ['sekunda', 'sekunde', 'sekundi'], + m: ['jedan minut', 'jedne minute'], + mm: ['minut', 'minute', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mesec', 'meseca', 'meseci'], + yy: ['godina', 'godine', 'godina'], + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 + ? wordKey[0] + : number >= 2 && number <= 4 + ? wordKey[1] + : wordKey[2]; + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return ( + number + + ' ' + + translator.correctGrammaticalCase(number, wordKey) + ); + } + }, + }; + + var sr = moment.defineLocale('sr', { + months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split( + '_' + ), + monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split( + '_' + ), + weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'), + weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'D. M. YYYY.', + LL: 'D. MMMM YYYY.', + LLL: 'D. MMMM YYYY. H:mm', + LLLL: 'dddd, D. MMMM YYYY. H:mm', + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sutra u] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedelju] [u] LT'; + case 3: + return '[u] [sredu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay: '[juče u] LT', + lastWeek: function () { + var lastWeekDays = [ + '[prošle] [nedelje] [u] LT', + '[prošlog] [ponedeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT', + ]; + return lastWeekDays[this.day()]; + }, + sameElse: 'L', + }, + relativeTime: { + future: 'za %s', + past: 'pre %s', + s: 'nekoliko sekundi', + ss: translator.translate, + m: translator.translate, + mm: translator.translate, + h: translator.translate, + hh: translator.translate, + d: 'dan', + dd: translator.translate, + M: 'mesec', + MM: translator.translate, + y: 'godinu', + yy: translator.translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return sr; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ss.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ss.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : siSwati [ss] +//! author : Nicolai Davies : https://github.com/nicolaidavies + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var ss = moment.defineLocale('ss', { + months: "Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split( + '_' + ), + monthsShort: 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'), + weekdays: 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split( + '_' + ), + weekdaysShort: 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'), + weekdaysMin: 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'h:mm A', + LTS: 'h:mm:ss A', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY h:mm A', + LLLL: 'dddd, D MMMM YYYY h:mm A', + }, + calendar: { + sameDay: '[Namuhla nga] LT', + nextDay: '[Kusasa nga] LT', + nextWeek: 'dddd [nga] LT', + lastDay: '[Itolo nga] LT', + lastWeek: 'dddd [leliphelile] [nga] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'nga %s', + past: 'wenteka nga %s', + s: 'emizuzwana lomcane', + ss: '%d mzuzwana', + m: 'umzuzu', + mm: '%d emizuzu', + h: 'lihora', + hh: '%d emahora', + d: 'lilanga', + dd: '%d emalanga', + M: 'inyanga', + MM: '%d tinyanga', + y: 'umnyaka', + yy: '%d iminyaka', + }, + meridiemParse: /ekuseni|emini|entsambama|ebusuku/, + meridiem: function (hours, minutes, isLower) { + if (hours < 11) { + return 'ekuseni'; + } else if (hours < 15) { + return 'emini'; + } else if (hours < 19) { + return 'entsambama'; + } else { + return 'ebusuku'; + } + }, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ekuseni') { + return hour; + } else if (meridiem === 'emini') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') { + if (hour === 0) { + return 0; + } + return hour + 12; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal: '%d', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return ss; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/sv.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/sv.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Swedish [sv] +//! author : Jens Alm : https://github.com/ulmus + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var sv = moment.defineLocale('sv', { + months: 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split( + '_' + ), + monthsShort: 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays: 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'), + weekdaysShort: 'sön_mån_tis_ons_tor_fre_lör'.split('_'), + weekdaysMin: 'sö_må_ti_on_to_fr_lö'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY-MM-DD', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY [kl.] HH:mm', + LLLL: 'dddd D MMMM YYYY [kl.] HH:mm', + lll: 'D MMM YYYY HH:mm', + llll: 'ddd D MMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Idag] LT', + nextDay: '[Imorgon] LT', + lastDay: '[Igår] LT', + nextWeek: '[På] dddd LT', + lastWeek: '[I] dddd[s] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'om %s', + past: 'för %s sedan', + s: 'några sekunder', + ss: '%d sekunder', + m: 'en minut', + mm: '%d minuter', + h: 'en timme', + hh: '%d timmar', + d: 'en dag', + dd: '%d dagar', + M: 'en månad', + MM: '%d månader', + y: 'ett år', + yy: '%d år', + }, + dayOfMonthOrdinalParse: /\d{1,2}(\:e|\:a)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? ':e' + : b === 1 + ? ':a' + : b === 2 + ? ':a' + : b === 3 + ? ':e' + : ':e'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return sv; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/sw.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/sw.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Swahili [sw] +//! author : Fahad Kassim : https://github.com/fadsel + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var sw = moment.defineLocale('sw', { + months: 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split( + '_' + ), + monthsShort: 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'), + weekdays: 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split( + '_' + ), + weekdaysShort: 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'), + weekdaysMin: 'J2_J3_J4_J5_Al_Ij_J1'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'hh:mm A', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[leo saa] LT', + nextDay: '[kesho saa] LT', + nextWeek: '[wiki ijayo] dddd [saat] LT', + lastDay: '[jana] LT', + lastWeek: '[wiki iliyopita] dddd [saat] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s baadaye', + past: 'tokea %s', + s: 'hivi punde', + ss: 'sekunde %d', + m: 'dakika moja', + mm: 'dakika %d', + h: 'saa limoja', + hh: 'masaa %d', + d: 'siku moja', + dd: 'siku %d', + M: 'mwezi mmoja', + MM: 'miezi %d', + y: 'mwaka mmoja', + yy: 'miaka %d', + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return sw; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ta.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ta.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Tamil [ta] +//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404 + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var symbolMap = { + 1: '௧', + 2: '௨', + 3: '௩', + 4: '௪', + 5: '௫', + 6: '௬', + 7: '௭', + 8: '௮', + 9: '௯', + 0: '௦', + }, + numberMap = { + '௧': '1', + '௨': '2', + '௩': '3', + '௪': '4', + '௫': '5', + '௬': '6', + '௭': '7', + '௮': '8', + '௯': '9', + '௦': '0', + }; + + var ta = moment.defineLocale('ta', { + months: 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split( + '_' + ), + monthsShort: 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split( + '_' + ), + weekdays: 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split( + '_' + ), + weekdaysShort: 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split( + '_' + ), + weekdaysMin: 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, HH:mm', + LLLL: 'dddd, D MMMM YYYY, HH:mm', + }, + calendar: { + sameDay: '[இன்று] LT', + nextDay: '[நாளை] LT', + nextWeek: 'dddd, LT', + lastDay: '[நேற்று] LT', + lastWeek: '[கடந்த வாரம்] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s இல்', + past: '%s முன்', + s: 'ஒரு சில விநாடிகள்', + ss: '%d விநாடிகள்', + m: 'ஒரு நிமிடம்', + mm: '%d நிமிடங்கள்', + h: 'ஒரு மணி நேரம்', + hh: '%d மணி நேரம்', + d: 'ஒரு நாள்', + dd: '%d நாட்கள்', + M: 'ஒரு மாதம்', + MM: '%d மாதங்கள்', + y: 'ஒரு வருடம்', + yy: '%d ஆண்டுகள்', + }, + dayOfMonthOrdinalParse: /\d{1,2}வது/, + ordinal: function (number) { + return number + 'வது'; + }, + preparse: function (string) { + return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // refer http://ta.wikipedia.org/s/1er1 + meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/, + meridiem: function (hour, minute, isLower) { + if (hour < 2) { + return ' யாமம்'; + } else if (hour < 6) { + return ' வைகறை'; // வைகறை + } else if (hour < 10) { + return ' காலை'; // காலை + } else if (hour < 14) { + return ' நண்பகல்'; // நண்பகல் + } else if (hour < 18) { + return ' எற்பாடு'; // எற்பாடு + } else if (hour < 22) { + return ' மாலை'; // மாலை + } else { + return ' யாமம்'; + } + }, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'யாமம்') { + return hour < 2 ? hour : hour + 12; + } else if (meridiem === 'வைகறை' || meridiem === 'காலை') { + return hour; + } else if (meridiem === 'நண்பகல்') { + return hour >= 10 ? hour : hour + 12; + } else { + return hour + 12; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return ta; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/te.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/te.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Telugu [te] +//! author : Krishna Chaitanya Thota : https://github.com/kcthota + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var te = moment.defineLocale('te', { + months: 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జులై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split( + '_' + ), + monthsShort: 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జులై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split( + '_' + ), + weekdaysShort: 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'), + weekdaysMin: 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'), + longDateFormat: { + LT: 'A h:mm', + LTS: 'A h:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm', + LLLL: 'dddd, D MMMM YYYY, A h:mm', + }, + calendar: { + sameDay: '[నేడు] LT', + nextDay: '[రేపు] LT', + nextWeek: 'dddd, LT', + lastDay: '[నిన్న] LT', + lastWeek: '[గత] dddd, LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s లో', + past: '%s క్రితం', + s: 'కొన్ని క్షణాలు', + ss: '%d సెకన్లు', + m: 'ఒక నిమిషం', + mm: '%d నిమిషాలు', + h: 'ఒక గంట', + hh: '%d గంటలు', + d: 'ఒక రోజు', + dd: '%d రోజులు', + M: 'ఒక నెల', + MM: '%d నెలలు', + y: 'ఒక సంవత్సరం', + yy: '%d సంవత్సరాలు', + }, + dayOfMonthOrdinalParse: /\d{1,2}వ/, + ordinal: '%dవ', + meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'రాత్రి') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ఉదయం') { + return hour; + } else if (meridiem === 'మధ్యాహ్నం') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'సాయంత్రం') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'రాత్రి'; + } else if (hour < 10) { + return 'ఉదయం'; + } else if (hour < 17) { + return 'మధ్యాహ్నం'; + } else if (hour < 20) { + return 'సాయంత్రం'; + } else { + return 'రాత్రి'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }, + }); + + return te; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/tet.js": +/*!*************************************************!*\ + !*** ../eyes/node_modules/moment/locale/tet.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Tetun Dili (East Timor) [tet] +//! author : Joshua Brooks : https://github.com/joshbrooks +//! author : Onorio De J. Afonso : https://github.com/marobo +//! author : Sonia Simoes : https://github.com/soniasimoes + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var tet = moment.defineLocale('tet', { + months: 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juñu_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru'.split( + '_' + ), + monthsShort: 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), + weekdays: 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu'.split('_'), + weekdaysShort: 'Dom_Seg_Ters_Kua_Kint_Sest_Sab'.split('_'), + weekdaysMin: 'Do_Seg_Te_Ku_Ki_Ses_Sa'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Ohin iha] LT', + nextDay: '[Aban iha] LT', + nextWeek: 'dddd [iha] LT', + lastDay: '[Horiseik iha] LT', + lastWeek: 'dddd [semana kotuk] [iha] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'iha %s', + past: '%s liuba', + s: 'segundu balun', + ss: 'segundu %d', + m: 'minutu ida', + mm: 'minutu %d', + h: 'oras ida', + hh: 'oras %d', + d: 'loron ida', + dd: 'loron %d', + M: 'fulan ida', + MM: 'fulan %d', + y: 'tinan ida', + yy: 'tinan %d', + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return tet; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/tg.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/tg.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Tajik [tg] +//! author : Orif N. Jr. : https://github.com/orif-jr + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var suffixes = { + 0: '-ум', + 1: '-ум', + 2: '-юм', + 3: '-юм', + 4: '-ум', + 5: '-ум', + 6: '-ум', + 7: '-ум', + 8: '-ум', + 9: '-ум', + 10: '-ум', + 12: '-ум', + 13: '-ум', + 20: '-ум', + 30: '-юм', + 40: '-ум', + 50: '-ум', + 60: '-ум', + 70: '-ум', + 80: '-ум', + 90: '-ум', + 100: '-ум', + }; + + var tg = moment.defineLocale('tg', { + months: { + format: 'январи_феврали_марти_апрели_майи_июни_июли_августи_сентябри_октябри_ноябри_декабри'.split( + '_' + ), + standalone: 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split( + '_' + ), + }, + monthsShort: 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), + weekdays: 'якшанбе_душанбе_сешанбе_чоршанбе_панҷшанбе_ҷумъа_шанбе'.split( + '_' + ), + weekdaysShort: 'яшб_дшб_сшб_чшб_пшб_ҷум_шнб'.split('_'), + weekdaysMin: 'яш_дш_сш_чш_пш_ҷм_шб'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Имрӯз соати] LT', + nextDay: '[Фардо соати] LT', + lastDay: '[Дирӯз соати] LT', + nextWeek: 'dddd[и] [ҳафтаи оянда соати] LT', + lastWeek: 'dddd[и] [ҳафтаи гузашта соати] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'баъди %s', + past: '%s пеш', + s: 'якчанд сония', + m: 'як дақиқа', + mm: '%d дақиқа', + h: 'як соат', + hh: '%d соат', + d: 'як рӯз', + dd: '%d рӯз', + M: 'як моҳ', + MM: '%d моҳ', + y: 'як сол', + yy: '%d сол', + }, + meridiemParse: /шаб|субҳ|рӯз|бегоҳ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'шаб') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'субҳ') { + return hour; + } else if (meridiem === 'рӯз') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'бегоҳ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'шаб'; + } else if (hour < 11) { + return 'субҳ'; + } else if (hour < 16) { + return 'рӯз'; + } else if (hour < 19) { + return 'бегоҳ'; + } else { + return 'шаб'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ум|юм)/, + ordinal: function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes[number] || suffixes[a] || suffixes[b]); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 1th is the first week of the year. + }, + }); + + return tg; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/th.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/th.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Thai [th] +//! author : Kridsada Thanabulpong : https://github.com/sirn + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var th = moment.defineLocale('th', { + months: 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split( + '_' + ), + monthsShort: 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'), + weekdaysShort: 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference + weekdaysMin: 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'H:mm', + LTS: 'H:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY เวลา H:mm', + LLLL: 'วันddddที่ D MMMM YYYY เวลา H:mm', + }, + meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/, + isPM: function (input) { + return input === 'หลังเที่ยง'; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ก่อนเที่ยง'; + } else { + return 'หลังเที่ยง'; + } + }, + calendar: { + sameDay: '[วันนี้ เวลา] LT', + nextDay: '[พรุ่งนี้ เวลา] LT', + nextWeek: 'dddd[หน้า เวลา] LT', + lastDay: '[เมื่อวานนี้ เวลา] LT', + lastWeek: '[วัน]dddd[ที่แล้ว เวลา] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'อีก %s', + past: '%sที่แล้ว', + s: 'ไม่กี่วินาที', + ss: '%d วินาที', + m: '1 นาที', + mm: '%d นาที', + h: '1 ชั่วโมง', + hh: '%d ชั่วโมง', + d: '1 วัน', + dd: '%d วัน', + w: '1 สัปดาห์', + ww: '%d สัปดาห์', + M: '1 เดือน', + MM: '%d เดือน', + y: '1 ปี', + yy: '%d ปี', + }, + }); + + return th; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/tk.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/tk.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Turkmen [tk] +//! author : Atamyrat Abdyrahmanov : https://github.com/atamyratabdy + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var suffixes = { + 1: "'inji", + 5: "'inji", + 8: "'inji", + 70: "'inji", + 80: "'inji", + 2: "'nji", + 7: "'nji", + 20: "'nji", + 50: "'nji", + 3: "'ünji", + 4: "'ünji", + 100: "'ünji", + 6: "'njy", + 9: "'unjy", + 10: "'unjy", + 30: "'unjy", + 60: "'ynjy", + 90: "'ynjy", + }; + + var tk = moment.defineLocale('tk', { + months: 'Ýanwar_Fewral_Mart_Aprel_Maý_Iýun_Iýul_Awgust_Sentýabr_Oktýabr_Noýabr_Dekabr'.split( + '_' + ), + monthsShort: 'Ýan_Few_Mar_Apr_Maý_Iýn_Iýl_Awg_Sen_Okt_Noý_Dek'.split('_'), + weekdays: 'Ýekşenbe_Duşenbe_Sişenbe_Çarşenbe_Penşenbe_Anna_Şenbe'.split( + '_' + ), + weekdaysShort: 'Ýek_Duş_Siş_Çar_Pen_Ann_Şen'.split('_'), + weekdaysMin: 'Ýk_Dş_Sş_Çr_Pn_An_Şn'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[bugün sagat] LT', + nextDay: '[ertir sagat] LT', + nextWeek: '[indiki] dddd [sagat] LT', + lastDay: '[düýn] LT', + lastWeek: '[geçen] dddd [sagat] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s soň', + past: '%s öň', + s: 'birnäçe sekunt', + m: 'bir minut', + mm: '%d minut', + h: 'bir sagat', + hh: '%d sagat', + d: 'bir gün', + dd: '%d gün', + M: 'bir aý', + MM: '%d aý', + y: 'bir ýyl', + yy: '%d ýyl', + }, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'Do': + case 'DD': + return number; + default: + if (number === 0) { + // special case for zero + return number + "'unjy"; + } + var a = number % 10, + b = (number % 100) - a, + c = number >= 100 ? 100 : null; + return number + (suffixes[a] || suffixes[b] || suffixes[c]); + } + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return tk; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/tl-ph.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/tl-ph.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Tagalog (Philippines) [tl-ph] +//! author : Dan Hagman : https://github.com/hagmandan + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var tlPh = moment.defineLocale('tl-ph', { + months: 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split( + '_' + ), + monthsShort: 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'), + weekdays: 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split( + '_' + ), + weekdaysShort: 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'), + weekdaysMin: 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'MM/D/YYYY', + LL: 'MMMM D, YYYY', + LLL: 'MMMM D, YYYY HH:mm', + LLLL: 'dddd, MMMM DD, YYYY HH:mm', + }, + calendar: { + sameDay: 'LT [ngayong araw]', + nextDay: '[Bukas ng] LT', + nextWeek: 'LT [sa susunod na] dddd', + lastDay: 'LT [kahapon]', + lastWeek: 'LT [noong nakaraang] dddd', + sameElse: 'L', + }, + relativeTime: { + future: 'sa loob ng %s', + past: '%s ang nakalipas', + s: 'ilang segundo', + ss: '%d segundo', + m: 'isang minuto', + mm: '%d minuto', + h: 'isang oras', + hh: '%d oras', + d: 'isang araw', + dd: '%d araw', + M: 'isang buwan', + MM: '%d buwan', + y: 'isang taon', + yy: '%d taon', + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal: function (number) { + return number; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return tlPh; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/tlh.js": +/*!*************************************************!*\ + !*** ../eyes/node_modules/moment/locale/tlh.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Klingon [tlh] +//! author : Dominika Kruk : https://github.com/amaranthrose + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_'); + + function translateFuture(output) { + var time = output; + time = + output.indexOf('jaj') !== -1 + ? time.slice(0, -3) + 'leS' + : output.indexOf('jar') !== -1 + ? time.slice(0, -3) + 'waQ' + : output.indexOf('DIS') !== -1 + ? time.slice(0, -3) + 'nem' + : time + ' pIq'; + return time; + } + + function translatePast(output) { + var time = output; + time = + output.indexOf('jaj') !== -1 + ? time.slice(0, -3) + 'Hu’' + : output.indexOf('jar') !== -1 + ? time.slice(0, -3) + 'wen' + : output.indexOf('DIS') !== -1 + ? time.slice(0, -3) + 'ben' + : time + ' ret'; + return time; + } + + function translate(number, withoutSuffix, string, isFuture) { + var numberNoun = numberAsNoun(number); + switch (string) { + case 'ss': + return numberNoun + ' lup'; + case 'mm': + return numberNoun + ' tup'; + case 'hh': + return numberNoun + ' rep'; + case 'dd': + return numberNoun + ' jaj'; + case 'MM': + return numberNoun + ' jar'; + case 'yy': + return numberNoun + ' DIS'; + } + } + + function numberAsNoun(number) { + var hundred = Math.floor((number % 1000) / 100), + ten = Math.floor((number % 100) / 10), + one = number % 10, + word = ''; + if (hundred > 0) { + word += numbersNouns[hundred] + 'vatlh'; + } + if (ten > 0) { + word += (word !== '' ? ' ' : '') + numbersNouns[ten] + 'maH'; + } + if (one > 0) { + word += (word !== '' ? ' ' : '') + numbersNouns[one]; + } + return word === '' ? 'pagh' : word; + } + + var tlh = moment.defineLocale('tlh', { + months: 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split( + '_' + ), + monthsShort: 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split( + '_' + ), + weekdaysShort: 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split( + '_' + ), + weekdaysMin: 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split( + '_' + ), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[DaHjaj] LT', + nextDay: '[wa’leS] LT', + nextWeek: 'LLL', + lastDay: '[wa’Hu’] LT', + lastWeek: 'LLL', + sameElse: 'L', + }, + relativeTime: { + future: translateFuture, + past: translatePast, + s: 'puS lup', + ss: translate, + m: 'wa’ tup', + mm: translate, + h: 'wa’ rep', + hh: translate, + d: 'wa’ jaj', + dd: translate, + M: 'wa’ jar', + MM: translate, + y: 'wa’ DIS', + yy: translate, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return tlh; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/tr.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/tr.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Turkish [tr] +//! authors : Erhan Gundogan : https://github.com/erhangundogan, +//! Burak Yiğit Kaya: https://github.com/BYK + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var suffixes = { + 1: "'inci", + 5: "'inci", + 8: "'inci", + 70: "'inci", + 80: "'inci", + 2: "'nci", + 7: "'nci", + 20: "'nci", + 50: "'nci", + 3: "'üncü", + 4: "'üncü", + 100: "'üncü", + 6: "'ncı", + 9: "'uncu", + 10: "'uncu", + 30: "'uncu", + 60: "'ıncı", + 90: "'ıncı", + }; + + var tr = moment.defineLocale('tr', { + months: 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split( + '_' + ), + monthsShort: 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'), + weekdays: 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split( + '_' + ), + weekdaysShort: 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'), + weekdaysMin: 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'), + meridiem: function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'öö' : 'ÖÖ'; + } else { + return isLower ? 'ös' : 'ÖS'; + } + }, + meridiemParse: /öö|ÖÖ|ös|ÖS/, + isPM: function (input) { + return input === 'ös' || input === 'ÖS'; + }, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[bugün saat] LT', + nextDay: '[yarın saat] LT', + nextWeek: '[gelecek] dddd [saat] LT', + lastDay: '[dün] LT', + lastWeek: '[geçen] dddd [saat] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s sonra', + past: '%s önce', + s: 'birkaç saniye', + ss: '%d saniye', + m: 'bir dakika', + mm: '%d dakika', + h: 'bir saat', + hh: '%d saat', + d: 'bir gün', + dd: '%d gün', + w: 'bir hafta', + ww: '%d hafta', + M: 'bir ay', + MM: '%d ay', + y: 'bir yıl', + yy: '%d yıl', + }, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'Do': + case 'DD': + return number; + default: + if (number === 0) { + // special case for zero + return number + "'ıncı"; + } + var a = number % 10, + b = (number % 100) - a, + c = number >= 100 ? 100 : null; + return number + (suffixes[a] || suffixes[b] || suffixes[c]); + } + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return tr; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/tzl.js": +/*!*************************************************!*\ + !*** ../eyes/node_modules/moment/locale/tzl.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Talossan [tzl] +//! author : Robin van der Vliet : https://github.com/robin0van0der0v +//! author : Iustì Canun + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + // After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals. + // This is currently too difficult (maybe even impossible) to add. + var tzl = moment.defineLocale('tzl', { + months: 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split( + '_' + ), + monthsShort: 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'), + weekdays: 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'), + weekdaysShort: 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'), + weekdaysMin: 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'), + longDateFormat: { + LT: 'HH.mm', + LTS: 'HH.mm.ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM [dallas] YYYY', + LLL: 'D. MMMM [dallas] YYYY HH.mm', + LLLL: 'dddd, [li] D. MMMM [dallas] YYYY HH.mm', + }, + meridiemParse: /d\'o|d\'a/i, + isPM: function (input) { + return "d'o" === input.toLowerCase(); + }, + meridiem: function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? "d'o" : "D'O"; + } else { + return isLower ? "d'a" : "D'A"; + } + }, + calendar: { + sameDay: '[oxhi à] LT', + nextDay: '[demà à] LT', + nextWeek: 'dddd [à] LT', + lastDay: '[ieiri à] LT', + lastWeek: '[sür el] dddd [lasteu à] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'osprei %s', + past: 'ja%s', + s: processRelativeTime, + ss: processRelativeTime, + m: processRelativeTime, + mm: processRelativeTime, + h: processRelativeTime, + hh: processRelativeTime, + d: processRelativeTime, + dd: processRelativeTime, + M: processRelativeTime, + MM: processRelativeTime, + y: processRelativeTime, + yy: processRelativeTime, + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + s: ['viensas secunds', "'iensas secunds"], + ss: [number + ' secunds', '' + number + ' secunds'], + m: ["'n míut", "'iens míut"], + mm: [number + ' míuts', '' + number + ' míuts'], + h: ["'n þora", "'iensa þora"], + hh: [number + ' þoras', '' + number + ' þoras'], + d: ["'n ziua", "'iensa ziua"], + dd: [number + ' ziuas', '' + number + ' ziuas'], + M: ["'n mes", "'iens mes"], + MM: [number + ' mesen', '' + number + ' mesen'], + y: ["'n ar", "'iens ar"], + yy: [number + ' ars', '' + number + ' ars'], + }; + return isFuture + ? format[key][0] + : withoutSuffix + ? format[key][0] + : format[key][1]; + } + + return tzl; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/tzm-latn.js": +/*!******************************************************!*\ + !*** ../eyes/node_modules/moment/locale/tzm-latn.js ***! + \******************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Central Atlas Tamazight Latin [tzm-latn] +//! author : Abdel Said : https://github.com/abdelsaid + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var tzmLatn = moment.defineLocale('tzm-latn', { + months: 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split( + '_' + ), + monthsShort: 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split( + '_' + ), + weekdays: 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysShort: 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysMin: 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[asdkh g] LT', + nextDay: '[aska g] LT', + nextWeek: 'dddd [g] LT', + lastDay: '[assant g] LT', + lastWeek: 'dddd [g] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'dadkh s yan %s', + past: 'yan %s', + s: 'imik', + ss: '%d imik', + m: 'minuḍ', + mm: '%d minuḍ', + h: 'saɛa', + hh: '%d tassaɛin', + d: 'ass', + dd: '%d ossan', + M: 'ayowr', + MM: '%d iyyirn', + y: 'asgas', + yy: '%d isgasn', + }, + week: { + dow: 6, // Saturday is the first day of the week. + doy: 12, // The week that contains Jan 12th is the first week of the year. + }, + }); + + return tzmLatn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/tzm.js": +/*!*************************************************!*\ + !*** ../eyes/node_modules/moment/locale/tzm.js ***! + \*************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Central Atlas Tamazight [tzm] +//! author : Abdel Said : https://github.com/abdelsaid + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var tzm = moment.defineLocale('tzm', { + months: 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split( + '_' + ), + monthsShort: 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split( + '_' + ), + weekdays: 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysShort: 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysMin: 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[ⴰⵙⴷⵅ ⴴ] LT', + nextDay: '[ⴰⵙⴽⴰ ⴴ] LT', + nextWeek: 'dddd [ⴴ] LT', + lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT', + lastWeek: 'dddd [ⴴ] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s', + past: 'ⵢⴰⵏ %s', + s: 'ⵉⵎⵉⴽ', + ss: '%d ⵉⵎⵉⴽ', + m: 'ⵎⵉⵏⵓⴺ', + mm: '%d ⵎⵉⵏⵓⴺ', + h: 'ⵙⴰⵄⴰ', + hh: '%d ⵜⴰⵙⵙⴰⵄⵉⵏ', + d: 'ⴰⵙⵙ', + dd: '%d oⵙⵙⴰⵏ', + M: 'ⴰⵢoⵓⵔ', + MM: '%d ⵉⵢⵢⵉⵔⵏ', + y: 'ⴰⵙⴳⴰⵙ', + yy: '%d ⵉⵙⴳⴰⵙⵏ', + }, + week: { + dow: 6, // Saturday is the first day of the week. + doy: 12, // The week that contains Jan 12th is the first week of the year. + }, + }); + + return tzm; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ug-cn.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ug-cn.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Uyghur (China) [ug-cn] +//! author: boyaq : https://github.com/boyaq + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var ugCn = moment.defineLocale('ug-cn', { + months: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( + '_' + ), + monthsShort: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( + '_' + ), + weekdays: 'يەكشەنبە_دۈشەنبە_سەيشەنبە_چارشەنبە_پەيشەنبە_جۈمە_شەنبە'.split( + '_' + ), + weekdaysShort: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), + weekdaysMin: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY-MM-DD', + LL: 'YYYY-يىلىM-ئاينىڭD-كۈنى', + LLL: 'YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm', + LLLL: 'dddd، YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm', + }, + meridiemParse: /يېرىم كېچە|سەھەر|چۈشتىن بۇرۇن|چۈش|چۈشتىن كېيىن|كەچ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ( + meridiem === 'يېرىم كېچە' || + meridiem === 'سەھەر' || + meridiem === 'چۈشتىن بۇرۇن' + ) { + return hour; + } else if (meridiem === 'چۈشتىن كېيىن' || meridiem === 'كەچ') { + return hour + 12; + } else { + return hour >= 11 ? hour : hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return 'يېرىم كېچە'; + } else if (hm < 900) { + return 'سەھەر'; + } else if (hm < 1130) { + return 'چۈشتىن بۇرۇن'; + } else if (hm < 1230) { + return 'چۈش'; + } else if (hm < 1800) { + return 'چۈشتىن كېيىن'; + } else { + return 'كەچ'; + } + }, + calendar: { + sameDay: '[بۈگۈن سائەت] LT', + nextDay: '[ئەتە سائەت] LT', + nextWeek: '[كېلەركى] dddd [سائەت] LT', + lastDay: '[تۆنۈگۈن] LT', + lastWeek: '[ئالدىنقى] dddd [سائەت] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s كېيىن', + past: '%s بۇرۇن', + s: 'نەچچە سېكونت', + ss: '%d سېكونت', + m: 'بىر مىنۇت', + mm: '%d مىنۇت', + h: 'بىر سائەت', + hh: '%d سائەت', + d: 'بىر كۈن', + dd: '%d كۈن', + M: 'بىر ئاي', + MM: '%d ئاي', + y: 'بىر يىل', + yy: '%d يىل', + }, + + dayOfMonthOrdinalParse: /\d{1,2}(-كۈنى|-ئاي|-ھەپتە)/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '-كۈنى'; + case 'w': + case 'W': + return number + '-ھەپتە'; + default: + return number; + } + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week: { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 1st is the first week of the year. + }, + }); + + return ugCn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/uk.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/uk.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Ukrainian [uk] +//! author : zemlanin : https://github.com/zemlanin +//! Author : Menelion Elensúle : https://github.com/Oire + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 + ? forms[0] + : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) + ? forms[1] + : forms[2]; + } + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + ss: withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд', + mm: withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин', + hh: withoutSuffix ? 'година_години_годин' : 'годину_години_годин', + dd: 'день_дні_днів', + MM: 'місяць_місяці_місяців', + yy: 'рік_роки_років', + }; + if (key === 'm') { + return withoutSuffix ? 'хвилина' : 'хвилину'; + } else if (key === 'h') { + return withoutSuffix ? 'година' : 'годину'; + } else { + return number + ' ' + plural(format[key], +number); + } + } + function weekdaysCaseReplace(m, format) { + var weekdays = { + nominative: 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split( + '_' + ), + accusative: 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split( + '_' + ), + genitive: 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split( + '_' + ), + }, + nounCase; + + if (m === true) { + return weekdays['nominative'] + .slice(1, 7) + .concat(weekdays['nominative'].slice(0, 1)); + } + if (!m) { + return weekdays['nominative']; + } + + nounCase = /(\[[ВвУу]\]) ?dddd/.test(format) + ? 'accusative' + : /\[?(?:минулої|наступної)? ?\] ?dddd/.test(format) + ? 'genitive' + : 'nominative'; + return weekdays[nounCase][m.day()]; + } + function processHoursFunction(str) { + return function () { + return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT'; + }; + } + + var uk = moment.defineLocale('uk', { + months: { + format: 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split( + '_' + ), + standalone: 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split( + '_' + ), + }, + monthsShort: 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split( + '_' + ), + weekdays: weekdaysCaseReplace, + weekdaysShort: 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin: 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D MMMM YYYY р.', + LLL: 'D MMMM YYYY р., HH:mm', + LLLL: 'dddd, D MMMM YYYY р., HH:mm', + }, + calendar: { + sameDay: processHoursFunction('[Сьогодні '), + nextDay: processHoursFunction('[Завтра '), + lastDay: processHoursFunction('[Вчора '), + nextWeek: processHoursFunction('[У] dddd ['), + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return processHoursFunction('[Минулої] dddd [').call(this); + case 1: + case 2: + case 4: + return processHoursFunction('[Минулого] dddd [').call(this); + } + }, + sameElse: 'L', + }, + relativeTime: { + future: 'за %s', + past: '%s тому', + s: 'декілька секунд', + ss: relativeTimeWithPlural, + m: relativeTimeWithPlural, + mm: relativeTimeWithPlural, + h: 'годину', + hh: relativeTimeWithPlural, + d: 'день', + dd: relativeTimeWithPlural, + M: 'місяць', + MM: relativeTimeWithPlural, + y: 'рік', + yy: relativeTimeWithPlural, + }, + // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason + meridiemParse: /ночі|ранку|дня|вечора/, + isPM: function (input) { + return /^(дня|вечора)$/.test(input); + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'ночі'; + } else if (hour < 12) { + return 'ранку'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечора'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return number + '-й'; + case 'D': + return number + '-го'; + default: + return number; + } + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return uk; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/ur.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/ur.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Urdu [ur] +//! author : Sawood Alam : https://github.com/ibnesayeed +//! author : Zack : https://github.com/ZackVision + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var months = [ + 'جنوری', + 'فروری', + 'مارچ', + 'اپریل', + 'مئی', + 'جون', + 'جولائی', + 'اگست', + 'ستمبر', + 'اکتوبر', + 'نومبر', + 'دسمبر', + ], + days = ['اتوار', 'پیر', 'منگل', 'بدھ', 'جمعرات', 'جمعہ', 'ہفتہ']; + + var ur = moment.defineLocale('ur', { + months: months, + monthsShort: months, + weekdays: days, + weekdaysShort: days, + weekdaysMin: days, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd، D MMMM YYYY HH:mm', + }, + meridiemParse: /صبح|شام/, + isPM: function (input) { + return 'شام' === input; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'صبح'; + } + return 'شام'; + }, + calendar: { + sameDay: '[آج بوقت] LT', + nextDay: '[کل بوقت] LT', + nextWeek: 'dddd [بوقت] LT', + lastDay: '[گذشتہ روز بوقت] LT', + lastWeek: '[گذشتہ] dddd [بوقت] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s بعد', + past: '%s قبل', + s: 'چند سیکنڈ', + ss: '%d سیکنڈ', + m: 'ایک منٹ', + mm: '%d منٹ', + h: 'ایک گھنٹہ', + hh: '%d گھنٹے', + d: 'ایک دن', + dd: '%d دن', + M: 'ایک ماہ', + MM: '%d ماہ', + y: 'ایک سال', + yy: '%d سال', + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return ur; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/uz-latn.js": +/*!*****************************************************!*\ + !*** ../eyes/node_modules/moment/locale/uz-latn.js ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Uzbek Latin [uz-latn] +//! author : Rasulbek Mirzayev : github.com/Rasulbeeek + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var uzLatn = moment.defineLocale('uz-latn', { + months: 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split( + '_' + ), + monthsShort: 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'), + weekdays: 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split( + '_' + ), + weekdaysShort: 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'), + weekdaysMin: 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'D MMMM YYYY, dddd HH:mm', + }, + calendar: { + sameDay: '[Bugun soat] LT [da]', + nextDay: '[Ertaga] LT [da]', + nextWeek: 'dddd [kuni soat] LT [da]', + lastDay: '[Kecha soat] LT [da]', + lastWeek: "[O'tgan] dddd [kuni soat] LT [da]", + sameElse: 'L', + }, + relativeTime: { + future: 'Yaqin %s ichida', + past: 'Bir necha %s oldin', + s: 'soniya', + ss: '%d soniya', + m: 'bir daqiqa', + mm: '%d daqiqa', + h: 'bir soat', + hh: '%d soat', + d: 'bir kun', + dd: '%d kun', + M: 'bir oy', + MM: '%d oy', + y: 'bir yil', + yy: '%d yil', + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 7th is the first week of the year. + }, + }); + + return uzLatn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/uz.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/uz.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Uzbek [uz] +//! author : Sardor Muminov : https://github.com/muminoff + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var uz = moment.defineLocale('uz', { + months: 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split( + '_' + ), + monthsShort: 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), + weekdays: 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'), + weekdaysShort: 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'), + weekdaysMin: 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'D MMMM YYYY, dddd HH:mm', + }, + calendar: { + sameDay: '[Бугун соат] LT [да]', + nextDay: '[Эртага] LT [да]', + nextWeek: 'dddd [куни соат] LT [да]', + lastDay: '[Кеча соат] LT [да]', + lastWeek: '[Утган] dddd [куни соат] LT [да]', + sameElse: 'L', + }, + relativeTime: { + future: 'Якин %s ичида', + past: 'Бир неча %s олдин', + s: 'фурсат', + ss: '%d фурсат', + m: 'бир дакика', + mm: '%d дакика', + h: 'бир соат', + hh: '%d соат', + d: 'бир кун', + dd: '%d кун', + M: 'бир ой', + MM: '%d ой', + y: 'бир йил', + yy: '%d йил', + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 7, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return uz; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/vi.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/vi.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Vietnamese [vi] +//! author : Bang Nguyen : https://github.com/bangnk +//! author : Chien Kira : https://github.com/chienkira + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var vi = moment.defineLocale('vi', { + months: 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split( + '_' + ), + monthsShort: 'Thg 01_Thg 02_Thg 03_Thg 04_Thg 05_Thg 06_Thg 07_Thg 08_Thg 09_Thg 10_Thg 11_Thg 12'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split( + '_' + ), + weekdaysShort: 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + weekdaysMin: 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + weekdaysParseExact: true, + meridiemParse: /sa|ch/i, + isPM: function (input) { + return /^ch$/i.test(input); + }, + meridiem: function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'sa' : 'SA'; + } else { + return isLower ? 'ch' : 'CH'; + } + }, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM [năm] YYYY', + LLL: 'D MMMM [năm] YYYY HH:mm', + LLLL: 'dddd, D MMMM [năm] YYYY HH:mm', + l: 'DD/M/YYYY', + ll: 'D MMM YYYY', + lll: 'D MMM YYYY HH:mm', + llll: 'ddd, D MMM YYYY HH:mm', + }, + calendar: { + sameDay: '[Hôm nay lúc] LT', + nextDay: '[Ngày mai lúc] LT', + nextWeek: 'dddd [tuần tới lúc] LT', + lastDay: '[Hôm qua lúc] LT', + lastWeek: 'dddd [tuần trước lúc] LT', + sameElse: 'L', + }, + relativeTime: { + future: '%s tới', + past: '%s trước', + s: 'vài giây', + ss: '%d giây', + m: 'một phút', + mm: '%d phút', + h: 'một giờ', + hh: '%d giờ', + d: 'một ngày', + dd: '%d ngày', + w: 'một tuần', + ww: '%d tuần', + M: 'một tháng', + MM: '%d tháng', + y: 'một năm', + yy: '%d năm', + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal: function (number) { + return number; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return vi; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/x-pseudo.js": +/*!******************************************************!*\ + !*** ../eyes/node_modules/moment/locale/x-pseudo.js ***! + \******************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Pseudo [x-pseudo] +//! author : Andrew Hood : https://github.com/andrewhood125 + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var xPseudo = moment.defineLocale('x-pseudo', { + months: 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split( + '_' + ), + monthsShort: 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split( + '_' + ), + monthsParseExact: true, + weekdays: 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split( + '_' + ), + weekdaysShort: 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'), + weekdaysMin: 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm', + }, + calendar: { + sameDay: '[T~ódá~ý át] LT', + nextDay: '[T~ómó~rró~w át] LT', + nextWeek: 'dddd [át] LT', + lastDay: '[Ý~ést~érdá~ý át] LT', + lastWeek: '[L~ást] dddd [át] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'í~ñ %s', + past: '%s á~gó', + s: 'á ~féw ~sécó~ñds', + ss: '%d s~écóñ~ds', + m: 'á ~míñ~úté', + mm: '%d m~íñú~tés', + h: 'á~ñ hó~úr', + hh: '%d h~óúrs', + d: 'á ~dáý', + dd: '%d d~áýs', + M: 'á ~móñ~th', + MM: '%d m~óñt~hs', + y: 'á ~ýéár', + yy: '%d ý~éárs', + }, + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal: function (number) { + var b = number % 10, + output = + ~~((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return xPseudo; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/yo.js": +/*!************************************************!*\ + !*** ../eyes/node_modules/moment/locale/yo.js ***! + \************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Yoruba Nigeria [yo] +//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var yo = moment.defineLocale('yo', { + months: 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split( + '_' + ), + monthsShort: 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'), + weekdays: 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'), + weekdaysShort: 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'), + weekdaysMin: 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'), + longDateFormat: { + LT: 'h:mm A', + LTS: 'h:mm:ss A', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY h:mm A', + LLLL: 'dddd, D MMMM YYYY h:mm A', + }, + calendar: { + sameDay: '[Ònì ni] LT', + nextDay: '[Ọ̀la ni] LT', + nextWeek: "dddd [Ọsẹ̀ tón'bọ] [ni] LT", + lastDay: '[Àna ni] LT', + lastWeek: 'dddd [Ọsẹ̀ tólọ́] [ni] LT', + sameElse: 'L', + }, + relativeTime: { + future: 'ní %s', + past: '%s kọjá', + s: 'ìsẹjú aayá die', + ss: 'aayá %d', + m: 'ìsẹjú kan', + mm: 'ìsẹjú %d', + h: 'wákati kan', + hh: 'wákati %d', + d: 'ọjọ́ kan', + dd: 'ọjọ́ %d', + M: 'osù kan', + MM: 'osù %d', + y: 'ọdún kan', + yy: 'ọdún %d', + }, + dayOfMonthOrdinalParse: /ọjọ́\s\d{1,2}/, + ordinal: 'ọjọ́ %d', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return yo; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/zh-cn.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/zh-cn.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Chinese (China) [zh-cn] +//! author : suupic : https://github.com/suupic +//! author : Zeno Zeng : https://github.com/zenozeng +//! author : uu109 : https://github.com/uu109 + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var zhCn = moment.defineLocale('zh-cn', { + months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split( + '_' + ), + monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split( + '_' + ), + weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'), + weekdaysMin: '日_一_二_三_四_五_六'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY/MM/DD', + LL: 'YYYY年M月D日', + LLL: 'YYYY年M月D日Ah点mm分', + LLLL: 'YYYY年M月D日ddddAh点mm分', + l: 'YYYY/M/D', + ll: 'YYYY年M月D日', + lll: 'YYYY年M月D日 HH:mm', + llll: 'YYYY年M月D日dddd HH:mm', + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } else { + // '中午' + return hour >= 11 ? hour : hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar: { + sameDay: '[今天]LT', + nextDay: '[明天]LT', + nextWeek: function (now) { + if (now.week() !== this.week()) { + return '[下]dddLT'; + } else { + return '[本]dddLT'; + } + }, + lastDay: '[昨天]LT', + lastWeek: function (now) { + if (this.week() !== now.week()) { + return '[上]dddLT'; + } else { + return '[本]dddLT'; + } + }, + sameElse: 'L', + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + case 'M': + return number + '月'; + case 'w': + case 'W': + return number + '周'; + default: + return number; + } + }, + relativeTime: { + future: '%s后', + past: '%s前', + s: '几秒', + ss: '%d 秒', + m: '1 分钟', + mm: '%d 分钟', + h: '1 小时', + hh: '%d 小时', + d: '1 天', + dd: '%d 天', + w: '1 周', + ww: '%d 周', + M: '1 个月', + MM: '%d 个月', + y: '1 年', + yy: '%d 年', + }, + week: { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow: 1, // Monday is the first day of the week. + doy: 4, // The week that contains Jan 4th is the first week of the year. + }, + }); + + return zhCn; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/zh-hk.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/zh-hk.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Chinese (Hong Kong) [zh-hk] +//! author : Ben : https://github.com/ben-lin +//! author : Chris Lam : https://github.com/hehachris +//! author : Konstantin : https://github.com/skfd +//! author : Anthony : https://github.com/anthonylau + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var zhHk = moment.defineLocale('zh-hk', { + months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split( + '_' + ), + monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split( + '_' + ), + weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin: '日_一_二_三_四_五_六'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY/MM/DD', + LL: 'YYYY年M月D日', + LLL: 'YYYY年M月D日 HH:mm', + LLLL: 'YYYY年M月D日dddd HH:mm', + l: 'YYYY/M/D', + ll: 'YYYY年M月D日', + lll: 'YYYY年M月D日 HH:mm', + llll: 'YYYY年M月D日dddd HH:mm', + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1200) { + return '上午'; + } else if (hm === 1200) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar: { + sameDay: '[今天]LT', + nextDay: '[明天]LT', + nextWeek: '[下]ddddLT', + lastDay: '[昨天]LT', + lastWeek: '[上]ddddLT', + sameElse: 'L', + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + case 'M': + return number + '月'; + case 'w': + case 'W': + return number + '週'; + default: + return number; + } + }, + relativeTime: { + future: '%s後', + past: '%s前', + s: '幾秒', + ss: '%d 秒', + m: '1 分鐘', + mm: '%d 分鐘', + h: '1 小時', + hh: '%d 小時', + d: '1 天', + dd: '%d 天', + M: '1 個月', + MM: '%d 個月', + y: '1 年', + yy: '%d 年', + }, + }); + + return zhHk; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/zh-mo.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/zh-mo.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Chinese (Macau) [zh-mo] +//! author : Ben : https://github.com/ben-lin +//! author : Chris Lam : https://github.com/hehachris +//! author : Tan Yuanhong : https://github.com/le0tan + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var zhMo = moment.defineLocale('zh-mo', { + months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split( + '_' + ), + monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split( + '_' + ), + weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin: '日_一_二_三_四_五_六'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'YYYY年M月D日', + LLL: 'YYYY年M月D日 HH:mm', + LLLL: 'YYYY年M月D日dddd HH:mm', + l: 'D/M/YYYY', + ll: 'YYYY年M月D日', + lll: 'YYYY年M月D日 HH:mm', + llll: 'YYYY年M月D日dddd HH:mm', + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar: { + sameDay: '[今天] LT', + nextDay: '[明天] LT', + nextWeek: '[下]dddd LT', + lastDay: '[昨天] LT', + lastWeek: '[上]dddd LT', + sameElse: 'L', + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + case 'M': + return number + '月'; + case 'w': + case 'W': + return number + '週'; + default: + return number; + } + }, + relativeTime: { + future: '%s內', + past: '%s前', + s: '幾秒', + ss: '%d 秒', + m: '1 分鐘', + mm: '%d 分鐘', + h: '1 小時', + hh: '%d 小時', + d: '1 天', + dd: '%d 天', + M: '1 個月', + MM: '%d 個月', + y: '1 年', + yy: '%d 年', + }, + }); + + return zhMo; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/locale/zh-tw.js": +/*!***************************************************!*\ + !*** ../eyes/node_modules/moment/locale/zh-tw.js ***! + \***************************************************/ +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + +//! moment.js locale configuration +//! locale : Chinese (Taiwan) [zh-tw] +//! author : Ben : https://github.com/ben-lin +//! author : Chris Lam : https://github.com/hehachris + +;(function (global, factory) { + true ? factory(__webpack_require__(/*! ../moment */ "../eyes/node_modules/moment/moment.js")) : + 0 +}(this, (function (moment) { 'use strict'; + + //! moment.js locale configuration + + var zhTw = moment.defineLocale('zh-tw', { + months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split( + '_' + ), + monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split( + '_' + ), + weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin: '日_一_二_三_四_五_六'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY/MM/DD', + LL: 'YYYY年M月D日', + LLL: 'YYYY年M月D日 HH:mm', + LLLL: 'YYYY年M月D日dddd HH:mm', + l: 'YYYY/M/D', + ll: 'YYYY年M月D日', + lll: 'YYYY年M月D日 HH:mm', + llll: 'YYYY年M月D日dddd HH:mm', + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar: { + sameDay: '[今天] LT', + nextDay: '[明天] LT', + nextWeek: '[下]dddd LT', + lastDay: '[昨天] LT', + lastWeek: '[上]dddd LT', + sameElse: 'L', + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + case 'M': + return number + '月'; + case 'w': + case 'W': + return number + '週'; + default: + return number; + } + }, + relativeTime: { + future: '%s後', + past: '%s前', + s: '幾秒', + ss: '%d 秒', + m: '1 分鐘', + mm: '%d 分鐘', + h: '1 小時', + hh: '%d 小時', + d: '1 天', + dd: '%d 天', + M: '1 個月', + MM: '%d 個月', + y: '1 年', + yy: '%d 年', + }, + }); + + return zhTw; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/moment/moment.js": +/*!*********************************************!*\ + !*** ../eyes/node_modules/moment/moment.js ***! + \*********************************************/ +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +/* module decorator */ module = __webpack_require__.nmd(module); +//! moment.js +//! version : 2.29.1 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com + +;(function (global, factory) { + true ? module.exports = factory() : + 0 +}(this, (function () { 'use strict'; + + var hookCallback; + + function hooks() { + return hookCallback.apply(null, arguments); + } + + // This is done to register the method called with moment() + // without creating circular dependencies. + function setHookCallback(callback) { + hookCallback = callback; + } + + function isArray(input) { + return ( + input instanceof Array || + Object.prototype.toString.call(input) === '[object Array]' + ); + } + + function isObject(input) { + // IE8 will treat undefined and null as object if it wasn't for + // input != null + return ( + input != null && + Object.prototype.toString.call(input) === '[object Object]' + ); + } + + function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); + } + + function isObjectEmpty(obj) { + if (Object.getOwnPropertyNames) { + return Object.getOwnPropertyNames(obj).length === 0; + } else { + var k; + for (k in obj) { + if (hasOwnProp(obj, k)) { + return false; + } + } + return true; + } + } + + function isUndefined(input) { + return input === void 0; + } + + function isNumber(input) { + return ( + typeof input === 'number' || + Object.prototype.toString.call(input) === '[object Number]' + ); + } + + function isDate(input) { + return ( + input instanceof Date || + Object.prototype.toString.call(input) === '[object Date]' + ); + } + + function map(arr, fn) { + var res = [], + i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; + } + + function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } + + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; + } + + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } + + return a; + } + + function createUTC(input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); + } + + function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty: false, + unusedTokens: [], + unusedInput: [], + overflow: -2, + charsLeftOver: 0, + nullInput: false, + invalidEra: null, + invalidMonth: null, + invalidFormat: false, + userInvalidated: false, + iso: false, + parsedDateParts: [], + era: null, + meridiem: null, + rfc2822: false, + weekdayMismatch: false, + }; + } + + function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + return m._pf; + } + + var some; + if (Array.prototype.some) { + some = Array.prototype.some; + } else { + some = function (fun) { + var t = Object(this), + len = t.length >>> 0, + i; + + for (i = 0; i < len; i++) { + if (i in t && fun.call(this, t[i], i, t)) { + return true; + } + } + + return false; + }; + } + + function isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m), + parsedParts = some.call(flags.parsedDateParts, function (i) { + return i != null; + }), + isNowValid = + !isNaN(m._d.getTime()) && + flags.overflow < 0 && + !flags.empty && + !flags.invalidEra && + !flags.invalidMonth && + !flags.invalidWeekday && + !flags.weekdayMismatch && + !flags.nullInput && + !flags.invalidFormat && + !flags.userInvalidated && + (!flags.meridiem || (flags.meridiem && parsedParts)); + + if (m._strict) { + isNowValid = + isNowValid && + flags.charsLeftOver === 0 && + flags.unusedTokens.length === 0 && + flags.bigHour === undefined; + } + + if (Object.isFrozen == null || !Object.isFrozen(m)) { + m._isValid = isNowValid; + } else { + return isNowValid; + } + } + return m._isValid; + } + + function createInvalid(flags) { + var m = createUTC(NaN); + if (flags != null) { + extend(getParsingFlags(m), flags); + } else { + getParsingFlags(m).userInvalidated = true; + } + + return m; + } + + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + var momentProperties = (hooks.momentProperties = []), + updateInProgress = false; + + function copyConfig(to, from) { + var i, prop, val; + + if (!isUndefined(from._isAMomentObject)) { + to._isAMomentObject = from._isAMomentObject; + } + if (!isUndefined(from._i)) { + to._i = from._i; + } + if (!isUndefined(from._f)) { + to._f = from._f; + } + if (!isUndefined(from._l)) { + to._l = from._l; + } + if (!isUndefined(from._strict)) { + to._strict = from._strict; + } + if (!isUndefined(from._tzm)) { + to._tzm = from._tzm; + } + if (!isUndefined(from._isUTC)) { + to._isUTC = from._isUTC; + } + if (!isUndefined(from._offset)) { + to._offset = from._offset; + } + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); + } + if (!isUndefined(from._locale)) { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i = 0; i < momentProperties.length; i++) { + prop = momentProperties[i]; + val = from[prop]; + if (!isUndefined(val)) { + to[prop] = val; + } + } + } + + return to; + } + + // Moment prototype object + function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + if (!this.isValid()) { + this._d = new Date(NaN); + } + // Prevent infinite loop in case updateOffset creates new moment + // objects. + if (updateInProgress === false) { + updateInProgress = true; + hooks.updateOffset(this); + updateInProgress = false; + } + } + + function isMoment(obj) { + return ( + obj instanceof Moment || (obj != null && obj._isAMomentObject != null) + ); + } + + function warn(msg) { + if ( + hooks.suppressDeprecationWarnings === false && + typeof console !== 'undefined' && + console.warn + ) { + console.warn('Deprecation warning: ' + msg); + } + } + + function deprecate(msg, fn) { + var firstTime = true; + + return extend(function () { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(null, msg); + } + if (firstTime) { + var args = [], + arg, + i, + key; + for (i = 0; i < arguments.length; i++) { + arg = ''; + if (typeof arguments[i] === 'object') { + arg += '\n[' + i + '] '; + for (key in arguments[0]) { + if (hasOwnProp(arguments[0], key)) { + arg += key + ': ' + arguments[0][key] + ', '; + } + } + arg = arg.slice(0, -2); // Remove trailing comma and space + } else { + arg = arguments[i]; + } + args.push(arg); + } + warn( + msg + + '\nArguments: ' + + Array.prototype.slice.call(args).join('') + + '\n' + + new Error().stack + ); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } + + var deprecations = {}; + + function deprecateSimple(name, msg) { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(name, msg); + } + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } + } + + hooks.suppressDeprecationWarnings = false; + hooks.deprecationHandler = null; + + function isFunction(input) { + return ( + (typeof Function !== 'undefined' && input instanceof Function) || + Object.prototype.toString.call(input) === '[object Function]' + ); + } + + function set(config) { + var prop, i; + for (i in config) { + if (hasOwnProp(config, i)) { + prop = config[i]; + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + } + this._config = config; + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. + // TODO: Remove "ordinalParse" fallback in next major release. + this._dayOfMonthOrdinalParseLenient = new RegExp( + (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + + '|' + + /\d{1,2}/.source + ); + } + + function mergeConfigs(parentConfig, childConfig) { + var res = extend({}, parentConfig), + prop; + for (prop in childConfig) { + if (hasOwnProp(childConfig, prop)) { + if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { + res[prop] = {}; + extend(res[prop], parentConfig[prop]); + extend(res[prop], childConfig[prop]); + } else if (childConfig[prop] != null) { + res[prop] = childConfig[prop]; + } else { + delete res[prop]; + } + } + } + for (prop in parentConfig) { + if ( + hasOwnProp(parentConfig, prop) && + !hasOwnProp(childConfig, prop) && + isObject(parentConfig[prop]) + ) { + // make sure changes to properties don't modify parent config + res[prop] = extend({}, res[prop]); + } + } + return res; + } + + function Locale(config) { + if (config != null) { + this.set(config); + } + } + + var keys; + + if (Object.keys) { + keys = Object.keys; + } else { + keys = function (obj) { + var i, + res = []; + for (i in obj) { + if (hasOwnProp(obj, i)) { + res.push(i); + } + } + return res; + }; + } + + var defaultCalendar = { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'dddd [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: '[Last] dddd [at] LT', + sameElse: 'L', + }; + + function calendar(key, mom, now) { + var output = this._calendar[key] || this._calendar['sameElse']; + return isFunction(output) ? output.call(mom, now) : output; + } + + function zeroFill(number, targetLength, forceSign) { + var absNumber = '' + Math.abs(number), + zerosToFill = targetLength - absNumber.length, + sign = number >= 0; + return ( + (sign ? (forceSign ? '+' : '') : '-') + + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + + absNumber + ); + } + + var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g, + localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, + formatFunctions = {}, + formatTokenFunctions = {}; + + // token: 'M' + // padded: ['MM', 2] + // ordinal: 'Mo' + // callback: function () { this.month() + 1 } + function addFormatToken(token, padded, ordinal, callback) { + var func = callback; + if (typeof callback === 'string') { + func = function () { + return this[callback](); + }; + } + if (token) { + formatTokenFunctions[token] = func; + } + if (padded) { + formatTokenFunctions[padded[0]] = function () { + return zeroFill(func.apply(this, arguments), padded[1], padded[2]); + }; + } + if (ordinal) { + formatTokenFunctions[ordinal] = function () { + return this.localeData().ordinal( + func.apply(this, arguments), + token + ); + }; + } + } + + function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + return input.replace(/\\/g, ''); + } + + function makeFormatFunction(format) { + var array = format.match(formattingTokens), + i, + length; + + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } + + return function (mom) { + var output = '', + i; + for (i = 0; i < length; i++) { + output += isFunction(array[i]) + ? array[i].call(mom, format) + : array[i]; + } + return output; + }; + } + + // format date using native date object + function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } + + format = expandFormat(format, m.localeData()); + formatFunctions[format] = + formatFunctions[format] || makeFormatFunction(format); + + return formatFunctions[format](m); + } + + function expandFormat(format, locale) { + var i = 5; + + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } + + localFormattingTokens.lastIndex = 0; + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace( + localFormattingTokens, + replaceLongDateFormatTokens + ); + localFormattingTokens.lastIndex = 0; + i -= 1; + } + + return format; + } + + var defaultLongDateFormat = { + LTS: 'h:mm:ss A', + LT: 'h:mm A', + L: 'MM/DD/YYYY', + LL: 'MMMM D, YYYY', + LLL: 'MMMM D, YYYY h:mm A', + LLLL: 'dddd, MMMM D, YYYY h:mm A', + }; + + function longDateFormat(key) { + var format = this._longDateFormat[key], + formatUpper = this._longDateFormat[key.toUpperCase()]; + + if (format || !formatUpper) { + return format; + } + + this._longDateFormat[key] = formatUpper + .match(formattingTokens) + .map(function (tok) { + if ( + tok === 'MMMM' || + tok === 'MM' || + tok === 'DD' || + tok === 'dddd' + ) { + return tok.slice(1); + } + return tok; + }) + .join(''); + + return this._longDateFormat[key]; + } + + var defaultInvalidDate = 'Invalid date'; + + function invalidDate() { + return this._invalidDate; + } + + var defaultOrdinal = '%d', + defaultDayOfMonthOrdinalParse = /\d{1,2}/; + + function ordinal(number) { + return this._ordinal.replace('%d', number); + } + + var defaultRelativeTime = { + future: 'in %s', + past: '%s ago', + s: 'a few seconds', + ss: '%d seconds', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + w: 'a week', + ww: '%d weeks', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years', + }; + + function relativeTime(number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return isFunction(output) + ? output(number, withoutSuffix, string, isFuture) + : output.replace(/%d/i, number); + } + + function pastFuture(diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return isFunction(format) ? format(output) : format.replace(/%s/i, output); + } + + var aliases = {}; + + function addUnitAlias(unit, shorthand) { + var lowerCase = unit.toLowerCase(); + aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; + } + + function normalizeUnits(units) { + return typeof units === 'string' + ? aliases[units] || aliases[units.toLowerCase()] + : undefined; + } + + function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; + + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } + + return normalizedInput; + } + + var priorities = {}; + + function addUnitPriority(unit, priority) { + priorities[unit] = priority; + } + + function getPrioritizedUnits(unitsObj) { + var units = [], + u; + for (u in unitsObj) { + if (hasOwnProp(unitsObj, u)) { + units.push({ unit: u, priority: priorities[u] }); + } + } + units.sort(function (a, b) { + return a.priority - b.priority; + }); + return units; + } + + function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; + } + + function absFloor(number) { + if (number < 0) { + // -0 -> 0 + return Math.ceil(number) || 0; + } else { + return Math.floor(number); + } + } + + function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; + + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + value = absFloor(coercedNumber); + } + + return value; + } + + function makeGetSet(unit, keepTime) { + return function (value) { + if (value != null) { + set$1(this, unit, value); + hooks.updateOffset(this, keepTime); + return this; + } else { + return get(this, unit); + } + }; + } + + function get(mom, unit) { + return mom.isValid() + ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() + : NaN; + } + + function set$1(mom, unit, value) { + if (mom.isValid() && !isNaN(value)) { + if ( + unit === 'FullYear' && + isLeapYear(mom.year()) && + mom.month() === 1 && + mom.date() === 29 + ) { + value = toInt(value); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit]( + value, + mom.month(), + daysInMonth(value, mom.month()) + ); + } else { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + } + + // MOMENTS + + function stringGet(units) { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](); + } + return this; + } + + function stringSet(units, value) { + if (typeof units === 'object') { + units = normalizeObjectUnits(units); + var prioritized = getPrioritizedUnits(units), + i; + for (i = 0; i < prioritized.length; i++) { + this[prioritized[i].unit](units[prioritized[i].unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; + } + + var match1 = /\d/, // 0 - 9 + match2 = /\d\d/, // 00 - 99 + match3 = /\d{3}/, // 000 - 999 + match4 = /\d{4}/, // 0000 - 9999 + match6 = /[+-]?\d{6}/, // -999999 - 999999 + match1to2 = /\d\d?/, // 0 - 99 + match3to4 = /\d\d\d\d?/, // 999 - 9999 + match5to6 = /\d\d\d\d\d\d?/, // 99999 - 999999 + match1to3 = /\d{1,3}/, // 0 - 999 + match1to4 = /\d{1,4}/, // 0 - 9999 + match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999 + matchUnsigned = /\d+/, // 0 - inf + matchSigned = /[+-]?\d+/, // -inf - inf + matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z + matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z + matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 + // any word (or two) characters or numbers including two/three word month in arabic. + // includes scottish gaelic two word and hyphenated months + matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i, + regexes; + + regexes = {}; + + function addRegexToken(token, regex, strictRegex) { + regexes[token] = isFunction(regex) + ? regex + : function (isStrict, localeData) { + return isStrict && strictRegex ? strictRegex : regex; + }; + } + + function getParseRegexForToken(token, config) { + if (!hasOwnProp(regexes, token)) { + return new RegExp(unescapeFormat(token)); + } + + return regexes[token](config._strict, config._locale); + } + + // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript + function unescapeFormat(s) { + return regexEscape( + s + .replace('\\', '') + .replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function ( + matched, + p1, + p2, + p3, + p4 + ) { + return p1 || p2 || p3 || p4; + }) + ); + } + + function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } + + var tokens = {}; + + function addParseToken(token, callback) { + var i, + func = callback; + if (typeof token === 'string') { + token = [token]; + } + if (isNumber(callback)) { + func = function (input, array) { + array[callback] = toInt(input); + }; + } + for (i = 0; i < token.length; i++) { + tokens[token[i]] = func; + } + } + + function addWeekParseToken(token, callback) { + addParseToken(token, function (input, array, config, token) { + config._w = config._w || {}; + callback(input, config._w, config, token); + }); + } + + function addTimeToArrayFromToken(token, input, config) { + if (input != null && hasOwnProp(tokens, token)) { + tokens[token](input, config._a, config, token); + } + } + + var YEAR = 0, + MONTH = 1, + DATE = 2, + HOUR = 3, + MINUTE = 4, + SECOND = 5, + MILLISECOND = 6, + WEEK = 7, + WEEKDAY = 8; + + function mod(n, x) { + return ((n % x) + x) % x; + } + + var indexOf; + + if (Array.prototype.indexOf) { + indexOf = Array.prototype.indexOf; + } else { + indexOf = function (o) { + // I know + var i; + for (i = 0; i < this.length; ++i) { + if (this[i] === o) { + return i; + } + } + return -1; + }; + } + + function daysInMonth(year, month) { + if (isNaN(year) || isNaN(month)) { + return NaN; + } + var modMonth = mod(month, 12); + year += (month - modMonth) / 12; + return modMonth === 1 + ? isLeapYear(year) + ? 29 + : 28 + : 31 - ((modMonth % 7) % 2); + } + + // FORMATTING + + addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; + }); + + addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); + }); + + addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); + }); + + // ALIASES + + addUnitAlias('month', 'M'); + + // PRIORITY + + addUnitPriority('month', 8); + + // PARSING + + addRegexToken('M', match1to2); + addRegexToken('MM', match1to2, match2); + addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); + }); + addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); + }); + + addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; + }); + + addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); + // if we didn't find a month name, mark the date as invalid. + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } + }); + + // LOCALES + + var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split( + '_' + ), + MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/, + defaultMonthsShortRegex = matchWord, + defaultMonthsRegex = matchWord; + + function localeMonths(m, format) { + if (!m) { + return isArray(this._months) + ? this._months + : this._months['standalone']; + } + return isArray(this._months) + ? this._months[m.month()] + : this._months[ + (this._months.isFormat || MONTHS_IN_FORMAT).test(format) + ? 'format' + : 'standalone' + ][m.month()]; + } + + function localeMonthsShort(m, format) { + if (!m) { + return isArray(this._monthsShort) + ? this._monthsShort + : this._monthsShort['standalone']; + } + return isArray(this._monthsShort) + ? this._monthsShort[m.month()] + : this._monthsShort[ + MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone' + ][m.month()]; + } + + function handleStrictParse(monthName, format, strict) { + var i, + ii, + mom, + llc = monthName.toLocaleLowerCase(); + if (!this._monthsParse) { + // this is not used + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + for (i = 0; i < 12; ++i) { + mom = createUTC([2000, i]); + this._shortMonthsParse[i] = this.monthsShort( + mom, + '' + ).toLocaleLowerCase(); + this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } + } + + function localeMonthsParse(monthName, format, strict) { + var i, mom, regex; + + if (this._monthsParseExact) { + return handleStrictParse.call(this, monthName, format, strict); + } + + if (!this._monthsParse) { + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + } + + // TODO: add sorting + // Sorting makes sure if one month (or abbr) is a prefix of another + // see sorting in computeMonthsParse + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp( + '^' + this.months(mom, '').replace('.', '') + '$', + 'i' + ); + this._shortMonthsParse[i] = new RegExp( + '^' + this.monthsShort(mom, '').replace('.', '') + '$', + 'i' + ); + } + if (!strict && !this._monthsParse[i]) { + regex = + '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if ( + strict && + format === 'MMMM' && + this._longMonthsParse[i].test(monthName) + ) { + return i; + } else if ( + strict && + format === 'MMM' && + this._shortMonthsParse[i].test(monthName) + ) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { + return i; + } + } + } + + // MOMENTS + + function setMonth(mom, value) { + var dayOfMonth; + + if (!mom.isValid()) { + // No op + return mom; + } + + if (typeof value === 'string') { + if (/^\d+$/.test(value)) { + value = toInt(value); + } else { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (!isNumber(value)) { + return mom; + } + } + } + + dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; + } + + function getSetMonth(value) { + if (value != null) { + setMonth(this, value); + hooks.updateOffset(this, true); + return this; + } else { + return get(this, 'Month'); + } + } + + function getDaysInMonth() { + return daysInMonth(this.year(), this.month()); + } + + function monthsShortRegex(isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + if (!hasOwnProp(this, '_monthsShortRegex')) { + this._monthsShortRegex = defaultMonthsShortRegex; + } + return this._monthsShortStrictRegex && isStrict + ? this._monthsShortStrictRegex + : this._monthsShortRegex; + } + } + + function monthsRegex(isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + if (!hasOwnProp(this, '_monthsRegex')) { + this._monthsRegex = defaultMonthsRegex; + } + return this._monthsStrictRegex && isStrict + ? this._monthsStrictRegex + : this._monthsRegex; + } + } + + function computeMonthsParse() { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var shortPieces = [], + longPieces = [], + mixedPieces = [], + i, + mom; + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } + // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + } + for (i = 0; i < 24; i++) { + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp( + '^(' + longPieces.join('|') + ')', + 'i' + ); + this._monthsShortStrictRegex = new RegExp( + '^(' + shortPieces.join('|') + ')', + 'i' + ); + } + + // FORMATTING + + addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? zeroFill(y, 4) : '+' + y; + }); + + addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; + }); + + addFormatToken(0, ['YYYY', 4], 0, 'year'); + addFormatToken(0, ['YYYYY', 5], 0, 'year'); + addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + + // ALIASES + + addUnitAlias('year', 'y'); + + // PRIORITIES + + addUnitPriority('year', 1); + + // PARSING + + addRegexToken('Y', matchSigned); + addRegexToken('YY', match1to2, match2); + addRegexToken('YYYY', match1to4, match4); + addRegexToken('YYYYY', match1to6, match6); + addRegexToken('YYYYYY', match1to6, match6); + + addParseToken(['YYYYY', 'YYYYYY'], YEAR); + addParseToken('YYYY', function (input, array) { + array[YEAR] = + input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); + }); + addParseToken('YY', function (input, array) { + array[YEAR] = hooks.parseTwoDigitYear(input); + }); + addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); + }); + + // HELPERS + + function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; + } + + // HOOKS + + hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + }; + + // MOMENTS + + var getSetYear = makeGetSet('FullYear', true); + + function getIsLeapYear() { + return isLeapYear(this.year()); + } + + function createDate(y, m, d, h, M, s, ms) { + // can't just apply() to create a date: + // https://stackoverflow.com/q/181348 + var date; + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + date = new Date(y + 400, m, d, h, M, s, ms); + if (isFinite(date.getFullYear())) { + date.setFullYear(y); + } + } else { + date = new Date(y, m, d, h, M, s, ms); + } + + return date; + } + + function createUTCDate(y) { + var date, args; + // the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + args = Array.prototype.slice.call(arguments); + // preserve leap years using a full 400 year cycle, then reset + args[0] = y + 400; + date = new Date(Date.UTC.apply(null, args)); + if (isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + } else { + date = new Date(Date.UTC.apply(null, arguments)); + } + + return date; + } + + // start-of-first-week - start-of-year + function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + + return -fwdlw + fwd - 1; + } + + // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday + function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, + resDayOfYear; + + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; + } + + return { + year: resYear, + dayOfYear: resDayOfYear, + }; + } + + function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, + resYear; + + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } + + return { + week: resWeek, + year: resYear, + }; + } + + function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; + } + + // FORMATTING + + addFormatToken('w', ['ww', 2], 'wo', 'week'); + addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); + + // ALIASES + + addUnitAlias('week', 'w'); + addUnitAlias('isoWeek', 'W'); + + // PRIORITIES + + addUnitPriority('week', 5); + addUnitPriority('isoWeek', 5); + + // PARSING + + addRegexToken('w', match1to2); + addRegexToken('ww', match1to2, match2); + addRegexToken('W', match1to2); + addRegexToken('WW', match1to2, match2); + + addWeekParseToken(['w', 'ww', 'W', 'WW'], function ( + input, + week, + config, + token + ) { + week[token.substr(0, 1)] = toInt(input); + }); + + // HELPERS + + // LOCALES + + function localeWeek(mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; + } + + var defaultLocaleWeek = { + dow: 0, // Sunday is the first day of the week. + doy: 6, // The week that contains Jan 6th is the first week of the year. + }; + + function localeFirstDayOfWeek() { + return this._week.dow; + } + + function localeFirstDayOfYear() { + return this._week.doy; + } + + // MOMENTS + + function getSetWeek(input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + function getSetISOWeek(input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + // FORMATTING + + addFormatToken('d', 0, 'do', 'day'); + + addFormatToken('dd', 0, 0, function (format) { + return this.localeData().weekdaysMin(this, format); + }); + + addFormatToken('ddd', 0, 0, function (format) { + return this.localeData().weekdaysShort(this, format); + }); + + addFormatToken('dddd', 0, 0, function (format) { + return this.localeData().weekdays(this, format); + }); + + addFormatToken('e', 0, 0, 'weekday'); + addFormatToken('E', 0, 0, 'isoWeekday'); + + // ALIASES + + addUnitAlias('day', 'd'); + addUnitAlias('weekday', 'e'); + addUnitAlias('isoWeekday', 'E'); + + // PRIORITY + addUnitPriority('day', 11); + addUnitPriority('weekday', 11); + addUnitPriority('isoWeekday', 11); + + // PARSING + + addRegexToken('d', match1to2); + addRegexToken('e', match1to2); + addRegexToken('E', match1to2); + addRegexToken('dd', function (isStrict, locale) { + return locale.weekdaysMinRegex(isStrict); + }); + addRegexToken('ddd', function (isStrict, locale) { + return locale.weekdaysShortRegex(isStrict); + }); + addRegexToken('dddd', function (isStrict, locale) { + return locale.weekdaysRegex(isStrict); + }); + + addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); + // if we didn't get a weekday name, mark the date as invalid + if (weekday != null) { + week.d = weekday; + } else { + getParsingFlags(config).invalidWeekday = input; + } + }); + + addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { + week[token] = toInt(input); + }); + + // HELPERS + + function parseWeekday(input, locale) { + if (typeof input !== 'string') { + return input; + } + + if (!isNaN(input)) { + return parseInt(input, 10); + } + + input = locale.weekdaysParse(input); + if (typeof input === 'number') { + return input; + } + + return null; + } + + function parseIsoWeekday(input, locale) { + if (typeof input === 'string') { + return locale.weekdaysParse(input) % 7 || 7; + } + return isNaN(input) ? null : input; + } + + // LOCALES + function shiftWeekdays(ws, n) { + return ws.slice(n, 7).concat(ws.slice(0, n)); + } + + var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( + '_' + ), + defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + defaultWeekdaysRegex = matchWord, + defaultWeekdaysShortRegex = matchWord, + defaultWeekdaysMinRegex = matchWord; + + function localeWeekdays(m, format) { + var weekdays = isArray(this._weekdays) + ? this._weekdays + : this._weekdays[ + m && m !== true && this._weekdays.isFormat.test(format) + ? 'format' + : 'standalone' + ]; + return m === true + ? shiftWeekdays(weekdays, this._week.dow) + : m + ? weekdays[m.day()] + : weekdays; + } + + function localeWeekdaysShort(m) { + return m === true + ? shiftWeekdays(this._weekdaysShort, this._week.dow) + : m + ? this._weekdaysShort[m.day()] + : this._weekdaysShort; + } + + function localeWeekdaysMin(m) { + return m === true + ? shiftWeekdays(this._weekdaysMin, this._week.dow) + : m + ? this._weekdaysMin[m.day()] + : this._weekdaysMin; + } + + function handleStrictParse$1(weekdayName, format, strict) { + var i, + ii, + mom, + llc = weekdayName.toLocaleLowerCase(); + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._shortWeekdaysParse = []; + this._minWeekdaysParse = []; + + for (i = 0; i < 7; ++i) { + mom = createUTC([2000, 1]).day(i); + this._minWeekdaysParse[i] = this.weekdaysMin( + mom, + '' + ).toLocaleLowerCase(); + this._shortWeekdaysParse[i] = this.weekdaysShort( + mom, + '' + ).toLocaleLowerCase(); + this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } + } + + function localeWeekdaysParse(weekdayName, format, strict) { + var i, mom, regex; + + if (this._weekdaysParseExact) { + return handleStrictParse$1.call(this, weekdayName, format, strict); + } + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + + mom = createUTC([2000, 1]).day(i); + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp( + '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', + 'i' + ); + this._shortWeekdaysParse[i] = new RegExp( + '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', + 'i' + ); + this._minWeekdaysParse[i] = new RegExp( + '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', + 'i' + ); + } + if (!this._weekdaysParse[i]) { + regex = + '^' + + this.weekdays(mom, '') + + '|^' + + this.weekdaysShort(mom, '') + + '|^' + + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if ( + strict && + format === 'dddd' && + this._fullWeekdaysParse[i].test(weekdayName) + ) { + return i; + } else if ( + strict && + format === 'ddd' && + this._shortWeekdaysParse[i].test(weekdayName) + ) { + return i; + } else if ( + strict && + format === 'dd' && + this._minWeekdaysParse[i].test(weekdayName) + ) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } + } + + // MOMENTS + + function getSetDayOfWeek(input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } + } + + function getSetLocaleDayOfWeek(input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); + } + + function getSetISODayOfWeek(input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + + if (input != null) { + var weekday = parseIsoWeekday(input, this.localeData()); + return this.day(this.day() % 7 ? weekday : weekday - 7); + } else { + return this.day() || 7; + } + } + + function weekdaysRegex(isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysStrictRegex; + } else { + return this._weekdaysRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysRegex')) { + this._weekdaysRegex = defaultWeekdaysRegex; + } + return this._weekdaysStrictRegex && isStrict + ? this._weekdaysStrictRegex + : this._weekdaysRegex; + } + } + + function weekdaysShortRegex(isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysShortStrictRegex; + } else { + return this._weekdaysShortRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysShortRegex')) { + this._weekdaysShortRegex = defaultWeekdaysShortRegex; + } + return this._weekdaysShortStrictRegex && isStrict + ? this._weekdaysShortStrictRegex + : this._weekdaysShortRegex; + } + } + + function weekdaysMinRegex(isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysMinStrictRegex; + } else { + return this._weekdaysMinRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysMinRegex')) { + this._weekdaysMinRegex = defaultWeekdaysMinRegex; + } + return this._weekdaysMinStrictRegex && isStrict + ? this._weekdaysMinStrictRegex + : this._weekdaysMinRegex; + } + } + + function computeWeekdaysParse() { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var minPieces = [], + shortPieces = [], + longPieces = [], + mixedPieces = [], + i, + mom, + minp, + shortp, + longp; + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, 1]).day(i); + minp = regexEscape(this.weekdaysMin(mom, '')); + shortp = regexEscape(this.weekdaysShort(mom, '')); + longp = regexEscape(this.weekdays(mom, '')); + minPieces.push(minp); + shortPieces.push(shortp); + longPieces.push(longp); + mixedPieces.push(minp); + mixedPieces.push(shortp); + mixedPieces.push(longp); + } + // Sorting makes sure if one weekday (or abbr) is a prefix of another it + // will match the longer piece. + minPieces.sort(cmpLenRev); + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + + this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._weekdaysShortRegex = this._weekdaysRegex; + this._weekdaysMinRegex = this._weekdaysRegex; + + this._weekdaysStrictRegex = new RegExp( + '^(' + longPieces.join('|') + ')', + 'i' + ); + this._weekdaysShortStrictRegex = new RegExp( + '^(' + shortPieces.join('|') + ')', + 'i' + ); + this._weekdaysMinStrictRegex = new RegExp( + '^(' + minPieces.join('|') + ')', + 'i' + ); + } + + // FORMATTING + + function hFormat() { + return this.hours() % 12 || 12; + } + + function kFormat() { + return this.hours() || 24; + } + + addFormatToken('H', ['HH', 2], 0, 'hour'); + addFormatToken('h', ['hh', 2], 0, hFormat); + addFormatToken('k', ['kk', 2], 0, kFormat); + + addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); + }); + + addFormatToken('hmmss', 0, 0, function () { + return ( + '' + + hFormat.apply(this) + + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2) + ); + }); + + addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); + }); + + addFormatToken('Hmmss', 0, 0, function () { + return ( + '' + + this.hours() + + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2) + ); + }); + + function meridiem(token, lowercase) { + addFormatToken(token, 0, 0, function () { + return this.localeData().meridiem( + this.hours(), + this.minutes(), + lowercase + ); + }); + } + + meridiem('a', true); + meridiem('A', false); + + // ALIASES + + addUnitAlias('hour', 'h'); + + // PRIORITY + addUnitPriority('hour', 13); + + // PARSING + + function matchMeridiem(isStrict, locale) { + return locale._meridiemParse; + } + + addRegexToken('a', matchMeridiem); + addRegexToken('A', matchMeridiem); + addRegexToken('H', match1to2); + addRegexToken('h', match1to2); + addRegexToken('k', match1to2); + addRegexToken('HH', match1to2, match2); + addRegexToken('hh', match1to2, match2); + addRegexToken('kk', match1to2, match2); + + addRegexToken('hmm', match3to4); + addRegexToken('hmmss', match5to6); + addRegexToken('Hmm', match3to4); + addRegexToken('Hmmss', match5to6); + + addParseToken(['H', 'HH'], HOUR); + addParseToken(['k', 'kk'], function (input, array, config) { + var kInput = toInt(input); + array[HOUR] = kInput === 24 ? 0 : kInput; + }); + addParseToken(['a', 'A'], function (input, array, config) { + config._isPm = config._locale.isPM(input); + config._meridiem = input; + }); + addParseToken(['h', 'hh'], function (input, array, config) { + array[HOUR] = toInt(input); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4, + pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + }); + addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4, + pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + }); + + // LOCALES + + function localeIsPM(input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return (input + '').toLowerCase().charAt(0) === 'p'; + } + + var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i, + // Setting the hour should keep the time, because the user explicitly + // specified which hour they want. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + getSetHour = makeGetSet('Hours', true); + + function localeMeridiem(hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } + } + + var baseConfig = { + calendar: defaultCalendar, + longDateFormat: defaultLongDateFormat, + invalidDate: defaultInvalidDate, + ordinal: defaultOrdinal, + dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, + relativeTime: defaultRelativeTime, + + months: defaultLocaleMonths, + monthsShort: defaultLocaleMonthsShort, + + week: defaultLocaleWeek, + + weekdays: defaultLocaleWeekdays, + weekdaysMin: defaultLocaleWeekdaysMin, + weekdaysShort: defaultLocaleWeekdaysShort, + + meridiemParse: defaultLocaleMeridiemParse, + }; + + // internal storage for locale config files + var locales = {}, + localeFamilies = {}, + globalLocale; + + function commonPrefix(arr1, arr2) { + var i, + minl = Math.min(arr1.length, arr2.length); + for (i = 0; i < minl; i += 1) { + if (arr1[i] !== arr2[i]) { + return i; + } + } + return minl; + } + + function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; + } + + // pick the locale from the array + // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + function chooseLocale(names) { + var i = 0, + j, + next, + locale, + split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if ( + next && + next.length >= j && + commonPrefix(split, next) >= j - 1 + ) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return globalLocale; + } + + function loadLocale(name) { + var oldLocale = null, + aliasedRequire; + // TODO: Find a better way to register and load all the locales in Node + if ( + locales[name] === undefined && + "object" !== 'undefined' && + module && + module.exports + ) { + try { + oldLocale = globalLocale._abbr; + aliasedRequire = undefined; + __webpack_require__("../eyes/node_modules/moment/locale sync recursive ^\\.\\/.*$")("./" + name); + getSetGlobalLocale(oldLocale); + } catch (e) { + // mark as not found to avoid repeating expensive file require call causing high CPU + // when trying to find en-US, en_US, en-us for every format call + locales[name] = null; // null means not found + } + } + return locales[name]; + } + + // This function will load locale and then set the global locale. If + // no arguments are passed in, it will simply return the current global + // locale key. + function getSetGlobalLocale(key, values) { + var data; + if (key) { + if (isUndefined(values)) { + data = getLocale(key); + } else { + data = defineLocale(key, values); + } + + if (data) { + // moment.duration._locale = moment._locale = data; + globalLocale = data; + } else { + if (typeof console !== 'undefined' && console.warn) { + //warn user if arguments are passed but the locale could not be set + console.warn( + 'Locale ' + key + ' not found. Did you forget to load it?' + ); + } + } + } + + return globalLocale._abbr; + } + + function defineLocale(name, config) { + if (config !== null) { + var locale, + parentConfig = baseConfig; + config.abbr = name; + if (locales[name] != null) { + deprecateSimple( + 'defineLocaleOverride', + 'use moment.updateLocale(localeName, config) to change ' + + 'an existing locale. moment.defineLocale(localeName, ' + + 'config) should only be used for creating a new locale ' + + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.' + ); + parentConfig = locales[name]._config; + } else if (config.parentLocale != null) { + if (locales[config.parentLocale] != null) { + parentConfig = locales[config.parentLocale]._config; + } else { + locale = loadLocale(config.parentLocale); + if (locale != null) { + parentConfig = locale._config; + } else { + if (!localeFamilies[config.parentLocale]) { + localeFamilies[config.parentLocale] = []; + } + localeFamilies[config.parentLocale].push({ + name: name, + config: config, + }); + return null; + } + } + } + locales[name] = new Locale(mergeConfigs(parentConfig, config)); + + if (localeFamilies[name]) { + localeFamilies[name].forEach(function (x) { + defineLocale(x.name, x.config); + }); + } + + // backwards compat for now: also set the locale + // make sure we set the locale AFTER all child locales have been + // created, so we won't end up with the child locale set. + getSetGlobalLocale(name); + + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } + } + + function updateLocale(name, config) { + if (config != null) { + var locale, + tmpLocale, + parentConfig = baseConfig; + + if (locales[name] != null && locales[name].parentLocale != null) { + // Update existing child locale in-place to avoid memory-leaks + locales[name].set(mergeConfigs(locales[name]._config, config)); + } else { + // MERGE + tmpLocale = loadLocale(name); + if (tmpLocale != null) { + parentConfig = tmpLocale._config; + } + config = mergeConfigs(parentConfig, config); + if (tmpLocale == null) { + // updateLocale is called for creating a new locale + // Set abbr so it will have a name (getters return + // undefined otherwise). + config.abbr = name; + } + locale = new Locale(config); + locale.parentLocale = locales[name]; + locales[name] = locale; + } + + // backwards compat for now: also set the locale + getSetGlobalLocale(name); + } else { + // pass null for config to unupdate, useful for tests + if (locales[name] != null) { + if (locales[name].parentLocale != null) { + locales[name] = locales[name].parentLocale; + if (name === getSetGlobalLocale()) { + getSetGlobalLocale(name); + } + } else if (locales[name] != null) { + delete locales[name]; + } + } + } + return locales[name]; + } + + // returns locale data + function getLocale(key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return globalLocale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } + + return chooseLocale(key); + } + + function listLocales() { + return keys(locales); + } + + function checkOverflow(m) { + var overflow, + a = m._a; + + if (a && getParsingFlags(m).overflow === -2) { + overflow = + a[MONTH] < 0 || a[MONTH] > 11 + ? MONTH + : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) + ? DATE + : a[HOUR] < 0 || + a[HOUR] > 24 || + (a[HOUR] === 24 && + (a[MINUTE] !== 0 || + a[SECOND] !== 0 || + a[MILLISECOND] !== 0)) + ? HOUR + : a[MINUTE] < 0 || a[MINUTE] > 59 + ? MINUTE + : a[SECOND] < 0 || a[SECOND] > 59 + ? SECOND + : a[MILLISECOND] < 0 || a[MILLISECOND] > 999 + ? MILLISECOND + : -1; + + if ( + getParsingFlags(m)._overflowDayOfYear && + (overflow < YEAR || overflow > DATE) + ) { + overflow = DATE; + } + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } + + getParsingFlags(m).overflow = overflow; + } + + return m; + } + + // iso 8601 regex + // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) + var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, + basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, + tzRegex = /Z|[+-]\d\d(?::?\d\d)?/, + isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], + ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], + ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], + ['GGGG-[W]WW', /\d{4}-W\d\d/, false], + ['YYYY-DDD', /\d{4}-\d{3}/], + ['YYYY-MM', /\d{4}-\d\d/, false], + ['YYYYYYMMDD', /[+-]\d{10}/], + ['YYYYMMDD', /\d{8}/], + ['GGGG[W]WWE', /\d{4}W\d{3}/], + ['GGGG[W]WW', /\d{4}W\d{2}/, false], + ['YYYYDDD', /\d{7}/], + ['YYYYMM', /\d{6}/, false], + ['YYYY', /\d{4}/, false], + ], + // iso time formats and regexes + isoTimes = [ + ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], + ['HH:mm:ss', /\d\d:\d\d:\d\d/], + ['HH:mm', /\d\d:\d\d/], + ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], + ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], + ['HHmmss', /\d\d\d\d\d\d/], + ['HHmm', /\d\d\d\d/], + ['HH', /\d\d/], + ], + aspNetJsonRegex = /^\/?Date\((-?\d+)/i, + // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 + rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/, + obsOffsets = { + UT: 0, + GMT: 0, + EDT: -4 * 60, + EST: -5 * 60, + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60, + }; + + // date from iso format + function configFromISO(config) { + var i, + l, + string = config._i, + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, + dateFormat, + timeFormat, + tzFormat; + + if (match) { + getParsingFlags(config).iso = true; + + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; + break; + } + } + if (dateFormat == null) { + config._isValid = false; + return; + } + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + if (timeFormat == null) { + config._isValid = false; + return; + } + } + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; + } + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); + configFromStringAndFormat(config); + } else { + config._isValid = false; + } + } + + function extractFromRFC2822Strings( + yearStr, + monthStr, + dayStr, + hourStr, + minuteStr, + secondStr + ) { + var result = [ + untruncateYear(yearStr), + defaultLocaleMonthsShort.indexOf(monthStr), + parseInt(dayStr, 10), + parseInt(hourStr, 10), + parseInt(minuteStr, 10), + ]; + + if (secondStr) { + result.push(parseInt(secondStr, 10)); + } + + return result; + } + + function untruncateYear(yearStr) { + var year = parseInt(yearStr, 10); + if (year <= 49) { + return 2000 + year; + } else if (year <= 999) { + return 1900 + year; + } + return year; + } + + function preprocessRFC2822(s) { + // Remove comments and folding whitespace and replace multiple-spaces with a single space + return s + .replace(/\([^)]*\)|[\n\t]/g, ' ') + .replace(/(\s\s+)/g, ' ') + .replace(/^\s\s*/, '') + .replace(/\s\s*$/, ''); + } + + function checkWeekday(weekdayStr, parsedInput, config) { + if (weekdayStr) { + // TODO: Replace the vanilla JS Date object with an independent day-of-week check. + var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), + weekdayActual = new Date( + parsedInput[0], + parsedInput[1], + parsedInput[2] + ).getDay(); + if (weekdayProvided !== weekdayActual) { + getParsingFlags(config).weekdayMismatch = true; + config._isValid = false; + return false; + } + } + return true; + } + + function calculateOffset(obsOffset, militaryOffset, numOffset) { + if (obsOffset) { + return obsOffsets[obsOffset]; + } else if (militaryOffset) { + // the only allowed military tz is Z + return 0; + } else { + var hm = parseInt(numOffset, 10), + m = hm % 100, + h = (hm - m) / 100; + return h * 60 + m; + } + } + + // date and time from ref 2822 format + function configFromRFC2822(config) { + var match = rfc2822.exec(preprocessRFC2822(config._i)), + parsedArray; + if (match) { + parsedArray = extractFromRFC2822Strings( + match[4], + match[3], + match[2], + match[5], + match[6], + match[7] + ); + if (!checkWeekday(match[1], parsedArray, config)) { + return; + } + + config._a = parsedArray; + config._tzm = calculateOffset(match[8], match[9], match[10]); + + config._d = createUTCDate.apply(null, config._a); + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + + getParsingFlags(config).rfc2822 = true; + } else { + config._isValid = false; + } + } + + // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict + function configFromString(config) { + var matched = aspNetJsonRegex.exec(config._i); + if (matched !== null) { + config._d = new Date(+matched[1]); + return; + } + + configFromISO(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + configFromRFC2822(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + if (config._strict) { + config._isValid = false; + } else { + // Final attempt, use Input Fallback + hooks.createFromInputFallback(config); + } + } + + hooks.createFromInputFallback = deprecate( + 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + + 'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } + ); + + // Pick the first defined of two or three arguments. + function defaults(a, b, c) { + if (a != null) { + return a; + } + if (b != null) { + return b; + } + return c; + } + + function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(hooks.now()); + if (config._useUTC) { + return [ + nowValue.getUTCFullYear(), + nowValue.getUTCMonth(), + nowValue.getUTCDate(), + ]; + } + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; + } + + // convert an array to a date. + // the array should mirror the parameters below + // note: all values past the year are optional and will default to the lowest possible value. + // [year, month, day , hour, minute, second, millisecond] + function configFromArray(config) { + var i, + date, + input = [], + currentDate, + expectedWeekday, + yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); + + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + + //if the day of the year is set, figure out what it is + if (config._dayOfYear != null) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + + if ( + config._dayOfYear > daysInYear(yearToUse) || + config._dayOfYear === 0 + ) { + getParsingFlags(config)._overflowDayOfYear = true; + } + + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } + + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = + config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i]; + } + + // Check for 24:00:00.000 + if ( + config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0 + ) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply( + null, + input + ); + expectedWeekday = config._useUTC + ? config._d.getUTCDay() + : config._d.getDay(); + + // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } + + // check for mismatching day of week + if ( + config._w && + typeof config._w.d !== 'undefined' && + config._w.d !== expectedWeekday + ) { + getParsingFlags(config).weekdayMismatch = true; + } + } + + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults( + w.GG, + config._a[YEAR], + weekOfYear(createLocal(), 1, 4).year + ); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + curWeek = weekOfYear(createLocal(), dow, doy); + + weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); + + // Default to current week. + week = defaults(w.w, curWeek.week); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from beginning of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to beginning of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } + } + + // constant that refers to the ISO standard + hooks.ISO_8601 = function () {}; + + // constant that refers to the RFC 2822 form + hooks.RFC_2822 = function () {}; + + // date from string and format string + function configFromStringAndFormat(config) { + // TODO: Move this to another part of the creation flow to prevent circular deps + if (config._f === hooks.ISO_8601) { + configFromISO(config); + return; + } + if (config._f === hooks.RFC_2822) { + configFromRFC2822(config); + return; + } + config._a = []; + getParsingFlags(config).empty = true; + + // This array is used to make a Date, either with `new Date` or `Date.UTC` + var string = '' + config._i, + i, + parsedInput, + tokens, + token, + skipped, + stringLength = string.length, + totalParsedInputLength = 0, + era; + + tokens = + expandFormat(config._f, config._locale).match(formattingTokens) || []; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || + [])[0]; + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + if (skipped.length > 0) { + getParsingFlags(config).unusedInput.push(skipped); + } + string = string.slice( + string.indexOf(parsedInput) + parsedInput.length + ); + totalParsedInputLength += parsedInput.length; + } + // don't parse if it's not a known token + if (formatTokenFunctions[token]) { + if (parsedInput) { + getParsingFlags(config).empty = false; + } else { + getParsingFlags(config).unusedTokens.push(token); + } + addTimeToArrayFromToken(token, parsedInput, config); + } else if (config._strict && !parsedInput) { + getParsingFlags(config).unusedTokens.push(token); + } + } + + // add remaining unparsed input length to the string + getParsingFlags(config).charsLeftOver = + stringLength - totalParsedInputLength; + if (string.length > 0) { + getParsingFlags(config).unusedInput.push(string); + } + + // clear _12h flag if hour is <= 12 + if ( + config._a[HOUR] <= 12 && + getParsingFlags(config).bigHour === true && + config._a[HOUR] > 0 + ) { + getParsingFlags(config).bigHour = undefined; + } + + getParsingFlags(config).parsedDateParts = config._a.slice(0); + getParsingFlags(config).meridiem = config._meridiem; + // handle meridiem + config._a[HOUR] = meridiemFixWrap( + config._locale, + config._a[HOUR], + config._meridiem + ); + + // handle era + era = getParsingFlags(config).era; + if (era !== null) { + config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]); + } + + configFromArray(config); + checkOverflow(config); + } + + function meridiemFixWrap(locale, hour, meridiem) { + var isPm; + + if (meridiem == null) { + // nothing to do + return hour; + } + if (locale.meridiemHour != null) { + return locale.meridiemHour(hour, meridiem); + } else if (locale.isPM != null) { + // Fallback + isPm = locale.isPM(meridiem); + if (isPm && hour < 12) { + hour += 12; + } + if (!isPm && hour === 12) { + hour = 0; + } + return hour; + } else { + // this is not supposed to happen + return hour; + } + } + + // date from string and array of format strings + function configFromStringAndArray(config) { + var tempConfig, + bestMoment, + scoreToBeat, + i, + currentScore, + validFormatFound, + bestFormatIsValid = false; + + if (config._f.length === 0) { + getParsingFlags(config).invalidFormat = true; + config._d = new Date(NaN); + return; + } + + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + validFormatFound = false; + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } + tempConfig._f = config._f[i]; + configFromStringAndFormat(tempConfig); + + if (isValid(tempConfig)) { + validFormatFound = true; + } + + // if there is any input that was not parsed add a penalty for that format + currentScore += getParsingFlags(tempConfig).charsLeftOver; + + //or tokens + currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; + + getParsingFlags(tempConfig).score = currentScore; + + if (!bestFormatIsValid) { + if ( + scoreToBeat == null || + currentScore < scoreToBeat || + validFormatFound + ) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + if (validFormatFound) { + bestFormatIsValid = true; + } + } + } else { + if (currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } + } + } + + extend(config, bestMoment || tempConfig); + } + + function configFromObject(config) { + if (config._d) { + return; + } + + var i = normalizeObjectUnits(config._i), + dayOrDate = i.day === undefined ? i.date : i.day; + config._a = map( + [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond], + function (obj) { + return obj && parseInt(obj, 10); + } + ); + + configFromArray(config); + } + + function createFromConfig(config) { + var res = new Moment(checkOverflow(prepareConfig(config))); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; + } + + return res; + } + + function prepareConfig(config) { + var input = config._i, + format = config._f; + + config._locale = config._locale || getLocale(config._l); + + if (input === null || (format === undefined && input === '')) { + return createInvalid({ nullInput: true }); + } + + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } + + if (isMoment(input)) { + return new Moment(checkOverflow(input)); + } else if (isDate(input)) { + config._d = input; + } else if (isArray(format)) { + configFromStringAndArray(config); + } else if (format) { + configFromStringAndFormat(config); + } else { + configFromInput(config); + } + + if (!isValid(config)) { + config._d = null; + } + + return config; + } + + function configFromInput(config) { + var input = config._i; + if (isUndefined(input)) { + config._d = new Date(hooks.now()); + } else if (isDate(input)) { + config._d = new Date(input.valueOf()); + } else if (typeof input === 'string') { + configFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + configFromArray(config); + } else if (isObject(input)) { + configFromObject(config); + } else if (isNumber(input)) { + // from milliseconds + config._d = new Date(input); + } else { + hooks.createFromInputFallback(config); + } + } + + function createLocalOrUTC(input, format, locale, strict, isUTC) { + var c = {}; + + if (format === true || format === false) { + strict = format; + format = undefined; + } + + if (locale === true || locale === false) { + strict = locale; + locale = undefined; + } + + if ( + (isObject(input) && isObjectEmpty(input)) || + (isArray(input) && input.length === 0) + ) { + input = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c._isAMomentObject = true; + c._useUTC = c._isUTC = isUTC; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; + + return createFromConfig(c); + } + + function createLocal(input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, false); + } + + var prototypeMin = deprecate( + 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return createInvalid(); + } + } + ), + prototypeMax = deprecate( + 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return createInvalid(); + } + } + ); + + // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return createLocal(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (!moments[i].isValid() || moments[i][fn](res)) { + res = moments[i]; + } + } + return res; + } + + // TODO: Use [].sort instead? + function min() { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); + } + + function max() { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); + } + + var now = function () { + return Date.now ? Date.now() : +new Date(); + }; + + var ordering = [ + 'year', + 'quarter', + 'month', + 'week', + 'day', + 'hour', + 'minute', + 'second', + 'millisecond', + ]; + + function isDurationValid(m) { + var key, + unitHasDecimal = false, + i; + for (key in m) { + if ( + hasOwnProp(m, key) && + !( + indexOf.call(ordering, key) !== -1 && + (m[key] == null || !isNaN(m[key])) + ) + ) { + return false; + } + } + + for (i = 0; i < ordering.length; ++i) { + if (m[ordering[i]]) { + if (unitHasDecimal) { + return false; // only allow non-integers for smallest unit + } + if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { + unitHasDecimal = true; + } + } + } + + return true; + } + + function isValid$1() { + return this._isValid; + } + + function createInvalid$1() { + return createDuration(NaN); + } + + function Duration(duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || normalizedInput.isoWeek || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; + + this._isValid = isDurationValid(normalizedInput); + + // representation for dateAddRemove + this._milliseconds = + +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + weeks * 7; + // It is impossible to translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + quarters * 3 + years * 12; + + this._data = {}; + + this._locale = getLocale(); + + this._bubble(); + } + + function isDuration(obj) { + return obj instanceof Duration; + } + + function absRound(number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } + } + + // compare two arrays, return the number of differences + function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if ( + (dontConvert && array1[i] !== array2[i]) || + (!dontConvert && toInt(array1[i]) !== toInt(array2[i])) + ) { + diffs++; + } + } + return diffs + lengthDiff; + } + + // FORMATTING + + function offset(token, separator) { + addFormatToken(token, 0, 0, function () { + var offset = this.utcOffset(), + sign = '+'; + if (offset < 0) { + offset = -offset; + sign = '-'; + } + return ( + sign + + zeroFill(~~(offset / 60), 2) + + separator + + zeroFill(~~offset % 60, 2) + ); + }); + } + + offset('Z', ':'); + offset('ZZ', ''); + + // PARSING + + addRegexToken('Z', matchShortOffset); + addRegexToken('ZZ', matchShortOffset); + addParseToken(['Z', 'ZZ'], function (input, array, config) { + config._useUTC = true; + config._tzm = offsetFromString(matchShortOffset, input); + }); + + // HELPERS + + // timezone chunker + // '+10:00' > ['10', '00'] + // '-1530' > ['-15', '30'] + var chunkOffset = /([\+\-]|\d\d)/gi; + + function offsetFromString(matcher, string) { + var matches = (string || '').match(matcher), + chunk, + parts, + minutes; + + if (matches === null) { + return null; + } + + chunk = matches[matches.length - 1] || []; + parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; + minutes = +(parts[1] * 60) + toInt(parts[2]); + + return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes; + } + + // Return a moment from input, that is local/utc/zone equivalent to model. + function cloneWithOffset(input, model) { + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = + (isMoment(input) || isDate(input) + ? input.valueOf() + : createLocal(input).valueOf()) - res.valueOf(); + // Use low-level api, because this fn is low-level api. + res._d.setTime(res._d.valueOf() + diff); + hooks.updateOffset(res, false); + return res; + } else { + return createLocal(input).local(); + } + } + + function getDateOffset(m) { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return -Math.round(m._d.getTimezoneOffset()); + } + + // HOOKS + + // This function will be called whenever a moment is mutated. + // It is intended to keep the offset in sync with the timezone. + hooks.updateOffset = function () {}; + + // MOMENTS + + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + function getSetOffset(input, keepLocalTime, keepMinutes) { + var offset = this._offset || 0, + localAdjust; + if (!this.isValid()) { + return input != null ? this : NaN; + } + if (input != null) { + if (typeof input === 'string') { + input = offsetFromString(matchShortOffset, input); + if (input === null) { + return this; + } + } else if (Math.abs(input) < 16 && !keepMinutes) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = getDateOffset(this); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.add(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + addSubtract( + this, + createDuration(input - offset, 'm'), + 1, + false + ); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + hooks.updateOffset(this, true); + this._changeInProgress = null; + } + } + return this; + } else { + return this._isUTC ? offset : getDateOffset(this); + } + } + + function getSetZone(input, keepLocalTime) { + if (input != null) { + if (typeof input !== 'string') { + input = -input; + } + + this.utcOffset(input, keepLocalTime); + + return this; + } else { + return -this.utcOffset(); + } + } + + function setOffsetToUTC(keepLocalTime) { + return this.utcOffset(0, keepLocalTime); + } + + function setOffsetToLocal(keepLocalTime) { + if (this._isUTC) { + this.utcOffset(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.subtract(getDateOffset(this), 'm'); + } + } + return this; + } + + function setOffsetToParsedOffset() { + if (this._tzm != null) { + this.utcOffset(this._tzm, false, true); + } else if (typeof this._i === 'string') { + var tZone = offsetFromString(matchOffset, this._i); + if (tZone != null) { + this.utcOffset(tZone); + } else { + this.utcOffset(0, true); + } + } + return this; + } + + function hasAlignedHourOffset(input) { + if (!this.isValid()) { + return false; + } + input = input ? createLocal(input).utcOffset() : 0; + + return (this.utcOffset() - input) % 60 === 0; + } + + function isDaylightSavingTime() { + return ( + this.utcOffset() > this.clone().month(0).utcOffset() || + this.utcOffset() > this.clone().month(5).utcOffset() + ); + } + + function isDaylightSavingTimeShifted() { + if (!isUndefined(this._isDSTShifted)) { + return this._isDSTShifted; + } + + var c = {}, + other; + + copyConfig(c, this); + c = prepareConfig(c); + + if (c._a) { + other = c._isUTC ? createUTC(c._a) : createLocal(c._a); + this._isDSTShifted = + this.isValid() && compareArrays(c._a, other.toArray()) > 0; + } else { + this._isDSTShifted = false; + } + + return this._isDSTShifted; + } + + function isLocal() { + return this.isValid() ? !this._isUTC : false; + } + + function isUtcOffset() { + return this.isValid() ? this._isUTC : false; + } + + function isUtc() { + return this.isValid() ? this._isUTC && this._offset === 0 : false; + } + + // ASP.NET json date format regex + var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/, + // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html + // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere + // and further modified to allow for strings containing both week and day + isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; + + function createDuration(input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + diffRes; + + if (isDuration(input)) { + duration = { + ms: input._milliseconds, + d: input._days, + M: input._months, + }; + } else if (isNumber(input) || !isNaN(+input)) { + duration = {}; + if (key) { + duration[key] = +input; + } else { + duration.milliseconds = +input; + } + } else if ((match = aspNetRegex.exec(input))) { + sign = match[1] === '-' ? -1 : 1; + duration = { + y: 0, + d: toInt(match[DATE]) * sign, + h: toInt(match[HOUR]) * sign, + m: toInt(match[MINUTE]) * sign, + s: toInt(match[SECOND]) * sign, + ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match + }; + } else if ((match = isoRegex.exec(input))) { + sign = match[1] === '-' ? -1 : 1; + duration = { + y: parseIso(match[2], sign), + M: parseIso(match[3], sign), + w: parseIso(match[4], sign), + d: parseIso(match[5], sign), + h: parseIso(match[6], sign), + m: parseIso(match[7], sign), + s: parseIso(match[8], sign), + }; + } else if (duration == null) { + // checks for null or undefined + duration = {}; + } else if ( + typeof duration === 'object' && + ('from' in duration || 'to' in duration) + ) { + diffRes = momentsDifference( + createLocal(duration.from), + createLocal(duration.to) + ); + + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + + ret = new Duration(duration); + + if (isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; + } + + if (isDuration(input) && hasOwnProp(input, '_isValid')) { + ret._isValid = input._isValid; + } + + return ret; + } + + createDuration.fn = Duration.prototype; + createDuration.invalid = createInvalid$1; + + function parseIso(inp, sign) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; + } + + function positiveMomentsDifference(base, other) { + var res = {}; + + res.months = + other.month() - base.month() + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +base.clone().add(res.months, 'M'); + + return res; + } + + function momentsDifference(base, other) { + var res; + if (!(base.isValid() && other.isValid())) { + return { milliseconds: 0, months: 0 }; + } + + other = cloneWithOffset(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; + } + + // TODO: remove 'name' arg after deprecation is removed + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple( + name, + 'moment().' + + name + + '(period, number) is deprecated. Please use moment().' + + name + + '(number, period). ' + + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.' + ); + tmp = val; + val = period; + period = tmp; + } + + dur = createDuration(val, period); + addSubtract(this, dur, direction); + return this; + }; + } + + function addSubtract(mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = absRound(duration._days), + months = absRound(duration._months); + + if (!mom.isValid()) { + // No op + return; + } + + updateOffset = updateOffset == null ? true : updateOffset; + + if (months) { + setMonth(mom, get(mom, 'Month') + months * isAdding); + } + if (days) { + set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); + } + if (milliseconds) { + mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); + } + if (updateOffset) { + hooks.updateOffset(mom, days || months); + } + } + + var add = createAdder(1, 'add'), + subtract = createAdder(-1, 'subtract'); + + function isString(input) { + return typeof input === 'string' || input instanceof String; + } + + // type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined + function isMomentInput(input) { + return ( + isMoment(input) || + isDate(input) || + isString(input) || + isNumber(input) || + isNumberOrStringArray(input) || + isMomentInputObject(input) || + input === null || + input === undefined + ); + } + + function isMomentInputObject(input) { + var objectTest = isObject(input) && !isObjectEmpty(input), + propertyTest = false, + properties = [ + 'years', + 'year', + 'y', + 'months', + 'month', + 'M', + 'days', + 'day', + 'd', + 'dates', + 'date', + 'D', + 'hours', + 'hour', + 'h', + 'minutes', + 'minute', + 'm', + 'seconds', + 'second', + 's', + 'milliseconds', + 'millisecond', + 'ms', + ], + i, + property; + + for (i = 0; i < properties.length; i += 1) { + property = properties[i]; + propertyTest = propertyTest || hasOwnProp(input, property); + } + + return objectTest && propertyTest; + } + + function isNumberOrStringArray(input) { + var arrayTest = isArray(input), + dataTypeTest = false; + if (arrayTest) { + dataTypeTest = + input.filter(function (item) { + return !isNumber(item) && isString(input); + }).length === 0; + } + return arrayTest && dataTypeTest; + } + + function isCalendarSpec(input) { + var objectTest = isObject(input) && !isObjectEmpty(input), + propertyTest = false, + properties = [ + 'sameDay', + 'nextDay', + 'lastDay', + 'nextWeek', + 'lastWeek', + 'sameElse', + ], + i, + property; + + for (i = 0; i < properties.length; i += 1) { + property = properties[i]; + propertyTest = propertyTest || hasOwnProp(input, property); + } + + return objectTest && propertyTest; + } + + function getCalendarFormat(myMoment, now) { + var diff = myMoment.diff(now, 'days', true); + return diff < -6 + ? 'sameElse' + : diff < -1 + ? 'lastWeek' + : diff < 0 + ? 'lastDay' + : diff < 1 + ? 'sameDay' + : diff < 2 + ? 'nextDay' + : diff < 7 + ? 'nextWeek' + : 'sameElse'; + } + + function calendar$1(time, formats) { + // Support for single parameter, formats only overload to the calendar function + if (arguments.length === 1) { + if (!arguments[0]) { + time = undefined; + formats = undefined; + } else if (isMomentInput(arguments[0])) { + time = arguments[0]; + formats = undefined; + } else if (isCalendarSpec(arguments[0])) { + formats = arguments[0]; + time = undefined; + } + } + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + format = hooks.calendarFormat(this, sod) || 'sameElse', + output = + formats && + (isFunction(formats[format]) + ? formats[format].call(this, now) + : formats[format]); + + return this.format( + output || this.localeData().calendar(format, this, createLocal(now)) + ); + } + + function clone() { + return new Moment(this); + } + + function isAfter(input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units) || 'millisecond'; + if (units === 'millisecond') { + return this.valueOf() > localInput.valueOf(); + } else { + return localInput.valueOf() < this.clone().startOf(units).valueOf(); + } + } + + function isBefore(input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units) || 'millisecond'; + if (units === 'millisecond') { + return this.valueOf() < localInput.valueOf(); + } else { + return this.clone().endOf(units).valueOf() < localInput.valueOf(); + } + } + + function isBetween(from, to, units, inclusivity) { + var localFrom = isMoment(from) ? from : createLocal(from), + localTo = isMoment(to) ? to : createLocal(to); + if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { + return false; + } + inclusivity = inclusivity || '()'; + return ( + (inclusivity[0] === '(' + ? this.isAfter(localFrom, units) + : !this.isBefore(localFrom, units)) && + (inclusivity[1] === ')' + ? this.isBefore(localTo, units) + : !this.isAfter(localTo, units)) + ); + } + + function isSame(input, units) { + var localInput = isMoment(input) ? input : createLocal(input), + inputMs; + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units) || 'millisecond'; + if (units === 'millisecond') { + return this.valueOf() === localInput.valueOf(); + } else { + inputMs = localInput.valueOf(); + return ( + this.clone().startOf(units).valueOf() <= inputMs && + inputMs <= this.clone().endOf(units).valueOf() + ); + } + } + + function isSameOrAfter(input, units) { + return this.isSame(input, units) || this.isAfter(input, units); + } + + function isSameOrBefore(input, units) { + return this.isSame(input, units) || this.isBefore(input, units); + } + + function diff(input, units, asFloat) { + var that, zoneDelta, output; + + if (!this.isValid()) { + return NaN; + } + + that = cloneWithOffset(input, this); + + if (!that.isValid()) { + return NaN; + } + + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + + units = normalizeUnits(units); + + switch (units) { + case 'year': + output = monthDiff(this, that) / 12; + break; + case 'month': + output = monthDiff(this, that); + break; + case 'quarter': + output = monthDiff(this, that) / 3; + break; + case 'second': + output = (this - that) / 1e3; + break; // 1000 + case 'minute': + output = (this - that) / 6e4; + break; // 1000 * 60 + case 'hour': + output = (this - that) / 36e5; + break; // 1000 * 60 * 60 + case 'day': + output = (this - that - zoneDelta) / 864e5; + break; // 1000 * 60 * 60 * 24, negate dst + case 'week': + output = (this - that - zoneDelta) / 6048e5; + break; // 1000 * 60 * 60 * 24 * 7, negate dst + default: + output = this - that; + } + + return asFloat ? output : absFloor(output); + } + + function monthDiff(a, b) { + if (a.date() < b.date()) { + // end-of-month calculations work correct when the start month has more + // days than the end month. + return -monthDiff(b, a); + } + // difference in months + var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()), + // b is in (anchor - 1 month, anchor + 1 month) + anchor = a.clone().add(wholeMonthDiff, 'months'), + anchor2, + adjust; + + if (b - anchor < 0) { + anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor - anchor2); + } else { + anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor2 - anchor); + } + + //check for negative zero, return zero if negative zero + return -(wholeMonthDiff + adjust) || 0; + } + + hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; + hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; + + function toString() { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); + } + + function toISOString(keepOffset) { + if (!this.isValid()) { + return null; + } + var utc = keepOffset !== true, + m = utc ? this.clone().utc() : this; + if (m.year() < 0 || m.year() > 9999) { + return formatMoment( + m, + utc + ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' + : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ' + ); + } + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + if (utc) { + return this.toDate().toISOString(); + } else { + return new Date(this.valueOf() + this.utcOffset() * 60 * 1000) + .toISOString() + .replace('Z', formatMoment(m, 'Z')); + } + } + return formatMoment( + m, + utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ' + ); + } + + /** + * Return a human readable representation of a moment that can + * also be evaluated to get a new moment which is the same + * + * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects + */ + function inspect() { + if (!this.isValid()) { + return 'moment.invalid(/* ' + this._i + ' */)'; + } + var func = 'moment', + zone = '', + prefix, + year, + datetime, + suffix; + if (!this.isLocal()) { + func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; + zone = 'Z'; + } + prefix = '[' + func + '("]'; + year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY'; + datetime = '-MM-DD[T]HH:mm:ss.SSS'; + suffix = zone + '[")]'; + + return this.format(prefix + year + datetime + suffix); + } + + function format(inputString) { + if (!inputString) { + inputString = this.isUtc() + ? hooks.defaultFormatUtc + : hooks.defaultFormat; + } + var output = formatMoment(this, inputString); + return this.localeData().postformat(output); + } + + function from(time, withoutSuffix) { + if ( + this.isValid() && + ((isMoment(time) && time.isValid()) || createLocal(time).isValid()) + ) { + return createDuration({ to: this, from: time }) + .locale(this.locale()) + .humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function fromNow(withoutSuffix) { + return this.from(createLocal(), withoutSuffix); + } + + function to(time, withoutSuffix) { + if ( + this.isValid() && + ((isMoment(time) && time.isValid()) || createLocal(time).isValid()) + ) { + return createDuration({ from: this, to: time }) + .locale(this.locale()) + .humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function toNow(withoutSuffix) { + return this.to(createLocal(), withoutSuffix); + } + + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration + // variables for this instance. + function locale(key) { + var newLocaleData; + + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = getLocale(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } + return this; + } + } + + var lang = deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } + ); + + function localeData() { + return this._locale; + } + + var MS_PER_SECOND = 1000, + MS_PER_MINUTE = 60 * MS_PER_SECOND, + MS_PER_HOUR = 60 * MS_PER_MINUTE, + MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; + + // actual modulo - handles negative numbers (for dates before 1970): + function mod$1(dividend, divisor) { + return ((dividend % divisor) + divisor) % divisor; + } + + function localStartOfDate(y, m, d) { + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + return new Date(y + 400, m, d) - MS_PER_400_YEARS; + } else { + return new Date(y, m, d).valueOf(); + } + } + + function utcStartOfDate(y, m, d) { + // Date.UTC remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; + } else { + return Date.UTC(y, m, d); + } + } + + function startOf(units) { + var time, startOfDate; + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond' || !this.isValid()) { + return this; + } + + startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; + + switch (units) { + case 'year': + time = startOfDate(this.year(), 0, 1); + break; + case 'quarter': + time = startOfDate( + this.year(), + this.month() - (this.month() % 3), + 1 + ); + break; + case 'month': + time = startOfDate(this.year(), this.month(), 1); + break; + case 'week': + time = startOfDate( + this.year(), + this.month(), + this.date() - this.weekday() + ); + break; + case 'isoWeek': + time = startOfDate( + this.year(), + this.month(), + this.date() - (this.isoWeekday() - 1) + ); + break; + case 'day': + case 'date': + time = startOfDate(this.year(), this.month(), this.date()); + break; + case 'hour': + time = this._d.valueOf(); + time -= mod$1( + time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), + MS_PER_HOUR + ); + break; + case 'minute': + time = this._d.valueOf(); + time -= mod$1(time, MS_PER_MINUTE); + break; + case 'second': + time = this._d.valueOf(); + time -= mod$1(time, MS_PER_SECOND); + break; + } + + this._d.setTime(time); + hooks.updateOffset(this, true); + return this; + } + + function endOf(units) { + var time, startOfDate; + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond' || !this.isValid()) { + return this; + } + + startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; + + switch (units) { + case 'year': + time = startOfDate(this.year() + 1, 0, 1) - 1; + break; + case 'quarter': + time = + startOfDate( + this.year(), + this.month() - (this.month() % 3) + 3, + 1 + ) - 1; + break; + case 'month': + time = startOfDate(this.year(), this.month() + 1, 1) - 1; + break; + case 'week': + time = + startOfDate( + this.year(), + this.month(), + this.date() - this.weekday() + 7 + ) - 1; + break; + case 'isoWeek': + time = + startOfDate( + this.year(), + this.month(), + this.date() - (this.isoWeekday() - 1) + 7 + ) - 1; + break; + case 'day': + case 'date': + time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; + break; + case 'hour': + time = this._d.valueOf(); + time += + MS_PER_HOUR - + mod$1( + time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), + MS_PER_HOUR + ) - + 1; + break; + case 'minute': + time = this._d.valueOf(); + time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; + break; + case 'second': + time = this._d.valueOf(); + time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; + break; + } + + this._d.setTime(time); + hooks.updateOffset(this, true); + return this; + } + + function valueOf() { + return this._d.valueOf() - (this._offset || 0) * 60000; + } + + function unix() { + return Math.floor(this.valueOf() / 1000); + } + + function toDate() { + return new Date(this.valueOf()); + } + + function toArray() { + var m = this; + return [ + m.year(), + m.month(), + m.date(), + m.hour(), + m.minute(), + m.second(), + m.millisecond(), + ]; + } + + function toObject() { + var m = this; + return { + years: m.year(), + months: m.month(), + date: m.date(), + hours: m.hours(), + minutes: m.minutes(), + seconds: m.seconds(), + milliseconds: m.milliseconds(), + }; + } + + function toJSON() { + // new Date(NaN).toJSON() === null + return this.isValid() ? this.toISOString() : null; + } + + function isValid$2() { + return isValid(this); + } + + function parsingFlags() { + return extend({}, getParsingFlags(this)); + } + + function invalidAt() { + return getParsingFlags(this).overflow; + } + + function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict, + }; + } + + addFormatToken('N', 0, 0, 'eraAbbr'); + addFormatToken('NN', 0, 0, 'eraAbbr'); + addFormatToken('NNN', 0, 0, 'eraAbbr'); + addFormatToken('NNNN', 0, 0, 'eraName'); + addFormatToken('NNNNN', 0, 0, 'eraNarrow'); + + addFormatToken('y', ['y', 1], 'yo', 'eraYear'); + addFormatToken('y', ['yy', 2], 0, 'eraYear'); + addFormatToken('y', ['yyy', 3], 0, 'eraYear'); + addFormatToken('y', ['yyyy', 4], 0, 'eraYear'); + + addRegexToken('N', matchEraAbbr); + addRegexToken('NN', matchEraAbbr); + addRegexToken('NNN', matchEraAbbr); + addRegexToken('NNNN', matchEraName); + addRegexToken('NNNNN', matchEraNarrow); + + addParseToken(['N', 'NN', 'NNN', 'NNNN', 'NNNNN'], function ( + input, + array, + config, + token + ) { + var era = config._locale.erasParse(input, token, config._strict); + if (era) { + getParsingFlags(config).era = era; + } else { + getParsingFlags(config).invalidEra = input; + } + }); + + addRegexToken('y', matchUnsigned); + addRegexToken('yy', matchUnsigned); + addRegexToken('yyy', matchUnsigned); + addRegexToken('yyyy', matchUnsigned); + addRegexToken('yo', matchEraYearOrdinal); + + addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR); + addParseToken(['yo'], function (input, array, config, token) { + var match; + if (config._locale._eraYearOrdinalRegex) { + match = input.match(config._locale._eraYearOrdinalRegex); + } + + if (config._locale.eraYearOrdinalParse) { + array[YEAR] = config._locale.eraYearOrdinalParse(input, match); + } else { + array[YEAR] = parseInt(input, 10); + } + }); + + function localeEras(m, format) { + var i, + l, + date, + eras = this._eras || getLocale('en')._eras; + for (i = 0, l = eras.length; i < l; ++i) { + switch (typeof eras[i].since) { + case 'string': + // truncate time + date = hooks(eras[i].since).startOf('day'); + eras[i].since = date.valueOf(); + break; + } + + switch (typeof eras[i].until) { + case 'undefined': + eras[i].until = +Infinity; + break; + case 'string': + // truncate time + date = hooks(eras[i].until).startOf('day').valueOf(); + eras[i].until = date.valueOf(); + break; + } + } + return eras; + } + + function localeErasParse(eraName, format, strict) { + var i, + l, + eras = this.eras(), + name, + abbr, + narrow; + eraName = eraName.toUpperCase(); + + for (i = 0, l = eras.length; i < l; ++i) { + name = eras[i].name.toUpperCase(); + abbr = eras[i].abbr.toUpperCase(); + narrow = eras[i].narrow.toUpperCase(); + + if (strict) { + switch (format) { + case 'N': + case 'NN': + case 'NNN': + if (abbr === eraName) { + return eras[i]; + } + break; + + case 'NNNN': + if (name === eraName) { + return eras[i]; + } + break; + + case 'NNNNN': + if (narrow === eraName) { + return eras[i]; + } + break; + } + } else if ([name, abbr, narrow].indexOf(eraName) >= 0) { + return eras[i]; + } + } + } + + function localeErasConvertYear(era, year) { + var dir = era.since <= era.until ? +1 : -1; + if (year === undefined) { + return hooks(era.since).year(); + } else { + return hooks(era.since).year() + (year - era.offset) * dir; + } + } + + function getEraName() { + var i, + l, + val, + eras = this.localeData().eras(); + for (i = 0, l = eras.length; i < l; ++i) { + // truncate time + val = this.clone().startOf('day').valueOf(); + + if (eras[i].since <= val && val <= eras[i].until) { + return eras[i].name; + } + if (eras[i].until <= val && val <= eras[i].since) { + return eras[i].name; + } + } + + return ''; + } + + function getEraNarrow() { + var i, + l, + val, + eras = this.localeData().eras(); + for (i = 0, l = eras.length; i < l; ++i) { + // truncate time + val = this.clone().startOf('day').valueOf(); + + if (eras[i].since <= val && val <= eras[i].until) { + return eras[i].narrow; + } + if (eras[i].until <= val && val <= eras[i].since) { + return eras[i].narrow; + } + } + + return ''; + } + + function getEraAbbr() { + var i, + l, + val, + eras = this.localeData().eras(); + for (i = 0, l = eras.length; i < l; ++i) { + // truncate time + val = this.clone().startOf('day').valueOf(); + + if (eras[i].since <= val && val <= eras[i].until) { + return eras[i].abbr; + } + if (eras[i].until <= val && val <= eras[i].since) { + return eras[i].abbr; + } + } + + return ''; + } + + function getEraYear() { + var i, + l, + dir, + val, + eras = this.localeData().eras(); + for (i = 0, l = eras.length; i < l; ++i) { + dir = eras[i].since <= eras[i].until ? +1 : -1; + + // truncate time + val = this.clone().startOf('day').valueOf(); + + if ( + (eras[i].since <= val && val <= eras[i].until) || + (eras[i].until <= val && val <= eras[i].since) + ) { + return ( + (this.year() - hooks(eras[i].since).year()) * dir + + eras[i].offset + ); + } + } + + return this.year(); + } + + function erasNameRegex(isStrict) { + if (!hasOwnProp(this, '_erasNameRegex')) { + computeErasParse.call(this); + } + return isStrict ? this._erasNameRegex : this._erasRegex; + } + + function erasAbbrRegex(isStrict) { + if (!hasOwnProp(this, '_erasAbbrRegex')) { + computeErasParse.call(this); + } + return isStrict ? this._erasAbbrRegex : this._erasRegex; + } + + function erasNarrowRegex(isStrict) { + if (!hasOwnProp(this, '_erasNarrowRegex')) { + computeErasParse.call(this); + } + return isStrict ? this._erasNarrowRegex : this._erasRegex; + } + + function matchEraAbbr(isStrict, locale) { + return locale.erasAbbrRegex(isStrict); + } + + function matchEraName(isStrict, locale) { + return locale.erasNameRegex(isStrict); + } + + function matchEraNarrow(isStrict, locale) { + return locale.erasNarrowRegex(isStrict); + } + + function matchEraYearOrdinal(isStrict, locale) { + return locale._eraYearOrdinalRegex || matchUnsigned; + } + + function computeErasParse() { + var abbrPieces = [], + namePieces = [], + narrowPieces = [], + mixedPieces = [], + i, + l, + eras = this.eras(); + + for (i = 0, l = eras.length; i < l; ++i) { + namePieces.push(regexEscape(eras[i].name)); + abbrPieces.push(regexEscape(eras[i].abbr)); + narrowPieces.push(regexEscape(eras[i].narrow)); + + mixedPieces.push(regexEscape(eras[i].name)); + mixedPieces.push(regexEscape(eras[i].abbr)); + mixedPieces.push(regexEscape(eras[i].narrow)); + } + + this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i'); + this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i'); + this._erasNarrowRegex = new RegExp( + '^(' + narrowPieces.join('|') + ')', + 'i' + ); + } + + // FORMATTING + + addFormatToken(0, ['gg', 2], 0, function () { + return this.weekYear() % 100; + }); + + addFormatToken(0, ['GG', 2], 0, function () { + return this.isoWeekYear() % 100; + }); + + function addWeekYearFormatToken(token, getter) { + addFormatToken(0, [token, token.length], 0, getter); + } + + addWeekYearFormatToken('gggg', 'weekYear'); + addWeekYearFormatToken('ggggg', 'weekYear'); + addWeekYearFormatToken('GGGG', 'isoWeekYear'); + addWeekYearFormatToken('GGGGG', 'isoWeekYear'); + + // ALIASES + + addUnitAlias('weekYear', 'gg'); + addUnitAlias('isoWeekYear', 'GG'); + + // PRIORITY + + addUnitPriority('weekYear', 1); + addUnitPriority('isoWeekYear', 1); + + // PARSING + + addRegexToken('G', matchSigned); + addRegexToken('g', matchSigned); + addRegexToken('GG', match1to2, match2); + addRegexToken('gg', match1to2, match2); + addRegexToken('GGGG', match1to4, match4); + addRegexToken('gggg', match1to4, match4); + addRegexToken('GGGGG', match1to6, match6); + addRegexToken('ggggg', match1to6, match6); + + addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function ( + input, + week, + config, + token + ) { + week[token.substr(0, 2)] = toInt(input); + }); + + addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { + week[token] = hooks.parseTwoDigitYear(input); + }); + + // MOMENTS + + function getSetWeekYear(input) { + return getSetWeekYearHelper.call( + this, + input, + this.week(), + this.weekday(), + this.localeData()._week.dow, + this.localeData()._week.doy + ); + } + + function getSetISOWeekYear(input) { + return getSetWeekYearHelper.call( + this, + input, + this.isoWeek(), + this.isoWeekday(), + 1, + 4 + ); + } + + function getISOWeeksInYear() { + return weeksInYear(this.year(), 1, 4); + } + + function getISOWeeksInISOWeekYear() { + return weeksInYear(this.isoWeekYear(), 1, 4); + } + + function getWeeksInYear() { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); + } + + function getWeeksInWeekYear() { + var weekInfo = this.localeData()._week; + return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy); + } + + function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + if (week > weeksTarget) { + week = weeksTarget; + } + return setWeekAll.call(this, input, week, weekday, dow, doy); + } + } + + function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; + } + + // FORMATTING + + addFormatToken('Q', 0, 'Qo', 'quarter'); + + // ALIASES + + addUnitAlias('quarter', 'Q'); + + // PRIORITY + + addUnitPriority('quarter', 7); + + // PARSING + + addRegexToken('Q', match1); + addParseToken('Q', function (input, array) { + array[MONTH] = (toInt(input) - 1) * 3; + }); + + // MOMENTS + + function getSetQuarter(input) { + return input == null + ? Math.ceil((this.month() + 1) / 3) + : this.month((input - 1) * 3 + (this.month() % 3)); + } + + // FORMATTING + + addFormatToken('D', ['DD', 2], 'Do', 'date'); + + // ALIASES + + addUnitAlias('date', 'D'); + + // PRIORITY + addUnitPriority('date', 9); + + // PARSING + + addRegexToken('D', match1to2); + addRegexToken('DD', match1to2, match2); + addRegexToken('Do', function (isStrict, locale) { + // TODO: Remove "ordinalParse" fallback in next major release. + return isStrict + ? locale._dayOfMonthOrdinalParse || locale._ordinalParse + : locale._dayOfMonthOrdinalParseLenient; + }); + + addParseToken(['D', 'DD'], DATE); + addParseToken('Do', function (input, array) { + array[DATE] = toInt(input.match(match1to2)[0]); + }); + + // MOMENTS + + var getSetDayOfMonth = makeGetSet('Date', true); + + // FORMATTING + + addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); + + // ALIASES + + addUnitAlias('dayOfYear', 'DDD'); + + // PRIORITY + addUnitPriority('dayOfYear', 4); + + // PARSING + + addRegexToken('DDD', match1to3); + addRegexToken('DDDD', match3); + addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); + }); + + // HELPERS + + // MOMENTS + + function getSetDayOfYear(input) { + var dayOfYear = + Math.round( + (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5 + ) + 1; + return input == null ? dayOfYear : this.add(input - dayOfYear, 'd'); + } + + // FORMATTING + + addFormatToken('m', ['mm', 2], 0, 'minute'); + + // ALIASES + + addUnitAlias('minute', 'm'); + + // PRIORITY + + addUnitPriority('minute', 14); + + // PARSING + + addRegexToken('m', match1to2); + addRegexToken('mm', match1to2, match2); + addParseToken(['m', 'mm'], MINUTE); + + // MOMENTS + + var getSetMinute = makeGetSet('Minutes', false); + + // FORMATTING + + addFormatToken('s', ['ss', 2], 0, 'second'); + + // ALIASES + + addUnitAlias('second', 's'); + + // PRIORITY + + addUnitPriority('second', 15); + + // PARSING + + addRegexToken('s', match1to2); + addRegexToken('ss', match1to2, match2); + addParseToken(['s', 'ss'], SECOND); + + // MOMENTS + + var getSetSecond = makeGetSet('Seconds', false); + + // FORMATTING + + addFormatToken('S', 0, 0, function () { + return ~~(this.millisecond() / 100); + }); + + addFormatToken(0, ['SS', 2], 0, function () { + return ~~(this.millisecond() / 10); + }); + + addFormatToken(0, ['SSS', 3], 0, 'millisecond'); + addFormatToken(0, ['SSSS', 4], 0, function () { + return this.millisecond() * 10; + }); + addFormatToken(0, ['SSSSS', 5], 0, function () { + return this.millisecond() * 100; + }); + addFormatToken(0, ['SSSSSS', 6], 0, function () { + return this.millisecond() * 1000; + }); + addFormatToken(0, ['SSSSSSS', 7], 0, function () { + return this.millisecond() * 10000; + }); + addFormatToken(0, ['SSSSSSSS', 8], 0, function () { + return this.millisecond() * 100000; + }); + addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { + return this.millisecond() * 1000000; + }); + + // ALIASES + + addUnitAlias('millisecond', 'ms'); + + // PRIORITY + + addUnitPriority('millisecond', 16); + + // PARSING + + addRegexToken('S', match1to3, match1); + addRegexToken('SS', match1to3, match2); + addRegexToken('SSS', match1to3, match3); + + var token, getSetMillisecond; + for (token = 'SSSS'; token.length <= 9; token += 'S') { + addRegexToken(token, matchUnsigned); + } + + function parseMs(input, array) { + array[MILLISECOND] = toInt(('0.' + input) * 1000); + } + + for (token = 'S'; token.length <= 9; token += 'S') { + addParseToken(token, parseMs); + } + + getSetMillisecond = makeGetSet('Milliseconds', false); + + // FORMATTING + + addFormatToken('z', 0, 0, 'zoneAbbr'); + addFormatToken('zz', 0, 0, 'zoneName'); + + // MOMENTS + + function getZoneAbbr() { + return this._isUTC ? 'UTC' : ''; + } + + function getZoneName() { + return this._isUTC ? 'Coordinated Universal Time' : ''; + } + + var proto = Moment.prototype; + + proto.add = add; + proto.calendar = calendar$1; + proto.clone = clone; + proto.diff = diff; + proto.endOf = endOf; + proto.format = format; + proto.from = from; + proto.fromNow = fromNow; + proto.to = to; + proto.toNow = toNow; + proto.get = stringGet; + proto.invalidAt = invalidAt; + proto.isAfter = isAfter; + proto.isBefore = isBefore; + proto.isBetween = isBetween; + proto.isSame = isSame; + proto.isSameOrAfter = isSameOrAfter; + proto.isSameOrBefore = isSameOrBefore; + proto.isValid = isValid$2; + proto.lang = lang; + proto.locale = locale; + proto.localeData = localeData; + proto.max = prototypeMax; + proto.min = prototypeMin; + proto.parsingFlags = parsingFlags; + proto.set = stringSet; + proto.startOf = startOf; + proto.subtract = subtract; + proto.toArray = toArray; + proto.toObject = toObject; + proto.toDate = toDate; + proto.toISOString = toISOString; + proto.inspect = inspect; + if (typeof Symbol !== 'undefined' && Symbol.for != null) { + proto[Symbol.for('nodejs.util.inspect.custom')] = function () { + return 'Moment<' + this.format() + '>'; + }; + } + proto.toJSON = toJSON; + proto.toString = toString; + proto.unix = unix; + proto.valueOf = valueOf; + proto.creationData = creationData; + proto.eraName = getEraName; + proto.eraNarrow = getEraNarrow; + proto.eraAbbr = getEraAbbr; + proto.eraYear = getEraYear; + proto.year = getSetYear; + proto.isLeapYear = getIsLeapYear; + proto.weekYear = getSetWeekYear; + proto.isoWeekYear = getSetISOWeekYear; + proto.quarter = proto.quarters = getSetQuarter; + proto.month = getSetMonth; + proto.daysInMonth = getDaysInMonth; + proto.week = proto.weeks = getSetWeek; + proto.isoWeek = proto.isoWeeks = getSetISOWeek; + proto.weeksInYear = getWeeksInYear; + proto.weeksInWeekYear = getWeeksInWeekYear; + proto.isoWeeksInYear = getISOWeeksInYear; + proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear; + proto.date = getSetDayOfMonth; + proto.day = proto.days = getSetDayOfWeek; + proto.weekday = getSetLocaleDayOfWeek; + proto.isoWeekday = getSetISODayOfWeek; + proto.dayOfYear = getSetDayOfYear; + proto.hour = proto.hours = getSetHour; + proto.minute = proto.minutes = getSetMinute; + proto.second = proto.seconds = getSetSecond; + proto.millisecond = proto.milliseconds = getSetMillisecond; + proto.utcOffset = getSetOffset; + proto.utc = setOffsetToUTC; + proto.local = setOffsetToLocal; + proto.parseZone = setOffsetToParsedOffset; + proto.hasAlignedHourOffset = hasAlignedHourOffset; + proto.isDST = isDaylightSavingTime; + proto.isLocal = isLocal; + proto.isUtcOffset = isUtcOffset; + proto.isUtc = isUtc; + proto.isUTC = isUtc; + proto.zoneAbbr = getZoneAbbr; + proto.zoneName = getZoneName; + proto.dates = deprecate( + 'dates accessor is deprecated. Use date instead.', + getSetDayOfMonth + ); + proto.months = deprecate( + 'months accessor is deprecated. Use month instead', + getSetMonth + ); + proto.years = deprecate( + 'years accessor is deprecated. Use year instead', + getSetYear + ); + proto.zone = deprecate( + 'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', + getSetZone + ); + proto.isDSTShifted = deprecate( + 'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', + isDaylightSavingTimeShifted + ); + + function createUnix(input) { + return createLocal(input * 1000); + } + + function createInZone() { + return createLocal.apply(null, arguments).parseZone(); + } + + function preParsePostFormat(string) { + return string; + } + + var proto$1 = Locale.prototype; + + proto$1.calendar = calendar; + proto$1.longDateFormat = longDateFormat; + proto$1.invalidDate = invalidDate; + proto$1.ordinal = ordinal; + proto$1.preparse = preParsePostFormat; + proto$1.postformat = preParsePostFormat; + proto$1.relativeTime = relativeTime; + proto$1.pastFuture = pastFuture; + proto$1.set = set; + proto$1.eras = localeEras; + proto$1.erasParse = localeErasParse; + proto$1.erasConvertYear = localeErasConvertYear; + proto$1.erasAbbrRegex = erasAbbrRegex; + proto$1.erasNameRegex = erasNameRegex; + proto$1.erasNarrowRegex = erasNarrowRegex; + + proto$1.months = localeMonths; + proto$1.monthsShort = localeMonthsShort; + proto$1.monthsParse = localeMonthsParse; + proto$1.monthsRegex = monthsRegex; + proto$1.monthsShortRegex = monthsShortRegex; + proto$1.week = localeWeek; + proto$1.firstDayOfYear = localeFirstDayOfYear; + proto$1.firstDayOfWeek = localeFirstDayOfWeek; + + proto$1.weekdays = localeWeekdays; + proto$1.weekdaysMin = localeWeekdaysMin; + proto$1.weekdaysShort = localeWeekdaysShort; + proto$1.weekdaysParse = localeWeekdaysParse; + + proto$1.weekdaysRegex = weekdaysRegex; + proto$1.weekdaysShortRegex = weekdaysShortRegex; + proto$1.weekdaysMinRegex = weekdaysMinRegex; + + proto$1.isPM = localeIsPM; + proto$1.meridiem = localeMeridiem; + + function get$1(format, index, field, setter) { + var locale = getLocale(), + utc = createUTC().set(setter, index); + return locale[field](utc, format); + } + + function listMonthsImpl(format, index, field) { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + + if (index != null) { + return get$1(format, index, field, 'month'); + } + + var i, + out = []; + for (i = 0; i < 12; i++) { + out[i] = get$1(format, i, field, 'month'); + } + return out; + } + + // () + // (5) + // (fmt, 5) + // (fmt) + // (true) + // (true, 5) + // (true, fmt, 5) + // (true, fmt) + function listWeekdaysImpl(localeSorted, format, index, field) { + if (typeof localeSorted === 'boolean') { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } else { + format = localeSorted; + index = format; + localeSorted = false; + + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } + + var locale = getLocale(), + shift = localeSorted ? locale._week.dow : 0, + i, + out = []; + + if (index != null) { + return get$1(format, (index + shift) % 7, field, 'day'); + } + + for (i = 0; i < 7; i++) { + out[i] = get$1(format, (i + shift) % 7, field, 'day'); + } + return out; + } + + function listMonths(format, index) { + return listMonthsImpl(format, index, 'months'); + } + + function listMonthsShort(format, index) { + return listMonthsImpl(format, index, 'monthsShort'); + } + + function listWeekdays(localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); + } + + function listWeekdaysShort(localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); + } + + function listWeekdaysMin(localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); + } + + getSetGlobalLocale('en', { + eras: [ + { + since: '0001-01-01', + until: +Infinity, + offset: 1, + name: 'Anno Domini', + narrow: 'AD', + abbr: 'AD', + }, + { + since: '0000-12-31', + until: -Infinity, + offset: 1, + name: 'Before Christ', + narrow: 'BC', + abbr: 'BC', + }, + ], + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal: function (number) { + var b = number % 10, + output = + toInt((number % 100) / 10) === 1 + ? 'th' + : b === 1 + ? 'st' + : b === 2 + ? 'nd' + : b === 3 + ? 'rd' + : 'th'; + return number + output; + }, + }); + + // Side effect imports + + hooks.lang = deprecate( + 'moment.lang is deprecated. Use moment.locale instead.', + getSetGlobalLocale + ); + hooks.langData = deprecate( + 'moment.langData is deprecated. Use moment.localeData instead.', + getLocale + ); + + var mathAbs = Math.abs; + + function abs() { + var data = this._data; + + this._milliseconds = mathAbs(this._milliseconds); + this._days = mathAbs(this._days); + this._months = mathAbs(this._months); + + data.milliseconds = mathAbs(data.milliseconds); + data.seconds = mathAbs(data.seconds); + data.minutes = mathAbs(data.minutes); + data.hours = mathAbs(data.hours); + data.months = mathAbs(data.months); + data.years = mathAbs(data.years); + + return this; + } + + function addSubtract$1(duration, input, value, direction) { + var other = createDuration(input, value); + + duration._milliseconds += direction * other._milliseconds; + duration._days += direction * other._days; + duration._months += direction * other._months; + + return duration._bubble(); + } + + // supports only 2.0-style add(1, 's') or add(duration) + function add$1(input, value) { + return addSubtract$1(this, input, value, 1); + } + + // supports only 2.0-style subtract(1, 's') or subtract(duration) + function subtract$1(input, value) { + return addSubtract$1(this, input, value, -1); + } + + function absCeil(number) { + if (number < 0) { + return Math.floor(number); + } else { + return Math.ceil(number); + } + } + + function bubble() { + var milliseconds = this._milliseconds, + days = this._days, + months = this._months, + data = this._data, + seconds, + minutes, + hours, + years, + monthsFromDays; + + // if we have a mix of positive and negative values, bubble down first + // check: https://github.com/moment/moment/issues/2166 + if ( + !( + (milliseconds >= 0 && days >= 0 && months >= 0) || + (milliseconds <= 0 && days <= 0 && months <= 0) + ) + ) { + milliseconds += absCeil(monthsToDays(months) + days) * 864e5; + days = 0; + months = 0; + } + + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; + + seconds = absFloor(milliseconds / 1000); + data.seconds = seconds % 60; + + minutes = absFloor(seconds / 60); + data.minutes = minutes % 60; + + hours = absFloor(minutes / 60); + data.hours = hours % 24; + + days += absFloor(hours / 24); + + // convert days to months + monthsFromDays = absFloor(daysToMonths(days)); + months += monthsFromDays; + days -= absCeil(monthsToDays(monthsFromDays)); + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + data.days = days; + data.months = months; + data.years = years; + + return this; + } + + function daysToMonths(days) { + // 400 years have 146097 days (taking into account leap year rules) + // 400 years have 12 months === 4800 + return (days * 4800) / 146097; + } + + function monthsToDays(months) { + // the reverse of daysToMonths + return (months * 146097) / 4800; + } + + function as(units) { + if (!this.isValid()) { + return NaN; + } + var days, + months, + milliseconds = this._milliseconds; + + units = normalizeUnits(units); + + if (units === 'month' || units === 'quarter' || units === 'year') { + days = this._days + milliseconds / 864e5; + months = this._months + daysToMonths(days); + switch (units) { + case 'month': + return months; + case 'quarter': + return months / 3; + case 'year': + return months / 12; + } + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(monthsToDays(this._months)); + switch (units) { + case 'week': + return days / 7 + milliseconds / 6048e5; + case 'day': + return days + milliseconds / 864e5; + case 'hour': + return days * 24 + milliseconds / 36e5; + case 'minute': + return days * 1440 + milliseconds / 6e4; + case 'second': + return days * 86400 + milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': + return Math.floor(days * 864e5) + milliseconds; + default: + throw new Error('Unknown unit ' + units); + } + } + } + + // TODO: Use this.as('ms')? + function valueOf$1() { + if (!this.isValid()) { + return NaN; + } + return ( + this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6 + ); + } + + function makeAs(alias) { + return function () { + return this.as(alias); + }; + } + + var asMilliseconds = makeAs('ms'), + asSeconds = makeAs('s'), + asMinutes = makeAs('m'), + asHours = makeAs('h'), + asDays = makeAs('d'), + asWeeks = makeAs('w'), + asMonths = makeAs('M'), + asQuarters = makeAs('Q'), + asYears = makeAs('y'); + + function clone$1() { + return createDuration(this); + } + + function get$2(units) { + units = normalizeUnits(units); + return this.isValid() ? this[units + 's']() : NaN; + } + + function makeGetter(name) { + return function () { + return this.isValid() ? this._data[name] : NaN; + }; + } + + var milliseconds = makeGetter('milliseconds'), + seconds = makeGetter('seconds'), + minutes = makeGetter('minutes'), + hours = makeGetter('hours'), + days = makeGetter('days'), + months = makeGetter('months'), + years = makeGetter('years'); + + function weeks() { + return absFloor(this.days() / 7); + } + + var round = Math.round, + thresholds = { + ss: 44, // a few seconds to seconds + s: 45, // seconds to minute + m: 45, // minutes to hour + h: 22, // hours to day + d: 26, // days to month/week + w: null, // weeks to month + M: 11, // months to year + }; + + // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + } + + function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) { + var duration = createDuration(posNegDuration).abs(), + seconds = round(duration.as('s')), + minutes = round(duration.as('m')), + hours = round(duration.as('h')), + days = round(duration.as('d')), + months = round(duration.as('M')), + weeks = round(duration.as('w')), + years = round(duration.as('y')), + a = + (seconds <= thresholds.ss && ['s', seconds]) || + (seconds < thresholds.s && ['ss', seconds]) || + (minutes <= 1 && ['m']) || + (minutes < thresholds.m && ['mm', minutes]) || + (hours <= 1 && ['h']) || + (hours < thresholds.h && ['hh', hours]) || + (days <= 1 && ['d']) || + (days < thresholds.d && ['dd', days]); + + if (thresholds.w != null) { + a = + a || + (weeks <= 1 && ['w']) || + (weeks < thresholds.w && ['ww', weeks]); + } + a = a || + (months <= 1 && ['M']) || + (months < thresholds.M && ['MM', months]) || + (years <= 1 && ['y']) || ['yy', years]; + + a[2] = withoutSuffix; + a[3] = +posNegDuration > 0; + a[4] = locale; + return substituteTimeAgo.apply(null, a); + } + + // This function allows you to set the rounding function for relative time strings + function getSetRelativeTimeRounding(roundingFunction) { + if (roundingFunction === undefined) { + return round; + } + if (typeof roundingFunction === 'function') { + round = roundingFunction; + return true; + } + return false; + } + + // This function allows you to set a threshold for relative time strings + function getSetRelativeTimeThreshold(threshold, limit) { + if (thresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return thresholds[threshold]; + } + thresholds[threshold] = limit; + if (threshold === 's') { + thresholds.ss = limit - 1; + } + return true; + } + + function humanize(argWithSuffix, argThresholds) { + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var withSuffix = false, + th = thresholds, + locale, + output; + + if (typeof argWithSuffix === 'object') { + argThresholds = argWithSuffix; + argWithSuffix = false; + } + if (typeof argWithSuffix === 'boolean') { + withSuffix = argWithSuffix; + } + if (typeof argThresholds === 'object') { + th = Object.assign({}, thresholds, argThresholds); + if (argThresholds.s != null && argThresholds.ss == null) { + th.ss = argThresholds.s - 1; + } + } + + locale = this.localeData(); + output = relativeTime$1(this, !withSuffix, th, locale); + + if (withSuffix) { + output = locale.pastFuture(+this, output); + } + + return locale.postformat(output); + } + + var abs$1 = Math.abs; + + function sign(x) { + return (x > 0) - (x < 0) || +x; + } + + function toISOString$1() { + // for ISO strings we do not use the normal bubbling rules: + // * milliseconds bubble up until they become hours + // * days do not bubble at all + // * months bubble up until they become years + // This is because there is no context-free conversion between hours and days + // (think of clock changes) + // and also not between days and months (28-31 days per month) + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var seconds = abs$1(this._milliseconds) / 1000, + days = abs$1(this._days), + months = abs$1(this._months), + minutes, + hours, + years, + s, + total = this.asSeconds(), + totalSign, + ymSign, + daysSign, + hmsSign; + + if (!total) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } + + // 3600 seconds -> 60 minutes -> 1 hour + minutes = absFloor(seconds / 60); + hours = absFloor(minutes / 60); + seconds %= 60; + minutes %= 60; + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; + + totalSign = total < 0 ? '-' : ''; + ymSign = sign(this._months) !== sign(total) ? '-' : ''; + daysSign = sign(this._days) !== sign(total) ? '-' : ''; + hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; + + return ( + totalSign + + 'P' + + (years ? ymSign + years + 'Y' : '') + + (months ? ymSign + months + 'M' : '') + + (days ? daysSign + days + 'D' : '') + + (hours || minutes || seconds ? 'T' : '') + + (hours ? hmsSign + hours + 'H' : '') + + (minutes ? hmsSign + minutes + 'M' : '') + + (seconds ? hmsSign + s + 'S' : '') + ); + } + + var proto$2 = Duration.prototype; + + proto$2.isValid = isValid$1; + proto$2.abs = abs; + proto$2.add = add$1; + proto$2.subtract = subtract$1; + proto$2.as = as; + proto$2.asMilliseconds = asMilliseconds; + proto$2.asSeconds = asSeconds; + proto$2.asMinutes = asMinutes; + proto$2.asHours = asHours; + proto$2.asDays = asDays; + proto$2.asWeeks = asWeeks; + proto$2.asMonths = asMonths; + proto$2.asQuarters = asQuarters; + proto$2.asYears = asYears; + proto$2.valueOf = valueOf$1; + proto$2._bubble = bubble; + proto$2.clone = clone$1; + proto$2.get = get$2; + proto$2.milliseconds = milliseconds; + proto$2.seconds = seconds; + proto$2.minutes = minutes; + proto$2.hours = hours; + proto$2.days = days; + proto$2.weeks = weeks; + proto$2.months = months; + proto$2.years = years; + proto$2.humanize = humanize; + proto$2.toISOString = toISOString$1; + proto$2.toString = toISOString$1; + proto$2.toJSON = toISOString$1; + proto$2.locale = locale; + proto$2.localeData = localeData; + + proto$2.toIsoString = deprecate( + 'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', + toISOString$1 + ); + proto$2.lang = lang; + + // FORMATTING + + addFormatToken('X', 0, 0, 'unix'); + addFormatToken('x', 0, 0, 'valueOf'); + + // PARSING + + addRegexToken('x', matchSigned); + addRegexToken('X', matchTimestamp); + addParseToken('X', function (input, array, config) { + config._d = new Date(parseFloat(input) * 1000); + }); + addParseToken('x', function (input, array, config) { + config._d = new Date(toInt(input)); + }); + + //! moment.js + + hooks.version = '2.29.1'; + + setHookCallback(createLocal); + + hooks.fn = proto; + hooks.min = min; + hooks.max = max; + hooks.now = now; + hooks.utc = createUTC; + hooks.unix = createUnix; + hooks.months = listMonths; + hooks.isDate = isDate; + hooks.locale = getSetGlobalLocale; + hooks.invalid = createInvalid; + hooks.duration = createDuration; + hooks.isMoment = isMoment; + hooks.weekdays = listWeekdays; + hooks.parseZone = createInZone; + hooks.localeData = getLocale; + hooks.isDuration = isDuration; + hooks.monthsShort = listMonthsShort; + hooks.weekdaysMin = listWeekdaysMin; + hooks.defineLocale = defineLocale; + hooks.updateLocale = updateLocale; + hooks.locales = listLocales; + hooks.weekdaysShort = listWeekdaysShort; + hooks.normalizeUnits = normalizeUnits; + hooks.relativeTimeRounding = getSetRelativeTimeRounding; + hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; + hooks.calendarFormat = getCalendarFormat; + hooks.prototype = proto; + + // currently HTML5 input type only supports 24-hour formats + hooks.HTML5_FMT = { + DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // + DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // + DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // + DATE: 'YYYY-MM-DD', // + TIME: 'HH:mm', // + TIME_SECONDS: 'HH:mm:ss', // + TIME_MS: 'HH:mm:ss.SSS', // + WEEK: 'GGGG-[W]WW', // + MONTH: 'YYYY-MM', // + }; + + return hooks; + +}))); + + +/***/ }), + +/***/ "../eyes/node_modules/navigo/lib/navigo.min.js": +/*!*****************************************************!*\ + !*** ../eyes/node_modules/navigo/lib/navigo.min.js ***! + \*****************************************************/ +/***/ (function(module) { + +!function(e,t){ true?module.exports=t():0}(this,function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function t(){return!("undefined"==typeof window||!window.history||!window.history.pushState)}function n(e,n,o){this.root=null,this._routes=[],this._useHash=n,this._hash=void 0===o?"#":o,this._paused=!1,this._destroyed=!1,this._lastRouteResolved=null,this._notFoundHandler=null,this._defaultHandler=null,this._usePushState=!n&&t(),this._onLocationChange=this._onLocationChange.bind(this),this._genericHooks=null,this._historyAPIUpdateMethod="pushState",e?this.root=n?e.replace(/\/$/,"/"+this._hash):e.replace(/\/$/,""):n&&(this.root=this._cLoc().split(this._hash)[0].replace(/\/$/,"/"+this._hash)),this._listen(),this.updatePageLinks()}function o(e){return e instanceof RegExp?e:e.replace(/\/+$/,"").replace(/^\/+/,"^/")}function i(e){return e.replace(/\/$/,"").split("/").length}function s(e,t){return i(t)-i(e)}function r(e,t){return function(e){return(arguments.length>1&&void 0!==arguments[1]?arguments[1]:[]).map(function(t){var i=function(e){var t=[];return{regexp:e instanceof RegExp?e:new RegExp(e.replace(n.PARAMETER_REGEXP,function(e,o,i){return t.push(i),n.REPLACE_VARIABLE_REGEXP}).replace(n.WILDCARD_REGEXP,n.REPLACE_WILDCARD)+n.FOLLOWED_BY_SLASH_REGEXP,n.MATCH_REGEXP_FLAGS),paramNames:t}}(o(t.route)),s=i.regexp,r=i.paramNames,a=e.replace(/^\/+/,"/").match(s),h=function(e,t){return 0===t.length?null:e?e.slice(1,e.length).reduce(function(e,n,o){return null===e&&(e={}),e[t[o]]=decodeURIComponent(n),e},null):null}(a,r);return!!a&&{match:a,route:t,params:h}}).filter(function(e){return e})}(e,t)[0]||!1}function a(e,t){var n=t.map(function(t){return""===t.route||"*"===t.route?e:e.split(new RegExp(t.route+"($|/)"))[0]}),i=o(e);return n.length>1?n.reduce(function(e,t){return e.length>t.length&&(e=t),e},n[0]):1===n.length?n[0]:i}function h(e,n,o){var i,s=function(e){return e.split(/\?(.*)?$/)[0]};return void 0===o&&(o="#"),t()&&!n?s(e).split(o)[0]:(i=e.split(o)).length>1?s(i[1]):s(i[0])}function u(t,n,o){if(n&&"object"===(void 0===n?"undefined":e(n))){if(n.before)return void n.before(function(){(!(arguments.length>0&&void 0!==arguments[0])||arguments[0])&&(t(),n.after&&n.after(o))},o);if(n.after)return t(),void(n.after&&n.after(o))}t()}return n.prototype={helpers:{match:r,root:a,clean:o,getOnlyURL:h},navigate:function(e,t){var n;return e=e||"",this._usePushState?(n=(n=(t?"":this._getRoot()+"/")+e.replace(/^\/+/,"/")).replace(/([^:])(\/{2,})/g,"$1/"),history[this._historyAPIUpdateMethod]({},"",n),this.resolve()):"undefined"!=typeof window&&(e=e.replace(new RegExp("^"+this._hash),""),window.location.href=window.location.href.replace(/#$/,"").replace(new RegExp(this._hash+".*$"),"")+this._hash+e),this},on:function(){for(var t=this,n=arguments.length,o=Array(n),i=0;i=2)if("/"===o[0]){var r=o[1];"object"===e(o[1])&&(r=o[1].uses),this._defaultHandler={handler:r,hooks:o[2]}}else this._add(o[0],o[1],o[2]);else"object"===e(o[0])&&Object.keys(o[0]).sort(s).forEach(function(e){t.on(e,o[0][e])});return this},off:function(e){return null!==this._defaultHandler&&e===this._defaultHandler.handler?this._defaultHandler=null:null!==this._notFoundHandler&&e===this._notFoundHandler.handler&&(this._notFoundHandler=null),this._routes=this._routes.reduce(function(t,n){return n.handler!==e&&t.push(n),t},[]),this},notFound:function(e,t){return this._notFoundHandler={handler:e,hooks:t},this},resolve:function(e){var n,o,i=this,s=(e||this._cLoc()).replace(this._getRoot(),"");this._useHash&&(s=s.replace(new RegExp("^/"+this._hash),"/"));var a=function(e){return e.split(/\?(.*)?$/).slice(1).join("")}(e||this._cLoc()),l=h(s,this._useHash,this._hash);return!this._paused&&(this._lastRouteResolved&&l===this._lastRouteResolved.url&&a===this._lastRouteResolved.query?(this._lastRouteResolved.hooks&&this._lastRouteResolved.hooks.already&&this._lastRouteResolved.hooks.already(this._lastRouteResolved.params),!1):(o=r(l,this._routes))?(this._callLeave(),this._lastRouteResolved={url:l,query:a,hooks:o.route.hooks,params:o.params,name:o.route.name},n=o.route.handler,u(function(){u(function(){o.route.route instanceof RegExp?n.apply(void 0,o.match.slice(1,o.match.length)):n(o.params,a)},o.route.hooks,o.params,i._genericHooks)},this._genericHooks,o.params),o):this._defaultHandler&&(""===l||"/"===l||l===this._hash||function(e,n,o){if(t()&&!n)return!1;if(!e.match(o))return!1;var i=e.split(o);return i.length<2||""===i[1]}(l,this._useHash,this._hash))?(u(function(){u(function(){i._callLeave(),i._lastRouteResolved={url:l,query:a,hooks:i._defaultHandler.hooks},i._defaultHandler.handler(a)},i._defaultHandler.hooks)},this._genericHooks),!0):(this._notFoundHandler&&u(function(){u(function(){i._callLeave(),i._lastRouteResolved={url:l,query:a,hooks:i._notFoundHandler.hooks},i._notFoundHandler.handler(a)},i._notFoundHandler.hooks)},this._genericHooks),!1))},destroy:function(){this._routes=[],this._destroyed=!0,this._lastRouteResolved=null,this._genericHooks=null,clearTimeout(this._listeningInterval),"undefined"!=typeof window&&(window.removeEventListener("popstate",this._onLocationChange),window.removeEventListener("hashchange",this._onLocationChange))},updatePageLinks:function(){var e=this;"undefined"!=typeof document&&this._findLinks().forEach(function(t){t.hasListenerAttached||(t.addEventListener("click",function(n){if((n.ctrlKey||n.metaKey)&&"a"==n.target.tagName.toLowerCase())return!1;var o=e.getLinkPath(t);e._destroyed||(n.preventDefault(),e.navigate(o.replace(/\/+$/,"").replace(/^\/+/,"/")))}),t.hasListenerAttached=!0)})},generate:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=this._routes.reduce(function(n,o){var i;if(o.name===e)for(i in n=o.route,t)n=n.toString().replace(":"+i,t[i]);return n},"");return this._useHash?this._hash+n:n},link:function(e){return this._getRoot()+e},pause:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this._paused=e,this._historyAPIUpdateMethod=e?"replaceState":"pushState"},resume:function(){this.pause(!1)},historyAPIUpdateMethod:function(e){return void 0===e?this._historyAPIUpdateMethod:(this._historyAPIUpdateMethod=e,e)},disableIfAPINotAvailable:function(){t()||this.destroy()},lastRouteResolved:function(){return this._lastRouteResolved},getLinkPath:function(e){return e.getAttribute("href")},hooks:function(e){this._genericHooks=e},_add:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return"string"==typeof t&&(t=encodeURI(t)),this._routes.push("object"===(void 0===n?"undefined":e(n))?{route:t,handler:n.uses,name:n.as,hooks:o||n.hooks}:{route:t,handler:n,hooks:o}),this._add},_getRoot:function(){return null!==this.root?this.root:(this.root=a(this._cLoc().split("?")[0],this._routes),this.root)},_listen:function(){var e=this;if(this._usePushState)window.addEventListener("popstate",this._onLocationChange);else if("undefined"!=typeof window&&"onhashchange"in window)window.addEventListener("hashchange",this._onLocationChange);else{var t=this._cLoc(),n=void 0,o=void 0;(o=function(){n=e._cLoc(),t!==n&&(t=n,e.resolve()),e._listeningInterval=setTimeout(o,200)})()}},_cLoc:function(){return"undefined"!=typeof window?void 0!==window.__NAVIGO_WINDOW_LOCATION_MOCK__?window.__NAVIGO_WINDOW_LOCATION_MOCK__:o(window.location.href):""},_findLinks:function(){return[].slice.call(document.querySelectorAll("[data-navigo]"))},_onLocationChange:function(){this.resolve()},_callLeave:function(){var e=this._lastRouteResolved;e&&e.hooks&&e.hooks.leave&&e.hooks.leave(e.params)}},n.PARAMETER_REGEXP=/([:*])(\w+)/g,n.WILDCARD_REGEXP=/\*/g,n.REPLACE_VARIABLE_REGEXP="([^/]+)",n.REPLACE_WILDCARD="(?:.*)",n.FOLLOWED_BY_SLASH_REGEXP="(?:/$|$)",n.MATCH_REGEXP_FLAGS="",n}); +//# sourceMappingURL=navigo.min.js.map + + +/***/ }), + +/***/ "../eyes/node_modules/overlayscrollbars/js/OverlayScrollbars.js": +/*!**********************************************************************!*\ + !*** ../eyes/node_modules/overlayscrollbars/js/OverlayScrollbars.js ***! + \**********************************************************************/ +/***/ (function(module, exports, __webpack_require__) { + +var __WEBPACK_AMD_DEFINE_RESULT__;/*! + * OverlayScrollbars + * https://github.com/KingSora/OverlayScrollbars + * + * Version: 1.13.0 + * + * Copyright KingSora | Rene Haas. + * https://github.com/KingSora + * + * Released under the MIT license. + * Date: 02.08.2020 + */ + +(function (global, factory) { + if (true) + !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { return factory(global, global.document, undefined); }).call(exports, __webpack_require__, exports, module), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + else {} +}(typeof window !== 'undefined' ? window : this, + function (window, document, undefined) { + 'use strict'; + var PLUGINNAME = 'OverlayScrollbars'; + var TYPES = { + o: 'object', + f: 'function', + a: 'array', + s: 'string', + b: 'boolean', + n: 'number', + u: 'undefined', + z: 'null' + //d : 'date', + //e : 'error', + //r : 'regexp', + //y : 'symbol' + }; + var LEXICON = { + c: 'class', + s: 'style', + i: 'id', + l: 'length', + p: 'prototype', + ti: 'tabindex', + oH: 'offsetHeight', + cH: 'clientHeight', + sH: 'scrollHeight', + oW: 'offsetWidth', + cW: 'clientWidth', + sW: 'scrollWidth', + hOP: 'hasOwnProperty', + bCR: 'getBoundingClientRect' + }; + var VENDORS = (function () { + //https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix + var jsCache = {}; + var cssCache = {}; + var cssPrefixes = ['-webkit-', '-moz-', '-o-', '-ms-']; + var jsPrefixes = ['WebKit', 'Moz', 'O', 'MS']; + function firstLetterToUpper(str) { + return str.charAt(0).toUpperCase() + str.slice(1); + } + + return { + _cssPrefixes: cssPrefixes, + _jsPrefixes: jsPrefixes, + _cssProperty: function (name) { + var result = cssCache[name]; + + if (cssCache[LEXICON.hOP](name)) + return result; + + var uppercasedName = firstLetterToUpper(name); + var elmStyle = document.createElement('div')[LEXICON.s]; + var resultPossibilities; + var i = 0; + var v; + var currVendorWithoutDashes; + + for (; i < cssPrefixes.length; i++) { + currVendorWithoutDashes = cssPrefixes[i].replace(/-/g, ''); + resultPossibilities = [ + name, //transition + cssPrefixes[i] + name, //-webkit-transition + currVendorWithoutDashes + uppercasedName, //webkitTransition + firstLetterToUpper(currVendorWithoutDashes) + uppercasedName //WebkitTransition + ]; + for (v = 0; v < resultPossibilities[LEXICON.l]; v++) { + if (elmStyle[resultPossibilities[v]] !== undefined) { + result = resultPossibilities[v]; + break; + } + } + } + + cssCache[name] = result; + return result; + }, + _cssPropertyValue: function (property, values, suffix) { + var name = property + ' ' + values; + var result = cssCache[name]; + + if (cssCache[LEXICON.hOP](name)) + return result; + + var dummyStyle = document.createElement('div')[LEXICON.s]; + var possbleValues = values.split(' '); + var preparedSuffix = suffix || ''; + var i = 0; + var v = -1; + var prop; + + for (; i < possbleValues[LEXICON.l]; i++) { + for (; v < VENDORS._cssPrefixes[LEXICON.l]; v++) { + prop = v < 0 ? possbleValues[i] : VENDORS._cssPrefixes[v] + possbleValues[i]; + dummyStyle.cssText = property + ':' + prop + preparedSuffix; + if (dummyStyle[LEXICON.l]) { + result = prop; + break; + } + } + } + + cssCache[name] = result; + return result; + }, + _jsAPI: function (name, isInterface, fallback) { + var i = 0; + var result = jsCache[name]; + + if (!jsCache[LEXICON.hOP](name)) { + result = window[name]; + for (; i < jsPrefixes[LEXICON.l]; i++) + result = result || window[(isInterface ? jsPrefixes[i] : jsPrefixes[i].toLowerCase()) + firstLetterToUpper(name)]; + jsCache[name] = result; + } + return result || fallback; + } + } + })(); + var COMPATIBILITY = (function () { + function windowSize(x) { + return x ? window.innerWidth || document.documentElement[LEXICON.cW] || document.body[LEXICON.cW] : window.innerHeight || document.documentElement[LEXICON.cH] || document.body[LEXICON.cH]; + } + function bind(func, thisObj) { + if (typeof func != TYPES.f) { + throw "Can't bind function!"; + // closest thing possible to the ECMAScript 5 + // internal IsCallable function + //throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + var proto = LEXICON.p; + var aArgs = Array[proto].slice.call(arguments, 2); + var fNOP = function () { }; + var fBound = function () { return func.apply(this instanceof fNOP ? this : thisObj, aArgs.concat(Array[proto].slice.call(arguments))); }; + + if (func[proto]) + fNOP[proto] = func[proto]; // Function.prototype doesn't have a prototype property + fBound[proto] = new fNOP(); + + return fBound; + } + + return { + /** + * Gets the current window width. + * @returns {Number|number} The current window width in pixel. + */ + wW: bind(windowSize, 0, true), + + /** + * Gets the current window height. + * @returns {Number|number} The current window height in pixel. + */ + wH: bind(windowSize, 0), + + /** + * Gets the MutationObserver Object or undefined if not supported. + * @returns {MutationObserver|*|undefined} The MutationsObserver Object or undefined. + */ + mO: bind(VENDORS._jsAPI, 0, 'MutationObserver', true), + + /** + * Gets the ResizeObserver Object or undefined if not supported. + * @returns {MutationObserver|*|undefined} The ResizeObserver Object or undefined. + */ + rO: bind(VENDORS._jsAPI, 0, 'ResizeObserver', true), + + /** + * Gets the RequestAnimationFrame method or it's corresponding polyfill. + * @returns {*|Function} The RequestAnimationFrame method or it's corresponding polyfill. + */ + rAF: bind(VENDORS._jsAPI, 0, 'requestAnimationFrame', false, function (func) { return window.setTimeout(func, 1000 / 60); }), + + /** + * Gets the CancelAnimationFrame method or it's corresponding polyfill. + * @returns {*|Function} The CancelAnimationFrame method or it's corresponding polyfill. + */ + cAF: bind(VENDORS._jsAPI, 0, 'cancelAnimationFrame', false, function (id) { return window.clearTimeout(id); }), + + /** + * Gets the current time. + * @returns {number} The current time. + */ + now: function () { + return Date.now && Date.now() || new Date().getTime(); + }, + + /** + * Stops the propagation of the given event. + * @param event The event of which the propagation shall be stoped. + */ + stpP: function (event) { + if (event.stopPropagation) + event.stopPropagation(); + else + event.cancelBubble = true; + }, + + /** + * Prevents the default action of the given event. + * @param event The event of which the default action shall be prevented. + */ + prvD: function (event) { + if (event.preventDefault && event.cancelable) + event.preventDefault(); + else + event.returnValue = false; + }, + + /** + * Gets the pageX and pageY values of the given mouse event. + * @param event The mouse event of which the pageX and pageX shall be got. + * @returns {{x: number, y: number}} x = pageX value, y = pageY value. + */ + page: function (event) { + event = event.originalEvent || event; + + var strPage = 'page'; + var strClient = 'client'; + var strX = 'X'; + var strY = 'Y'; + var target = event.target || event.srcElement || document; + var eventDoc = target.ownerDocument || document; + var doc = eventDoc.documentElement; + var body = eventDoc.body; + + //if touch event return return pageX/Y of it + if (event.touches !== undefined) { + var touch = event.touches[0]; + return { + x: touch[strPage + strX], + y: touch[strPage + strY] + } + } + + // Calculate pageX/Y if not native supported + if (!event[strPage + strX] && event[strClient + strX] && event[strClient + strX] != null) { + + return { + x: event[strClient + strX] + + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - + (doc && doc.clientLeft || body && body.clientLeft || 0), + y: event[strClient + strY] + + (doc && doc.scrollTop || body && body.scrollTop || 0) - + (doc && doc.clientTop || body && body.clientTop || 0) + } + } + return { + x: event[strPage + strX], + y: event[strPage + strY] + }; + }, + + /** + * Gets the clicked mouse button of the given mouse event. + * @param event The mouse event of which the clicked button shal be got. + * @returns {number} The number of the clicked mouse button. (0 : none | 1 : leftButton | 2 : middleButton | 3 : rightButton) + */ + mBtn: function (event) { + var button = event.button; + if (!event.which && button !== undefined) + return (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0))); + else + return event.which; + }, + + /** + * Checks whether a item is in the given array and returns its index. + * @param item The item of which the position in the array shall be determined. + * @param arr The array. + * @returns {number} The zero based index of the item or -1 if the item isn't in the array. + */ + inA: function (item, arr) { + for (var i = 0; i < arr[LEXICON.l]; i++) + //Sometiems in IE a "SCRIPT70" Permission denied error occurs if HTML elements in a iFrame are compared + try { + if (arr[i] === item) + return i; + } + catch (e) { } + return -1; + }, + + /** + * Returns true if the given value is a array. + * @param arr The potential array. + * @returns {boolean} True if the given value is a array, false otherwise. + */ + isA: function (arr) { + var def = Array.isArray; + return def ? def(arr) : this.type(arr) == TYPES.a; + }, + + /** + * Determine the internal JavaScript [[Class]] of the given object. + * @param obj The object of which the type shall be determined. + * @returns {string} The type of the given object. + */ + type: function (obj) { + if (obj === undefined) + return obj + ''; + if (obj === null) + return obj + ''; + return Object[LEXICON.p].toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase(); + }, + + + bind: bind + + /** + * Gets the vendor-prefixed CSS property by the given name. + * For example the given name is "transform" and you're using a old Firefox browser then the returned value would be "-moz-transform". + * If the browser doesn't need a vendor-prefix, then the returned string is the given name. + * If the browser doesn't support the given property name at all (not even with a vendor-prefix) the returned value is null. + * @param propName The unprefixed CSS property name. + * @returns {string|null} The vendor-prefixed CSS property or null if the browser doesn't support the given CSS property. + + cssProp: function(propName) { + return VENDORS._cssProperty(propName); + } + */ + } + })(); + + + var MATH = Math; + var JQUERY = window.jQuery; + var EASING = (function () { + var _easingsMath = { + p: MATH.PI, + c: MATH.cos, + s: MATH.sin, + w: MATH.pow, + t: MATH.sqrt, + n: MATH.asin, + a: MATH.abs, + o: 1.70158 + }; + + /* + x : current percent (0 - 1), + t : current time (duration * percent), + b : start value (from), + c : end value (to), + d : duration + + easingName : function(x, t, b, c, d) { return easedValue; } + */ + + return { + swing: function (x, t, b, c, d) { + return 0.5 - _easingsMath.c(x * _easingsMath.p) / 2; + }, + linear: function (x, t, b, c, d) { + return x; + }, + easeInQuad: function (x, t, b, c, d) { + return c * (t /= d) * t + b; + }, + easeOutQuad: function (x, t, b, c, d) { + return -c * (t /= d) * (t - 2) + b; + }, + easeInOutQuad: function (x, t, b, c, d) { + return ((t /= d / 2) < 1) ? c / 2 * t * t + b : -c / 2 * ((--t) * (t - 2) - 1) + b; + }, + easeInCubic: function (x, t, b, c, d) { + return c * (t /= d) * t * t + b; + }, + easeOutCubic: function (x, t, b, c, d) { + return c * ((t = t / d - 1) * t * t + 1) + b; + }, + easeInOutCubic: function (x, t, b, c, d) { + return ((t /= d / 2) < 1) ? c / 2 * t * t * t + b : c / 2 * ((t -= 2) * t * t + 2) + b; + }, + easeInQuart: function (x, t, b, c, d) { + return c * (t /= d) * t * t * t + b; + }, + easeOutQuart: function (x, t, b, c, d) { + return -c * ((t = t / d - 1) * t * t * t - 1) + b; + }, + easeInOutQuart: function (x, t, b, c, d) { + return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t + b : -c / 2 * ((t -= 2) * t * t * t - 2) + b; + }, + easeInQuint: function (x, t, b, c, d) { + return c * (t /= d) * t * t * t * t + b; + }, + easeOutQuint: function (x, t, b, c, d) { + return c * ((t = t / d - 1) * t * t * t * t + 1) + b; + }, + easeInOutQuint: function (x, t, b, c, d) { + return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t * t + b : c / 2 * ((t -= 2) * t * t * t * t + 2) + b; + }, + easeInSine: function (x, t, b, c, d) { + return -c * _easingsMath.c(t / d * (_easingsMath.p / 2)) + c + b; + }, + easeOutSine: function (x, t, b, c, d) { + return c * _easingsMath.s(t / d * (_easingsMath.p / 2)) + b; + }, + easeInOutSine: function (x, t, b, c, d) { + return -c / 2 * (_easingsMath.c(_easingsMath.p * t / d) - 1) + b; + }, + easeInExpo: function (x, t, b, c, d) { + return (t == 0) ? b : c * _easingsMath.w(2, 10 * (t / d - 1)) + b; + }, + easeOutExpo: function (x, t, b, c, d) { + return (t == d) ? b + c : c * (-_easingsMath.w(2, -10 * t / d) + 1) + b; + }, + easeInOutExpo: function (x, t, b, c, d) { + if (t == 0) return b; + if (t == d) return b + c; + if ((t /= d / 2) < 1) return c / 2 * _easingsMath.w(2, 10 * (t - 1)) + b; + return c / 2 * (-_easingsMath.w(2, -10 * --t) + 2) + b; + }, + easeInCirc: function (x, t, b, c, d) { + return -c * (_easingsMath.t(1 - (t /= d) * t) - 1) + b; + }, + easeOutCirc: function (x, t, b, c, d) { + return c * _easingsMath.t(1 - (t = t / d - 1) * t) + b; + }, + easeInOutCirc: function (x, t, b, c, d) { + return ((t /= d / 2) < 1) ? -c / 2 * (_easingsMath.t(1 - t * t) - 1) + b : c / 2 * (_easingsMath.t(1 - (t -= 2) * t) + 1) + b; + }, + easeInElastic: function (x, t, b, c, d) { + var s = _easingsMath.o; var p = 0; var a = c; + if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3; + if (a < _easingsMath.a(c)) { a = c; s = p / 4; } + else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a); + return -(a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b; + }, + easeOutElastic: function (x, t, b, c, d) { + var s = _easingsMath.o; var p = 0; var a = c; + if (t == 0) return b; + if ((t /= d) == 1) return b + c; + if (!p) p = d * .3; + if (a < _easingsMath.a(c)) { a = c; s = p / 4; } + else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a); + return a * _easingsMath.w(2, -10 * t) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) + c + b; + }, + easeInOutElastic: function (x, t, b, c, d) { + var s = _easingsMath.o; var p = 0; var a = c; + if (t == 0) return b; + if ((t /= d / 2) == 2) return b + c; + if (!p) p = d * (.3 * 1.5); + if (a < _easingsMath.a(c)) { a = c; s = p / 4; } + else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a); + if (t < 1) return -.5 * (a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b; + return a * _easingsMath.w(2, -10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) * .5 + c + b; + }, + easeInBack: function (x, t, b, c, d, s) { + s = s || _easingsMath.o; + return c * (t /= d) * t * ((s + 1) * t - s) + b; + }, + easeOutBack: function (x, t, b, c, d, s) { + s = s || _easingsMath.o; + return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; + }, + easeInOutBack: function (x, t, b, c, d, s) { + s = s || _easingsMath.o; + return ((t /= d / 2) < 1) ? c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b : c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; + }, + easeInBounce: function (x, t, b, c, d) { + return c - this.easeOutBounce(x, d - t, 0, c, d) + b; + }, + easeOutBounce: function (x, t, b, c, d) { + var o = 7.5625; + if ((t /= d) < (1 / 2.75)) { + return c * (o * t * t) + b; + } else if (t < (2 / 2.75)) { + return c * (o * (t -= (1.5 / 2.75)) * t + .75) + b; + } else if (t < (2.5 / 2.75)) { + return c * (o * (t -= (2.25 / 2.75)) * t + .9375) + b; + } else { + return c * (o * (t -= (2.625 / 2.75)) * t + .984375) + b; + } + }, + easeInOutBounce: function (x, t, b, c, d) { + return (t < d / 2) ? this.easeInBounce(x, t * 2, 0, c, d) * .5 + b : this.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b; + } + }; + /* + * + * TERMS OF USE - EASING EQUATIONS + * + * Open source under the BSD License. + * + * Copyright © 2001 Robert Penner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + })(); + var FRAMEWORK = (function () { + var _rnothtmlwhite = (/[^\x20\t\r\n\f]+/g); + var _strSpace = ' '; + var _strEmpty = ''; + var _strScrollLeft = 'scrollLeft'; + var _strScrollTop = 'scrollTop'; + var _animations = []; + var _type = COMPATIBILITY.type; + var _cssNumber = { + animationIterationCount: true, + columnCount: true, + fillOpacity: true, + flexGrow: true, + flexShrink: true, + fontWeight: true, + lineHeight: true, + opacity: true, + order: true, + orphans: true, + widows: true, + zIndex: true, + zoom: true + }; + + function extend() { + var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, + i = 1, + length = arguments[LEXICON.l], + deep = false; + + // Handle a deep copy situation + if (_type(target) == TYPES.b) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if (_type(target) != TYPES.o && !_type(target) == TYPES.f) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if (length === i) { + target = FakejQuery; + --i; + } + + for (; i < length; i++) { + // Only deal with non-null/undefined values + if ((options = arguments[i]) != null) { + // Extend the base object + for (name in options) { + src = target[name]; + copy = options[name]; + + // Prevent never-ending loop + if (target === copy) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject(copy) || (copyIsArray = COMPATIBILITY.isA(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && COMPATIBILITY.isA(src) ? src : []; + + } else { + clone = src && isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[name] = extend(deep, clone, copy); + + // Don't bring in undefined values + } else if (copy !== undefined) { + target[name] = copy; + } + } + } + } + + // Return the modified object + return target; + }; + + function inArray(item, arr, fromIndex) { + for (var i = fromIndex || 0; i < arr[LEXICON.l]; i++) + if (arr[i] === item) + return i; + return -1; + } + + function isFunction(obj) { + return _type(obj) == TYPES.f; + }; + + function isEmptyObject(obj) { + for (var name in obj) + return false; + return true; + }; + + function isPlainObject(obj) { + if (!obj || _type(obj) != TYPES.o) + return false; + + var key; + var proto = LEXICON.p; + var hasOwnProperty = Object[proto].hasOwnProperty; + var hasOwnConstructor = hasOwnProperty.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor[proto] && hasOwnProperty.call(obj.constructor[proto], 'isPrototypeOf'); + + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } + + + for (key in obj) { /**/ } + + return _type(key) == TYPES.u || hasOwnProperty.call(obj, key); + }; + + function each(obj, callback) { + var i = 0; + + if (isArrayLike(obj)) { + for (; i < obj[LEXICON.l]; i++) { + if (callback.call(obj[i], i, obj[i]) === false) + break; + } + } + else { + for (i in obj) { + if (callback.call(obj[i], i, obj[i]) === false) + break; + } + } + + return obj; + }; + + function isArrayLike(obj) { + var length = !!obj && [LEXICON.l] in obj && obj[LEXICON.l]; + var t = _type(obj); + return isFunction(t) ? false : (t == TYPES.a || length === 0 || _type(length) == TYPES.n && length > 0 && (length - 1) in obj); + } + + function stripAndCollapse(value) { + var tokens = value.match(_rnothtmlwhite) || []; + return tokens.join(_strSpace); + } + + function matches(elem, selector) { + var nodeList = (elem.parentNode || document).querySelectorAll(selector) || []; + var i = nodeList[LEXICON.l]; + + while (i--) + if (nodeList[i] == elem) + return true; + + return false; + } + + function insertAdjacentElement(el, strategy, child) { + if (COMPATIBILITY.isA(child)) { + for (var i = 0; i < child[LEXICON.l]; i++) + insertAdjacentElement(el, strategy, child[i]); + } + else if (_type(child) == TYPES.s) + el.insertAdjacentHTML(strategy, child); + else + el.insertAdjacentElement(strategy, child.nodeType ? child : child[0]); + } + + function setCSSVal(el, prop, val) { + try { + if (el[LEXICON.s][prop] !== undefined) + el[LEXICON.s][prop] = parseCSSVal(prop, val); + } catch (e) { } + } + + function parseCSSVal(prop, val) { + if (!_cssNumber[prop.toLowerCase()] && _type(val) == TYPES.n) + val += 'px'; + return val; + } + + function startNextAnimationInQ(animObj, removeFromQ) { + var index; + var nextAnim; + if (removeFromQ !== false) + animObj.q.splice(0, 1); + if (animObj.q[LEXICON.l] > 0) { + nextAnim = animObj.q[0]; + animate(animObj.el, nextAnim.props, nextAnim.duration, nextAnim.easing, nextAnim.complete, true); + } + else { + index = inArray(animObj, _animations); + if (index > -1) + _animations.splice(index, 1); + } + } + + function setAnimationValue(el, prop, value) { + if (prop === _strScrollLeft || prop === _strScrollTop) + el[prop] = value; + else + setCSSVal(el, prop, value); + } + + function animate(el, props, options, easing, complete, guaranteedNext) { + var hasOptions = isPlainObject(options); + var from = {}; + var to = {}; + var i = 0; + var key; + var animObj; + var start; + var progress; + var step; + var specialEasing; + var duration; + if (hasOptions) { + easing = options.easing; + start = options.start; + progress = options.progress; + step = options.step; + specialEasing = options.specialEasing; + complete = options.complete; + duration = options.duration; + } + else + duration = options; + specialEasing = specialEasing || {}; + duration = duration || 400; + easing = easing || 'swing'; + guaranteedNext = guaranteedNext || false; + + for (; i < _animations[LEXICON.l]; i++) { + if (_animations[i].el === el) { + animObj = _animations[i]; + break; + } + } + + if (!animObj) { + animObj = { + el: el, + q: [] + }; + _animations.push(animObj); + } + + for (key in props) { + if (key === _strScrollLeft || key === _strScrollTop) + from[key] = el[key]; + else + from[key] = FakejQuery(el).css(key); + } + + for (key in from) { + if (from[key] !== props[key] && props[key] !== undefined) + to[key] = props[key]; + } + + if (!isEmptyObject(to)) { + var timeNow; + var end; + var percent; + var fromVal; + var toVal; + var easedVal; + var timeStart; + var frame; + var elapsed; + var qPos = guaranteedNext ? 0 : inArray(qObj, animObj.q); + var qObj = { + props: to, + duration: hasOptions ? options : duration, + easing: easing, + complete: complete + }; + if (qPos === -1) { + qPos = animObj.q[LEXICON.l]; + animObj.q.push(qObj); + } + + if (qPos === 0) { + if (duration > 0) { + timeStart = COMPATIBILITY.now(); + frame = function () { + timeNow = COMPATIBILITY.now(); + elapsed = (timeNow - timeStart); + end = qObj.stop || elapsed >= duration; + percent = 1 - ((MATH.max(0, timeStart + duration - timeNow) / duration) || 0); + + for (key in to) { + fromVal = parseFloat(from[key]); + toVal = parseFloat(to[key]); + easedVal = (toVal - fromVal) * EASING[specialEasing[key] || easing](percent, percent * duration, 0, 1, duration) + fromVal; + setAnimationValue(el, key, easedVal); + if (isFunction(step)) { + step(easedVal, { + elem: el, + prop: key, + start: fromVal, + now: easedVal, + end: toVal, + pos: percent, + options: { + easing: easing, + speacialEasing: specialEasing, + duration: duration, + complete: complete, + step: step + }, + startTime: timeStart + }); + } + } + + if (isFunction(progress)) + progress({}, percent, MATH.max(0, duration - elapsed)); + + if (end) { + startNextAnimationInQ(animObj); + if (isFunction(complete)) + complete(); + } + else + qObj.frame = COMPATIBILITY.rAF()(frame); + }; + qObj.frame = COMPATIBILITY.rAF()(frame); + } + else { + for (key in to) + setAnimationValue(el, key, to[key]); + startNextAnimationInQ(animObj); + } + } + } + else if (guaranteedNext) + startNextAnimationInQ(animObj); + } + + function stop(el, clearQ, jumpToEnd) { + var animObj; + var qObj; + var key; + var i = 0; + for (; i < _animations[LEXICON.l]; i++) { + animObj = _animations[i]; + if (animObj.el === el) { + if (animObj.q[LEXICON.l] > 0) { + qObj = animObj.q[0]; + qObj.stop = true; + COMPATIBILITY.cAF()(qObj.frame); + animObj.q.splice(0, 1); + + if (jumpToEnd) + for (key in qObj.props) + setAnimationValue(el, key, qObj.props[key]); + + if (clearQ) + animObj.q = []; + else + startNextAnimationInQ(animObj, false); + } + break; + } + } + } + + function elementIsVisible(el) { + return !!(el[LEXICON.oW] || el[LEXICON.oH] || el.getClientRects()[LEXICON.l]); + } + + function FakejQuery(selector) { + if (arguments[LEXICON.l] === 0) + return this; + + var base = new FakejQuery(); + var elements = selector; + var i = 0; + var elms; + var el; + + if (_type(selector) == TYPES.s) { + elements = []; + if (selector.charAt(0) === '<') { + el = document.createElement('div'); + el.innerHTML = selector; + elms = el.children; + } + else { + elms = document.querySelectorAll(selector); + } + + for (; i < elms[LEXICON.l]; i++) + elements.push(elms[i]); + } + + if (elements) { + if (_type(elements) != TYPES.s && (!isArrayLike(elements) || elements === window || elements === elements.self)) + elements = [elements]; + + for (i = 0; i < elements[LEXICON.l]; i++) + base[i] = elements[i]; + + base[LEXICON.l] = elements[LEXICON.l]; + } + + return base; + }; + + FakejQuery[LEXICON.p] = { + + //EVENTS: + + on: function (eventName, handler) { + eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty]; + + var eventNameLength = eventName[LEXICON.l]; + var i = 0; + var el; + return this.each(function () { + el = this; + try { + if (el.addEventListener) { + for (; i < eventNameLength; i++) + el.addEventListener(eventName[i], handler); + } + else if (el.detachEvent) { + for (; i < eventNameLength; i++) + el.attachEvent('on' + eventName[i], handler); + } + } catch (e) { } + }); + }, + + off: function (eventName, handler) { + eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty]; + + var eventNameLength = eventName[LEXICON.l]; + var i = 0; + var el; + return this.each(function () { + el = this; + try { + if (el.removeEventListener) { + for (; i < eventNameLength; i++) + el.removeEventListener(eventName[i], handler); + } + else if (el.detachEvent) { + for (; i < eventNameLength; i++) + el.detachEvent('on' + eventName[i], handler); + } + } catch (e) { } + }); + }, + + one: function (eventName, handler) { + eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty]; + return this.each(function () { + var el = FakejQuery(this); + FakejQuery.each(eventName, function (i, oneEventName) { + var oneHandler = function (e) { + handler.call(this, e); + el.off(oneEventName, oneHandler); + }; + el.on(oneEventName, oneHandler); + }); + }); + }, + + trigger: function (eventName) { + var el; + var event; + return this.each(function () { + el = this; + if (document.createEvent) { + event = document.createEvent('HTMLEvents'); + event.initEvent(eventName, true, false); + el.dispatchEvent(event); + } + else { + el.fireEvent('on' + eventName); + } + }); + }, + + //DOM NODE INSERTING / REMOVING: + + append: function (child) { + return this.each(function () { insertAdjacentElement(this, 'beforeend', child); }); + }, + + prepend: function (child) { + return this.each(function () { insertAdjacentElement(this, 'afterbegin', child); }); + }, + + before: function (child) { + return this.each(function () { insertAdjacentElement(this, 'beforebegin', child); }); + }, + + after: function (child) { + return this.each(function () { insertAdjacentElement(this, 'afterend', child); }); + }, + + remove: function () { + return this.each(function () { + var el = this; + var parentNode = el.parentNode; + if (parentNode != null) + parentNode.removeChild(el); + }); + }, + + unwrap: function () { + var parents = []; + var i; + var el; + var parent; + + this.each(function () { + parent = this.parentNode; + if (inArray(parent, parents) === - 1) + parents.push(parent); + }); + + for (i = 0; i < parents[LEXICON.l]; i++) { + el = parents[i]; + parent = el.parentNode; + while (el.firstChild) + parent.insertBefore(el.firstChild, el); + parent.removeChild(el); + } + + return this; + }, + + wrapAll: function (wrapperHTML) { + var i; + var nodes = this; + var wrapper = FakejQuery(wrapperHTML)[0]; + var deepest = wrapper; + var parent = nodes[0].parentNode; + var previousSibling = nodes[0].previousSibling; + while (deepest.childNodes[LEXICON.l] > 0) + deepest = deepest.childNodes[0]; + + for (i = 0; nodes[LEXICON.l] - i; deepest.firstChild === nodes[0] && i++) + deepest.appendChild(nodes[i]); + + var nextSibling = previousSibling ? previousSibling.nextSibling : parent.firstChild; + parent.insertBefore(wrapper, nextSibling); + + return this; + }, + + wrapInner: function (wrapperHTML) { + return this.each(function () { + var el = FakejQuery(this); + var contents = el.contents(); + + if (contents[LEXICON.l]) + contents.wrapAll(wrapperHTML); + else + el.append(wrapperHTML); + }); + }, + + wrap: function (wrapperHTML) { + return this.each(function () { FakejQuery(this).wrapAll(wrapperHTML); }); + }, + + + //DOM NODE MANIPULATION / INFORMATION: + + css: function (styles, val) { + var el; + var key; + var cptStyle; + var getCptStyle = window.getComputedStyle; + if (_type(styles) == TYPES.s) { + if (val === undefined) { + el = this[0]; + cptStyle = getCptStyle ? getCptStyle(el, null) : el.currentStyle[styles]; + + //https://bugzilla.mozilla.org/show_bug.cgi?id=548397 can be null sometimes if iframe with display: none (firefox only!) + return getCptStyle ? cptStyle != null ? cptStyle.getPropertyValue(styles) : el[LEXICON.s][styles] : cptStyle; + } + else { + return this.each(function () { + setCSSVal(this, styles, val); + }); + } + } + else { + return this.each(function () { + for (key in styles) + setCSSVal(this, key, styles[key]); + }); + } + }, + + hasClass: function (className) { + var elem, i = 0; + var classNamePrepared = _strSpace + className + _strSpace; + var classList; + + while ((elem = this[i++])) { + classList = elem.classList; + if (classList && classList.contains(className)) + return true; + else if (elem.nodeType === 1 && (_strSpace + stripAndCollapse(elem.className + _strEmpty) + _strSpace).indexOf(classNamePrepared) > -1) + return true; + } + + return false; + }, + + addClass: function (className) { + var classes; + var elem; + var cur; + var curValue; + var clazz; + var finalValue; + var supportClassList; + var elmClassList; + var i = 0; + var v = 0; + + if (className) { + classes = className.match(_rnothtmlwhite) || []; + + while ((elem = this[i++])) { + elmClassList = elem.classList; + if (supportClassList === undefined) + supportClassList = elmClassList !== undefined; + + if (supportClassList) { + while ((clazz = classes[v++])) + elmClassList.add(clazz); + } + else { + curValue = elem.className + _strEmpty; + cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace); + + if (cur) { + while ((clazz = classes[v++])) + if (cur.indexOf(_strSpace + clazz + _strSpace) < 0) + cur += clazz + _strSpace; + + finalValue = stripAndCollapse(cur); + if (curValue !== finalValue) + elem.className = finalValue; + } + } + } + } + + return this; + }, + + removeClass: function (className) { + var classes; + var elem; + var cur; + var curValue; + var clazz; + var finalValue; + var supportClassList; + var elmClassList; + var i = 0; + var v = 0; + + if (className) { + classes = className.match(_rnothtmlwhite) || []; + + while ((elem = this[i++])) { + elmClassList = elem.classList; + if (supportClassList === undefined) + supportClassList = elmClassList !== undefined; + + if (supportClassList) { + while ((clazz = classes[v++])) + elmClassList.remove(clazz); + } + else { + curValue = elem.className + _strEmpty; + cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace); + + if (cur) { + while ((clazz = classes[v++])) + while (cur.indexOf(_strSpace + clazz + _strSpace) > -1) + cur = cur.replace(_strSpace + clazz + _strSpace, _strSpace); + + finalValue = stripAndCollapse(cur); + if (curValue !== finalValue) + elem.className = finalValue; + } + } + } + } + + return this; + }, + + hide: function () { + return this.each(function () { this[LEXICON.s].display = 'none'; }); + }, + + show: function () { + return this.each(function () { this[LEXICON.s].display = 'block'; }); + }, + + attr: function (attrName, value) { + var i = 0; + var el; + while (el = this[i++]) { + if (value === undefined) + return el.getAttribute(attrName); + el.setAttribute(attrName, value); + } + return this; + }, + + removeAttr: function (attrName) { + return this.each(function () { this.removeAttribute(attrName); }); + }, + + offset: function () { + var el = this[0]; + var rect = el[LEXICON.bCR](); + var scrollLeft = window.pageXOffset || document.documentElement[_strScrollLeft]; + var scrollTop = window.pageYOffset || document.documentElement[_strScrollTop]; + return { + top: rect.top + scrollTop, + left: rect.left + scrollLeft + }; + }, + + position: function () { + var el = this[0]; + return { + top: el.offsetTop, + left: el.offsetLeft + }; + }, + + scrollLeft: function (value) { + var i = 0; + var el; + while (el = this[i++]) { + if (value === undefined) + return el[_strScrollLeft]; + el[_strScrollLeft] = value; + } + return this; + }, + + scrollTop: function (value) { + var i = 0; + var el; + while (el = this[i++]) { + if (value === undefined) + return el[_strScrollTop]; + el[_strScrollTop] = value; + } + return this; + }, + + val: function (value) { + var el = this[0]; + if (!value) + return el.value; + el.value = value; + return this; + }, + + + //DOM TRAVERSAL / FILTERING: + + first: function () { + return this.eq(0); + }, + + last: function () { + return this.eq(-1); + }, + + eq: function (index) { + return FakejQuery(this[index >= 0 ? index : this[LEXICON.l] + index]); + }, + + find: function (selector) { + var children = []; + var i; + this.each(function () { + var el = this; + var ch = el.querySelectorAll(selector); + for (i = 0; i < ch[LEXICON.l]; i++) + children.push(ch[i]); + }); + return FakejQuery(children); + }, + + children: function (selector) { + var children = []; + var el; + var ch; + var i; + + this.each(function () { + ch = this.children; + for (i = 0; i < ch[LEXICON.l]; i++) { + el = ch[i]; + if (selector) { + if ((el.matches && el.matches(selector)) || matches(el, selector)) + children.push(el); + } + else + children.push(el); + } + }); + return FakejQuery(children); + }, + + parent: function (selector) { + var parents = []; + var parent; + this.each(function () { + parent = this.parentNode; + if (selector ? FakejQuery(parent).is(selector) : true) + parents.push(parent); + }); + return FakejQuery(parents); + }, + + is: function (selector) { + + var el; + var i; + for (i = 0; i < this[LEXICON.l]; i++) { + el = this[i]; + if (selector === ':visible') + return elementIsVisible(el); + if (selector === ':hidden') + return !elementIsVisible(el); + if ((el.matches && el.matches(selector)) || matches(el, selector)) + return true; + } + return false; + }, + + contents: function () { + var contents = []; + var childs; + var i; + + this.each(function () { + childs = this.childNodes; + for (i = 0; i < childs[LEXICON.l]; i++) + contents.push(childs[i]); + }); + + return FakejQuery(contents); + }, + + each: function (callback) { + return each(this, callback); + }, + + + //ANIMATION: + + animate: function (props, duration, easing, complete) { + return this.each(function () { animate(this, props, duration, easing, complete); }); + }, + + stop: function (clearQ, jump) { + return this.each(function () { stop(this, clearQ, jump); }); + } + }; + + extend(FakejQuery, { + extend: extend, + inArray: inArray, + isEmptyObject: isEmptyObject, + isPlainObject: isPlainObject, + each: each + }); + + return FakejQuery; + })(); + var INSTANCES = (function () { + var _targets = []; + var _instancePropertyString = '__overlayScrollbars__'; + + /** + * Register, unregister or get a certain (or all) instances. + * Register: Pass the target and the instance. + * Unregister: Pass the target and null. + * Get Instance: Pass the target from which the instance shall be got. + * Get Targets: Pass no arguments. + * @param target The target to which the instance shall be registered / from which the instance shall be unregistered / the instance shall be got + * @param instance The instance. + * @returns {*|void} Returns the instance from the given target. + */ + return function (target, instance) { + var argLen = arguments[LEXICON.l]; + if (argLen < 1) { + //return all targets + return _targets; + } + else { + if (instance) { + //register instance + target[_instancePropertyString] = instance; + _targets.push(target); + } + else { + var index = COMPATIBILITY.inA(target, _targets); + if (index > -1) { + if (argLen > 1) { + //unregister instance + delete target[_instancePropertyString]; + _targets.splice(index, 1); + } + else { + //get instance from target + return _targets[index][_instancePropertyString]; + } + } + } + } + } + })(); + var PLUGIN = (function () { + var _plugin; + var _pluginsGlobals; + var _pluginsAutoUpdateLoop; + var _pluginsExtensions = []; + var _pluginsOptions = (function () { + var type = COMPATIBILITY.type; + var possibleTemplateTypes = [ + TYPES.b, //boolean + TYPES.n, //number + TYPES.s, //string + TYPES.a, //array + TYPES.o, //object + TYPES.f, //function + TYPES.z //null + ]; + var restrictedStringsSplit = ' '; + var restrictedStringsPossibilitiesSplit = ':'; + var classNameAllowedValues = [TYPES.z, TYPES.s]; + var numberAllowedValues = TYPES.n; + var booleanNullAllowedValues = [TYPES.z, TYPES.b]; + var booleanTrueTemplate = [true, TYPES.b]; + var booleanFalseTemplate = [false, TYPES.b]; + var callbackTemplate = [null, [TYPES.z, TYPES.f]]; + var updateOnLoadTemplate = [['img'], [TYPES.s, TYPES.a, TYPES.z]]; + var inheritedAttrsTemplate = [['style', 'class'], [TYPES.s, TYPES.a, TYPES.z]]; + var resizeAllowedValues = 'n:none b:both h:horizontal v:vertical'; + var overflowBehaviorAllowedValues = 'v-h:visible-hidden v-s:visible-scroll s:scroll h:hidden'; + var scrollbarsVisibilityAllowedValues = 'v:visible h:hidden a:auto'; + var scrollbarsAutoHideAllowedValues = 'n:never s:scroll l:leave m:move'; + var optionsDefaultsAndTemplate = { + className: ['os-theme-dark', classNameAllowedValues], //null || string + resize: ['none', resizeAllowedValues], //none || both || horizontal || vertical || n || b || h || v + sizeAutoCapable: booleanTrueTemplate, //true || false + clipAlways: booleanTrueTemplate, //true || false + normalizeRTL: booleanTrueTemplate, //true || false + paddingAbsolute: booleanFalseTemplate, //true || false + autoUpdate: [null, booleanNullAllowedValues], //true || false || null + autoUpdateInterval: [33, numberAllowedValues], //number + updateOnLoad: updateOnLoadTemplate, //string || array || null + nativeScrollbarsOverlaid: { + showNativeScrollbars: booleanFalseTemplate, //true || false + initialize: booleanTrueTemplate //true || false + }, + overflowBehavior: { + x: ['scroll', overflowBehaviorAllowedValues], //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s + y: ['scroll', overflowBehaviorAllowedValues] //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s + }, + scrollbars: { + visibility: ['auto', scrollbarsVisibilityAllowedValues], //visible || hidden || auto || v || h || a + autoHide: ['never', scrollbarsAutoHideAllowedValues], //never || scroll || leave || move || n || s || l || m + autoHideDelay: [800, numberAllowedValues], //number + dragScrolling: booleanTrueTemplate, //true || false + clickScrolling: booleanFalseTemplate, //true || false + touchSupport: booleanTrueTemplate, //true || false + snapHandle: booleanFalseTemplate //true || false + }, + textarea: { + dynWidth: booleanFalseTemplate, //true || false + dynHeight: booleanFalseTemplate, //true || false + inheritedAttrs: inheritedAttrsTemplate //string || array || null + }, + callbacks: { + onInitialized: callbackTemplate, //null || function + onInitializationWithdrawn: callbackTemplate, //null || function + onDestroyed: callbackTemplate, //null || function + onScrollStart: callbackTemplate, //null || function + onScroll: callbackTemplate, //null || function + onScrollStop: callbackTemplate, //null || function + onOverflowChanged: callbackTemplate, //null || function + onOverflowAmountChanged: callbackTemplate, //null || function + onDirectionChanged: callbackTemplate, //null || function + onContentSizeChanged: callbackTemplate, //null || function + onHostSizeChanged: callbackTemplate, //null || function + onUpdated: callbackTemplate //null || function + } + }; + var convert = function (template) { + var recursive = function (obj) { + var key; + var val; + var valType; + for (key in obj) { + if (!obj[LEXICON.hOP](key)) + continue; + val = obj[key]; + valType = type(val); + if (valType == TYPES.a) + obj[key] = val[template ? 1 : 0]; + else if (valType == TYPES.o) + obj[key] = recursive(val); + } + return obj; + }; + return recursive(FRAMEWORK.extend(true, {}, optionsDefaultsAndTemplate)); + }; + + return { + _defaults: convert(), + + _template: convert(true), + + /** + * Validates the passed object by the passed template. + * @param obj The object which shall be validated. + * @param template The template which defines the allowed values and types. + * @param writeErrors True if errors shall be logged to the console. + * @param diffObj If a object is passed then only valid differences to this object will be returned. + * @returns {{}} A object which contains two objects called "default" and "prepared" which contains only the valid properties of the passed original object and discards not different values compared to the passed diffObj. + */ + _validate: function (obj, template, writeErrors, diffObj) { + var validatedOptions = {}; + var validatedOptionsPrepared = {}; + var objectCopy = FRAMEWORK.extend(true, {}, obj); + var inArray = FRAMEWORK.inArray; + var isEmptyObj = FRAMEWORK.isEmptyObject; + var checkObjectProps = function (data, template, diffData, validatedOptions, validatedOptionsPrepared, prevPropName) { + for (var prop in template) { + if (template[LEXICON.hOP](prop) && data[LEXICON.hOP](prop)) { + var isValid = false; + var isDiff = false; + var templateValue = template[prop]; + var templateValueType = type(templateValue); + var templateIsComplex = templateValueType == TYPES.o; + var templateTypes = !COMPATIBILITY.isA(templateValue) ? [templateValue] : templateValue; + var dataDiffValue = diffData[prop]; + var dataValue = data[prop]; + var dataValueType = type(dataValue); + var propPrefix = prevPropName ? prevPropName + '.' : ''; + var error = "The option \"" + propPrefix + prop + "\" wasn't set, because"; + var errorPossibleTypes = []; + var errorRestrictedStrings = []; + var restrictedStringValuesSplit; + var restrictedStringValuesPossibilitiesSplit; + var isRestrictedValue; + var mainPossibility; + var currType; + var i; + var v; + var j; + + dataDiffValue = dataDiffValue === undefined ? {} : dataDiffValue; + + //if the template has a object as value, it means that the options are complex (verschachtelt) + if (templateIsComplex && dataValueType == TYPES.o) { + validatedOptions[prop] = {}; + validatedOptionsPrepared[prop] = {}; + checkObjectProps(dataValue, templateValue, dataDiffValue, validatedOptions[prop], validatedOptionsPrepared[prop], propPrefix + prop); + FRAMEWORK.each([data, validatedOptions, validatedOptionsPrepared], function (index, value) { + if (isEmptyObj(value[prop])) { + delete value[prop]; + } + }); + } + else if (!templateIsComplex) { + for (i = 0; i < templateTypes[LEXICON.l]; i++) { + currType = templateTypes[i]; + templateValueType = type(currType); + //if currtype is string and starts with restrictedStringPrefix and end with restrictedStringSuffix + isRestrictedValue = templateValueType == TYPES.s && inArray(currType, possibleTemplateTypes) === -1; + if (isRestrictedValue) { + errorPossibleTypes.push(TYPES.s); + + //split it into a array which contains all possible values for example: ["y:yes", "n:no", "m:maybe"] + restrictedStringValuesSplit = currType.split(restrictedStringsSplit); + errorRestrictedStrings = errorRestrictedStrings.concat(restrictedStringValuesSplit); + for (v = 0; v < restrictedStringValuesSplit[LEXICON.l]; v++) { + //split the possible values into their possibiliteis for example: ["y", "yes"] -> the first is always the mainPossibility + restrictedStringValuesPossibilitiesSplit = restrictedStringValuesSplit[v].split(restrictedStringsPossibilitiesSplit); + mainPossibility = restrictedStringValuesPossibilitiesSplit[0]; + for (j = 0; j < restrictedStringValuesPossibilitiesSplit[LEXICON.l]; j++) { + //if any possibility matches with the dataValue, its valid + if (dataValue === restrictedStringValuesPossibilitiesSplit[j]) { + isValid = true; + break; + } + } + if (isValid) + break; + } + } + else { + errorPossibleTypes.push(currType); + + if (dataValueType === currType) { + isValid = true; + break; + } + } + } + + if (isValid) { + isDiff = dataValue !== dataDiffValue; + + if (isDiff) + validatedOptions[prop] = dataValue; + + if (isRestrictedValue ? inArray(dataDiffValue, restrictedStringValuesPossibilitiesSplit) < 0 : isDiff) + validatedOptionsPrepared[prop] = isRestrictedValue ? mainPossibility : dataValue; + } + else if (writeErrors) { + console.warn(error + " it doesn't accept the type [ " + dataValueType.toUpperCase() + " ] with the value of \"" + dataValue + "\".\r\n" + + "Accepted types are: [ " + errorPossibleTypes.join(', ').toUpperCase() + " ]." + + (errorRestrictedStrings[length] > 0 ? "\r\nValid strings are: [ " + errorRestrictedStrings.join(', ').split(restrictedStringsPossibilitiesSplit).join(', ') + " ]." : '')); + } + delete data[prop]; + } + } + } + }; + checkObjectProps(objectCopy, template, diffObj || {}, validatedOptions, validatedOptionsPrepared); + + //add values which aren't specified in the template to the finished validated object to prevent them from being discarded + /* + if(keepForeignProps) { + FRAMEWORK.extend(true, validatedOptions, objectCopy); + FRAMEWORK.extend(true, validatedOptionsPrepared, objectCopy); + } + */ + + if (!isEmptyObj(objectCopy) && writeErrors) + console.warn('The following options are discarded due to invalidity:\r\n' + window.JSON.stringify(objectCopy, null, 2)); + + return { + _default: validatedOptions, + _prepared: validatedOptionsPrepared + }; + } + } + }()); + + /** + * Initializes the object which contains global information about the plugin and each instance of it. + */ + function initOverlayScrollbarsStatics() { + if (!_pluginsGlobals) + _pluginsGlobals = new OverlayScrollbarsGlobals(_pluginsOptions._defaults); + if (!_pluginsAutoUpdateLoop) + _pluginsAutoUpdateLoop = new OverlayScrollbarsAutoUpdateLoop(_pluginsGlobals); + } + + /** + * The global object for the OverlayScrollbars objects. It contains resources which every OverlayScrollbars object needs. This object is initialized only once: if the first OverlayScrollbars object gets initialized. + * @param defaultOptions + * @constructor + */ + function OverlayScrollbarsGlobals(defaultOptions) { + var _base = this; + var strOverflow = 'overflow'; + var strHidden = 'hidden'; + var strScroll = 'scroll'; + var bodyElement = FRAMEWORK('body'); + var scrollbarDummyElement = FRAMEWORK('
        '); + var scrollbarDummyElement0 = scrollbarDummyElement[0]; + var dummyContainerChild = FRAMEWORK(scrollbarDummyElement.children('div').eq(0)); + + bodyElement.append(scrollbarDummyElement); + scrollbarDummyElement.hide().show(); //fix IE8 bug (incorrect measuring) + + var nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement0); + var nativeScrollbarIsOverlaid = { + x: nativeScrollbarSize.x === 0, + y: nativeScrollbarSize.y === 0 + }; + var msie = (function () { + var ua = window.navigator.userAgent; + var strIndexOf = 'indexOf'; + var strSubString = 'substring'; + var msie = ua[strIndexOf]('MSIE '); + var trident = ua[strIndexOf]('Trident/'); + var edge = ua[strIndexOf]('Edge/'); + var rv = ua[strIndexOf]('rv:'); + var result; + var parseIntFunc = parseInt; + + // IE 10 or older => return version number + if (msie > 0) + result = parseIntFunc(ua[strSubString](msie + 5, ua[strIndexOf]('.', msie)), 10); + + // IE 11 => return version number + else if (trident > 0) + result = parseIntFunc(ua[strSubString](rv + 3, ua[strIndexOf]('.', rv)), 10); + + // Edge (IE 12+) => return version number + else if (edge > 0) + result = parseIntFunc(ua[strSubString](edge + 5, ua[strIndexOf]('.', edge)), 10); + + // other browser + return result; + })(); + + FRAMEWORK.extend(_base, { + defaultOptions: defaultOptions, + msie: msie, + autoUpdateLoop: false, + autoUpdateRecommended: !COMPATIBILITY.mO(), + nativeScrollbarSize: nativeScrollbarSize, + nativeScrollbarIsOverlaid: nativeScrollbarIsOverlaid, + nativeScrollbarStyling: (function () { + var result = false; + scrollbarDummyElement.addClass('os-viewport-native-scrollbars-invisible'); + try { + result = (scrollbarDummyElement.css('scrollbar-width') === 'none' && (msie > 9 || !msie)) || window.getComputedStyle(scrollbarDummyElement0, '::-webkit-scrollbar').getPropertyValue('display') === 'none'; + } catch (ex) { } + + //fix opera bug: scrollbar styles will only appear if overflow value is scroll or auto during the activation of the style. + //and set overflow to scroll + //scrollbarDummyElement.css(strOverflow, strHidden).hide().css(strOverflow, strScroll).show(); + //return (scrollbarDummyElement0[LEXICON.oH] - scrollbarDummyElement0[LEXICON.cH]) === 0 && (scrollbarDummyElement0[LEXICON.oW] - scrollbarDummyElement0[LEXICON.cW]) === 0; + + return result; + })(), + overlayScrollbarDummySize: { x: 30, y: 30 }, + cssCalc: VENDORS._cssPropertyValue('width', 'calc', '(1px)') || null, + restrictedMeasuring: (function () { + //https://bugzilla.mozilla.org/show_bug.cgi?id=1439305 + //since 1.11.0 always false -> fixed via CSS (hopefully) + scrollbarDummyElement.css(strOverflow, strHidden); + var scrollSize = { + w: scrollbarDummyElement0[LEXICON.sW], + h: scrollbarDummyElement0[LEXICON.sH] + }; + scrollbarDummyElement.css(strOverflow, 'visible'); + var scrollSize2 = { + w: scrollbarDummyElement0[LEXICON.sW], + h: scrollbarDummyElement0[LEXICON.sH] + }; + return (scrollSize.w - scrollSize2.w) !== 0 || (scrollSize.h - scrollSize2.h) !== 0; + })(), + rtlScrollBehavior: (function () { + scrollbarDummyElement.css({ 'overflow-y': strHidden, 'overflow-x': strScroll, 'direction': 'rtl' }).scrollLeft(0); + var dummyContainerOffset = scrollbarDummyElement.offset(); + var dummyContainerChildOffset = dummyContainerChild.offset(); + //https://github.com/KingSora/OverlayScrollbars/issues/187 + scrollbarDummyElement.scrollLeft(-999); + var dummyContainerChildOffsetAfterScroll = dummyContainerChild.offset(); + return { + //origin direction = determines if the zero scroll position is on the left or right side + //'i' means 'invert' (i === true means that the axis must be inverted to be correct) + //true = on the left side + //false = on the right side + i: dummyContainerOffset.left === dummyContainerChildOffset.left, + //negative = determines if the maximum scroll is positive or negative + //'n' means 'negate' (n === true means that the axis must be negated to be correct) + //true = negative + //false = positive + n: dummyContainerChildOffset.left !== dummyContainerChildOffsetAfterScroll.left + }; + })(), + supportTransform: !!VENDORS._cssProperty('transform'), + supportTransition: !!VENDORS._cssProperty('transition'), + supportPassiveEvents: (function () { + var supportsPassive = false; + try { + window.addEventListener('test', null, Object.defineProperty({}, 'passive', { + get: function () { + supportsPassive = true; + } + })); + } catch (e) { } + return supportsPassive; + })(), + supportResizeObserver: !!COMPATIBILITY.rO(), + supportMutationObserver: !!COMPATIBILITY.mO() + }); + + scrollbarDummyElement.removeAttr(LEXICON.s).remove(); + + //Catch zoom event: + (function () { + if (nativeScrollbarIsOverlaid.x && nativeScrollbarIsOverlaid.y) + return; + + var abs = MATH.abs; + var windowWidth = COMPATIBILITY.wW(); + var windowHeight = COMPATIBILITY.wH(); + var windowDpr = getWindowDPR(); + var onResize = function () { + if (INSTANCES().length > 0) { + var newW = COMPATIBILITY.wW(); + var newH = COMPATIBILITY.wH(); + var deltaW = newW - windowWidth; + var deltaH = newH - windowHeight; + + if (deltaW === 0 && deltaH === 0) + return; + + var deltaWRatio = MATH.round(newW / (windowWidth / 100.0)); + var deltaHRatio = MATH.round(newH / (windowHeight / 100.0)); + var absDeltaW = abs(deltaW); + var absDeltaH = abs(deltaH); + var absDeltaWRatio = abs(deltaWRatio); + var absDeltaHRatio = abs(deltaHRatio); + var newDPR = getWindowDPR(); + + var deltaIsBigger = absDeltaW > 2 && absDeltaH > 2; + var difference = !differenceIsBiggerThanOne(absDeltaWRatio, absDeltaHRatio); + var dprChanged = newDPR !== windowDpr && windowDpr > 0; + var isZoom = deltaIsBigger && difference && dprChanged; + var oldScrollbarSize = _base.nativeScrollbarSize; + var newScrollbarSize; + + if (isZoom) { + bodyElement.append(scrollbarDummyElement); + newScrollbarSize = _base.nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement[0]); + scrollbarDummyElement.remove(); + if (oldScrollbarSize.x !== newScrollbarSize.x || oldScrollbarSize.y !== newScrollbarSize.y) { + FRAMEWORK.each(INSTANCES(), function () { + if (INSTANCES(this)) + INSTANCES(this).update('zoom'); + }); + } + } + + windowWidth = newW; + windowHeight = newH; + windowDpr = newDPR; + } + }; + + function differenceIsBiggerThanOne(valOne, valTwo) { + var absValOne = abs(valOne); + var absValTwo = abs(valTwo); + return !(absValOne === absValTwo || absValOne + 1 === absValTwo || absValOne - 1 === absValTwo); + } + + function getWindowDPR() { + var dDPI = window.screen.deviceXDPI || 0; + var sDPI = window.screen.logicalXDPI || 1; + return window.devicePixelRatio || (dDPI / sDPI); + } + + FRAMEWORK(window).on('resize', onResize); + })(); + + function calcNativeScrollbarSize(measureElement) { + return { + x: measureElement[LEXICON.oH] - measureElement[LEXICON.cH], + y: measureElement[LEXICON.oW] - measureElement[LEXICON.cW] + }; + } + } + + /** + * The object which manages the auto update loop for all OverlayScrollbars objects. This object is initialized only once: if the first OverlayScrollbars object gets initialized. + * @constructor + */ + function OverlayScrollbarsAutoUpdateLoop(globals) { + var _base = this; + var _inArray = FRAMEWORK.inArray; + var _getNow = COMPATIBILITY.now; + var _strAutoUpdate = 'autoUpdate'; + var _strAutoUpdateInterval = _strAutoUpdate + 'Interval'; + var _strLength = LEXICON.l; + var _loopingInstances = []; + var _loopingInstancesIntervalCache = []; + var _loopIsActive = false; + var _loopIntervalDefault = 33; + var _loopInterval = _loopIntervalDefault; + var _loopTimeOld = _getNow(); + var _loopID; + + + /** + * The auto update loop which will run every 50 milliseconds or less if the update interval of a instance is lower than 50 milliseconds. + */ + var loop = function () { + if (_loopingInstances[_strLength] > 0 && _loopIsActive) { + _loopID = COMPATIBILITY.rAF()(function () { + loop(); + }); + var timeNew = _getNow(); + var timeDelta = timeNew - _loopTimeOld; + var lowestInterval; + var instance; + var instanceOptions; + var instanceAutoUpdateAllowed; + var instanceAutoUpdateInterval; + var now; + + if (timeDelta > _loopInterval) { + _loopTimeOld = timeNew - (timeDelta % _loopInterval); + lowestInterval = _loopIntervalDefault; + for (var i = 0; i < _loopingInstances[_strLength]; i++) { + instance = _loopingInstances[i]; + if (instance !== undefined) { + instanceOptions = instance.options(); + instanceAutoUpdateAllowed = instanceOptions[_strAutoUpdate]; + instanceAutoUpdateInterval = MATH.max(1, instanceOptions[_strAutoUpdateInterval]); + now = _getNow(); + + if ((instanceAutoUpdateAllowed === true || instanceAutoUpdateAllowed === null) && (now - _loopingInstancesIntervalCache[i]) > instanceAutoUpdateInterval) { + instance.update('auto'); + _loopingInstancesIntervalCache[i] = new Date(now += instanceAutoUpdateInterval); + } + + lowestInterval = MATH.max(1, MATH.min(lowestInterval, instanceAutoUpdateInterval)); + } + } + _loopInterval = lowestInterval; + } + } else { + _loopInterval = _loopIntervalDefault; + } + }; + + /** + * Add OverlayScrollbars instance to the auto update loop. Only successful if the instance isn't already added. + * @param instance The instance which shall be updated in a loop automatically. + */ + _base.add = function (instance) { + if (_inArray(instance, _loopingInstances) === -1) { + _loopingInstances.push(instance); + _loopingInstancesIntervalCache.push(_getNow()); + if (_loopingInstances[_strLength] > 0 && !_loopIsActive) { + _loopIsActive = true; + globals.autoUpdateLoop = _loopIsActive; + loop(); + } + } + }; + + /** + * Remove OverlayScrollbars instance from the auto update loop. Only successful if the instance was added before. + * @param instance The instance which shall be updated in a loop automatically. + */ + _base.remove = function (instance) { + var index = _inArray(instance, _loopingInstances); + if (index > -1) { + //remove from loopingInstances list + _loopingInstancesIntervalCache.splice(index, 1); + _loopingInstances.splice(index, 1); + + //correct update loop behavior + if (_loopingInstances[_strLength] === 0 && _loopIsActive) { + _loopIsActive = false; + globals.autoUpdateLoop = _loopIsActive; + if (_loopID !== undefined) { + COMPATIBILITY.cAF()(_loopID); + _loopID = -1; + } + } + } + }; + } + + /** + * A object which manages the scrollbars visibility of the target element. + * @param pluginTargetElement The element from which the scrollbars shall be hidden. + * @param options The custom options. + * @param extensions The custom extensions. + * @param globals + * @param autoUpdateLoop + * @returns {*} + * @constructor + */ + function OverlayScrollbarsInstance(pluginTargetElement, options, extensions, globals, autoUpdateLoop) { + //shortcuts + var type = COMPATIBILITY.type; + var inArray = FRAMEWORK.inArray; + var each = FRAMEWORK.each; + + //make correct instanceof + var _base = new _plugin(); + var _frameworkProto = FRAMEWORK[LEXICON.p]; + + //if passed element is no HTML element: skip and return + if (!isHTMLElement(pluginTargetElement)) + return; + + //if passed element is already initialized: set passed options if there are any and return its instance + if (INSTANCES(pluginTargetElement)) { + var inst = INSTANCES(pluginTargetElement); + inst.options(options); + return inst; + } + + //globals: + var _nativeScrollbarIsOverlaid; + var _overlayScrollbarDummySize; + var _rtlScrollBehavior; + var _autoUpdateRecommended; + var _msieVersion; + var _nativeScrollbarStyling; + var _cssCalc; + var _nativeScrollbarSize; + var _supportTransition; + var _supportTransform; + var _supportPassiveEvents; + var _supportResizeObserver; + var _supportMutationObserver; + var _restrictedMeasuring; + + //general readonly: + var _initialized; + var _destroyed; + var _isTextarea; + var _isBody; + var _documentMixed; + var _domExists; + + //general: + var _isBorderBox; + var _sizeAutoObserverAdded; + var _paddingX; + var _paddingY; + var _borderX; + var _borderY; + var _marginX; + var _marginY; + var _isRTL; + var _sleeping; + var _contentBorderSize = {}; + var _scrollHorizontalInfo = {}; + var _scrollVerticalInfo = {}; + var _viewportSize = {}; + var _nativeScrollbarMinSize = {}; + + //naming: + var _strMinusHidden = '-hidden'; + var _strMarginMinus = 'margin-'; + var _strPaddingMinus = 'padding-'; + var _strBorderMinus = 'border-'; + var _strTop = 'top'; + var _strRight = 'right'; + var _strBottom = 'bottom'; + var _strLeft = 'left'; + var _strMinMinus = 'min-'; + var _strMaxMinus = 'max-'; + var _strWidth = 'width'; + var _strHeight = 'height'; + var _strFloat = 'float'; + var _strEmpty = ''; + var _strAuto = 'auto'; + var _strSync = 'sync'; + var _strScroll = 'scroll'; + var _strHundredPercent = '100%'; + var _strX = 'x'; + var _strY = 'y'; + var _strDot = '.'; + var _strSpace = ' '; + var _strScrollbar = 'scrollbar'; + var _strMinusHorizontal = '-horizontal'; + var _strMinusVertical = '-vertical'; + var _strScrollLeft = _strScroll + 'Left'; + var _strScrollTop = _strScroll + 'Top'; + var _strMouseTouchDownEvent = 'mousedown touchstart'; + var _strMouseTouchUpEvent = 'mouseup touchend touchcancel'; + var _strMouseTouchMoveEvent = 'mousemove touchmove'; + var _strMouseEnter = 'mouseenter'; + var _strMouseLeave = 'mouseleave'; + var _strKeyDownEvent = 'keydown'; + var _strKeyUpEvent = 'keyup'; + var _strSelectStartEvent = 'selectstart'; + var _strTransitionEndEvent = 'transitionend webkitTransitionEnd oTransitionEnd'; + var _strResizeObserverProperty = '__overlayScrollbarsRO__'; + + //class names: + var _cassNamesPrefix = 'os-'; + var _classNameHTMLElement = _cassNamesPrefix + 'html'; + var _classNameHostElement = _cassNamesPrefix + 'host'; + var _classNameHostElementForeign = _classNameHostElement + '-foreign'; + var _classNameHostTextareaElement = _classNameHostElement + '-textarea'; + var _classNameHostScrollbarHorizontalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusHorizontal + _strMinusHidden; + var _classNameHostScrollbarVerticalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusVertical + _strMinusHidden; + var _classNameHostTransition = _classNameHostElement + '-transition'; + var _classNameHostRTL = _classNameHostElement + '-rtl'; + var _classNameHostResizeDisabled = _classNameHostElement + '-resize-disabled'; + var _classNameHostScrolling = _classNameHostElement + '-scrolling'; + var _classNameHostOverflow = _classNameHostElement + '-overflow'; + var _classNameHostOverflow = _classNameHostElement + '-overflow'; + var _classNameHostOverflowX = _classNameHostOverflow + '-x'; + var _classNameHostOverflowY = _classNameHostOverflow + '-y'; + var _classNameTextareaElement = _cassNamesPrefix + 'textarea'; + var _classNameTextareaCoverElement = _classNameTextareaElement + '-cover'; + var _classNamePaddingElement = _cassNamesPrefix + 'padding'; + var _classNameViewportElement = _cassNamesPrefix + 'viewport'; + var _classNameViewportNativeScrollbarsInvisible = _classNameViewportElement + '-native-scrollbars-invisible'; + var _classNameViewportNativeScrollbarsOverlaid = _classNameViewportElement + '-native-scrollbars-overlaid'; + var _classNameContentElement = _cassNamesPrefix + 'content'; + var _classNameContentArrangeElement = _cassNamesPrefix + 'content-arrange'; + var _classNameContentGlueElement = _cassNamesPrefix + 'content-glue'; + var _classNameSizeAutoObserverElement = _cassNamesPrefix + 'size-auto-observer'; + var _classNameResizeObserverElement = _cassNamesPrefix + 'resize-observer'; + var _classNameResizeObserverItemElement = _cassNamesPrefix + 'resize-observer-item'; + var _classNameResizeObserverItemFinalElement = _classNameResizeObserverItemElement + '-final'; + var _classNameTextInherit = _cassNamesPrefix + 'text-inherit'; + var _classNameScrollbar = _cassNamesPrefix + _strScrollbar; + var _classNameScrollbarTrack = _classNameScrollbar + '-track'; + var _classNameScrollbarTrackOff = _classNameScrollbarTrack + '-off'; + var _classNameScrollbarHandle = _classNameScrollbar + '-handle'; + var _classNameScrollbarHandleOff = _classNameScrollbarHandle + '-off'; + var _classNameScrollbarUnusable = _classNameScrollbar + '-unusable'; + var _classNameScrollbarAutoHidden = _classNameScrollbar + '-' + _strAuto + _strMinusHidden; + var _classNameScrollbarCorner = _classNameScrollbar + '-corner'; + var _classNameScrollbarCornerResize = _classNameScrollbarCorner + '-resize'; + var _classNameScrollbarCornerResizeB = _classNameScrollbarCornerResize + '-both'; + var _classNameScrollbarCornerResizeH = _classNameScrollbarCornerResize + _strMinusHorizontal; + var _classNameScrollbarCornerResizeV = _classNameScrollbarCornerResize + _strMinusVertical; + var _classNameScrollbarHorizontal = _classNameScrollbar + _strMinusHorizontal; + var _classNameScrollbarVertical = _classNameScrollbar + _strMinusVertical; + var _classNameDragging = _cassNamesPrefix + 'dragging'; + var _classNameThemeNone = _cassNamesPrefix + 'theme-none'; + var _classNamesDynamicDestroy = [ + _classNameViewportNativeScrollbarsInvisible, + _classNameViewportNativeScrollbarsOverlaid, + _classNameScrollbarTrackOff, + _classNameScrollbarHandleOff, + _classNameScrollbarUnusable, + _classNameScrollbarAutoHidden, + _classNameScrollbarCornerResize, + _classNameScrollbarCornerResizeB, + _classNameScrollbarCornerResizeH, + _classNameScrollbarCornerResizeV, + _classNameDragging].join(_strSpace); + + //callbacks: + var _callbacksInitQeueue = []; + + //attrs viewport shall inherit from target + var _viewportAttrsFromTarget = [LEXICON.ti]; + + //options: + var _defaultOptions; + var _currentOptions; + var _currentPreparedOptions; + + //extensions: + var _extensions = {}; + var _extensionsPrivateMethods = 'added removed on contract'; + + //update + var _lastUpdateTime; + var _swallowedUpdateHints = {}; + var _swallowedUpdateTimeout; + var _swallowUpdateLag = 42; + var _updateOnLoadEventName = 'load'; + var _updateOnLoadElms = []; + + //DOM elements: + var _windowElement; + var _documentElement; + var _htmlElement; + var _bodyElement; + var _targetElement; //the target element of this OverlayScrollbars object + var _hostElement; //the host element of this OverlayScrollbars object -> may be the same as targetElement + var _sizeAutoObserverElement; //observes size auto changes + var _sizeObserverElement; //observes size and padding changes + var _paddingElement; //manages the padding + var _viewportElement; //is the viewport of our scrollbar model + var _contentElement; //the element which holds the content + var _contentArrangeElement; //is needed for correct sizing of the content element (only if native scrollbars are overlays) + var _contentGlueElement; //has always the size of the content element + var _textareaCoverElement; //only applied if target is a textarea element. Used for correct size calculation and for prevention of uncontrolled scrolling + var _scrollbarCornerElement; + var _scrollbarHorizontalElement; + var _scrollbarHorizontalTrackElement; + var _scrollbarHorizontalHandleElement; + var _scrollbarVerticalElement; + var _scrollbarVerticalTrackElement; + var _scrollbarVerticalHandleElement; + var _windowElementNative; + var _documentElementNative; + var _targetElementNative; + var _hostElementNative; + var _sizeAutoObserverElementNative; + var _sizeObserverElementNative; + var _paddingElementNative; + var _viewportElementNative; + var _contentElementNative; + + //Cache: + var _hostSizeCache; + var _contentScrollSizeCache; + var _arrangeContentSizeCache; + var _hasOverflowCache; + var _hideOverflowCache; + var _widthAutoCache; + var _heightAutoCache; + var _cssBoxSizingCache; + var _cssPaddingCache; + var _cssBorderCache; + var _cssMarginCache; + var _cssDirectionCache; + var _cssDirectionDetectedCache; + var _paddingAbsoluteCache; + var _clipAlwaysCache; + var _contentGlueSizeCache; + var _overflowBehaviorCache; + var _overflowAmountCache; + var _ignoreOverlayScrollbarHidingCache; + var _autoUpdateCache; + var _sizeAutoCapableCache; + var _contentElementScrollSizeChangeDetectedCache; + var _hostElementSizeChangeDetectedCache; + var _scrollbarsVisibilityCache; + var _scrollbarsAutoHideCache; + var _scrollbarsClickScrollingCache; + var _scrollbarsDragScrollingCache; + var _resizeCache; + var _normalizeRTLCache; + var _classNameCache; + var _oldClassName; + var _textareaAutoWrappingCache; + var _textareaInfoCache; + var _textareaSizeCache; + var _textareaDynHeightCache; + var _textareaDynWidthCache; + var _bodyMinSizeCache; + var _updateAutoCache = {}; + + //MutationObserver: + var _mutationObserverHost; + var _mutationObserverContent; + var _mutationObserverHostCallback; + var _mutationObserverContentCallback; + var _mutationObserversConnected; + var _mutationObserverAttrsTextarea = ['wrap', 'cols', 'rows']; + var _mutationObserverAttrsHost = [LEXICON.i, LEXICON.c, LEXICON.s, 'open'].concat(_viewportAttrsFromTarget); + + //events: + var _destroyEvents = []; + + //textarea: + var _textareaHasFocus; + + //scrollbars: + var _scrollbarsAutoHideTimeoutId; + var _scrollbarsAutoHideMoveTimeoutId; + var _scrollbarsAutoHideDelay; + var _scrollbarsAutoHideNever; + var _scrollbarsAutoHideScroll; + var _scrollbarsAutoHideMove; + var _scrollbarsAutoHideLeave; + var _scrollbarsHandleHovered; + var _scrollbarsHandlesDefineScrollPos; + + //resize + var _resizeNone; + var _resizeBoth; + var _resizeHorizontal; + var _resizeVertical; + + + //==== Event Listener ====// + + /** + * Adds or removes a event listener from the given element. + * @param element The element to which the event listener shall be applied or removed. + * @param eventNames The name(s) of the events. + * @param listener The method which shall be called. + * @param remove True if the handler shall be removed, false or undefined if the handler shall be added. + * @param passiveOrOptions The options for the event. + */ + function setupResponsiveEventListener(element, eventNames, listener, remove, passiveOrOptions) { + var collected = COMPATIBILITY.isA(eventNames) && COMPATIBILITY.isA(listener); + var method = remove ? 'removeEventListener' : 'addEventListener'; + var onOff = remove ? 'off' : 'on'; + var events = collected ? false : eventNames.split(_strSpace) + var i = 0; + + var passiveOrOptionsIsObj = FRAMEWORK.isPlainObject(passiveOrOptions); + var passive = (_supportPassiveEvents && (passiveOrOptionsIsObj ? (passiveOrOptions._passive) : passiveOrOptions)) || false; + var capture = passiveOrOptionsIsObj && (passiveOrOptions._capture || false); + var nativeParam = _supportPassiveEvents ? { + passive: passive, + capture: capture, + } : capture; + + if (collected) { + for (; i < eventNames[LEXICON.l]; i++) + setupResponsiveEventListener(element, eventNames[i], listener[i], remove, passiveOrOptions); + } + else { + for (; i < events[LEXICON.l]; i++) { + if(_supportPassiveEvents) { + element[0][method](events[i], listener, nativeParam); + } + else { + element[onOff](events[i], listener); + } + } + } + } + + + function addDestroyEventListener(element, eventNames, listener, passive) { + setupResponsiveEventListener(element, eventNames, listener, false, passive); + _destroyEvents.push(COMPATIBILITY.bind(setupResponsiveEventListener, 0, element, eventNames, listener, true, passive)); + } + + //==== Resize Observer ====// + + /** + * Adds or removes a resize observer from the given element. + * @param targetElement The element to which the resize observer shall be added or removed. + * @param onElementResizedCallback The callback which is fired every time the resize observer registers a size change or false / undefined if the resizeObserver shall be removed. + */ + function setupResizeObserver(targetElement, onElementResizedCallback) { + if (targetElement) { + var resizeObserver = COMPATIBILITY.rO(); + var strAnimationStartEvent = 'animationstart mozAnimationStart webkitAnimationStart MSAnimationStart'; + var strChildNodes = 'childNodes'; + var constScroll = 3333333; + var callback = function () { + targetElement[_strScrollTop](constScroll)[_strScrollLeft](_isRTL ? _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll : constScroll); + onElementResizedCallback(); + }; + //add resize observer: + if (onElementResizedCallback) { + if (_supportResizeObserver) { + var element = targetElement.addClass('observed').append(generateDiv(_classNameResizeObserverElement)).contents()[0]; + var observer = element[_strResizeObserverProperty] = new resizeObserver(callback); + observer.observe(element); + } + else { + if (_msieVersion > 9 || !_autoUpdateRecommended) { + targetElement.prepend( + generateDiv(_classNameResizeObserverElement, + generateDiv({ c: _classNameResizeObserverItemElement, dir: 'ltr' }, + generateDiv(_classNameResizeObserverItemElement, + generateDiv(_classNameResizeObserverItemFinalElement) + ) + + generateDiv(_classNameResizeObserverItemElement, + generateDiv({ c: _classNameResizeObserverItemFinalElement, style: 'width: 200%; height: 200%' }) + ) + ) + ) + ); + + var observerElement = targetElement[0][strChildNodes][0][strChildNodes][0]; + var shrinkElement = FRAMEWORK(observerElement[strChildNodes][1]); + var expandElement = FRAMEWORK(observerElement[strChildNodes][0]); + var expandElementChild = FRAMEWORK(expandElement[0][strChildNodes][0]); + var widthCache = observerElement[LEXICON.oW]; + var heightCache = observerElement[LEXICON.oH]; + var isDirty; + var rAFId; + var currWidth; + var currHeight; + var factor = 2; + var nativeScrollbarSize = globals.nativeScrollbarSize; //care don't make changes to this object!!! + var reset = function () { + /* + var sizeResetWidth = observerElement[LEXICON.oW] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y; + var sizeResetHeight = observerElement[LEXICON.oH] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y; + var expandChildCSS = {}; + expandChildCSS[_strWidth] = sizeResetWidth; + expandChildCSS[_strHeight] = sizeResetHeight; + expandElementChild.css(expandChildCSS); + + + expandElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight); + shrinkElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight); + */ + expandElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll); + shrinkElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll); + }; + var onResized = function () { + rAFId = 0; + if (!isDirty) + return; + + widthCache = currWidth; + heightCache = currHeight; + callback(); + }; + var onScroll = function (event) { + currWidth = observerElement[LEXICON.oW]; + currHeight = observerElement[LEXICON.oH]; + isDirty = currWidth != widthCache || currHeight != heightCache; + + if (event && isDirty && !rAFId) { + COMPATIBILITY.cAF()(rAFId); + rAFId = COMPATIBILITY.rAF()(onResized); + } + else if (!event) + onResized(); + + reset(); + if (event) { + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + return false; + }; + var expandChildCSS = {}; + var observerElementCSS = {}; + + setTopRightBottomLeft(observerElementCSS, _strEmpty, [ + -((nativeScrollbarSize.y + 1) * factor), + nativeScrollbarSize.x * -factor, + nativeScrollbarSize.y * -factor, + -((nativeScrollbarSize.x + 1) * factor) + ]); + + FRAMEWORK(observerElement).css(observerElementCSS); + expandElement.on(_strScroll, onScroll); + shrinkElement.on(_strScroll, onScroll); + targetElement.on(strAnimationStartEvent, function () { + onScroll(false); + }); + //lets assume that the divs will never be that large and a constant value is enough + expandChildCSS[_strWidth] = constScroll; + expandChildCSS[_strHeight] = constScroll; + expandElementChild.css(expandChildCSS); + + reset(); + } + else { + var attachEvent = _documentElementNative.attachEvent; + var isIE = _msieVersion !== undefined; + if (attachEvent) { + targetElement.prepend(generateDiv(_classNameResizeObserverElement)); + findFirst(targetElement, _strDot + _classNameResizeObserverElement)[0].attachEvent('onresize', callback); + } + else { + var obj = _documentElementNative.createElement(TYPES.o); + obj.setAttribute(LEXICON.ti, '-1'); + obj.setAttribute(LEXICON.c, _classNameResizeObserverElement); + obj.onload = function () { + var wnd = this.contentDocument.defaultView; + wnd.addEventListener('resize', callback); + wnd.document.documentElement.style.display = 'none'; + }; + obj.type = 'text/html'; + if (isIE) + targetElement.prepend(obj); + obj.data = 'about:blank'; + if (!isIE) + targetElement.prepend(obj); + targetElement.on(strAnimationStartEvent, callback); + } + } + } + + if (targetElement[0] === _sizeObserverElementNative) { + var directionChanged = function () { + var dir = _hostElement.css('direction'); + var css = {}; + var scrollLeftValue = 0; + var result = false; + if (dir !== _cssDirectionDetectedCache) { + if (dir === 'ltr') { + css[_strLeft] = 0; + css[_strRight] = _strAuto; + scrollLeftValue = constScroll; + } + else { + css[_strLeft] = _strAuto; + css[_strRight] = 0; + scrollLeftValue = _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll; + } + //execution order is important for IE!!! + _sizeObserverElement.children().eq(0).css(css); + _sizeObserverElement[_strScrollLeft](scrollLeftValue)[_strScrollTop](constScroll); + _cssDirectionDetectedCache = dir; + result = true; + } + return result; + }; + directionChanged(); + addDestroyEventListener(targetElement, _strScroll, function (event) { + if (directionChanged()) + update(); + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + return false; + }); + } + } + //remove resize observer: + else { + if (_supportResizeObserver) { + var element = targetElement.contents()[0]; + var resizeObserverObj = element[_strResizeObserverProperty]; + if (resizeObserverObj) { + resizeObserverObj.disconnect(); + delete element[_strResizeObserverProperty]; + } + } + else { + remove(targetElement.children(_strDot + _classNameResizeObserverElement).eq(0)); + } + } + } + } + + /** + * Freezes or unfreezes the given resize observer. + * @param targetElement The element to which the target resize observer is applied. + * @param freeze True if the resize observer shall be frozen, false otherwise. + + function freezeResizeObserver(targetElement, freeze) { + if (targetElement !== undefined) { + if(freeze) { + if (_supportResizeObserver) { + var element = targetElement.contents()[0]; + element[_strResizeObserverProperty].unobserve(element); + } + else { + targetElement = targetElement.children(_strDot + _classNameResizeObserverElement).eq(0); + var w = targetElement.css(_strWidth); + var h = targetElement.css(_strHeight); + var css = {}; + css[_strWidth] = w; + css[_strHeight] = h; + targetElement.css(css); + } + } + else { + if (_supportResizeObserver) { + var element = targetElement.contents()[0]; + element[_strResizeObserverProperty].observe(element); + } + else { + var css = { }; + css[_strHeight] = _strEmpty; + css[_strWidth] = _strEmpty; + targetElement.children(_strDot + _classNameResizeObserverElement).eq(0).css(css); + } + } + } + } + */ + + + //==== Mutation Observers ====// + + /** + * Creates MutationObservers for the host and content Element if they are supported. + */ + function createMutationObservers() { + if (_supportMutationObserver) { + var mutationObserverContentLag = 11; + var mutationObserver = COMPATIBILITY.mO(); + var contentLastUpdate = COMPATIBILITY.now(); + var mutationTarget; + var mutationAttrName; + var mutationIsClass; + var oldMutationVal; + var newClassVal; + var hostClassNameRegex; + var contentTimeout; + var now; + var sizeAuto; + var action; + + _mutationObserverHostCallback = function (mutations) { + + var doUpdate = false; + var doUpdateForce = false; + var mutation; + var mutatedAttrs = []; + + if (_initialized && !_sleeping) { + each(mutations, function () { + mutation = this; + mutationTarget = mutation.target; + mutationAttrName = mutation.attributeName; + mutationIsClass = mutationAttrName === LEXICON.c; + oldMutationVal = mutation.oldValue; + newClassVal = mutationTarget.className; + + if (_domExists && mutationIsClass && !doUpdateForce) { + // if old class value contains _classNameHostElementForeign and new class value doesn't + if (oldMutationVal.indexOf(_classNameHostElementForeign) > -1 && newClassVal.indexOf(_classNameHostElementForeign) < 0) { + hostClassNameRegex = createHostClassNameRegExp(true); + _hostElementNative.className = newClassVal.split(_strSpace).concat(oldMutationVal.split(_strSpace).filter(function (name) { + return name.match(hostClassNameRegex); + })).join(_strSpace); + doUpdate = doUpdateForce = true; + } + } + + if (!doUpdate) { + doUpdate = mutationIsClass + ? hostClassNamesChanged(oldMutationVal, newClassVal) + : mutationAttrName === LEXICON.s + ? oldMutationVal !== mutationTarget[LEXICON.s].cssText + : true; + } + + mutatedAttrs.push(mutationAttrName); + }); + + updateViewportAttrsFromTarget(mutatedAttrs); + + if (doUpdate) + _base.update(doUpdateForce || _strAuto); + } + return doUpdate; + }; + _mutationObserverContentCallback = function (mutations) { + var doUpdate = false; + var mutation; + + if (_initialized && !_sleeping) { + each(mutations, function () { + mutation = this; + doUpdate = isUnknownMutation(mutation); + return !doUpdate; + }); + + if (doUpdate) { + now = COMPATIBILITY.now(); + sizeAuto = (_heightAutoCache || _widthAutoCache); + action = function () { + if (!_destroyed) { + contentLastUpdate = now; + + //if cols, rows or wrap attr was changed + if (_isTextarea) + textareaUpdate(); + + if (sizeAuto) + update(); + else + _base.update(_strAuto); + } + }; + clearTimeout(contentTimeout); + if (mutationObserverContentLag <= 0 || now - contentLastUpdate > mutationObserverContentLag || !sizeAuto) + action(); + else + contentTimeout = setTimeout(action, mutationObserverContentLag); + } + } + return doUpdate; + } + + _mutationObserverHost = new mutationObserver(_mutationObserverHostCallback); + _mutationObserverContent = new mutationObserver(_mutationObserverContentCallback); + } + } + + /** + * Connects the MutationObservers if they are supported. + */ + function connectMutationObservers() { + if (_supportMutationObserver && !_mutationObserversConnected) { + _mutationObserverHost.observe(_hostElementNative, { + attributes: true, + attributeOldValue: true, + attributeFilter: _mutationObserverAttrsHost + }); + + _mutationObserverContent.observe(_isTextarea ? _targetElementNative : _contentElementNative, { + attributes: true, + attributeOldValue: true, + subtree: !_isTextarea, + childList: !_isTextarea, + characterData: !_isTextarea, + attributeFilter: _isTextarea ? _mutationObserverAttrsTextarea : _mutationObserverAttrsHost + }); + + _mutationObserversConnected = true; + } + } + + /** + * Disconnects the MutationObservers if they are supported. + */ + function disconnectMutationObservers() { + if (_supportMutationObserver && _mutationObserversConnected) { + _mutationObserverHost.disconnect(); + _mutationObserverContent.disconnect(); + + _mutationObserversConnected = false; + } + } + + + //==== Events of elements ====// + + /** + * This method gets called every time the host element gets resized. IMPORTANT: Padding changes are detected too!! + * It refreshes the hostResizedEventArgs and the hostSizeResizeCache. + * If there are any size changes, the update method gets called. + */ + function hostOnResized() { + if (!_sleeping) { + var changed; + var hostSize = { + w: _sizeObserverElementNative[LEXICON.sW], + h: _sizeObserverElementNative[LEXICON.sH] + }; + + changed = checkCache(hostSize, _hostElementSizeChangeDetectedCache); + _hostElementSizeChangeDetectedCache = hostSize; + if (changed) + update({ _hostSizeChanged: true }); + } + } + + /** + * The mouse enter event of the host element. This event is only needed for the autoHide feature. + */ + function hostOnMouseEnter() { + if (_scrollbarsAutoHideLeave) + refreshScrollbarsAutoHide(true); + } + + /** + * The mouse leave event of the host element. This event is only needed for the autoHide feature. + */ + function hostOnMouseLeave() { + if (_scrollbarsAutoHideLeave && !_bodyElement.hasClass(_classNameDragging)) + refreshScrollbarsAutoHide(false); + } + + /** + * The mouse move event of the host element. This event is only needed for the autoHide "move" feature. + */ + function hostOnMouseMove() { + if (_scrollbarsAutoHideMove) { + refreshScrollbarsAutoHide(true); + clearTimeout(_scrollbarsAutoHideMoveTimeoutId); + _scrollbarsAutoHideMoveTimeoutId = setTimeout(function () { + if (_scrollbarsAutoHideMove && !_destroyed) + refreshScrollbarsAutoHide(false); + }, 100); + } + } + + /** + * Prevents text from deselection if attached to the document element on the mousedown event of a DOM element. + * @param event The select start event. + */ + function documentOnSelectStart(event) { + COMPATIBILITY.prvD(event); + return false; + } + + /** + * A callback which will be called after a element has loaded. + */ + function updateOnLoadCallback(event) { + var elm = FRAMEWORK(event.target); + + eachUpdateOnLoad(function (i, updateOnLoadSelector) { + if (elm.is(updateOnLoadSelector)) { + update({ _contentSizeChanged: true }); + } + }); + } + + /** + * Adds or removes mouse & touch events of the host element. (for handling auto-hiding of the scrollbars) + * @param destroy Indicates whether the events shall be added or removed. + */ + function setupHostMouseTouchEvents(destroy) { + if (!destroy) + setupHostMouseTouchEvents(true); + + setupResponsiveEventListener(_hostElement, + _strMouseTouchMoveEvent.split(_strSpace)[0], + hostOnMouseMove, + (!_scrollbarsAutoHideMove || destroy), true); + setupResponsiveEventListener(_hostElement, + [_strMouseEnter, _strMouseLeave], + [hostOnMouseEnter, hostOnMouseLeave], + (!_scrollbarsAutoHideLeave || destroy), true); + + //if the plugin is initialized and the mouse is over the host element, make the scrollbars visible + if (!_initialized && !destroy) + _hostElement.one('mouseover', hostOnMouseEnter); + } + + + //==== Update Detection ====// + + /** + * Measures the min width and min height of the body element and refreshes the related cache. + * @returns {boolean} True if the min width or min height has changed, false otherwise. + */ + function bodyMinSizeChanged() { + var bodyMinSize = {}; + if (_isBody && _contentArrangeElement) { + bodyMinSize.w = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strWidth)); + bodyMinSize.h = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strHeight)); + bodyMinSize.c = checkCache(bodyMinSize, _bodyMinSizeCache); + bodyMinSize.f = true; //flag for "measured at least once" + } + _bodyMinSizeCache = bodyMinSize; + return !!bodyMinSize.c; + } + + /** + * Returns true if the class names really changed (new class without plugin host prefix) + * @param oldClassNames The old ClassName string or array. + * @param newClassNames The new ClassName string or array. + * @returns {boolean} True if the class names has really changed, false otherwise. + */ + function hostClassNamesChanged(oldClassNames, newClassNames) { + var currClasses = typeof newClassNames == TYPES.s ? newClassNames.split(_strSpace) : []; + var oldClasses = typeof oldClassNames == TYPES.s ? oldClassNames.split(_strSpace) : []; + var diff = getArrayDifferences(oldClasses, currClasses); + + // remove none theme from diff list to prevent update + var idx = inArray(_classNameThemeNone, diff); + var i; + var regex; + + if (idx > -1) + diff.splice(idx, 1); + + if (diff[LEXICON.l] > 0) { + regex = createHostClassNameRegExp(true, true); + for (i = 0; i < diff.length; i++) { + if (!diff[i].match(regex)) { + return true; + } + } + } + return false; + } + + /** + * Returns true if the given mutation is not from a from the plugin generated element. If the target element is a textarea the mutation is always unknown. + * @param mutation The mutation which shall be checked. + * @returns {boolean} True if the mutation is from a unknown element, false otherwise. + */ + function isUnknownMutation(mutation) { + var attributeName = mutation.attributeName; + var mutationTarget = mutation.target; + var mutationType = mutation.type; + var strClosest = 'closest'; + + if (mutationTarget === _contentElementNative) + return attributeName === null; + if (mutationType === 'attributes' && (attributeName === LEXICON.c || attributeName === LEXICON.s) && !_isTextarea) { + //ignore className changes by the plugin + if (attributeName === LEXICON.c && FRAMEWORK(mutationTarget).hasClass(_classNameHostElement)) + return hostClassNamesChanged(mutation.oldValue, mutationTarget.className); + + //only do it of browser support it natively + if (typeof mutationTarget[strClosest] != TYPES.f) + return true; + if (mutationTarget[strClosest](_strDot + _classNameResizeObserverElement) !== null || + mutationTarget[strClosest](_strDot + _classNameScrollbar) !== null || + mutationTarget[strClosest](_strDot + _classNameScrollbarCorner) !== null) + return false; + } + return true; + } + + /** + * Returns true if the content size was changed since the last time this method was called. + * @returns {boolean} True if the content size was changed, false otherwise. + */ + function updateAutoContentSizeChanged() { + if (_sleeping) + return false; + + var contentMeasureElement = getContentMeasureElement(); + var textareaValueLength = _isTextarea && _widthAutoCache && !_textareaAutoWrappingCache ? _targetElement.val().length : 0; + var setCSS = !_mutationObserversConnected && _widthAutoCache && !_isTextarea; + var css = {}; + var float; + var bodyMinSizeC; + var changed; + var contentElementScrollSize; + + if (setCSS) { + float = _contentElement.css(_strFloat); + css[_strFloat] = _isRTL ? _strRight : _strLeft; + css[_strWidth] = _strAuto; + _contentElement.css(css); + } + contentElementScrollSize = { + w: contentMeasureElement[LEXICON.sW] + textareaValueLength, + h: contentMeasureElement[LEXICON.sH] + textareaValueLength + }; + if (setCSS) { + css[_strFloat] = float; + css[_strWidth] = _strHundredPercent; + _contentElement.css(css); + } + + bodyMinSizeC = bodyMinSizeChanged(); + changed = checkCache(contentElementScrollSize, _contentElementScrollSizeChangeDetectedCache); + + _contentElementScrollSizeChangeDetectedCache = contentElementScrollSize; + + return changed || bodyMinSizeC; + } + + /** + * Returns true when a attribute which the MutationObserver would observe has changed. + * @returns {boolean} True if one of the attributes which a MutationObserver would observe has changed, false or undefined otherwise. + */ + function meaningfulAttrsChanged() { + if (_sleeping || _mutationObserversConnected) + return; + + var elem; + var curr; + var cache; + var changedAttrs = []; + var checks = [ + { + _elem: _hostElement, + _attrs: _mutationObserverAttrsHost.concat(':visible') + }, + { + _elem: _isTextarea ? _targetElement : undefined, + _attrs: _mutationObserverAttrsTextarea + } + ]; + + each(checks, function (index, check) { + elem = check._elem; + if (elem) { + each(check._attrs, function (index, attr) { + curr = attr.charAt(0) === ':' ? elem.is(attr) : elem.attr(attr); + cache = _updateAutoCache[attr]; + + if (checkCache(curr, cache)) { + changedAttrs.push(attr); + } + + _updateAutoCache[attr] = curr; + }); + } + }); + + updateViewportAttrsFromTarget(changedAttrs); + + return changedAttrs[LEXICON.l] > 0; + } + + /** + * Checks is a CSS Property of a child element is affecting the scroll size of the content. + * @param propertyName The CSS property name. + * @returns {boolean} True if the property is affecting the content scroll size, false otherwise. + */ + function isSizeAffectingCSSProperty(propertyName) { + if (!_initialized) + return true; + var flexGrow = 'flex-grow'; + var flexShrink = 'flex-shrink'; + var flexBasis = 'flex-basis'; + var affectingPropsX = [ + _strWidth, + _strMinMinus + _strWidth, + _strMaxMinus + _strWidth, + _strMarginMinus + _strLeft, + _strMarginMinus + _strRight, + _strLeft, + _strRight, + 'font-weight', + 'word-spacing', + flexGrow, + flexShrink, + flexBasis + ]; + var affectingPropsXContentBox = [ + _strPaddingMinus + _strLeft, + _strPaddingMinus + _strRight, + _strBorderMinus + _strLeft + _strWidth, + _strBorderMinus + _strRight + _strWidth + ]; + var affectingPropsY = [ + _strHeight, + _strMinMinus + _strHeight, + _strMaxMinus + _strHeight, + _strMarginMinus + _strTop, + _strMarginMinus + _strBottom, + _strTop, + _strBottom, + 'line-height', + flexGrow, + flexShrink, + flexBasis + ]; + var affectingPropsYContentBox = [ + _strPaddingMinus + _strTop, + _strPaddingMinus + _strBottom, + _strBorderMinus + _strTop + _strWidth, + _strBorderMinus + _strBottom + _strWidth + ]; + var _strS = 's'; + var _strVS = 'v-s'; + var checkX = _overflowBehaviorCache.x === _strS || _overflowBehaviorCache.x === _strVS; + var checkY = _overflowBehaviorCache.y === _strS || _overflowBehaviorCache.y === _strVS; + var sizeIsAffected = false; + var checkPropertyName = function (arr, name) { + for (var i = 0; i < arr[LEXICON.l]; i++) { + if (arr[i] === name) + return true; + } + return false; + }; + + if (checkY) { + sizeIsAffected = checkPropertyName(affectingPropsY, propertyName); + if (!sizeIsAffected && !_isBorderBox) + sizeIsAffected = checkPropertyName(affectingPropsYContentBox, propertyName); + } + if (checkX && !sizeIsAffected) { + sizeIsAffected = checkPropertyName(affectingPropsX, propertyName); + if (!sizeIsAffected && !_isBorderBox) + sizeIsAffected = checkPropertyName(affectingPropsXContentBox, propertyName); + } + return sizeIsAffected; + } + + + //==== Update ====// + + /** + * Sets the attribute values of the viewport element to the values from the target element. + * The value of a attribute is only set if the attribute is whitelisted. + * @attrs attrs The array of attributes which shall be set or undefined if all whitelisted shall be set. + */ + function updateViewportAttrsFromTarget(attrs) { + attrs = attrs || _viewportAttrsFromTarget; + each(attrs, function (index, attr) { + if (COMPATIBILITY.inA(attr, _viewportAttrsFromTarget) > -1) { + var targetAttr = _targetElement.attr(attr); + if (type(targetAttr) == TYPES.s) { + _viewportElement.attr(attr, targetAttr); + } + else { + _viewportElement.removeAttr(attr); + } + } + }); + } + + /** + * Updates the variables and size of the textarea element, and manages the scroll on new line or new character. + */ + function textareaUpdate() { + if (!_sleeping) { + var wrapAttrOff = !_textareaAutoWrappingCache; + var minWidth = _viewportSize.w; + var minHeight = _viewportSize.h; + var css = {}; + var doMeasure = _widthAutoCache || wrapAttrOff; + var origWidth; + var width; + var origHeight; + var height; + + //reset min size + css[_strMinMinus + _strWidth] = _strEmpty; + css[_strMinMinus + _strHeight] = _strEmpty; + + //set width auto + css[_strWidth] = _strAuto; + _targetElement.css(css); + + //measure width + origWidth = _targetElementNative[LEXICON.oW]; + width = doMeasure ? MATH.max(origWidth, _targetElementNative[LEXICON.sW] - 1) : 1; + /*width += (_widthAutoCache ? _marginX + (!_isBorderBox ? wrapAttrOff ? 0 : _paddingX + _borderX : 0) : 0);*/ + + //set measured width + css[_strWidth] = _widthAutoCache ? _strAuto /*width*/ : _strHundredPercent; + css[_strMinMinus + _strWidth] = _strHundredPercent; + + //set height auto + css[_strHeight] = _strAuto; + _targetElement.css(css); + + //measure height + origHeight = _targetElementNative[LEXICON.oH]; + height = MATH.max(origHeight, _targetElementNative[LEXICON.sH] - 1); + + //append correct size values + css[_strWidth] = width; + css[_strHeight] = height; + _textareaCoverElement.css(css); + + //apply min width / min height to prevent textarea collapsing + css[_strMinMinus + _strWidth] = minWidth /*+ (!_isBorderBox && _widthAutoCache ? _paddingX + _borderX : 0)*/; + css[_strMinMinus + _strHeight] = minHeight /*+ (!_isBorderBox && _heightAutoCache ? _paddingY + _borderY : 0)*/; + _targetElement.css(css); + + return { + _originalWidth: origWidth, + _originalHeight: origHeight, + _dynamicWidth: width, + _dynamicHeight: height + }; + } + } + + /** + * Updates the plugin and DOM to the current options. + * This method should only be called if a update is 100% required. + * @param updateHints A objects which contains hints for this update: + * { + * _hostSizeChanged : boolean, + * _contentSizeChanged : boolean, + * _force : boolean, == preventSwallowing + * _changedOptions : { }, == preventSwallowing && preventSleep + * } + */ + function update(updateHints) { + clearTimeout(_swallowedUpdateTimeout); + updateHints = updateHints || {}; + _swallowedUpdateHints._hostSizeChanged |= updateHints._hostSizeChanged; + _swallowedUpdateHints._contentSizeChanged |= updateHints._contentSizeChanged; + _swallowedUpdateHints._force |= updateHints._force; + + var now = COMPATIBILITY.now(); + var hostSizeChanged = !!_swallowedUpdateHints._hostSizeChanged; + var contentSizeChanged = !!_swallowedUpdateHints._contentSizeChanged; + var force = !!_swallowedUpdateHints._force; + var changedOptions = updateHints._changedOptions; + var swallow = _swallowUpdateLag > 0 && _initialized && !_destroyed && !force && !changedOptions && (now - _lastUpdateTime) < _swallowUpdateLag && (!_heightAutoCache && !_widthAutoCache); + var displayIsHidden; + + if (swallow) + _swallowedUpdateTimeout = setTimeout(update, _swallowUpdateLag); + + //abort update due to: + //destroyed + //swallowing + //sleeping + //host is hidden or has false display + if (_destroyed || swallow || (_sleeping && !changedOptions) || (_initialized && !force && (displayIsHidden = _hostElement.is(':hidden'))) || _hostElement.css('display') === 'inline') + return; + + _lastUpdateTime = now; + _swallowedUpdateHints = {}; + + //if scrollbar styling is possible and native scrollbars aren't overlaid the scrollbar styling will be applied which hides the native scrollbars completely. + if (_nativeScrollbarStyling && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) { + //native scrollbars are hidden, so change the values to zero + _nativeScrollbarSize.x = 0; + _nativeScrollbarSize.y = 0; + } + else { + //refresh native scrollbar size (in case of zoom) + _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize); + } + + // Scrollbar padding is needed for firefox, because firefox hides scrollbar automatically if the size of the div is too small. + // The calculation: [scrollbar size +3 *3] + // (+3 because of possible decoration e.g. borders, margins etc., but only if native scrollbar is NOT a overlaid scrollbar) + // (*3 because (1)increase / (2)decrease -button and (3)resize handle) + _nativeScrollbarMinSize = { + x: (_nativeScrollbarSize.x + (_nativeScrollbarIsOverlaid.x ? 0 : 3)) * 3, + y: (_nativeScrollbarSize.y + (_nativeScrollbarIsOverlaid.y ? 0 : 3)) * 3 + }; + + changedOptions = changedOptions || {}; + //freezeResizeObserver(_sizeObserverElement, true); + //freezeResizeObserver(_sizeAutoObserverElement, true); + + var checkCacheAutoForce = function () { + return checkCache.apply(this, [].slice.call(arguments).concat([force])); + }; + + //save current scroll offset + var currScroll = { + x: _viewportElement[_strScrollLeft](), + y: _viewportElement[_strScrollTop]() + }; + + var currentPreparedOptionsScrollbars = _currentPreparedOptions.scrollbars; + var currentPreparedOptionsTextarea = _currentPreparedOptions.textarea; + + //scrollbars visibility: + var scrollbarsVisibility = currentPreparedOptionsScrollbars.visibility; + var scrollbarsVisibilityChanged = checkCacheAutoForce(scrollbarsVisibility, _scrollbarsVisibilityCache); + + //scrollbars autoHide: + var scrollbarsAutoHide = currentPreparedOptionsScrollbars.autoHide; + var scrollbarsAutoHideChanged = checkCacheAutoForce(scrollbarsAutoHide, _scrollbarsAutoHideCache); + + //scrollbars click scrolling + var scrollbarsClickScrolling = currentPreparedOptionsScrollbars.clickScrolling; + var scrollbarsClickScrollingChanged = checkCacheAutoForce(scrollbarsClickScrolling, _scrollbarsClickScrollingCache); + + //scrollbars drag scrolling + var scrollbarsDragScrolling = currentPreparedOptionsScrollbars.dragScrolling; + var scrollbarsDragScrollingChanged = checkCacheAutoForce(scrollbarsDragScrolling, _scrollbarsDragScrollingCache); + + //className + var className = _currentPreparedOptions.className; + var classNameChanged = checkCacheAutoForce(className, _classNameCache); + + //resize + var resize = _currentPreparedOptions.resize; + var resizeChanged = checkCacheAutoForce(resize, _resizeCache) && !_isBody; //body can't be resized since the window itself acts as resize possibility. + + //paddingAbsolute + var paddingAbsolute = _currentPreparedOptions.paddingAbsolute; + var paddingAbsoluteChanged = checkCacheAutoForce(paddingAbsolute, _paddingAbsoluteCache); + + //clipAlways + var clipAlways = _currentPreparedOptions.clipAlways; + var clipAlwaysChanged = checkCacheAutoForce(clipAlways, _clipAlwaysCache); + + //sizeAutoCapable + var sizeAutoCapable = _currentPreparedOptions.sizeAutoCapable && !_isBody; //body can never be size auto, because it shall be always as big as the viewport. + var sizeAutoCapableChanged = checkCacheAutoForce(sizeAutoCapable, _sizeAutoCapableCache); + + //showNativeScrollbars + var ignoreOverlayScrollbarHiding = _currentPreparedOptions.nativeScrollbarsOverlaid.showNativeScrollbars; + var ignoreOverlayScrollbarHidingChanged = checkCacheAutoForce(ignoreOverlayScrollbarHiding, _ignoreOverlayScrollbarHidingCache); + + //autoUpdate + var autoUpdate = _currentPreparedOptions.autoUpdate; + var autoUpdateChanged = checkCacheAutoForce(autoUpdate, _autoUpdateCache); + + //overflowBehavior + var overflowBehavior = _currentPreparedOptions.overflowBehavior; + var overflowBehaviorChanged = checkCacheAutoForce(overflowBehavior, _overflowBehaviorCache, force); + + //dynWidth: + var textareaDynWidth = currentPreparedOptionsTextarea.dynWidth; + var textareaDynWidthChanged = checkCacheAutoForce(_textareaDynWidthCache, textareaDynWidth); + + //dynHeight: + var textareaDynHeight = currentPreparedOptionsTextarea.dynHeight; + var textareaDynHeightChanged = checkCacheAutoForce(_textareaDynHeightCache, textareaDynHeight); + + //scrollbars visibility + _scrollbarsAutoHideNever = scrollbarsAutoHide === 'n'; + _scrollbarsAutoHideScroll = scrollbarsAutoHide === 's'; + _scrollbarsAutoHideMove = scrollbarsAutoHide === 'm'; + _scrollbarsAutoHideLeave = scrollbarsAutoHide === 'l'; + + //scrollbars autoHideDelay + _scrollbarsAutoHideDelay = currentPreparedOptionsScrollbars.autoHideDelay; + + //old className + _oldClassName = _classNameCache; + + //resize + _resizeNone = resize === 'n'; + _resizeBoth = resize === 'b'; + _resizeHorizontal = resize === 'h'; + _resizeVertical = resize === 'v'; + + //normalizeRTL + _normalizeRTLCache = _currentPreparedOptions.normalizeRTL; + + //ignore overlay scrollbar hiding + ignoreOverlayScrollbarHiding = ignoreOverlayScrollbarHiding && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y); + + //refresh options cache + _scrollbarsVisibilityCache = scrollbarsVisibility; + _scrollbarsAutoHideCache = scrollbarsAutoHide; + _scrollbarsClickScrollingCache = scrollbarsClickScrolling; + _scrollbarsDragScrollingCache = scrollbarsDragScrolling; + _classNameCache = className; + _resizeCache = resize; + _paddingAbsoluteCache = paddingAbsolute; + _clipAlwaysCache = clipAlways; + _sizeAutoCapableCache = sizeAutoCapable; + _ignoreOverlayScrollbarHidingCache = ignoreOverlayScrollbarHiding; + _autoUpdateCache = autoUpdate; + _overflowBehaviorCache = extendDeep({}, overflowBehavior); + _textareaDynWidthCache = textareaDynWidth; + _textareaDynHeightCache = textareaDynHeight; + _hasOverflowCache = _hasOverflowCache || { x: false, y: false }; + + //set correct class name to the host element + if (classNameChanged) { + removeClass(_hostElement, _oldClassName + _strSpace + _classNameThemeNone); + addClass(_hostElement, className !== undefined && className !== null && className.length > 0 ? className : _classNameThemeNone); + } + + //set correct auto Update + if (autoUpdateChanged) { + if (autoUpdate === true || (autoUpdate === null && _autoUpdateRecommended)) { + disconnectMutationObservers(); + autoUpdateLoop.add(_base); + } + else { + autoUpdateLoop.remove(_base); + connectMutationObservers(); + } + } + + //activate or deactivate size auto capability + if (sizeAutoCapableChanged) { + if (sizeAutoCapable) { + if (_contentGlueElement) { + _contentGlueElement.show(); + } + else { + _contentGlueElement = FRAMEWORK(generateDiv(_classNameContentGlueElement)); + _paddingElement.before(_contentGlueElement); + } + if (_sizeAutoObserverAdded) { + _sizeAutoObserverElement.show(); + } + else { + _sizeAutoObserverElement = FRAMEWORK(generateDiv(_classNameSizeAutoObserverElement)); + _sizeAutoObserverElementNative = _sizeAutoObserverElement[0]; + + _contentGlueElement.before(_sizeAutoObserverElement); + var oldSize = { w: -1, h: -1 }; + setupResizeObserver(_sizeAutoObserverElement, function () { + var newSize = { + w: _sizeAutoObserverElementNative[LEXICON.oW], + h: _sizeAutoObserverElementNative[LEXICON.oH] + }; + if (checkCache(newSize, oldSize)) { + if (_initialized && (_heightAutoCache && newSize.h > 0) || (_widthAutoCache && newSize.w > 0)) { + update(); + } + else if (_initialized && (!_heightAutoCache && newSize.h === 0) || (!_widthAutoCache && newSize.w === 0)) { + update(); + } + } + oldSize = newSize; + }); + _sizeAutoObserverAdded = true; + //fix heightAuto detector bug if height is fixed but contentHeight is 0. + //the probability this bug will ever happen is very very low, thats why its ok if we use calc which isn't supported in IE8. + if (_cssCalc !== null) + _sizeAutoObserverElement.css(_strHeight, _cssCalc + '(100% + 1px)'); + } + } + else { + if (_sizeAutoObserverAdded) + _sizeAutoObserverElement.hide(); + if (_contentGlueElement) + _contentGlueElement.hide(); + } + } + + //if force, update all resizeObservers too + if (force) { + _sizeObserverElement.find('*').trigger(_strScroll); + if (_sizeAutoObserverAdded) + _sizeAutoObserverElement.find('*').trigger(_strScroll); + } + + //display hidden: + displayIsHidden = displayIsHidden === undefined ? _hostElement.is(':hidden') : displayIsHidden; + + //textarea AutoWrapping: + var textareaAutoWrapping = _isTextarea ? _targetElement.attr('wrap') !== 'off' : false; + var textareaAutoWrappingChanged = checkCacheAutoForce(textareaAutoWrapping, _textareaAutoWrappingCache); + + //detect direction: + var cssDirection = _hostElement.css('direction'); + var cssDirectionChanged = checkCacheAutoForce(cssDirection, _cssDirectionCache); + + //detect box-sizing: + var boxSizing = _hostElement.css('box-sizing'); + var boxSizingChanged = checkCacheAutoForce(boxSizing, _cssBoxSizingCache); + + //detect padding: + var padding = getTopRightBottomLeftHost(_strPaddingMinus); + + //width + height auto detecting var: + var sizeAutoObserverElementBCRect; + //exception occurs in IE8 sometimes (unknown exception) + try { + sizeAutoObserverElementBCRect = _sizeAutoObserverAdded ? _sizeAutoObserverElementNative[LEXICON.bCR]() : null; + } catch (ex) { + return; + } + + _isRTL = cssDirection === 'rtl'; + _isBorderBox = (boxSizing === 'border-box'); + var isRTLLeft = _isRTL ? _strLeft : _strRight; + var isRTLRight = _isRTL ? _strRight : _strLeft; + + //detect width auto: + var widthAutoResizeDetection = false; + var widthAutoObserverDetection = (_sizeAutoObserverAdded && (_hostElement.css(_strFloat) !== 'none' /*|| _isTextarea */)) ? (MATH.round(sizeAutoObserverElementBCRect.right - sizeAutoObserverElementBCRect.left) === 0) && (!paddingAbsolute ? (_hostElementNative[LEXICON.cW] - _paddingX) > 0 : true) : false; + if (sizeAutoCapable && !widthAutoObserverDetection) { + var tmpCurrHostWidth = _hostElementNative[LEXICON.oW]; + var tmpCurrContentGlueWidth = _contentGlueElement.css(_strWidth); + _contentGlueElement.css(_strWidth, _strAuto); + + var tmpNewHostWidth = _hostElementNative[LEXICON.oW]; + _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth); + widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth; + if (!widthAutoResizeDetection) { + _contentGlueElement.css(_strWidth, tmpCurrHostWidth + 1); + tmpNewHostWidth = _hostElementNative[LEXICON.oW]; + _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth); + widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth; + } + } + var widthAuto = (widthAutoObserverDetection || widthAutoResizeDetection) && sizeAutoCapable && !displayIsHidden; + var widthAutoChanged = checkCacheAutoForce(widthAuto, _widthAutoCache); + var wasWidthAuto = !widthAuto && _widthAutoCache; + + //detect height auto: + var heightAuto = _sizeAutoObserverAdded && sizeAutoCapable && !displayIsHidden ? (MATH.round(sizeAutoObserverElementBCRect.bottom - sizeAutoObserverElementBCRect.top) === 0) /* && (!paddingAbsolute && (_msieVersion > 9 || !_msieVersion) ? true : true) */ : false; + var heightAutoChanged = checkCacheAutoForce(heightAuto, _heightAutoCache); + var wasHeightAuto = !heightAuto && _heightAutoCache; + + //detect border: + //we need the border only if border box and auto size + var updateBorderX = (widthAuto && _isBorderBox) || !_isBorderBox; + var updateBorderY = (heightAuto && _isBorderBox) || !_isBorderBox; + var border = getTopRightBottomLeftHost(_strBorderMinus, '-' + _strWidth, !updateBorderX, !updateBorderY) + + //detect margin: + var margin = getTopRightBottomLeftHost(_strMarginMinus); + + //vars to apply correct css + var contentElementCSS = {}; + var contentGlueElementCSS = {}; + + //funcs + var getHostSize = function () { + //has to be clientSize because offsetSize respect borders + return { + w: _hostElementNative[LEXICON.cW], + h: _hostElementNative[LEXICON.cH] + }; + }; + var getViewportSize = function () { + //viewport size is padding container because it never has padding, margin and a border + //determine zoom rounding error -> sometimes scrollWidth/Height is smaller than clientWidth/Height + //if this happens add the difference to the viewportSize to compensate the rounding error + return { + w: _paddingElementNative[LEXICON.oW] + MATH.max(0, _contentElementNative[LEXICON.cW] - _contentElementNative[LEXICON.sW]), + h: _paddingElementNative[LEXICON.oH] + MATH.max(0, _contentElementNative[LEXICON.cH] - _contentElementNative[LEXICON.sH]) + }; + }; + + //set info for padding + var paddingAbsoluteX = _paddingX = padding.l + padding.r; + var paddingAbsoluteY = _paddingY = padding.t + padding.b; + paddingAbsoluteX *= paddingAbsolute ? 1 : 0; + paddingAbsoluteY *= paddingAbsolute ? 1 : 0; + padding.c = checkCacheAutoForce(padding, _cssPaddingCache); + + //set info for border + _borderX = border.l + border.r; + _borderY = border.t + border.b; + border.c = checkCacheAutoForce(border, _cssBorderCache); + + //set info for margin + _marginX = margin.l + margin.r; + _marginY = margin.t + margin.b; + margin.c = checkCacheAutoForce(margin, _cssMarginCache); + + //refresh cache + _textareaAutoWrappingCache = textareaAutoWrapping; + _cssDirectionCache = cssDirection; + _cssBoxSizingCache = boxSizing; + _widthAutoCache = widthAuto; + _heightAutoCache = heightAuto; + _cssPaddingCache = padding; + _cssBorderCache = border; + _cssMarginCache = margin; + + //IEFix direction changed + if (cssDirectionChanged && _sizeAutoObserverAdded) + _sizeAutoObserverElement.css(_strFloat, isRTLRight); + + //apply padding: + if (padding.c || cssDirectionChanged || paddingAbsoluteChanged || widthAutoChanged || heightAutoChanged || boxSizingChanged || sizeAutoCapableChanged) { + var paddingElementCSS = {}; + var textareaCSS = {}; + var paddingValues = [padding.t, padding.r, padding.b, padding.l]; + + setTopRightBottomLeft(contentGlueElementCSS, _strMarginMinus, [-padding.t, -padding.r, -padding.b, -padding.l]); + if (paddingAbsolute) { + setTopRightBottomLeft(paddingElementCSS, _strEmpty, paddingValues); + setTopRightBottomLeft(_isTextarea ? textareaCSS : contentElementCSS, _strPaddingMinus); + } + else { + setTopRightBottomLeft(paddingElementCSS, _strEmpty); + setTopRightBottomLeft(_isTextarea ? textareaCSS : contentElementCSS, _strPaddingMinus, paddingValues); + } + + _paddingElement.css(paddingElementCSS); + _targetElement.css(textareaCSS); + } + + //viewport size is padding container because it never has padding, margin and a border. + _viewportSize = getViewportSize(); + + //update Textarea + var textareaSize = _isTextarea ? textareaUpdate() : false; + var textareaSizeChanged = _isTextarea && checkCacheAutoForce(textareaSize, _textareaSizeCache); + var textareaDynOrigSize = _isTextarea && textareaSize ? { + w: textareaDynWidth ? textareaSize._dynamicWidth : textareaSize._originalWidth, + h: textareaDynHeight ? textareaSize._dynamicHeight : textareaSize._originalHeight + } : {}; + _textareaSizeCache = textareaSize; + + //fix height auto / width auto in cooperation with current padding & boxSizing behavior: + if (heightAuto && (heightAutoChanged || paddingAbsoluteChanged || boxSizingChanged || padding.c || border.c)) { + contentElementCSS[_strHeight] = _strAuto; + } + else if (heightAutoChanged || paddingAbsoluteChanged) { + contentElementCSS[_strHeight] = _strHundredPercent; + } + if (widthAuto && (widthAutoChanged || paddingAbsoluteChanged || boxSizingChanged || padding.c || border.c || cssDirectionChanged)) { + contentElementCSS[_strWidth] = _strAuto; + contentGlueElementCSS[_strMaxMinus + _strWidth] = _strHundredPercent; //IE Fix + } + else if (widthAutoChanged || paddingAbsoluteChanged) { + contentElementCSS[_strWidth] = _strHundredPercent; + contentElementCSS[_strFloat] = _strEmpty; + contentGlueElementCSS[_strMaxMinus + _strWidth] = _strEmpty; //IE Fix + } + if (widthAuto) { + //textareaDynOrigSize.w || _strAuto :: doesnt works because applied margin will shift width + contentGlueElementCSS[_strWidth] = _strAuto; + + contentElementCSS[_strWidth] = VENDORS._cssPropertyValue(_strWidth, 'max-content intrinsic') || _strAuto; + contentElementCSS[_strFloat] = isRTLRight; + } + else { + contentGlueElementCSS[_strWidth] = _strEmpty; + } + if (heightAuto) { + //textareaDynOrigSize.h || _contentElementNative[LEXICON.cH] :: use for anti scroll jumping + contentGlueElementCSS[_strHeight] = textareaDynOrigSize.h || _contentElementNative[LEXICON.cH]; + } + else { + contentGlueElementCSS[_strHeight] = _strEmpty; + } + if (sizeAutoCapable) + _contentGlueElement.css(contentGlueElementCSS); + _contentElement.css(contentElementCSS); + + //CHECKPOINT HERE ~ + contentElementCSS = {}; + contentGlueElementCSS = {}; + + //if [content(host) client / scroll size, or target element direction, or content(host) max-sizes] changed, or force is true + if (hostSizeChanged || contentSizeChanged || textareaSizeChanged || cssDirectionChanged || boxSizingChanged || paddingAbsoluteChanged || widthAutoChanged || widthAuto || heightAutoChanged || heightAuto || ignoreOverlayScrollbarHidingChanged || overflowBehaviorChanged || clipAlwaysChanged || resizeChanged || scrollbarsVisibilityChanged || scrollbarsAutoHideChanged || scrollbarsDragScrollingChanged || scrollbarsClickScrollingChanged || textareaDynWidthChanged || textareaDynHeightChanged || textareaAutoWrappingChanged) { + var strOverflow = 'overflow'; + var strOverflowX = strOverflow + '-x'; + var strOverflowY = strOverflow + '-y'; + var strHidden = 'hidden'; + var strVisible = 'visible'; + + //Reset the viewport (very important for natively overlaid scrollbars and zoom change + //don't change the overflow prop as it is very expensive and affects performance !A LOT! + if (!_nativeScrollbarStyling) { + var viewportElementResetCSS = {}; + var resetXTmp = _hasOverflowCache.y && _hideOverflowCache.ys && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.y ? _viewportElement.css(isRTLLeft) : -_nativeScrollbarSize.y) : 0; + var resetBottomTmp = _hasOverflowCache.x && _hideOverflowCache.xs && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.x ? _viewportElement.css(_strBottom) : -_nativeScrollbarSize.x) : 0; + setTopRightBottomLeft(viewportElementResetCSS, _strEmpty); + _viewportElement.css(viewportElementResetCSS); + } + + //measure several sizes: + var contentMeasureElement = getContentMeasureElement(); + //in Firefox content element has to have overflow hidden, else element margins aren't calculated properly, this element prevents this bug, but only if scrollbars aren't overlaid + var contentSize = { + //use clientSize because natively overlaidScrollbars add borders + w: textareaDynOrigSize.w || contentMeasureElement[LEXICON.cW], + h: textareaDynOrigSize.h || contentMeasureElement[LEXICON.cH] + }; + var scrollSize = { + w: contentMeasureElement[LEXICON.sW], + h: contentMeasureElement[LEXICON.sH] + }; + + //apply the correct viewport style and measure viewport size + if (!_nativeScrollbarStyling) { + viewportElementResetCSS[_strBottom] = wasHeightAuto ? _strEmpty : resetBottomTmp; + viewportElementResetCSS[isRTLLeft] = wasWidthAuto ? _strEmpty : resetXTmp; + _viewportElement.css(viewportElementResetCSS); + } + _viewportSize = getViewportSize(); + + //measure and correct several sizes + var hostSize = getHostSize(); + var hostAbsoluteRectSize = { + w: hostSize.w - _marginX - _borderX - (_isBorderBox ? 0 : _paddingX), + h: hostSize.h - _marginY - _borderY - (_isBorderBox ? 0 : _paddingY) + }; + var contentGlueSize = { + //client/scrollSize + AbsolutePadding -> because padding is only applied to the paddingElement if its absolute, so you have to add it manually + //hostSize is clientSize -> so padding should be added manually, right? FALSE! Because content glue is inside hostElement, so we don't have to worry about padding + w: MATH.max((widthAuto ? contentSize.w : scrollSize.w) + paddingAbsoluteX, hostAbsoluteRectSize.w), + h: MATH.max((heightAuto ? contentSize.h : scrollSize.h) + paddingAbsoluteY, hostAbsoluteRectSize.h) + }; + contentGlueSize.c = checkCacheAutoForce(contentGlueSize, _contentGlueSizeCache); + _contentGlueSizeCache = contentGlueSize; + + //apply correct contentGlue size + if (sizeAutoCapable) { + //size contentGlue correctly to make sure the element has correct size if the sizing switches to auto + if (contentGlueSize.c || (heightAuto || widthAuto)) { + contentGlueElementCSS[_strWidth] = contentGlueSize.w; + contentGlueElementCSS[_strHeight] = contentGlueSize.h; + + //textarea-sizes are already calculated correctly at this point + if (!_isTextarea) { + contentSize = { + //use clientSize because natively overlaidScrollbars add borders + w: contentMeasureElement[LEXICON.cW], + h: contentMeasureElement[LEXICON.cH] + }; + } + } + var textareaCoverCSS = {}; + var setContentGlueElementCSSfunction = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var wh = scrollbarVars._w_h; + var strWH = scrollbarVars._width_height; + var autoSize = horizontal ? widthAuto : heightAuto; + var borderSize = horizontal ? _borderX : _borderY; + var paddingSize = horizontal ? _paddingX : _paddingY; + var marginSize = horizontal ? _marginX : _marginY; + var viewportSize = _viewportSize[wh] - borderSize - marginSize - (_isBorderBox ? 0 : paddingSize); + + //make contentGlue size -1 if element is not auto sized, to make sure that a resize event happens when the element shrinks + if (!autoSize || (!autoSize && border.c)) + contentGlueElementCSS[strWH] = hostAbsoluteRectSize[wh] - 1; + + //if size is auto and host is smaller than size as min size, make content glue size -1 to make sure size changes will be detected (this is only needed if padding is 0) + if (autoSize && (contentSize[wh] < viewportSize) && (horizontal && _isTextarea ? !textareaAutoWrapping : true)) { + if (_isTextarea) + textareaCoverCSS[strWH] = parseToZeroOrNumber(_textareaCoverElement.css(strWH)) - 1; + contentGlueElementCSS[strWH] -= 1; + } + + //make sure content glue size is at least 1 + if (contentSize[wh] > 0) + contentGlueElementCSS[strWH] = MATH.max(1, contentGlueElementCSS[strWH]); + }; + setContentGlueElementCSSfunction(true); + setContentGlueElementCSSfunction(false); + + if (_isTextarea) + _textareaCoverElement.css(textareaCoverCSS); + _contentGlueElement.css(contentGlueElementCSS); + } + if (widthAuto) + contentElementCSS[_strWidth] = _strHundredPercent; + if (widthAuto && !_isBorderBox && !_mutationObserversConnected) + contentElementCSS[_strFloat] = 'none'; + + //apply and reset content style + _contentElement.css(contentElementCSS); + contentElementCSS = {}; + + //measure again, but this time all correct sizes: + var contentScrollSize = { + w: contentMeasureElement[LEXICON.sW], + h: contentMeasureElement[LEXICON.sH], + }; + contentScrollSize.c = contentSizeChanged = checkCacheAutoForce(contentScrollSize, _contentScrollSizeCache); + _contentScrollSizeCache = contentScrollSize; + + //refresh viewport size after correct measuring + _viewportSize = getViewportSize(); + + hostSize = getHostSize(); + hostSizeChanged = checkCacheAutoForce(hostSize, _hostSizeCache); + _hostSizeCache = hostSize; + + var hideOverflowForceTextarea = _isTextarea && (_viewportSize.w === 0 || _viewportSize.h === 0); + var previousOverflowAmount = _overflowAmountCache; + var overflowBehaviorIsVS = {}; + var overflowBehaviorIsVH = {}; + var overflowBehaviorIsS = {}; + var overflowAmount = {}; + var hasOverflow = {}; + var hideOverflow = {}; + var canScroll = {}; + var viewportRect = _paddingElementNative[LEXICON.bCR](); + var setOverflowVariables = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var scrollbarVarsInverted = getScrollbarVars(!horizontal); + var xyI = scrollbarVarsInverted._x_y; + var xy = scrollbarVars._x_y; + var wh = scrollbarVars._w_h; + var widthHeight = scrollbarVars._width_height; + var scrollMax = _strScroll + scrollbarVars._Left_Top + 'Max'; + var fractionalOverflowAmount = viewportRect[widthHeight] ? MATH.abs(viewportRect[widthHeight] - _viewportSize[wh]) : 0; + var checkFractionalOverflowAmount = previousOverflowAmount && previousOverflowAmount[xy] > 0 && _viewportElementNative[scrollMax] === 0; + overflowBehaviorIsVS[xy] = overflowBehavior[xy] === 'v-s'; + overflowBehaviorIsVH[xy] = overflowBehavior[xy] === 'v-h'; + overflowBehaviorIsS[xy] = overflowBehavior[xy] === 's'; + overflowAmount[xy] = MATH.max(0, MATH.round((contentScrollSize[wh] - _viewportSize[wh]) * 100) / 100); + overflowAmount[xy] *= (hideOverflowForceTextarea || (checkFractionalOverflowAmount && fractionalOverflowAmount > 0 && fractionalOverflowAmount < 1)) ? 0 : 1; + hasOverflow[xy] = overflowAmount[xy] > 0; + + //hideOverflow: + //x || y : true === overflow is hidden by "overflow: scroll" OR "overflow: hidden" + //xs || ys : true === overflow is hidden by "overflow: scroll" + hideOverflow[xy] = overflowBehaviorIsVS[xy] || overflowBehaviorIsVH[xy] ? (hasOverflow[xyI] && !overflowBehaviorIsVS[xyI] && !overflowBehaviorIsVH[xyI]) : hasOverflow[xy]; + hideOverflow[xy + 's'] = hideOverflow[xy] ? (overflowBehaviorIsS[xy] || overflowBehaviorIsVS[xy]) : false; + + canScroll[xy] = hasOverflow[xy] && hideOverflow[xy + 's']; + }; + setOverflowVariables(true); + setOverflowVariables(false); + + overflowAmount.c = checkCacheAutoForce(overflowAmount, _overflowAmountCache); + _overflowAmountCache = overflowAmount; + hasOverflow.c = checkCacheAutoForce(hasOverflow, _hasOverflowCache); + _hasOverflowCache = hasOverflow; + hideOverflow.c = checkCacheAutoForce(hideOverflow, _hideOverflowCache); + _hideOverflowCache = hideOverflow; + + //if native scrollbar is overlay at x OR y axis, prepare DOM + if (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y) { + var borderDesign = 'px solid transparent'; + var contentArrangeElementCSS = {}; + var arrangeContent = {}; + var arrangeChanged = force; + var setContentElementCSS; + + if (hasOverflow.x || hasOverflow.y) { + arrangeContent.w = _nativeScrollbarIsOverlaid.y && hasOverflow.y ? contentScrollSize.w + _overlayScrollbarDummySize.y : _strEmpty; + arrangeContent.h = _nativeScrollbarIsOverlaid.x && hasOverflow.x ? contentScrollSize.h + _overlayScrollbarDummySize.x : _strEmpty; + arrangeChanged = checkCacheAutoForce(arrangeContent, _arrangeContentSizeCache); + _arrangeContentSizeCache = arrangeContent; + } + + if (hasOverflow.c || hideOverflow.c || contentScrollSize.c || cssDirectionChanged || widthAutoChanged || heightAutoChanged || widthAuto || heightAuto || ignoreOverlayScrollbarHidingChanged) { + contentElementCSS[_strMarginMinus + isRTLRight] = contentElementCSS[_strBorderMinus + isRTLRight] = _strEmpty; + setContentElementCSS = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var scrollbarVarsInverted = getScrollbarVars(!horizontal); + var xy = scrollbarVars._x_y; + var strDirection = horizontal ? _strBottom : isRTLLeft; + var invertedAutoSize = horizontal ? heightAuto : widthAuto; + + if (_nativeScrollbarIsOverlaid[xy] && hasOverflow[xy] && hideOverflow[xy + 's']) { + contentElementCSS[_strMarginMinus + strDirection] = invertedAutoSize ? (ignoreOverlayScrollbarHiding ? _strEmpty : _overlayScrollbarDummySize[xy]) : _strEmpty; + contentElementCSS[_strBorderMinus + strDirection] = ((horizontal ? !invertedAutoSize : true) && !ignoreOverlayScrollbarHiding) ? (_overlayScrollbarDummySize[xy] + borderDesign) : _strEmpty; + } + else { + arrangeContent[scrollbarVarsInverted._w_h] = + contentElementCSS[_strMarginMinus + strDirection] = + contentElementCSS[_strBorderMinus + strDirection] = _strEmpty; + arrangeChanged = true; + } + }; + + if (_nativeScrollbarStyling) { + addRemoveClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible, !ignoreOverlayScrollbarHiding) + } + else { + setContentElementCSS(true); + setContentElementCSS(false); + } + } + if (ignoreOverlayScrollbarHiding) { + arrangeContent.w = arrangeContent.h = _strEmpty; + arrangeChanged = true; + } + if (arrangeChanged && !_nativeScrollbarStyling) { + contentArrangeElementCSS[_strWidth] = hideOverflow.y ? arrangeContent.w : _strEmpty; + contentArrangeElementCSS[_strHeight] = hideOverflow.x ? arrangeContent.h : _strEmpty; + + if (!_contentArrangeElement) { + _contentArrangeElement = FRAMEWORK(generateDiv(_classNameContentArrangeElement)); + _viewportElement.prepend(_contentArrangeElement); + } + _contentArrangeElement.css(contentArrangeElementCSS); + } + _contentElement.css(contentElementCSS); + } + + var viewportElementCSS = {}; + var paddingElementCSS = {}; + var setViewportCSS; + if (hostSizeChanged || hasOverflow.c || hideOverflow.c || contentScrollSize.c || overflowBehaviorChanged || boxSizingChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged || clipAlwaysChanged || heightAutoChanged) { + viewportElementCSS[isRTLRight] = _strEmpty; + setViewportCSS = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var scrollbarVarsInverted = getScrollbarVars(!horizontal); + var xy = scrollbarVars._x_y; + var XY = scrollbarVars._X_Y; + var strDirection = horizontal ? _strBottom : isRTLLeft; + + var reset = function () { + viewportElementCSS[strDirection] = _strEmpty; + _contentBorderSize[scrollbarVarsInverted._w_h] = 0; + }; + if (hasOverflow[xy] && hideOverflow[xy + 's']) { + viewportElementCSS[strOverflow + XY] = _strScroll; + if (ignoreOverlayScrollbarHiding || _nativeScrollbarStyling) { + reset(); + } + else { + viewportElementCSS[strDirection] = -(_nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[xy] : _nativeScrollbarSize[xy]); + _contentBorderSize[scrollbarVarsInverted._w_h] = _nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[scrollbarVarsInverted._x_y] : 0; + } + } else { + viewportElementCSS[strOverflow + XY] = _strEmpty; + reset(); + } + }; + setViewportCSS(true); + setViewportCSS(false); + + // if the scroll container is too small and if there is any overflow with no overlay scrollbar (and scrollbar styling isn't possible), + // make viewport element greater in size (Firefox hide Scrollbars fix) + // because firefox starts hiding scrollbars on too small elements + // with this behavior the overflow calculation may be incorrect or the scrollbars would appear suddenly + // https://bugzilla.mozilla.org/show_bug.cgi?id=292284 + if (!_nativeScrollbarStyling + && (_viewportSize.h < _nativeScrollbarMinSize.x || _viewportSize.w < _nativeScrollbarMinSize.y) + && ((hasOverflow.x && hideOverflow.x && !_nativeScrollbarIsOverlaid.x) || (hasOverflow.y && hideOverflow.y && !_nativeScrollbarIsOverlaid.y))) { + viewportElementCSS[_strPaddingMinus + _strTop] = _nativeScrollbarMinSize.x; + viewportElementCSS[_strMarginMinus + _strTop] = -_nativeScrollbarMinSize.x; + + viewportElementCSS[_strPaddingMinus + isRTLRight] = _nativeScrollbarMinSize.y; + viewportElementCSS[_strMarginMinus + isRTLRight] = -_nativeScrollbarMinSize.y; + } + else { + viewportElementCSS[_strPaddingMinus + _strTop] = + viewportElementCSS[_strMarginMinus + _strTop] = + viewportElementCSS[_strPaddingMinus + isRTLRight] = + viewportElementCSS[_strMarginMinus + isRTLRight] = _strEmpty; + } + viewportElementCSS[_strPaddingMinus + isRTLLeft] = + viewportElementCSS[_strMarginMinus + isRTLLeft] = _strEmpty; + + //if there is any overflow (x OR y axis) and this overflow shall be hidden, make overflow hidden, else overflow visible + if ((hasOverflow.x && hideOverflow.x) || (hasOverflow.y && hideOverflow.y) || hideOverflowForceTextarea) { + //only hide if is Textarea + if (_isTextarea && hideOverflowForceTextarea) { + paddingElementCSS[strOverflowX] = + paddingElementCSS[strOverflowY] = strHidden; + } + } + else { + if (!clipAlways || (overflowBehaviorIsVH.x || overflowBehaviorIsVS.x || overflowBehaviorIsVH.y || overflowBehaviorIsVS.y)) { + //only un-hide if Textarea + if (_isTextarea) { + paddingElementCSS[strOverflowX] = + paddingElementCSS[strOverflowY] = _strEmpty; + } + viewportElementCSS[strOverflowX] = + viewportElementCSS[strOverflowY] = strVisible; + } + } + + _paddingElement.css(paddingElementCSS); + _viewportElement.css(viewportElementCSS); + viewportElementCSS = {}; + + //force soft redraw in webkit because without the scrollbars will may appear because DOM wont be redrawn under special conditions + if ((hasOverflow.c || boxSizingChanged || widthAutoChanged || heightAutoChanged) && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) { + var elementStyle = _contentElementNative[LEXICON.s]; + var dump; + elementStyle.webkitTransform = 'scale(1)'; + elementStyle.display = 'run-in'; + dump = _contentElementNative[LEXICON.oH]; + elementStyle.display = _strEmpty; //|| dump; //use dump to prevent it from deletion if minify + elementStyle.webkitTransform = _strEmpty; + } + /* + //force hard redraw in webkit if native overlaid scrollbars shall appear + if (ignoreOverlayScrollbarHidingChanged && ignoreOverlayScrollbarHiding) { + _hostElement.hide(); + var dump = _hostElementNative[LEXICON.oH]; + _hostElement.show(); + } + */ + } + + //change to direction RTL and width auto Bugfix in Webkit + //without this fix, the DOM still thinks the scrollbar is LTR and thus the content is shifted to the left + contentElementCSS = {}; + if (cssDirectionChanged || widthAutoChanged || heightAutoChanged) { + if (_isRTL && widthAuto) { + var floatTmp = _contentElement.css(_strFloat); + var posLeftWithoutFloat = MATH.round(_contentElement.css(_strFloat, _strEmpty).css(_strLeft, _strEmpty).position().left); + _contentElement.css(_strFloat, floatTmp); + var posLeftWithFloat = MATH.round(_contentElement.position().left); + + if (posLeftWithoutFloat !== posLeftWithFloat) + contentElementCSS[_strLeft] = posLeftWithoutFloat; + } + else { + contentElementCSS[_strLeft] = _strEmpty; + } + } + _contentElement.css(contentElementCSS); + + //handle scroll position + if (_isTextarea && contentSizeChanged) { + var textareaInfo = getTextareaInfo(); + if (textareaInfo) { + var textareaRowsChanged = _textareaInfoCache === undefined ? true : textareaInfo._rows !== _textareaInfoCache._rows; + var cursorRow = textareaInfo._cursorRow; + var cursorCol = textareaInfo._cursorColumn; + var widestRow = textareaInfo._widestRow; + var lastRow = textareaInfo._rows; + var lastCol = textareaInfo._columns; + var cursorPos = textareaInfo._cursorPosition; + var cursorMax = textareaInfo._cursorMax; + var cursorIsLastPosition = (cursorPos >= cursorMax && _textareaHasFocus); + var textareaScrollAmount = { + x: (!textareaAutoWrapping && (cursorCol === lastCol && cursorRow === widestRow)) ? _overflowAmountCache.x : -1, + y: (textareaAutoWrapping ? cursorIsLastPosition || textareaRowsChanged && (previousOverflowAmount ? (currScroll.y === previousOverflowAmount.y) : false) : (cursorIsLastPosition || textareaRowsChanged) && cursorRow === lastRow) ? _overflowAmountCache.y : -1 + }; + currScroll.x = textareaScrollAmount.x > -1 ? (_isRTL && _normalizeRTLCache && _rtlScrollBehavior.i ? 0 : textareaScrollAmount.x) : currScroll.x; //if inverted, scroll to 0 -> normalized this means to max scroll offset. + currScroll.y = textareaScrollAmount.y > -1 ? textareaScrollAmount.y : currScroll.y; + } + _textareaInfoCache = textareaInfo; + } + if (_isRTL && _rtlScrollBehavior.i && _nativeScrollbarIsOverlaid.y && hasOverflow.x && _normalizeRTLCache) + currScroll.x += _contentBorderSize.w || 0; + if (widthAuto) + _hostElement[_strScrollLeft](0); + if (heightAuto) + _hostElement[_strScrollTop](0); + _viewportElement[_strScrollLeft](currScroll.x)[_strScrollTop](currScroll.y); + + //scrollbars management: + var scrollbarsVisibilityVisible = scrollbarsVisibility === 'v'; + var scrollbarsVisibilityHidden = scrollbarsVisibility === 'h'; + var scrollbarsVisibilityAuto = scrollbarsVisibility === 'a'; + var refreshScrollbarsVisibility = function (showX, showY) { + showY = showY === undefined ? showX : showY; + refreshScrollbarAppearance(true, showX, canScroll.x) + refreshScrollbarAppearance(false, showY, canScroll.y) + }; + + //manage class name which indicates scrollable overflow + addRemoveClass(_hostElement, _classNameHostOverflow, hideOverflow.x || hideOverflow.y); + addRemoveClass(_hostElement, _classNameHostOverflowX, hideOverflow.x); + addRemoveClass(_hostElement, _classNameHostOverflowY, hideOverflow.y); + + //add or remove rtl class name for styling purposes except when its body, then the scrollbar stays + if (cssDirectionChanged && !_isBody) { + addRemoveClass(_hostElement, _classNameHostRTL, _isRTL); + } + + //manage the resize feature (CSS3 resize "polyfill" for this plugin) + if (_isBody) + addClass(_hostElement, _classNameHostResizeDisabled); + if (resizeChanged) { + addRemoveClass(_hostElement, _classNameHostResizeDisabled, _resizeNone); + addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResize, !_resizeNone); + addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeB, _resizeBoth); + addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeH, _resizeHorizontal); + addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeV, _resizeVertical); + } + + //manage the scrollbars general visibility + the scrollbar interactivity (unusable class name) + if (scrollbarsVisibilityChanged || overflowBehaviorChanged || hideOverflow.c || hasOverflow.c || ignoreOverlayScrollbarHidingChanged) { + if (ignoreOverlayScrollbarHiding) { + if (ignoreOverlayScrollbarHidingChanged) { + removeClass(_hostElement, _classNameHostScrolling); + if (ignoreOverlayScrollbarHiding) { + refreshScrollbarsVisibility(false); + } + } + } + else if (scrollbarsVisibilityAuto) { + refreshScrollbarsVisibility(canScroll.x, canScroll.y); + } + else if (scrollbarsVisibilityVisible) { + refreshScrollbarsVisibility(true); + } + else if (scrollbarsVisibilityHidden) { + refreshScrollbarsVisibility(false); + } + } + + //manage the scrollbars auto hide feature (auto hide them after specific actions) + if (scrollbarsAutoHideChanged || ignoreOverlayScrollbarHidingChanged) { + setupHostMouseTouchEvents(!_scrollbarsAutoHideLeave && !_scrollbarsAutoHideMove); + refreshScrollbarsAutoHide(_scrollbarsAutoHideNever, !_scrollbarsAutoHideNever); + } + + //manage scrollbars handle length & offset - don't remove! + if (hostSizeChanged || overflowAmount.c || heightAutoChanged || widthAutoChanged || resizeChanged || boxSizingChanged || paddingAbsoluteChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged) { + refreshScrollbarHandleLength(true); + refreshScrollbarHandleOffset(true); + refreshScrollbarHandleLength(false); + refreshScrollbarHandleOffset(false); + } + + //manage interactivity + if (scrollbarsClickScrollingChanged) + refreshScrollbarsInteractive(true, scrollbarsClickScrolling); + if (scrollbarsDragScrollingChanged) + refreshScrollbarsInteractive(false, scrollbarsDragScrolling); + + //callbacks: + dispatchCallback('onDirectionChanged', { + isRTL: _isRTL, + dir: cssDirection + }, cssDirectionChanged); + dispatchCallback('onHostSizeChanged', { + width: _hostSizeCache.w, + height: _hostSizeCache.h + }, hostSizeChanged); + dispatchCallback('onContentSizeChanged', { + width: _contentScrollSizeCache.w, + height: _contentScrollSizeCache.h + }, contentSizeChanged); + dispatchCallback('onOverflowChanged', { + x: hasOverflow.x, + y: hasOverflow.y, + xScrollable: hideOverflow.xs, + yScrollable: hideOverflow.ys, + clipped: hideOverflow.x || hideOverflow.y + }, hasOverflow.c || hideOverflow.c); + dispatchCallback('onOverflowAmountChanged', { + x: overflowAmount.x, + y: overflowAmount.y + }, overflowAmount.c); + } + + //fix body min size + if (_isBody && _bodyMinSizeCache && (_hasOverflowCache.c || _bodyMinSizeCache.c)) { + //its possible that no min size was measured until now, because the content arrange element was just added now, in this case, measure now the min size. + if (!_bodyMinSizeCache.f) + bodyMinSizeChanged(); + if (_nativeScrollbarIsOverlaid.y && _hasOverflowCache.x) + _contentElement.css(_strMinMinus + _strWidth, _bodyMinSizeCache.w + _overlayScrollbarDummySize.y); + if (_nativeScrollbarIsOverlaid.x && _hasOverflowCache.y) + _contentElement.css(_strMinMinus + _strHeight, _bodyMinSizeCache.h + _overlayScrollbarDummySize.x); + _bodyMinSizeCache.c = false; + } + + if (_initialized && changedOptions.updateOnLoad) { + updateElementsOnLoad(); + } + + //freezeResizeObserver(_sizeObserverElement, false); + //freezeResizeObserver(_sizeAutoObserverElement, false); + + dispatchCallback('onUpdated', { forced: force }); + } + + /** + * Updates the found elements of which the load event shall be handled. + */ + function updateElementsOnLoad() { + if (!_isTextarea) { + eachUpdateOnLoad(function (i, updateOnLoadSelector) { + _contentElement.find(updateOnLoadSelector).each(function (i, el) { + // if element doesn't have a updateOnLoadCallback applied + if (COMPATIBILITY.inA(el, _updateOnLoadElms) < 0) { + _updateOnLoadElms.push(el); + FRAMEWORK(el) + .off(_updateOnLoadEventName, updateOnLoadCallback) + .on(_updateOnLoadEventName, updateOnLoadCallback); + } + }); + }); + } + } + + //==== Options ====// + + /** + * Sets new options but doesn't call the update method. + * @param newOptions The object which contains the new options. + * @returns {*} A object which contains the changed options. + */ + function setOptions(newOptions) { + var validatedOpts = _pluginsOptions._validate(newOptions, _pluginsOptions._template, true, _currentOptions) + + _currentOptions = extendDeep({}, _currentOptions, validatedOpts._default); + _currentPreparedOptions = extendDeep({}, _currentPreparedOptions, validatedOpts._prepared); + + return validatedOpts._prepared; + } + + + //==== Structure ====// + + /** + * Builds or destroys the wrapper and helper DOM elements. + * @param destroy Indicates whether the DOM shall be build or destroyed. + */ + /** + * Builds or destroys the wrapper and helper DOM elements. + * @param destroy Indicates whether the DOM shall be build or destroyed. + */ + function setupStructureDOM(destroy) { + var strParent = 'parent'; + var classNameResizeObserverHost = 'os-resize-observer-host'; + var classNameTextareaElementFull = _classNameTextareaElement + _strSpace + _classNameTextInherit; + var textareaClass = _isTextarea ? _strSpace + _classNameTextInherit : _strEmpty; + var adoptAttrs = _currentPreparedOptions.textarea.inheritedAttrs; + var adoptAttrsMap = {}; + var applyAdoptedAttrs = function () { + var applyAdoptedAttrsElm = destroy ? _targetElement : _hostElement; + each(adoptAttrsMap, function (key, value) { + if (type(value) == TYPES.s) { + if (key == LEXICON.c) + applyAdoptedAttrsElm.addClass(value); + else + applyAdoptedAttrsElm.attr(key, value); + } + }); + }; + var hostElementClassNames = [ + _classNameHostElement, + _classNameHostElementForeign, + _classNameHostTextareaElement, + _classNameHostResizeDisabled, + _classNameHostRTL, + _classNameHostScrollbarHorizontalHidden, + _classNameHostScrollbarVerticalHidden, + _classNameHostTransition, + _classNameHostScrolling, + _classNameHostOverflow, + _classNameHostOverflowX, + _classNameHostOverflowY, + _classNameThemeNone, + _classNameTextareaElement, + _classNameTextInherit, + _classNameCache].join(_strSpace); + var hostElementCSS = {}; + + //get host element as first element, because that's the most upper element and required for the other elements + _hostElement = _hostElement || (_isTextarea ? (_domExists ? _targetElement[strParent]()[strParent]()[strParent]()[strParent]() : FRAMEWORK(generateDiv(_classNameHostTextareaElement))) : _targetElement); + _contentElement = _contentElement || selectOrGenerateDivByClass(_classNameContentElement + textareaClass); + _viewportElement = _viewportElement || selectOrGenerateDivByClass(_classNameViewportElement + textareaClass); + _paddingElement = _paddingElement || selectOrGenerateDivByClass(_classNamePaddingElement + textareaClass); + _sizeObserverElement = _sizeObserverElement || selectOrGenerateDivByClass(classNameResizeObserverHost); + _textareaCoverElement = _textareaCoverElement || (_isTextarea ? selectOrGenerateDivByClass(_classNameTextareaCoverElement) : undefined); + + //add this class to workaround class changing issues with UI frameworks especially Vue + if (_domExists) + addClass(_hostElement, _classNameHostElementForeign); + + //on destroy, remove all generated class names from the host element before collecting the adopted attributes + //to prevent adopting generated class names + if (destroy) + removeClass(_hostElement, hostElementClassNames); + + //collect all adopted attributes + adoptAttrs = type(adoptAttrs) == TYPES.s ? adoptAttrs.split(_strSpace) : adoptAttrs; + if (COMPATIBILITY.isA(adoptAttrs) && _isTextarea) { + each(adoptAttrs, function (i, v) { + if (type(v) == TYPES.s) { + adoptAttrsMap[v] = destroy ? _hostElement.attr(v) : _targetElement.attr(v); + } + }); + } + + if (!destroy) { + if (_isTextarea) { + if (!_currentPreparedOptions.sizeAutoCapable) { + hostElementCSS[_strWidth] = _targetElement.css(_strWidth); + hostElementCSS[_strHeight] = _targetElement.css(_strHeight); + } + + if (!_domExists) + _targetElement.addClass(_classNameTextInherit).wrap(_hostElement); + + //jQuery clones elements in wrap functions, so we have to select them again + _hostElement = _targetElement[strParent]().css(hostElementCSS); + } + + if (!_domExists) { + //add the correct class to the target element + addClass(_targetElement, _isTextarea ? classNameTextareaElementFull : _classNameHostElement); + + //wrap the content into the generated elements to create the required DOM + _hostElement.wrapInner(_contentElement) + .wrapInner(_viewportElement) + .wrapInner(_paddingElement) + .prepend(_sizeObserverElement); + + //jQuery clones elements in wrap functions, so we have to select them again + _contentElement = findFirst(_hostElement, _strDot + _classNameContentElement); + _viewportElement = findFirst(_hostElement, _strDot + _classNameViewportElement); + _paddingElement = findFirst(_hostElement, _strDot + _classNamePaddingElement); + + if (_isTextarea) { + _contentElement.prepend(_textareaCoverElement); + applyAdoptedAttrs(); + } + } + + if (_nativeScrollbarStyling) + addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); + if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y) + addClass(_viewportElement, _classNameViewportNativeScrollbarsOverlaid); + if (_isBody) + addClass(_htmlElement, _classNameHTMLElement); + + _sizeObserverElementNative = _sizeObserverElement[0]; + _hostElementNative = _hostElement[0]; + _paddingElementNative = _paddingElement[0]; + _viewportElementNative = _viewportElement[0]; + _contentElementNative = _contentElement[0]; + + updateViewportAttrsFromTarget(); + } + else { + if (_domExists && _initialized) { + //clear size observer + _sizeObserverElement.children().remove(); + + //remove the style property and classes from already generated elements + each([_paddingElement, _viewportElement, _contentElement, _textareaCoverElement], function (i, elm) { + if (elm) { + removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy); + } + }); + + //add classes to the host element which was removed previously to match the expected DOM + addClass(_hostElement, _isTextarea ? _classNameHostTextareaElement : _classNameHostElement); + } + else { + //remove size observer + remove(_sizeObserverElement); + + //unwrap the content to restore DOM + _contentElement.contents() + .unwrap() + .unwrap() + .unwrap(); + + if (_isTextarea) { + _targetElement.unwrap(); + remove(_hostElement); + remove(_textareaCoverElement); + applyAdoptedAttrs(); + } + } + + if (_isTextarea) + _targetElement.removeAttr(LEXICON.s); + + if (_isBody) + removeClass(_htmlElement, _classNameHTMLElement); + } + } + + /** + * Adds or removes all wrapper elements interactivity events. + * @param destroy Indicates whether the Events shall be added or removed. + */ + function setupStructureEvents() { + var textareaKeyDownRestrictedKeyCodes = [ + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, //F1 to F12 + 33, 34, //page up, page down + 37, 38, 39, 40, //left, up, right, down arrows + 16, 17, 18, 19, 20, 144 //Shift, Ctrl, Alt, Pause, CapsLock, NumLock + ]; + var textareaKeyDownKeyCodesList = []; + var textareaUpdateIntervalID; + var scrollStopTimeoutId; + var scrollStopDelay = 175; + var strFocus = 'focus'; + + function updateTextarea(doClearInterval) { + textareaUpdate(); + _base.update(_strAuto); + if (doClearInterval && _autoUpdateRecommended) + clearInterval(textareaUpdateIntervalID); + } + function textareaOnScroll(event) { + _targetElement[_strScrollLeft](_rtlScrollBehavior.i && _normalizeRTLCache ? 9999999 : 0); + _targetElement[_strScrollTop](0); + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + return false; + } + function textareaOnDrop(event) { + setTimeout(function () { + if (!_destroyed) + updateTextarea(); + }, 50); + } + function textareaOnFocus() { + _textareaHasFocus = true; + addClass(_hostElement, strFocus); + } + function textareaOnFocusout() { + _textareaHasFocus = false; + textareaKeyDownKeyCodesList = []; + removeClass(_hostElement, strFocus); + updateTextarea(true); + } + function textareaOnKeyDown(event) { + var keyCode = event.keyCode; + + if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) { + if (!textareaKeyDownKeyCodesList[LEXICON.l]) { + updateTextarea(); + textareaUpdateIntervalID = setInterval(updateTextarea, 1000 / 60); + } + if (inArray(keyCode, textareaKeyDownKeyCodesList) < 0) + textareaKeyDownKeyCodesList.push(keyCode); + } + } + function textareaOnKeyUp(event) { + var keyCode = event.keyCode; + var index = inArray(keyCode, textareaKeyDownKeyCodesList); + + if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) { + if (index > -1) + textareaKeyDownKeyCodesList.splice(index, 1); + if (!textareaKeyDownKeyCodesList[LEXICON.l]) + updateTextarea(true); + } + } + function contentOnTransitionEnd(event) { + if (_autoUpdateCache === true) + return; + event = event.originalEvent || event; + if (isSizeAffectingCSSProperty(event.propertyName)) + _base.update(_strAuto); + } + function viewportOnScroll(event) { + if (!_sleeping) { + if (scrollStopTimeoutId !== undefined) + clearTimeout(scrollStopTimeoutId); + else { + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(true); + + if (!nativeOverlayScrollbarsAreActive()) + addClass(_hostElement, _classNameHostScrolling); + + dispatchCallback('onScrollStart', event); + } + + //if a scrollbars handle gets dragged, the mousemove event is responsible for refreshing the handle offset + //because if CSS scroll-snap is used, the handle offset gets only refreshed on every snap point + //this looks laggy & clunky, it looks much better if the offset refreshes with the mousemove + if (!_scrollbarsHandlesDefineScrollPos) { + refreshScrollbarHandleOffset(true); + refreshScrollbarHandleOffset(false); + } + dispatchCallback('onScroll', event); + + scrollStopTimeoutId = setTimeout(function () { + if (!_destroyed) { + //OnScrollStop: + clearTimeout(scrollStopTimeoutId); + scrollStopTimeoutId = undefined; + + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(false); + + if (!nativeOverlayScrollbarsAreActive()) + removeClass(_hostElement, _classNameHostScrolling); + + dispatchCallback('onScrollStop', event); + } + }, scrollStopDelay); + } + } + + + if (_isTextarea) { + if (_msieVersion > 9 || !_autoUpdateRecommended) { + addDestroyEventListener(_targetElement, 'input', updateTextarea); + } + else { + addDestroyEventListener(_targetElement, + [_strKeyDownEvent, _strKeyUpEvent], + [textareaOnKeyDown, textareaOnKeyUp]); + } + + addDestroyEventListener(_targetElement, + [_strScroll, 'drop', strFocus, strFocus + 'out'], + [textareaOnScroll, textareaOnDrop, textareaOnFocus, textareaOnFocusout]); + } + else { + addDestroyEventListener(_contentElement, _strTransitionEndEvent, contentOnTransitionEnd); + } + addDestroyEventListener(_viewportElement, _strScroll, viewportOnScroll, true); + } + + + //==== Scrollbars ====// + + /** + * Builds or destroys all scrollbar DOM elements (scrollbar, track, handle) + * @param destroy Indicates whether the DOM shall be build or destroyed. + */ + function setupScrollbarsDOM(destroy) { + var selectOrGenerateScrollbarDOM = function (isHorizontal) { + var scrollbarClassName = isHorizontal ? _classNameScrollbarHorizontal : _classNameScrollbarVertical; + var scrollbar = selectOrGenerateDivByClass(_classNameScrollbar + _strSpace + scrollbarClassName, true); + var track = selectOrGenerateDivByClass(_classNameScrollbarTrack, scrollbar); + var handle = selectOrGenerateDivByClass(_classNameScrollbarHandle, scrollbar); + + if (!_domExists && !destroy) { + scrollbar.append(track); + track.append(handle); + } + + return { + _scrollbar: scrollbar, + _track: track, + _handle: handle + }; + }; + function resetScrollbarDOM(isHorizontal) { + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbar = scrollbarVars._scrollbar; + var track = scrollbarVars._track; + var handle = scrollbarVars._handle; + + if (_domExists && _initialized) { + each([scrollbar, track, handle], function (i, elm) { + removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy); + }); + } + else { + remove(scrollbar || selectOrGenerateScrollbarDOM(isHorizontal)._scrollbar); + } + } + var horizontalElements; + var verticalElements; + + if (!destroy) { + horizontalElements = selectOrGenerateScrollbarDOM(true); + verticalElements = selectOrGenerateScrollbarDOM(); + + _scrollbarHorizontalElement = horizontalElements._scrollbar; + _scrollbarHorizontalTrackElement = horizontalElements._track; + _scrollbarHorizontalHandleElement = horizontalElements._handle; + _scrollbarVerticalElement = verticalElements._scrollbar; + _scrollbarVerticalTrackElement = verticalElements._track; + _scrollbarVerticalHandleElement = verticalElements._handle; + + if (!_domExists) { + _paddingElement.after(_scrollbarVerticalElement); + _paddingElement.after(_scrollbarHorizontalElement); + } + } + else { + resetScrollbarDOM(true); + resetScrollbarDOM(); + } + } + + /** + * Initializes all scrollbar interactivity events. (track and handle dragging, clicking, scrolling) + * @param isHorizontal True if the target scrollbar is the horizontal scrollbar, false if the target scrollbar is the vertical scrollbar. + */ + function setupScrollbarEvents(isHorizontal) { + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbarVarsInfo = scrollbarVars._info; + var insideIFrame = _windowElementNative.top !== _windowElementNative; + var xy = scrollbarVars._x_y; + var XY = scrollbarVars._X_Y; + var scroll = _strScroll + scrollbarVars._Left_Top; + var strActive = 'active'; + var strSnapHandle = 'snapHandle'; + var strClickEvent = 'click'; + var scrollDurationFactor = 1; + var increaseDecreaseScrollAmountKeyCodes = [16, 17]; //shift, ctrl + var trackTimeout; + var mouseDownScroll; + var mouseDownOffset; + var mouseDownInvertedScale; + + function getPointerPosition(event) { + return _msieVersion && insideIFrame ? event['screen' + XY] : COMPATIBILITY.page(event)[xy]; //use screen coordinates in EDGE & IE because the page values are incorrect in frames. + } + function getPreparedScrollbarsOption(name) { + return _currentPreparedOptions.scrollbars[name]; + } + function increaseTrackScrollAmount() { + scrollDurationFactor = 0.5; + } + function decreaseTrackScrollAmount() { + scrollDurationFactor = 1; + } + function stopClickEventPropagation(event) { + COMPATIBILITY.stpP(event); + } + function documentKeyDown(event) { + if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1) + increaseTrackScrollAmount(); + } + function documentKeyUp(event) { + if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1) + decreaseTrackScrollAmount(); + } + function onMouseTouchDownContinue(event) { + var originalEvent = event.originalEvent || event; + var isTouchEvent = originalEvent.touches !== undefined; + return _sleeping || _destroyed || nativeOverlayScrollbarsAreActive() || !_scrollbarsDragScrollingCache || (isTouchEvent && !getPreparedScrollbarsOption('touchSupport')) ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent; + } + function documentDragMove(event) { + if (onMouseTouchDownContinue(event)) { + var trackLength = scrollbarVarsInfo._trackLength; + var handleLength = scrollbarVarsInfo._handleLength; + var scrollRange = scrollbarVarsInfo._maxScroll; + var scrollRaw = (getPointerPosition(event) - mouseDownOffset) * mouseDownInvertedScale; + var scrollDeltaPercent = scrollRaw / (trackLength - handleLength); + var scrollDelta = (scrollRange * scrollDeltaPercent); + scrollDelta = isFinite(scrollDelta) ? scrollDelta : 0; + if (_isRTL && isHorizontal && !_rtlScrollBehavior.i) + scrollDelta *= -1; + + _viewportElement[scroll](MATH.round(mouseDownScroll + scrollDelta)); + + if (_scrollbarsHandlesDefineScrollPos) + refreshScrollbarHandleOffset(isHorizontal, mouseDownScroll + scrollDelta); + + if (!_supportPassiveEvents) + COMPATIBILITY.prvD(event); + } + else + documentMouseTouchUp(event); + } + function documentMouseTouchUp(event) { + event = event || event.originalEvent; + + setupResponsiveEventListener(_documentElement, + [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent], + [documentDragMove, documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart], + true); + COMPATIBILITY.rAF()(function() { + setupResponsiveEventListener(_documentElement, strClickEvent, stopClickEventPropagation, true, { _capture: true }); + }); + + + if (_scrollbarsHandlesDefineScrollPos) + refreshScrollbarHandleOffset(isHorizontal, true); + + _scrollbarsHandlesDefineScrollPos = false; + removeClass(_bodyElement, _classNameDragging); + removeClass(scrollbarVars._handle, strActive); + removeClass(scrollbarVars._track, strActive); + removeClass(scrollbarVars._scrollbar, strActive); + + mouseDownScroll = undefined; + mouseDownOffset = undefined; + mouseDownInvertedScale = 1; + + decreaseTrackScrollAmount(); + + if (trackTimeout !== undefined) { + _base.scrollStop(); + clearTimeout(trackTimeout); + trackTimeout = undefined; + } + + if (event) { + var rect = _hostElementNative[LEXICON.bCR](); + var mouseInsideHost = event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom; + + //if mouse is outside host element + if (!mouseInsideHost) + hostOnMouseLeave(); + + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(false); + } + } + function onHandleMouseTouchDown(event) { + if (onMouseTouchDownContinue(event)) + onHandleMouseTouchDownAction(event); + } + function onHandleMouseTouchDownAction(event) { + mouseDownScroll = _viewportElement[scroll](); + mouseDownScroll = isNaN(mouseDownScroll) ? 0 : mouseDownScroll; + if (_isRTL && isHorizontal && !_rtlScrollBehavior.n || !_isRTL) + mouseDownScroll = mouseDownScroll < 0 ? 0 : mouseDownScroll; + + mouseDownInvertedScale = getHostElementInvertedScale()[xy]; + mouseDownOffset = getPointerPosition(event); + + _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle); + addClass(_bodyElement, _classNameDragging); + addClass(scrollbarVars._handle, strActive); + addClass(scrollbarVars._scrollbar, strActive); + + setupResponsiveEventListener(_documentElement, + [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strSelectStartEvent], + [documentDragMove, documentMouseTouchUp, documentOnSelectStart]); + COMPATIBILITY.rAF()(function() { + setupResponsiveEventListener(_documentElement, strClickEvent, stopClickEventPropagation, false, { _capture: true }); + }); + + + if (_msieVersion || !_documentMixed) + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + function onTrackMouseTouchDown(event) { + if (onMouseTouchDownContinue(event)) { + var handleToViewportRatio = scrollbarVars._info._handleLength / Math.round(MATH.min(1, _viewportSize[scrollbarVars._w_h] / _contentScrollSizeCache[scrollbarVars._w_h]) * scrollbarVars._info._trackLength); + var scrollDistance = MATH.round(_viewportSize[scrollbarVars._w_h] * handleToViewportRatio); + var scrollBaseDuration = 270 * handleToViewportRatio; + var scrollFirstIterationDelay = 400 * handleToViewportRatio; + var trackOffset = scrollbarVars._track.offset()[scrollbarVars._left_top]; + var ctrlKey = event.ctrlKey; + var instantScroll = event.shiftKey; + var instantScrollTransition = instantScroll && ctrlKey; + var isFirstIteration = true; + var easing = 'linear'; + var decreaseScroll; + var finishedCondition; + var scrollActionFinsished = function (transition) { + if (_scrollbarsHandlesDefineScrollPos) + refreshScrollbarHandleOffset(isHorizontal, transition); + }; + var scrollActionInstantFinished = function () { + scrollActionFinsished(); + onHandleMouseTouchDownAction(event); + }; + var scrollAction = function () { + if (!_destroyed) { + var mouseOffset = (mouseDownOffset - trackOffset) * mouseDownInvertedScale; + var handleOffset = scrollbarVarsInfo._handleOffset; + var trackLength = scrollbarVarsInfo._trackLength; + var handleLength = scrollbarVarsInfo._handleLength; + var scrollRange = scrollbarVarsInfo._maxScroll; + var currScroll = scrollbarVarsInfo._currentScroll; + var scrollDuration = scrollBaseDuration * scrollDurationFactor; + var timeoutDelay = isFirstIteration ? MATH.max(scrollFirstIterationDelay, scrollDuration) : scrollDuration; + var instantScrollPosition = scrollRange * ((mouseOffset - (handleLength / 2)) / (trackLength - handleLength)); // 100% * positionPercent + var rtlIsNormal = _isRTL && isHorizontal && ((!_rtlScrollBehavior.i && !_rtlScrollBehavior.n) || _normalizeRTLCache); + var decreaseScrollCondition = rtlIsNormal ? handleOffset < mouseOffset : handleOffset > mouseOffset; + var scrollObj = {}; + var animationObj = { + easing: easing, + step: function (now) { + if (_scrollbarsHandlesDefineScrollPos) { + _viewportElement[scroll](now); //https://github.com/jquery/jquery/issues/4340 + refreshScrollbarHandleOffset(isHorizontal, now); + } + } + }; + instantScrollPosition = isFinite(instantScrollPosition) ? instantScrollPosition : 0; + instantScrollPosition = _isRTL && isHorizontal && !_rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition; + + //_base.scrollStop(); + + if (instantScroll) { + _viewportElement[scroll](instantScrollPosition); //scroll instantly to new position + if (instantScrollTransition) { + //get the scroll position after instant scroll (in case CSS Snap Points are used) to get the correct snapped scroll position + //and the animation stops at the correct point + instantScrollPosition = _viewportElement[scroll](); + //scroll back to the position before instant scrolling so animation can be performed + _viewportElement[scroll](currScroll); + + instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition; + instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.n ? -instantScrollPosition : instantScrollPosition; + + scrollObj[xy] = instantScrollPosition; + _base.scroll(scrollObj, extendDeep(animationObj, { + duration: 130, + complete: scrollActionInstantFinished + })); + } + else + scrollActionInstantFinished(); + } + else { + decreaseScroll = isFirstIteration ? decreaseScrollCondition : decreaseScroll; + finishedCondition = rtlIsNormal + ? (decreaseScroll ? handleOffset + handleLength >= mouseOffset : handleOffset <= mouseOffset) + : (decreaseScroll ? handleOffset <= mouseOffset : handleOffset + handleLength >= mouseOffset); + + if (finishedCondition) { + clearTimeout(trackTimeout); + _base.scrollStop(); + trackTimeout = undefined; + scrollActionFinsished(true); + } + else { + trackTimeout = setTimeout(scrollAction, timeoutDelay); + + scrollObj[xy] = (decreaseScroll ? '-=' : '+=') + scrollDistance; + _base.scroll(scrollObj, extendDeep(animationObj, { + duration: scrollDuration + })); + } + isFirstIteration = false; + } + } + }; + if (ctrlKey) + increaseTrackScrollAmount(); + + mouseDownInvertedScale = getHostElementInvertedScale()[xy]; + mouseDownOffset = COMPATIBILITY.page(event)[xy]; + + _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle); + addClass(_bodyElement, _classNameDragging); + addClass(scrollbarVars._track, strActive); + addClass(scrollbarVars._scrollbar, strActive); + + setupResponsiveEventListener(_documentElement, + [_strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent], + [documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart]); + + scrollAction(); + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + } + function onTrackMouseTouchEnter(event) { + //make sure both scrollbars will stay visible if one scrollbar is hovered if autoHide is "scroll" or "move". + _scrollbarsHandleHovered = true; + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(true); + } + function onTrackMouseTouchLeave(event) { + _scrollbarsHandleHovered = false; + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(false); + } + function onScrollbarMouseTouchDown(event) { + COMPATIBILITY.stpP(event); + } + + addDestroyEventListener(scrollbarVars._handle, + _strMouseTouchDownEvent, + onHandleMouseTouchDown); + addDestroyEventListener(scrollbarVars._track, + [_strMouseTouchDownEvent, _strMouseEnter, _strMouseLeave], + [onTrackMouseTouchDown, onTrackMouseTouchEnter, onTrackMouseTouchLeave]); + addDestroyEventListener(scrollbarVars._scrollbar, + _strMouseTouchDownEvent, + onScrollbarMouseTouchDown); + + if (_supportTransition) { + addDestroyEventListener(scrollbarVars._scrollbar, _strTransitionEndEvent, function (event) { + if (event.target !== scrollbarVars._scrollbar[0]) + return; + refreshScrollbarHandleLength(isHorizontal); + refreshScrollbarHandleOffset(isHorizontal); + }); + } + } + + /** + * Shows or hides the given scrollbar and applied a class name which indicates if the scrollbar is scrollable or not. + * @param isHorizontal True if the horizontal scrollbar is the target, false if the vertical scrollbar is the target. + * @param shallBeVisible True if the scrollbar shall be shown, false if hidden. + * @param canScroll True if the scrollbar is scrollable, false otherwise. + */ + function refreshScrollbarAppearance(isHorizontal, shallBeVisible, canScroll) { + var scrollbarHiddenClassName = isHorizontal ? _classNameHostScrollbarHorizontalHidden : _classNameHostScrollbarVerticalHidden; + var scrollbarElement = isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement; + + addRemoveClass(_hostElement, scrollbarHiddenClassName, !shallBeVisible); + addRemoveClass(scrollbarElement, _classNameScrollbarUnusable, !canScroll); + } + + /** + * Autoshows / autohides both scrollbars with. + * @param shallBeVisible True if the scrollbars shall be autoshown (only the case if they are hidden by a autohide), false if the shall be auto hidden. + * @param delayfree True if the scrollbars shall be hidden without a delay, false or undefined otherwise. + */ + function refreshScrollbarsAutoHide(shallBeVisible, delayfree) { + clearTimeout(_scrollbarsAutoHideTimeoutId); + if (shallBeVisible) { + //if(_hasOverflowCache.x && _hideOverflowCache.xs) + removeClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden); + //if(_hasOverflowCache.y && _hideOverflowCache.ys) + removeClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden); + } + else { + var anyActive; + var strActive = 'active'; + var hide = function () { + if (!_scrollbarsHandleHovered && !_destroyed) { + anyActive = _scrollbarHorizontalHandleElement.hasClass(strActive) || _scrollbarVerticalHandleElement.hasClass(strActive); + if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave)) + addClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden); + if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave)) + addClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden); + } + }; + if (_scrollbarsAutoHideDelay > 0 && delayfree !== true) + _scrollbarsAutoHideTimeoutId = setTimeout(hide, _scrollbarsAutoHideDelay); + else + hide(); + } + } + + /** + * Refreshes the handle length of the given scrollbar. + * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed. + */ + function refreshScrollbarHandleLength(isHorizontal) { + var handleCSS = {}; + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbarVarsInfo = scrollbarVars._info; + var digit = 1000000; + //get and apply intended handle length + var handleRatio = MATH.min(1, _viewportSize[scrollbarVars._w_h] / _contentScrollSizeCache[scrollbarVars._w_h]); + handleCSS[scrollbarVars._width_height] = (MATH.floor(handleRatio * 100 * digit) / digit) + '%'; //the last * digit / digit is for flooring to the 4th digit + + if (!nativeOverlayScrollbarsAreActive()) + scrollbarVars._handle.css(handleCSS); + + //measure the handle length to respect min & max length + scrollbarVarsInfo._handleLength = scrollbarVars._handle[0]['offset' + scrollbarVars._Width_Height]; + scrollbarVarsInfo._handleLengthRatio = handleRatio; + } + + /** + * Refreshes the handle offset of the given scrollbar. + * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed. + * @param scrollOrTransition The scroll position of the given scrollbar axis to which the handle shall be moved or a boolean which indicates whether a transition shall be applied. If undefined or boolean if the current scroll-offset is taken. (if isHorizontal ? scrollLeft : scrollTop) + */ + function refreshScrollbarHandleOffset(isHorizontal, scrollOrTransition) { + var transition = type(scrollOrTransition) == TYPES.b; + var transitionDuration = 250; + var isRTLisHorizontal = _isRTL && isHorizontal; + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbarVarsInfo = scrollbarVars._info; + var strTranslateBrace = 'translate('; + var strTransform = VENDORS._cssProperty('transform'); + var strTransition = VENDORS._cssProperty('transition'); + var nativeScroll = isHorizontal ? _viewportElement[_strScrollLeft]() : _viewportElement[_strScrollTop](); + var currentScroll = scrollOrTransition === undefined || transition ? nativeScroll : scrollOrTransition; + + //measure the handle length to respect min & max length + var handleLength = scrollbarVarsInfo._handleLength; + var trackLength = scrollbarVars._track[0]['offset' + scrollbarVars._Width_Height]; + var handleTrackDiff = trackLength - handleLength; + var handleCSS = {}; + var transformOffset; + var translateValue; + + //DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]' + // because its a bit behind during the small delay when content size updates + //(delay = mutationObserverContentLag, if its 0 then this var could be used) + var maxScroll = (_viewportElementNative[_strScroll + scrollbarVars._Width_Height] - _viewportElementNative['client' + scrollbarVars._Width_Height]) * (_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative + var getScrollRatio = function (base) { + return isNaN(base / maxScroll) ? 0 : MATH.max(0, MATH.min(1, base / maxScroll)); + }; + var getHandleOffset = function (scrollRatio) { + var offset = handleTrackDiff * scrollRatio; + offset = isNaN(offset) ? 0 : offset; + offset = (isRTLisHorizontal && !_rtlScrollBehavior.i) ? (trackLength - handleLength - offset) : offset; + offset = MATH.max(0, offset); + return offset; + }; + var scrollRatio = getScrollRatio(nativeScroll); + var unsnappedScrollRatio = getScrollRatio(currentScroll); + var handleOffset = getHandleOffset(unsnappedScrollRatio); + var snappedHandleOffset = getHandleOffset(scrollRatio); + + scrollbarVarsInfo._maxScroll = maxScroll; + scrollbarVarsInfo._currentScroll = nativeScroll; + scrollbarVarsInfo._currentScrollRatio = scrollRatio; + + if (_supportTransform) { + transformOffset = isRTLisHorizontal ? -(trackLength - handleLength - handleOffset) : handleOffset; //in px + //transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in % + translateValue = isHorizontal ? strTranslateBrace + transformOffset + 'px, 0)' : strTranslateBrace + '0, ' + transformOffset + 'px)'; + + handleCSS[strTransform] = translateValue; + + //apply or clear up transition + if (_supportTransition) + handleCSS[strTransition] = transition && MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1 ? getCSSTransitionString(scrollbarVars._handle) + ', ' + (strTransform + _strSpace + transitionDuration + 'ms') : _strEmpty; + } + else + handleCSS[scrollbarVars._left_top] = handleOffset; + + + //only apply css if offset has changed and overflow exists. + if (!nativeOverlayScrollbarsAreActive()) { + scrollbarVars._handle.css(handleCSS); + + //clear up transition + if (_supportTransform && _supportTransition && transition) { + scrollbarVars._handle.one(_strTransitionEndEvent, function () { + if (!_destroyed) + scrollbarVars._handle.css(strTransition, _strEmpty); + }); + } + } + + scrollbarVarsInfo._handleOffset = handleOffset; + scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset; + scrollbarVarsInfo._trackLength = trackLength; + } + + /** + * Refreshes the interactivity of the given scrollbar element. + * @param isTrack True if the track element is the target, false if the handle element is the target. + * @param value True for interactivity false for no interactivity. + */ + function refreshScrollbarsInteractive(isTrack, value) { + var action = value ? 'removeClass' : 'addClass'; + var element1 = isTrack ? _scrollbarHorizontalTrackElement : _scrollbarHorizontalHandleElement; + var element2 = isTrack ? _scrollbarVerticalTrackElement : _scrollbarVerticalHandleElement; + var className = isTrack ? _classNameScrollbarTrackOff : _classNameScrollbarHandleOff; + + element1[action](className); + element2[action](className); + } + + /** + * Returns a object which is used for fast access for specific variables. + * @param isHorizontal True if the horizontal scrollbar vars shall be accessed, false if the vertical scrollbar vars shall be accessed. + * @returns {{wh: string, WH: string, lt: string, _wh: string, _lt: string, t: *, h: *, c: {}, s: *}} + */ + function getScrollbarVars(isHorizontal) { + return { + _width_height: isHorizontal ? _strWidth : _strHeight, + _Width_Height: isHorizontal ? 'Width' : 'Height', + _left_top: isHorizontal ? _strLeft : _strTop, + _Left_Top: isHorizontal ? 'Left' : 'Top', + _x_y: isHorizontal ? _strX : _strY, + _X_Y: isHorizontal ? 'X' : 'Y', + _w_h: isHorizontal ? 'w' : 'h', + _l_t: isHorizontal ? 'l' : 't', + _track: isHorizontal ? _scrollbarHorizontalTrackElement : _scrollbarVerticalTrackElement, + _handle: isHorizontal ? _scrollbarHorizontalHandleElement : _scrollbarVerticalHandleElement, + _scrollbar: isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement, + _info: isHorizontal ? _scrollHorizontalInfo : _scrollVerticalInfo + }; + } + + + //==== Scrollbar Corner ====// + + /** + * Builds or destroys the scrollbar corner DOM element. + * @param destroy Indicates whether the DOM shall be build or destroyed. + */ + function setupScrollbarCornerDOM(destroy) { + _scrollbarCornerElement = _scrollbarCornerElement || selectOrGenerateDivByClass(_classNameScrollbarCorner, true); + + if (!destroy) { + if (!_domExists) { + _hostElement.append(_scrollbarCornerElement); + } + } + else { + if (_domExists && _initialized) { + removeClass(_scrollbarCornerElement.removeAttr(LEXICON.s), _classNamesDynamicDestroy); + } + else { + remove(_scrollbarCornerElement); + } + } + } + + /** + * Initializes all scrollbar corner interactivity events. + */ + function setupScrollbarCornerEvents() { + var insideIFrame = _windowElementNative.top !== _windowElementNative; + var mouseDownPosition = {}; + var mouseDownSize = {}; + var mouseDownInvertedScale = {}; + var reconnectMutationObserver; + + function documentDragMove(event) { + if (onMouseTouchDownContinue(event)) { + var pageOffset = getCoordinates(event); + var hostElementCSS = {}; + if (_resizeHorizontal || _resizeBoth) + hostElementCSS[_strWidth] = (mouseDownSize.w + (pageOffset.x - mouseDownPosition.x) * mouseDownInvertedScale.x); + if (_resizeVertical || _resizeBoth) + hostElementCSS[_strHeight] = (mouseDownSize.h + (pageOffset.y - mouseDownPosition.y) * mouseDownInvertedScale.y); + _hostElement.css(hostElementCSS); + COMPATIBILITY.stpP(event); + } + else { + documentMouseTouchUp(event); + } + } + function documentMouseTouchUp(event) { + var eventIsTrusted = event !== undefined; + + setupResponsiveEventListener(_documentElement, + [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent], + [documentOnSelectStart, documentDragMove, documentMouseTouchUp], + true); + + removeClass(_bodyElement, _classNameDragging); + if (_scrollbarCornerElement.releaseCapture) + _scrollbarCornerElement.releaseCapture(); + + if (eventIsTrusted) { + if (reconnectMutationObserver) + connectMutationObservers(); + _base.update(_strAuto); + } + reconnectMutationObserver = false; + } + function onMouseTouchDownContinue(event) { + var originalEvent = event.originalEvent || event; + var isTouchEvent = originalEvent.touches !== undefined; + return _sleeping || _destroyed ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent; + } + function getCoordinates(event) { + return _msieVersion && insideIFrame ? { x: event.screenX, y: event.screenY } : COMPATIBILITY.page(event); + } + + addDestroyEventListener(_scrollbarCornerElement, _strMouseTouchDownEvent, function (event) { + if (onMouseTouchDownContinue(event) && !_resizeNone) { + if (_mutationObserversConnected) { + reconnectMutationObserver = true; + disconnectMutationObservers(); + } + + mouseDownPosition = getCoordinates(event); + + mouseDownSize.w = _hostElementNative[LEXICON.oW] - (!_isBorderBox ? _paddingX : 0); + mouseDownSize.h = _hostElementNative[LEXICON.oH] - (!_isBorderBox ? _paddingY : 0); + mouseDownInvertedScale = getHostElementInvertedScale(); + + setupResponsiveEventListener(_documentElement, + [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent], + [documentOnSelectStart, documentDragMove, documentMouseTouchUp]); + + addClass(_bodyElement, _classNameDragging); + if (_scrollbarCornerElement.setCapture) + _scrollbarCornerElement.setCapture(); + + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + }); + } + + + //==== Utils ====// + + /** + * Calls the callback with the given name. The Context of this callback is always _base (this). + * @param name The name of the target which shall be called. + * @param args The args with which the callback shall be called. + * @param dependent Boolean which decides whether the callback shall be fired, undefined is like a "true" value. + */ + function dispatchCallback(name, args, dependent) { + if (dependent === false) + return; + if (_initialized) { + var callback = _currentPreparedOptions.callbacks[name]; + var extensionOnName = name; + var ext; + + if (extensionOnName.substr(0, 2) === 'on') + extensionOnName = extensionOnName.substr(2, 1).toLowerCase() + extensionOnName.substr(3); + + if (type(callback) == TYPES.f) + callback.call(_base, args); + + each(_extensions, function () { + ext = this; + if (type(ext.on) == TYPES.f) + ext.on(extensionOnName, args); + }); + } + else if (!_destroyed) + _callbacksInitQeueue.push({ n: name, a: args }); + } + + /** + * Sets the "top, right, bottom, left" properties, with a given prefix, of the given css object. + * @param targetCSSObject The css object to which the values shall be applied. + * @param prefix The prefix of the "top, right, bottom, left" css properties. (example: 'padding-' is a valid prefix) + * @param values A array of values which shall be applied to the "top, right, bottom, left" -properties. The array order is [top, right, bottom, left]. + * If this argument is undefined the value '' (empty string) will be applied to all properties. + */ + function setTopRightBottomLeft(targetCSSObject, prefix, values) { + prefix = prefix || _strEmpty; + values = values || [_strEmpty, _strEmpty, _strEmpty, _strEmpty]; + + targetCSSObject[prefix + _strTop] = values[0]; + targetCSSObject[prefix + _strRight] = values[1]; + targetCSSObject[prefix + _strBottom] = values[2]; + targetCSSObject[prefix + _strLeft] = values[3]; + } + + /** + * Gets the "top, right, bottom, left" CSS properties of the CSS property with the given prefix from the host element. + * @param prefix The prefix of the "top, right, bottom, left" css properties. (example: 'padding-' is a valid prefix) + * @param suffix The suffix of the "top, right, bottom, left" css properties. (example: 'border-' is a valid prefix with '-width' is a valid suffix) + * @param zeroX True if the x axis shall be 0. + * @param zeroY True if the y axis shall be 0. + * @returns {{}} The object which contains the numbers of the read CSS properties. + */ + function getTopRightBottomLeftHost(prefix, suffix, zeroX, zeroY) { + suffix = suffix || _strEmpty; + prefix = prefix || _strEmpty; + return { + t: zeroY ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strTop + suffix)), + r: zeroX ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strRight + suffix)), + b: zeroY ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strBottom + suffix)), + l: zeroX ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strLeft + suffix)) + }; + } + + /** + * Returns the computed CSS transition string from the given element. + * @param element The element from which the transition string shall be returned. + * @returns {string} The CSS transition string from the given element. + */ + function getCSSTransitionString(element) { + var transitionStr = VENDORS._cssProperty('transition'); + var assembledValue = element.css(transitionStr); + if (assembledValue) + return assembledValue; + var regExpString = '\\s*(' + '([^,(]+(\\(.+?\\))?)+' + ')[\\s,]*'; + var regExpMain = new RegExp(regExpString); + var regExpValidate = new RegExp('^(' + regExpString + ')+$'); + var properties = 'property duration timing-function delay'.split(' '); + var result = []; + var strResult; + var valueArray; + var i = 0; + var j; + var splitCssStyleByComma = function (str) { + strResult = []; + if (!str.match(regExpValidate)) + return str; + while (str.match(regExpMain)) { + strResult.push(RegExp.$1); + str = str.replace(regExpMain, _strEmpty); + } + + return strResult; + }; + for (; i < properties[LEXICON.l]; i++) { + valueArray = splitCssStyleByComma(element.css(transitionStr + '-' + properties[i])); + for (j = 0; j < valueArray[LEXICON.l]; j++) + result[j] = (result[j] ? result[j] + _strSpace : _strEmpty) + valueArray[j]; + } + return result.join(', '); + } + + /** + * Generates a Regular Expression which matches with a string which starts with 'os-host'. + * @param {boolean} withCurrClassNameOption The Regular Expression also matches if the string is the current ClassName option (multiple values splitted by space possible). + * @param {boolean} withOldClassNameOption The Regular Expression also matches if the string is the old ClassName option (multiple values splitted by space possible). + */ + function createHostClassNameRegExp(withCurrClassNameOption, withOldClassNameOption) { + var i; + var split; + var appendix; + var appendClasses = function (classes, condition) { + appendix = ''; + if (condition && typeof classes == TYPES.s) { + split = classes.split(_strSpace); + for (i = 0; i < split[LEXICON.l]; i++) + appendix += '|' + split[i] + '$'; + // split[i].replace(/[.*+?^${}()|[\]\\]/g, '\\$&') for escaping regex characters + } + return appendix; + }; + + return new RegExp( + '(^' + _classNameHostElement + '([-_].+|)$)' + + appendClasses(_classNameCache, withCurrClassNameOption) + + appendClasses(_oldClassName, withOldClassNameOption), 'g'); + } + + /** + * Calculates the host-elements inverted scale. (invertedScale = 1 / scale) + * @returns {{x: number, y: number}} The scale of the host-element. + */ + function getHostElementInvertedScale() { + var rect = _paddingElementNative[LEXICON.bCR](); + return { + x: _supportTransform ? 1 / (MATH.round(rect.width) / _paddingElementNative[LEXICON.oW]) || 1 : 1, + y: _supportTransform ? 1 / (MATH.round(rect.height) / _paddingElementNative[LEXICON.oH]) || 1 : 1 + }; + } + + /** + * Checks whether the given object is a HTMLElement. + * @param o The object which shall be checked. + * @returns {boolean} True the given object is a HTMLElement, false otherwise. + */ + function isHTMLElement(o) { + var strOwnerDocument = 'ownerDocument'; + var strHTMLElement = 'HTMLElement'; + var wnd = o && o[strOwnerDocument] ? (o[strOwnerDocument].parentWindow || window) : window; + return ( + typeof wnd[strHTMLElement] == TYPES.o ? o instanceof wnd[strHTMLElement] : //DOM2 + o && typeof o == TYPES.o && o !== null && o.nodeType === 1 && typeof o.nodeName == TYPES.s + ); + } + + /** + * Compares 2 arrays and returns the differences between them as a array. + * @param a1 The first array which shall be compared. + * @param a2 The second array which shall be compared. + * @returns {Array} The differences between the two arrays. + */ + function getArrayDifferences(a1, a2) { + var a = []; + var diff = []; + var i; + var k; + for (i = 0; i < a1.length; i++) + a[a1[i]] = true; + for (i = 0; i < a2.length; i++) { + if (a[a2[i]]) + delete a[a2[i]]; + else + a[a2[i]] = true; + } + for (k in a) + diff.push(k); + return diff; + } + + /** + * Returns Zero or the number to which the value can be parsed. + * @param value The value which shall be parsed. + * @param toFloat Indicates whether the number shall be parsed to a float. + */ + function parseToZeroOrNumber(value, toFloat) { + var num = toFloat ? parseFloat(value) : parseInt(value, 10); + return isNaN(num) ? 0 : num; + } + + /** + * Gets several information of the textarea and returns them as a object or undefined if the browser doesn't support it. + * @returns {{cursorRow: Number, cursorCol, rows: Number, cols: number, wRow: number, pos: number, max : number}} or undefined if not supported. + */ + function getTextareaInfo() { + //read needed values + var textareaCursorPosition = _targetElementNative.selectionStart; + if (textareaCursorPosition === undefined) + return; + + var textareaValue = _targetElement.val(); + var textareaLength = textareaValue[LEXICON.l]; + var textareaRowSplit = textareaValue.split('\n'); + var textareaLastRow = textareaRowSplit[LEXICON.l]; + var textareaCurrentCursorRowSplit = textareaValue.substr(0, textareaCursorPosition).split('\n'); + var widestRow = 0; + var textareaLastCol = 0; + var cursorRow = textareaCurrentCursorRowSplit[LEXICON.l]; + var cursorCol = textareaCurrentCursorRowSplit[textareaCurrentCursorRowSplit[LEXICON.l] - 1][LEXICON.l]; + var rowCols; + var i; + + //get widest Row and the last column of the textarea + for (i = 0; i < textareaRowSplit[LEXICON.l]; i++) { + rowCols = textareaRowSplit[i][LEXICON.l]; + if (rowCols > textareaLastCol) { + widestRow = i + 1; + textareaLastCol = rowCols; + } + } + + return { + _cursorRow: cursorRow, //cursorRow + _cursorColumn: cursorCol, //cursorCol + _rows: textareaLastRow, //rows + _columns: textareaLastCol, //cols + _widestRow: widestRow, //wRow + _cursorPosition: textareaCursorPosition, //pos + _cursorMax: textareaLength //max + }; + } + + /** + * Determines whether native overlay scrollbars are active. + * @returns {boolean} True if native overlay scrollbars are active, false otherwise. + */ + function nativeOverlayScrollbarsAreActive() { + return (_ignoreOverlayScrollbarHidingCache && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)); + } + + /** + * Gets the element which is used to measure the content size. + * @returns {*} TextareaCover if target element is textarea else the ContentElement. + */ + function getContentMeasureElement() { + return _isTextarea ? _textareaCoverElement[0] : _contentElementNative; + } + + /** + * Generates a string which represents a HTML div with the given classes or attributes. + * @param classesOrAttrs The class of the div as string or a object which represents the attributes of the div. (The class attribute can also be written as "className".) + * @param content The content of the div as string. + * @returns {string} The concated string which represents a HTML div and its content. + */ + function generateDiv(classesOrAttrs, content) { + return '
        ' + + (content || _strEmpty) + + '
        '; + } + + /** + * Selects or generates a div with the given class attribute. + * @param className The class names (divided by spaces) of the div which shall be selected or generated. + * @param selectParentOrOnlyChildren The parent element from which of the element shall be selected. (if undefined or boolean its hostElement) + * If its a boolean it decides whether only the children of the host element shall be selected. + * @returns {*} The generated or selected element. + */ + function selectOrGenerateDivByClass(className, selectParentOrOnlyChildren) { + var onlyChildren = type(selectParentOrOnlyChildren) == TYPES.b; + var selectParent = onlyChildren ? _hostElement : (selectParentOrOnlyChildren || _hostElement); + + return (_domExists && !selectParent[LEXICON.l]) + ? null + : _domExists + ? selectParent[onlyChildren ? 'children' : 'find'](_strDot + className.replace(/\s/g, _strDot)).eq(0) + : FRAMEWORK(generateDiv(className)) + } + + /** + * Gets the value of the given property from the given object. + * @param obj The object from which the property value shall be got. + * @param path The property of which the value shall be got. + * @returns {*} Returns the value of the searched property or undefined of the property wasn't found. + */ + function getObjectPropVal(obj, path) { + var splits = path.split(_strDot); + var i = 0; + var val; + for (; i < splits.length; i++) { + if (!obj[LEXICON.hOP](splits[i])) + return; + val = obj[splits[i]]; + if (i < splits.length && type(val) == TYPES.o) + obj = val; + } + return val; + } + + /** + * Sets the value of the given property from the given object. + * @param obj The object from which the property value shall be set. + * @param path The property of which the value shall be set. + * @param val The value of the property which shall be set. + */ + function setObjectPropVal(obj, path, val) { + var splits = path.split(_strDot); + var splitsLength = splits.length; + var i = 0; + var extendObj = {}; + var extendObjRoot = extendObj; + for (; i < splitsLength; i++) + extendObj = extendObj[splits[i]] = i + 1 < splitsLength ? {} : val; + FRAMEWORK.extend(obj, extendObjRoot, true); + } + + /** + * Runs a action for each selector inside the updateOnLoad option. + * @param {Function} action The action for each updateOnLoad selector, the arguments the function takes is the index and the value (the selector). + */ + function eachUpdateOnLoad(action) { + var updateOnLoad = _currentPreparedOptions.updateOnLoad; + updateOnLoad = type(updateOnLoad) == TYPES.s ? updateOnLoad.split(_strSpace) : updateOnLoad; + + if (COMPATIBILITY.isA(updateOnLoad) && !_destroyed) { + each(updateOnLoad, action); + } + } + + + //==== Utils Cache ====// + + /** + * Compares two values or objects and returns true if they aren't equal. + * @param current The first value or object which shall be compared. + * @param cache The second value or object which shall be compared. + * @param force If true the returned value is always true. + * @returns {boolean} True if both values or objects aren't equal or force is true, false otherwise. + */ + function checkCache(current, cache, force) { + if (force) + return force; + if (type(current) == TYPES.o && type(cache) == TYPES.o) { + for (var prop in current) { + if (prop !== 'c') { + if (current[LEXICON.hOP](prop) && cache[LEXICON.hOP](prop)) { + if (checkCache(current[prop], cache[prop])) + return true; + } + else { + return true; + } + } + } + } + else { + return current !== cache; + } + return false; + } + + + //==== Shortcuts ====// + + /** + * jQuery extend method shortcut with a appended "true" as first argument. + */ + function extendDeep() { + return FRAMEWORK.extend.apply(this, [true].concat([].slice.call(arguments))); + } + + /** + * jQuery addClass method shortcut. + */ + function addClass(el, classes) { + return _frameworkProto.addClass.call(el, classes); + } + + /** + * jQuery removeClass method shortcut. + */ + function removeClass(el, classes) { + return _frameworkProto.removeClass.call(el, classes); + } + + /** + * Adds or removes the given classes dependent on the boolean value. True for add, false for remove. + */ + function addRemoveClass(el, classes, doAdd) { + return doAdd ? addClass(el, classes) : removeClass(el, classes); + } + + /** + * jQuery remove method shortcut. + */ + function remove(el) { + return _frameworkProto.remove.call(el); + } + + /** + * Finds the first child element with the given selector of the given element. + * @param el The root element from which the selector shall be valid. + * @param selector The selector of the searched element. + * @returns {*} The first element which is a child of the given element and matches the givens selector. + */ + function findFirst(el, selector) { + return _frameworkProto.find.call(el, selector).eq(0); + } + + + //==== API ====// + + /** + * Puts the instance to sleep. It wont respond to any changes in the DOM and won't update. Scrollbar Interactivity is also disabled as well as the resize handle. + * This behavior can be reset by calling the update method. + */ + _base.sleep = function () { + _sleeping = true; + }; + + /** + * Updates the plugin and DOM to the current options. + * This method should only be called if a update is 100% required. + * @param force True if every property shall be updated and the cache shall be ignored. + * !INTERNAL USAGE! : force can be a string "auto", "sync" or "zoom" too + * if "auto" then before a real update the content size and host element attributes gets checked, and if they changed only then the update method will be called. + * if "sync" then the async update process (MutationObserver or UpdateLoop) gets synchronized and a corresponding update takes place if one was needed due to pending changes. + * if "zoom" then a update takes place where it's assumed that content and host size changed + * @returns {boolean|undefined} + * If force is "sync" then a boolean is returned which indicates whether a update was needed due to pending changes. + * If force is "auto" then a boolean is returned whether a update was needed due to attribute or size changes. + * undefined otherwise. + */ + _base.update = function (force) { + if (_destroyed) + return; + + var attrsChanged; + var contentSizeC; + var isString = type(force) == TYPES.s; + var doUpdateAuto; + var mutHost; + var mutContent; + + if (isString) { + if (force === _strAuto) { + attrsChanged = meaningfulAttrsChanged(); + contentSizeC = updateAutoContentSizeChanged(); + doUpdateAuto = attrsChanged || contentSizeC; + if (doUpdateAuto) { + update({ + _contentSizeChanged: contentSizeC, + _changedOptions: _initialized ? undefined : _currentPreparedOptions + }); + } + } + else if (force === _strSync) { + if (_mutationObserversConnected) { + mutHost = _mutationObserverHostCallback(_mutationObserverHost.takeRecords()); + mutContent = _mutationObserverContentCallback(_mutationObserverContent.takeRecords()); + } + else { + mutHost = _base.update(_strAuto); + } + } + else if (force === 'zoom') { + update({ + _hostSizeChanged: true, + _contentSizeChanged: true + }); + } + } + else { + force = _sleeping || force; + _sleeping = false; + if (!_base.update(_strSync) || force) + update({ _force: force }); + } + + updateElementsOnLoad(); + + return doUpdateAuto || mutHost || mutContent; + }; + + /** + Gets or sets the current options. The update method will be called automatically if new options were set. + * @param newOptions If new options are given, then the new options will be set, if new options aren't given (undefined or a not a plain object) then the current options will be returned. + * @param value If new options is a property path string, then this value will be used to set the option to which the property path string leads. + * @returns {*} + */ + _base.options = function (newOptions, value) { + var option = {}; + var changedOps; + + //return current options if newOptions are undefined or empty + if (FRAMEWORK.isEmptyObject(newOptions) || !FRAMEWORK.isPlainObject(newOptions)) { + if (type(newOptions) == TYPES.s) { + if (arguments.length > 1) { + setObjectPropVal(option, newOptions, value); + changedOps = setOptions(option); + } + else + return getObjectPropVal(_currentOptions, newOptions); + } + else + return _currentOptions; + } + else { + changedOps = setOptions(newOptions); + } + + if (!FRAMEWORK.isEmptyObject(changedOps)) { + update({ _changedOptions: changedOps }); + } + }; + + /** + * Restore the DOM, disconnects all observers, remove all resize observers and put the instance to sleep. + */ + _base.destroy = function () { + if (_destroyed) + return; + + //remove this instance from auto update loop + autoUpdateLoop.remove(_base); + + //disconnect all mutation observers + disconnectMutationObservers(); + + //remove all resize observers + setupResizeObserver(_sizeObserverElement); + setupResizeObserver(_sizeAutoObserverElement); + + //remove all extensions + for (var extName in _extensions) + _base.removeExt(extName); + + //remove all 'destroy' events + while (_destroyEvents[LEXICON.l] > 0) + _destroyEvents.pop()(); + + //remove all events from host element + setupHostMouseTouchEvents(true); + + //remove all helper / detection elements + if (_contentGlueElement) + remove(_contentGlueElement); + if (_contentArrangeElement) + remove(_contentArrangeElement); + if (_sizeAutoObserverAdded) + remove(_sizeAutoObserverElement); + + //remove all generated DOM + setupScrollbarsDOM(true); + setupScrollbarCornerDOM(true); + setupStructureDOM(true); + + //remove all generated image load events + for (var i = 0; i < _updateOnLoadElms[LEXICON.l]; i++) + FRAMEWORK(_updateOnLoadElms[i]).off(_updateOnLoadEventName, updateOnLoadCallback); + _updateOnLoadElms = undefined; + + _destroyed = true; + _sleeping = true; + + //remove this instance from the instances list + INSTANCES(pluginTargetElement, 0); + dispatchCallback('onDestroyed'); + + //remove all properties and methods + //for (var property in _base) + // delete _base[property]; + //_base = undefined; + }; + + /** + * Scrolls to a given position or element. + * @param coordinates + * 1. Can be "coordinates" which looks like: + * { x : ?, y : ? } OR Object with x and y properties + * { left : ?, top : ? } OR Object with left and top properties + * { l : ?, t : ? } OR Object with l and t properties + * [ ?, ? ] OR Array where the first two element are the coordinates (first is x, second is y) + * ? A single value which stays for both axis + * A value can be a number, a string or a calculation. + * + * Operators: + * [NONE] The current scroll will be overwritten by the value. + * '+=' The value will be added to the current scroll offset + * '-=' The value will be subtracted from the current scroll offset + * '*=' The current scroll wil be multiplicated by the value. + * '/=' The current scroll wil be divided by the value. + * + * Units: + * [NONE] The value is the final scroll amount. final = (value * 1) + * 'px' Same as none + * '%' The value is dependent on the current scroll value. final = ((currentScrollValue / 100) * value) + * 'vw' The value is multiplicated by the viewport width. final = (value * viewportWidth) + * 'vh' The value is multiplicated by the viewport height. final = (value * viewportHeight) + * + * example final values: + * 200, '200px', '50%', '1vw', '1vh', '+=200', '/=1vw', '*=2px', '-=5vh', '+=33%', '+= 50% - 2px', '-= 1vw - 50%' + * + * 2. Can be a HTML or jQuery element: + * The final scroll offset is the offset (without margin) of the given HTML / jQuery element. + * + * 3. Can be a object with a HTML or jQuery element with additional settings: + * { + * el : [HTMLElement, jQuery element], MUST be specified, else this object isn't valid. + * scroll : [string, array, object], Default value is 'always'. + * block : [string, array, object], Default value is 'begin'. + * margin : [number, boolean, array, object] Default value is false. + * } + * + * Possible scroll settings are: + * 'always' Scrolls always. + * 'ifneeded' Scrolls only if the element isnt fully in view. + * 'never' Scrolls never. + * + * Possible block settings are: + * 'begin' Both axis shall be docked to the "begin" edge. - The element will be docked to the top and left edge of the viewport. + * 'end' Both axis shall be docked to the "end" edge. - The element will be docked to the bottom and right edge of the viewport. (If direction is RTL to the bottom and left edge.) + * 'center' Both axis shall be docked to "center". - The element will be centered in the viewport. + * 'nearest' The element will be docked to the nearest edge(s). + * + * Possible margin settings are: -- The actual margin of the element wont be affect, this option affects only the final scroll offset. + * [BOOLEAN] If true the css margin of the element will be used, if false no margin will be used. + * [NUMBER] The margin will be used for all edges. + * + * @param duration The duration of the scroll animation, OR a jQuery animation configuration object. + * @param easing The animation easing. + * @param complete The animation complete callback. + * @returns {{ + * position: {x: number, y: number}, + * ratio: {x: number, y: number}, + * max: {x: number, y: number}, + * handleOffset: {x: number, y: number}, + * handleLength: {x: number, y: number}, + * handleLengthRatio: {x: number, y: number}, t + * rackLength: {x: number, y: number}, + * isRTL: boolean, + * isRTLNormalized: boolean + * }} + */ + _base.scroll = function (coordinates, duration, easing, complete) { + if (arguments.length === 0 || coordinates === undefined) { + var infoX = _scrollHorizontalInfo; + var infoY = _scrollVerticalInfo; + var normalizeInvert = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.i; + var normalizeNegate = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.n; + var scrollX = infoX._currentScroll; + var scrollXRatio = infoX._currentScrollRatio; + var maxScrollX = infoX._maxScroll; + scrollXRatio = normalizeInvert ? 1 - scrollXRatio : scrollXRatio; + scrollX = normalizeInvert ? maxScrollX - scrollX : scrollX; + scrollX *= normalizeNegate ? -1 : 1; + maxScrollX *= normalizeNegate ? -1 : 1; + + return { + position: { + x: scrollX, + y: infoY._currentScroll + }, + ratio: { + x: scrollXRatio, + y: infoY._currentScrollRatio + }, + max: { + x: maxScrollX, + y: infoY._maxScroll + }, + handleOffset: { + x: infoX._handleOffset, + y: infoY._handleOffset + }, + handleLength: { + x: infoX._handleLength, + y: infoY._handleLength + }, + handleLengthRatio: { + x: infoX._handleLengthRatio, + y: infoY._handleLengthRatio + }, + trackLength: { + x: infoX._trackLength, + y: infoY._trackLength + }, + snappedHandleOffset: { + x: infoX._snappedHandleOffset, + y: infoY._snappedHandleOffset + }, + isRTL: _isRTL, + isRTLNormalized: _normalizeRTLCache + }; + } + + _base.update(_strSync); + + var normalizeRTL = _normalizeRTLCache; + var coordinatesXAxisProps = [_strX, _strLeft, 'l']; + var coordinatesYAxisProps = [_strY, _strTop, 't']; + var coordinatesOperators = ['+=', '-=', '*=', '/=']; + var durationIsObject = type(duration) == TYPES.o; + var completeCallback = durationIsObject ? duration.complete : complete; + var i; + var finalScroll = {}; + var specialEasing = {}; + var doScrollLeft; + var doScrollTop; + var animationOptions; + var strEnd = 'end'; + var strBegin = 'begin'; + var strCenter = 'center'; + var strNearest = 'nearest'; + var strAlways = 'always'; + var strNever = 'never'; + var strIfNeeded = 'ifneeded'; + var strLength = LEXICON.l; + var settingsAxis; + var settingsScroll; + var settingsBlock; + var settingsMargin; + var finalElement; + var elementObjSettingsAxisValues = [_strX, _strY, 'xy', 'yx']; + var elementObjSettingsBlockValues = [strBegin, strEnd, strCenter, strNearest]; + var elementObjSettingsScrollValues = [strAlways, strNever, strIfNeeded]; + var coordinatesIsElementObj = coordinates[LEXICON.hOP]('el'); + var possibleElement = coordinatesIsElementObj ? coordinates.el : coordinates; + var possibleElementIsJQuery = possibleElement instanceof FRAMEWORK || JQUERY ? possibleElement instanceof JQUERY : false; + var possibleElementIsHTMLElement = possibleElementIsJQuery ? false : isHTMLElement(possibleElement); + var updateScrollbarInfos = function () { + if (doScrollLeft) + refreshScrollbarHandleOffset(true); + if (doScrollTop) + refreshScrollbarHandleOffset(false); + }; + var proxyCompleteCallback = type(completeCallback) != TYPES.f ? undefined : function () { + updateScrollbarInfos(); + completeCallback(); + }; + function checkSettingsStringValue(currValue, allowedValues) { + for (i = 0; i < allowedValues[strLength]; i++) { + if (currValue === allowedValues[i]) + return true; + } + return false; + } + function getRawScroll(isX, coordinates) { + var coordinateProps = isX ? coordinatesXAxisProps : coordinatesYAxisProps; + coordinates = type(coordinates) == TYPES.s || type(coordinates) == TYPES.n ? [coordinates, coordinates] : coordinates; + + if (COMPATIBILITY.isA(coordinates)) + return isX ? coordinates[0] : coordinates[1]; + else if (type(coordinates) == TYPES.o) { + //decides RTL normalization "hack" with .n + //normalizeRTL = type(coordinates.n) == TYPES.b ? coordinates.n : normalizeRTL; + for (i = 0; i < coordinateProps[strLength]; i++) + if (coordinateProps[i] in coordinates) + return coordinates[coordinateProps[i]]; + } + } + function getFinalScroll(isX, rawScroll) { + var isString = type(rawScroll) == TYPES.s; + var operator; + var amount; + var scrollInfo = isX ? _scrollHorizontalInfo : _scrollVerticalInfo; + var currScroll = scrollInfo._currentScroll; + var maxScroll = scrollInfo._maxScroll; + var mult = ' * '; + var finalValue; + var isRTLisX = _isRTL && isX; + var normalizeShortcuts = isRTLisX && _rtlScrollBehavior.n && !normalizeRTL; + var strReplace = 'replace'; + var evalFunc = eval; + var possibleOperator; + if (isString) { + //check operator + if (rawScroll[strLength] > 2) { + possibleOperator = rawScroll.substr(0, 2); + if (inArray(possibleOperator, coordinatesOperators) > -1) + operator = possibleOperator; + } + + //calculate units and shortcuts + rawScroll = operator ? rawScroll.substr(2) : rawScroll; + rawScroll = rawScroll + [strReplace](/min/g, 0) //'min' = 0% + [strReplace](//g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'>' = 100% + [strReplace](/px/g, _strEmpty) + [strReplace](/%/g, mult + (maxScroll * (isRTLisX && _rtlScrollBehavior.n ? -1 : 1) / 100.0)) + [strReplace](/vw/g, mult + _viewportSize.w) + [strReplace](/vh/g, mult + _viewportSize.h); + amount = parseToZeroOrNumber(isNaN(rawScroll) ? parseToZeroOrNumber(evalFunc(rawScroll), true).toFixed() : rawScroll); + } + else { + amount = rawScroll; + } + + if (amount !== undefined && !isNaN(amount) && type(amount) == TYPES.n) { + var normalizeIsRTLisX = normalizeRTL && isRTLisX; + var operatorCurrScroll = currScroll * (normalizeIsRTLisX && _rtlScrollBehavior.n ? -1 : 1); + var invert = normalizeIsRTLisX && _rtlScrollBehavior.i; + var negate = normalizeIsRTLisX && _rtlScrollBehavior.n; + operatorCurrScroll = invert ? (maxScroll - operatorCurrScroll) : operatorCurrScroll; + switch (operator) { + case '+=': + finalValue = operatorCurrScroll + amount; + break; + case '-=': + finalValue = operatorCurrScroll - amount; + break; + case '*=': + finalValue = operatorCurrScroll * amount; + break; + case '/=': + finalValue = operatorCurrScroll / amount; + break; + default: + finalValue = amount; + break; + } + finalValue = invert ? maxScroll - finalValue : finalValue; + finalValue *= negate ? -1 : 1; + finalValue = isRTLisX && _rtlScrollBehavior.n ? MATH.min(0, MATH.max(maxScroll, finalValue)) : MATH.max(0, MATH.min(maxScroll, finalValue)); + } + return finalValue === currScroll ? undefined : finalValue; + } + function getPerAxisValue(value, valueInternalType, defaultValue, allowedValues) { + var resultDefault = [defaultValue, defaultValue]; + var valueType = type(value); + var valueArrLength; + var valueArrItem; + + //value can be [ string, or array of two strings ] + if (valueType == valueInternalType) { + value = [value, value]; + } + else if (valueType == TYPES.a) { + valueArrLength = value[strLength]; + if (valueArrLength > 2 || valueArrLength < 1) + value = resultDefault; + else { + if (valueArrLength === 1) + value[1] = defaultValue; + for (i = 0; i < valueArrLength; i++) { + valueArrItem = value[i]; + if (type(valueArrItem) != valueInternalType || !checkSettingsStringValue(valueArrItem, allowedValues)) { + value = resultDefault; + break; + } + } + } + } + else if (valueType == TYPES.o) + value = [value[_strX] || defaultValue, value[_strY] || defaultValue]; + else + value = resultDefault; + return { x: value[0], y: value[1] }; + } + function generateMargin(marginTopRightBottomLeftArray) { + var result = []; + var currValue; + var currValueType; + var valueDirections = [_strTop, _strRight, _strBottom, _strLeft]; + for (i = 0; i < marginTopRightBottomLeftArray[strLength]; i++) { + if (i === valueDirections[strLength]) + break; + currValue = marginTopRightBottomLeftArray[i]; + currValueType = type(currValue); + if (currValueType == TYPES.b) + result.push(currValue ? parseToZeroOrNumber(finalElement.css(_strMarginMinus + valueDirections[i])) : 0); + else + result.push(currValueType == TYPES.n ? currValue : 0); + } + return result; + } + + if (possibleElementIsJQuery || possibleElementIsHTMLElement) { + //get settings + var margin = coordinatesIsElementObj ? coordinates.margin : 0; + var axis = coordinatesIsElementObj ? coordinates.axis : 0; + var scroll = coordinatesIsElementObj ? coordinates.scroll : 0; + var block = coordinatesIsElementObj ? coordinates.block : 0; + var marginDefault = [0, 0, 0, 0]; + var marginType = type(margin); + var marginLength; + finalElement = possibleElementIsJQuery ? possibleElement : FRAMEWORK(possibleElement); + + if (finalElement[strLength] > 0) { + //margin can be [ boolean, number, array of 2, array of 4, object ] + if (marginType == TYPES.n || marginType == TYPES.b) + margin = generateMargin([margin, margin, margin, margin]); + else if (marginType == TYPES.a) { + marginLength = margin[strLength]; + if (marginLength === 2) + margin = generateMargin([margin[0], margin[1], margin[0], margin[1]]); + else if (marginLength >= 4) + margin = generateMargin(margin); + else + margin = marginDefault; + } + else if (marginType == TYPES.o) + margin = generateMargin([margin[_strTop], margin[_strRight], margin[_strBottom], margin[_strLeft]]); + else + margin = marginDefault; + + //block = type(block) === TYPES.b ? block ? [ strNearest, strBegin ] : [ strNearest, strEnd ] : block; + settingsAxis = checkSettingsStringValue(axis, elementObjSettingsAxisValues) ? axis : 'xy'; + settingsScroll = getPerAxisValue(scroll, TYPES.s, strAlways, elementObjSettingsScrollValues); + settingsBlock = getPerAxisValue(block, TYPES.s, strBegin, elementObjSettingsBlockValues); + settingsMargin = margin; + + var viewportScroll = { + l: _scrollHorizontalInfo._currentScroll, + t: _scrollVerticalInfo._currentScroll + }; + // use padding element instead of viewport element because padding element has never padding, margin or position applied. + var viewportOffset = _paddingElement.offset(); + + //get coordinates + var elementOffset = finalElement.offset(); + var doNotScroll = { + x: settingsScroll.x == strNever || settingsAxis == _strY, + y: settingsScroll.y == strNever || settingsAxis == _strX + }; + elementOffset[_strTop] -= settingsMargin[0]; + elementOffset[_strLeft] -= settingsMargin[3]; + var elementScrollCoordinates = { + x: MATH.round(elementOffset[_strLeft] - viewportOffset[_strLeft] + viewportScroll.l), + y: MATH.round(elementOffset[_strTop] - viewportOffset[_strTop] + viewportScroll.t) + }; + if (_isRTL) { + if (!_rtlScrollBehavior.n && !_rtlScrollBehavior.i) + elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + viewportScroll.l); + if (_rtlScrollBehavior.n && normalizeRTL) + elementScrollCoordinates.x *= -1; + if (_rtlScrollBehavior.i && normalizeRTL) + elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + (_scrollHorizontalInfo._maxScroll - viewportScroll.l)); + } + + //measuring is required + if (settingsBlock.x != strBegin || settingsBlock.y != strBegin || settingsScroll.x == strIfNeeded || settingsScroll.y == strIfNeeded || _isRTL) { + var measuringElm = finalElement[0]; + var rawElementSize = _supportTransform ? measuringElm[LEXICON.bCR]() : { + width: measuringElm[LEXICON.oW], + height: measuringElm[LEXICON.oH] + }; + var elementSize = { + w: rawElementSize[_strWidth] + settingsMargin[3] + settingsMargin[1], + h: rawElementSize[_strHeight] + settingsMargin[0] + settingsMargin[2] + }; + var finalizeBlock = function (isX) { + var vars = getScrollbarVars(isX); + var wh = vars._w_h; + var lt = vars._left_top; + var xy = vars._x_y; + var blockIsEnd = settingsBlock[xy] == (isX ? _isRTL ? strBegin : strEnd : strEnd); + var blockIsCenter = settingsBlock[xy] == strCenter; + var blockIsNearest = settingsBlock[xy] == strNearest; + var scrollNever = settingsScroll[xy] == strNever; + var scrollIfNeeded = settingsScroll[xy] == strIfNeeded; + var vpSize = _viewportSize[wh]; + var vpOffset = viewportOffset[lt]; + var elSize = elementSize[wh]; + var elOffset = elementOffset[lt]; + var divide = blockIsCenter ? 2 : 1; + var elementCenterOffset = elOffset + (elSize / 2); + var viewportCenterOffset = vpOffset + (vpSize / 2); + var isInView = + elSize <= vpSize + && elOffset >= vpOffset + && elOffset + elSize <= vpOffset + vpSize; + + if (scrollNever) + doNotScroll[xy] = true; + else if (!doNotScroll[xy]) { + if (blockIsNearest || scrollIfNeeded) { + doNotScroll[xy] = scrollIfNeeded ? isInView : false; + blockIsEnd = elSize < vpSize ? elementCenterOffset > viewportCenterOffset : elementCenterOffset < viewportCenterOffset; + } + elementScrollCoordinates[xy] -= blockIsEnd || blockIsCenter ? ((vpSize / divide) - (elSize / divide)) * (isX && _isRTL && normalizeRTL ? -1 : 1) : 0; + } + }; + finalizeBlock(true); + finalizeBlock(false); + } + + if (doNotScroll.y) + delete elementScrollCoordinates.y; + if (doNotScroll.x) + delete elementScrollCoordinates.x; + + coordinates = elementScrollCoordinates; + } + } + + finalScroll[_strScrollLeft] = getFinalScroll(true, getRawScroll(true, coordinates)); + finalScroll[_strScrollTop] = getFinalScroll(false, getRawScroll(false, coordinates)); + doScrollLeft = finalScroll[_strScrollLeft] !== undefined; + doScrollTop = finalScroll[_strScrollTop] !== undefined; + + if ((doScrollLeft || doScrollTop) && (duration > 0 || durationIsObject)) { + if (durationIsObject) { + duration.complete = proxyCompleteCallback; + _viewportElement.animate(finalScroll, duration); + } + else { + animationOptions = { + duration: duration, + complete: proxyCompleteCallback + }; + if (COMPATIBILITY.isA(easing) || FRAMEWORK.isPlainObject(easing)) { + specialEasing[_strScrollLeft] = easing[0] || easing.x; + specialEasing[_strScrollTop] = easing[1] || easing.y; + animationOptions.specialEasing = specialEasing; + } + else { + animationOptions.easing = easing; + } + _viewportElement.animate(finalScroll, animationOptions); + } + } + else { + if (doScrollLeft) + _viewportElement[_strScrollLeft](finalScroll[_strScrollLeft]); + if (doScrollTop) + _viewportElement[_strScrollTop](finalScroll[_strScrollTop]); + updateScrollbarInfos(); + } + }; + + /** + * Stops all scroll animations. + * @returns {*} The current OverlayScrollbars instance (for chaining). + */ + _base.scrollStop = function (param1, param2, param3) { + _viewportElement.stop(param1, param2, param3); + return _base; + }; + + /** + * Returns all relevant elements. + * @param elementName The name of the element which shall be returned. + * @returns {{target: *, host: *, padding: *, viewport: *, content: *, scrollbarHorizontal: {scrollbar: *, track: *, handle: *}, scrollbarVertical: {scrollbar: *, track: *, handle: *}, scrollbarCorner: *} | *} + */ + _base.getElements = function (elementName) { + var obj = { + target: _targetElementNative, + host: _hostElementNative, + padding: _paddingElementNative, + viewport: _viewportElementNative, + content: _contentElementNative, + scrollbarHorizontal: { + scrollbar: _scrollbarHorizontalElement[0], + track: _scrollbarHorizontalTrackElement[0], + handle: _scrollbarHorizontalHandleElement[0] + }, + scrollbarVertical: { + scrollbar: _scrollbarVerticalElement[0], + track: _scrollbarVerticalTrackElement[0], + handle: _scrollbarVerticalHandleElement[0] + }, + scrollbarCorner: _scrollbarCornerElement[0] + }; + return type(elementName) == TYPES.s ? getObjectPropVal(obj, elementName) : obj; + }; + + /** + * Returns a object which describes the current state of this instance. + * @param stateProperty A specific property from the state object which shall be returned. + * @returns {{widthAuto, heightAuto, overflowAmount, hideOverflow, hasOverflow, contentScrollSize, viewportSize, hostSize, autoUpdate} | *} + */ + _base.getState = function (stateProperty) { + function prepare(obj) { + if (!FRAMEWORK.isPlainObject(obj)) + return obj; + var extended = extendDeep({}, obj); + var changePropertyName = function (from, to) { + if (extended[LEXICON.hOP](from)) { + extended[to] = extended[from]; + delete extended[from]; + } + }; + changePropertyName('w', _strWidth); //change w to width + changePropertyName('h', _strHeight); //change h to height + delete extended.c; //delete c (the 'changed' prop) + return extended; + }; + var obj = { + destroyed: !!prepare(_destroyed), + sleeping: !!prepare(_sleeping), + autoUpdate: prepare(!_mutationObserversConnected), + widthAuto: prepare(_widthAutoCache), + heightAuto: prepare(_heightAutoCache), + padding: prepare(_cssPaddingCache), + overflowAmount: prepare(_overflowAmountCache), + hideOverflow: prepare(_hideOverflowCache), + hasOverflow: prepare(_hasOverflowCache), + contentScrollSize: prepare(_contentScrollSizeCache), + viewportSize: prepare(_viewportSize), + hostSize: prepare(_hostSizeCache), + documentMixed: prepare(_documentMixed) + }; + return type(stateProperty) == TYPES.s ? getObjectPropVal(obj, stateProperty) : obj; + }; + + /** + * Gets all or specific extension instance. + * @param extName The name of the extension from which the instance shall be got. + * @returns {{}} The instance of the extension with the given name or undefined if the instance couldn't be found. + */ + _base.ext = function (extName) { + var result; + var privateMethods = _extensionsPrivateMethods.split(' '); + var i = 0; + if (type(extName) == TYPES.s) { + if (_extensions[LEXICON.hOP](extName)) { + result = extendDeep({}, _extensions[extName]); + for (; i < privateMethods.length; i++) + delete result[privateMethods[i]]; + } + } + else { + result = {}; + for (i in _extensions) + result[i] = extendDeep({}, _base.ext(i)); + } + return result; + }; + + /** + * Adds a extension to this instance. + * @param extName The name of the extension which shall be added. + * @param extensionOptions The extension options which shall be used. + * @returns {{}} The instance of the added extension or undefined if the extension couldn't be added properly. + */ + _base.addExt = function (extName, extensionOptions) { + var registeredExtensionObj = _plugin.extension(extName); + var instance; + var instanceAdded; + var instanceContract; + var contractResult; + var contractFulfilled = true; + if (registeredExtensionObj) { + if (!_extensions[LEXICON.hOP](extName)) { + instance = registeredExtensionObj.extensionFactory.call(_base, + extendDeep({}, registeredExtensionObj.defaultOptions), + FRAMEWORK, + COMPATIBILITY); + + if (instance) { + instanceContract = instance.contract; + if (type(instanceContract) == TYPES.f) { + contractResult = instanceContract(window); + contractFulfilled = type(contractResult) == TYPES.b ? contractResult : contractFulfilled; + } + if (contractFulfilled) { + _extensions[extName] = instance; + instanceAdded = instance.added; + if (type(instanceAdded) == TYPES.f) + instanceAdded(extensionOptions); + + return _base.ext(extName); + } + } + } + else + return _base.ext(extName); + } + else + console.warn("A extension with the name \"" + extName + "\" isn't registered."); + }; + + /** + * Removes a extension from this instance. + * @param extName The name of the extension which shall be removed. + * @returns {boolean} True if the extension was removed, false otherwise e.g. if the extension wasn't added before. + */ + _base.removeExt = function (extName) { + var instance = _extensions[extName]; + var instanceRemoved; + if (instance) { + delete _extensions[extName]; + + instanceRemoved = instance.removed; + if (type(instanceRemoved) == TYPES.f) + instanceRemoved(); + + return true; + } + return false; + }; + + /** + * Constructs the plugin. + * @param targetElement The element to which the plugin shall be applied. + * @param options The initial options of the plugin. + * @param extensions The extension(s) which shall be added right after the initialization. + * @returns {boolean} True if the plugin was successfully initialized, false otherwise. + */ + function construct(targetElement, options, extensions) { + _defaultOptions = globals.defaultOptions; + _nativeScrollbarStyling = globals.nativeScrollbarStyling; + _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize); + _nativeScrollbarIsOverlaid = extendDeep({}, globals.nativeScrollbarIsOverlaid); + _overlayScrollbarDummySize = extendDeep({}, globals.overlayScrollbarDummySize); + _rtlScrollBehavior = extendDeep({}, globals.rtlScrollBehavior); + + //parse & set options but don't update + setOptions(extendDeep({}, _defaultOptions, options)); + + _cssCalc = globals.cssCalc; + _msieVersion = globals.msie; + _autoUpdateRecommended = globals.autoUpdateRecommended; + _supportTransition = globals.supportTransition; + _supportTransform = globals.supportTransform; + _supportPassiveEvents = globals.supportPassiveEvents; + _supportResizeObserver = globals.supportResizeObserver; + _supportMutationObserver = globals.supportMutationObserver; + _restrictedMeasuring = globals.restrictedMeasuring; + _documentElement = FRAMEWORK(targetElement.ownerDocument); + _documentElementNative = _documentElement[0]; + _windowElement = FRAMEWORK(_documentElementNative.defaultView || _documentElementNative.parentWindow); + _windowElementNative = _windowElement[0]; + _htmlElement = findFirst(_documentElement, 'html'); + _bodyElement = findFirst(_htmlElement, 'body'); + _targetElement = FRAMEWORK(targetElement); + _targetElementNative = _targetElement[0]; + _isTextarea = _targetElement.is('textarea'); + _isBody = _targetElement.is('body'); + _documentMixed = _documentElementNative !== document; + + /* On a div Element The if checks only whether: + * - the targetElement has the class "os-host" + * - the targetElement has a a child with the class "os-padding" + * + * If that's the case, its assumed the DOM has already the following structure: + * (The ".os-host" element is the targetElement) + * + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + * + * ===================================================================================== + * + * On a Textarea Element The if checks only whether: + * - the targetElement has the class "os-textarea" + * - the targetElement is inside a element with the class "os-content" + * + * If that's the case, its assumed the DOM has already the following structure: + * (The ".os-textarea" (textarea) element is the targetElement) + * + *
        + *
        + *
        + *
        + *
        + *
        + * + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + *
        + */ + _domExists = _isTextarea + ? _targetElement.hasClass(_classNameTextareaElement) && _targetElement.parent().hasClass(_classNameContentElement) + : _targetElement.hasClass(_classNameHostElement) && _targetElement.children(_strDot + _classNamePaddingElement)[LEXICON.l]; + + var initBodyScroll; + var bodyMouseTouchDownListener; + + //check if the plugin hasn't to be initialized + if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y && !_currentPreparedOptions.nativeScrollbarsOverlaid.initialize) { + dispatchCallback('onInitializationWithdrawn'); + if (_domExists) { + setupStructureDOM(true); + setupScrollbarsDOM(true); + setupScrollbarCornerDOM(true); + } + + _destroyed = true; + _sleeping = true; + + return _base; + } + + if (_isBody) { + initBodyScroll = {}; + initBodyScroll.l = MATH.max(_targetElement[_strScrollLeft](), _htmlElement[_strScrollLeft](), _windowElement[_strScrollLeft]()); + initBodyScroll.t = MATH.max(_targetElement[_strScrollTop](), _htmlElement[_strScrollTop](), _windowElement[_strScrollTop]()); + + bodyMouseTouchDownListener = function () { + _viewportElement.removeAttr(LEXICON.ti); + setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, true, true); + } + } + + //build OverlayScrollbars DOM + setupStructureDOM(); + setupScrollbarsDOM(); + setupScrollbarCornerDOM(); + + //create OverlayScrollbars events + setupStructureEvents(); + setupScrollbarEvents(true); + setupScrollbarEvents(false); + setupScrollbarCornerEvents(); + + //create mutation observers + createMutationObservers(); + + //build resize observer for the host element + setupResizeObserver(_sizeObserverElement, hostOnResized); + + if (_isBody) { + //apply the body scroll to handle it right in the update method + _viewportElement[_strScrollLeft](initBodyScroll.l)[_strScrollTop](initBodyScroll.t); + + //set the focus on the viewport element so you dont have to click on the page to use keyboard keys (up / down / space) for scrolling + if (document.activeElement == targetElement && _viewportElementNative.focus) { + //set a tabindex to make the viewportElement focusable + _viewportElement.attr(LEXICON.ti, '-1'); + _viewportElementNative.focus(); + + /* the tabindex has to be removed due to; + * If you set the tabindex attribute on an
        , then its child content cannot be scrolled with the arrow keys unless you set tabindex on the content, too + * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex + */ + setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, false, true); + } + } + + //update for the first time & initialize cache + _base.update(_strAuto); + + //the plugin is initialized now! + _initialized = true; + dispatchCallback('onInitialized'); + + //call all callbacks which would fire before the initialized was complete + each(_callbacksInitQeueue, function (index, value) { dispatchCallback(value.n, value.a); }); + _callbacksInitQeueue = []; + + //add extensions + if (type(extensions) == TYPES.s) + extensions = [extensions]; + if (COMPATIBILITY.isA(extensions)) + each(extensions, function (index, value) { _base.addExt(value); }); + else if (FRAMEWORK.isPlainObject(extensions)) + each(extensions, function (key, value) { _base.addExt(key, value); }); + + //add the transition class for transitions AFTER the first update & AFTER the applied extensions (for preventing unwanted transitions) + setTimeout(function () { + if (_supportTransition && !_destroyed) + addClass(_hostElement, _classNameHostTransition); + }, 333); + + return _base; + } + + if (_plugin.valid(construct(pluginTargetElement, options, extensions))) { + INSTANCES(pluginTargetElement, _base); + } + + return _base; + } + + /** + * Initializes a new OverlayScrollbarsInstance object or changes options if already initialized or returns the current instance. + * @param pluginTargetElements The elements to which the Plugin shall be initialized. + * @param options The custom options with which the plugin shall be initialized. + * @param extensions The extension(s) which shall be added right after initialization. + * @returns {*} + */ + _plugin = window[PLUGINNAME] = function (pluginTargetElements, options, extensions) { + if (arguments[LEXICON.l] === 0) + return this; + + var arr = []; + var optsIsPlainObj = FRAMEWORK.isPlainObject(options); + var inst; + var result; + + //pluginTargetElements is null or undefined + if (!pluginTargetElements) + return optsIsPlainObj || !options ? result : arr; + + /* + pluginTargetElements will be converted to: + 1. A jQueryElement Array + 2. A HTMLElement Array + 3. A Array with a single HTML Element + so pluginTargetElements is always a array. + */ + pluginTargetElements = pluginTargetElements[LEXICON.l] != undefined ? pluginTargetElements : [pluginTargetElements[0] || pluginTargetElements]; + initOverlayScrollbarsStatics(); + + if (pluginTargetElements[LEXICON.l] > 0) { + if (optsIsPlainObj) { + FRAMEWORK.each(pluginTargetElements, function (i, v) { + inst = v; + if (inst !== undefined) + arr.push(OverlayScrollbarsInstance(inst, options, extensions, _pluginsGlobals, _pluginsAutoUpdateLoop)); + }); + } + else { + FRAMEWORK.each(pluginTargetElements, function (i, v) { + inst = INSTANCES(v); + if ((options === '!' && _plugin.valid(inst)) || (COMPATIBILITY.type(options) == TYPES.f && options(v, inst))) + arr.push(inst); + else if (options === undefined) + arr.push(inst); + }); + } + result = arr[LEXICON.l] === 1 ? arr[0] : arr; + } + return result; + }; + + /** + * Returns a object which contains global information about the plugin and each instance of it. + * The returned object is just a copy, that means that changes to the returned object won't have any effect to the original object. + */ + _plugin.globals = function () { + initOverlayScrollbarsStatics(); + var globals = FRAMEWORK.extend(true, {}, _pluginsGlobals); + delete globals['msie']; + return globals; + }; + + /** + * Gets or Sets the default options for each new plugin initialization. + * @param newDefaultOptions The object with which the default options shall be extended. + */ + _plugin.defaultOptions = function (newDefaultOptions) { + initOverlayScrollbarsStatics(); + var currDefaultOptions = _pluginsGlobals.defaultOptions; + if (newDefaultOptions === undefined) + return FRAMEWORK.extend(true, {}, currDefaultOptions); + + //set the new default options + _pluginsGlobals.defaultOptions = FRAMEWORK.extend(true, {}, currDefaultOptions, _pluginsOptions._validate(newDefaultOptions, _pluginsOptions._template, true, currDefaultOptions)._default); + }; + + /** + * Checks whether the passed instance is a non-destroyed OverlayScrollbars instance. + * @param osInstance The potential OverlayScrollbars instance which shall be checked. + * @returns {boolean} True if the passed value is a non-destroyed OverlayScrollbars instance, false otherwise. + */ + _plugin.valid = function (osInstance) { + return osInstance instanceof _plugin && !osInstance.getState().destroyed; + }; + + /** + * Registers, Unregisters or returns a extension. + * Register: Pass the name and the extension. (defaultOptions is optional) + * Unregister: Pass the name and anything except a function as extension parameter. + * Get extension: Pass the name of the extension which shall be got. + * Get all extensions: Pass no arguments. + * @param extensionName The name of the extension which shall be registered, unregistered or returned. + * @param extension A function which generates the instance of the extension or anything other to remove a already registered extension. + * @param defaultOptions The default options which shall be used for the registered extension. + */ + _plugin.extension = function (extensionName, extension, defaultOptions) { + var extNameTypeString = COMPATIBILITY.type(extensionName) == TYPES.s; + var argLen = arguments[LEXICON.l]; + var i = 0; + if (argLen < 1 || !extNameTypeString) { + //return a copy of all extension objects + return FRAMEWORK.extend(true, { length: _pluginsExtensions[LEXICON.l] }, _pluginsExtensions); + } + else if (extNameTypeString) { + if (COMPATIBILITY.type(extension) == TYPES.f) { + //register extension + _pluginsExtensions.push({ + name: extensionName, + extensionFactory: extension, + defaultOptions: defaultOptions + }); + } + else { + for (; i < _pluginsExtensions[LEXICON.l]; i++) { + if (_pluginsExtensions[i].name === extensionName) { + if (argLen > 1) + _pluginsExtensions.splice(i, 1); //remove extension + else + return FRAMEWORK.extend(true, {}, _pluginsExtensions[i]); //return extension with the given name + } + } + } + } + }; + + return _plugin; + })(); + + if (JQUERY && JQUERY.fn) { + /** + * The jQuery initialization interface. + * @param options The initial options for the construction of the plugin. To initialize the plugin, this option has to be a object! If it isn't a object, the instance(s) are returned and the plugin wont be initialized. + * @param extensions The extension(s) which shall be added right after initialization. + * @returns {*} After initialization it returns the jQuery element array, else it returns the instance(s) of the elements which are selected. + */ + JQUERY.fn.overlayScrollbars = function (options, extensions) { + var _elements = this; + if (JQUERY.isPlainObject(options)) { + JQUERY.each(_elements, function () { PLUGIN(this, options, extensions); }); + return _elements; + } + else + return PLUGIN(_elements, options); + }; + } + return PLUGIN; + } +)); + +/***/ }), + +/***/ "../eyes/node_modules/tippy.js/dist/tippy.esm.js": +/*!*******************************************************!*\ + !*** ../eyes/node_modules/tippy.js/dist/tippy.esm.js ***! + \*******************************************************/ +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "animateFill": function() { return /* binding */ animateFill; }, +/* harmony export */ "createSingleton": function() { return /* binding */ createSingleton; }, +/* harmony export */ "delegate": function() { return /* binding */ delegate; }, +/* harmony export */ "followCursor": function() { return /* binding */ followCursor; }, +/* harmony export */ "hideAll": function() { return /* binding */ hideAll; }, +/* harmony export */ "inlinePositioning": function() { return /* binding */ inlinePositioning; }, +/* harmony export */ "roundArrow": function() { return /* binding */ ROUND_ARROW; }, +/* harmony export */ "sticky": function() { return /* binding */ sticky; } +/* harmony export */ }); +/* harmony import */ var _popperjs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @popperjs/core */ "../eyes/node_modules/@popperjs/core/lib/popper.js"); +/* harmony import */ var _popperjs_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @popperjs/core */ "../eyes/node_modules/@popperjs/core/lib/modifiers/applyStyles.js"); +/**! +* tippy.js v6.3.7 +* (c) 2017-2021 atomiks +* MIT License +*/ + + +var ROUND_ARROW = ''; +var BOX_CLASS = "tippy-box"; +var CONTENT_CLASS = "tippy-content"; +var BACKDROP_CLASS = "tippy-backdrop"; +var ARROW_CLASS = "tippy-arrow"; +var SVG_ARROW_CLASS = "tippy-svg-arrow"; +var TOUCH_OPTIONS = { + passive: true, + capture: true +}; +var TIPPY_DEFAULT_APPEND_TO = function TIPPY_DEFAULT_APPEND_TO() { + return document.body; +}; + +function hasOwnProperty(obj, key) { + return {}.hasOwnProperty.call(obj, key); +} +function getValueAtIndexOrReturn(value, index, defaultValue) { + if (Array.isArray(value)) { + var v = value[index]; + return v == null ? Array.isArray(defaultValue) ? defaultValue[index] : defaultValue : v; + } + + return value; +} +function isType(value, type) { + var str = {}.toString.call(value); + return str.indexOf('[object') === 0 && str.indexOf(type + "]") > -1; +} +function invokeWithArgsOrReturn(value, args) { + return typeof value === 'function' ? value.apply(void 0, args) : value; +} +function debounce(fn, ms) { + // Avoid wrapping in `setTimeout` if ms is 0 anyway + if (ms === 0) { + return fn; + } + + var timeout; + return function (arg) { + clearTimeout(timeout); + timeout = setTimeout(function () { + fn(arg); + }, ms); + }; +} +function removeProperties(obj, keys) { + var clone = Object.assign({}, obj); + keys.forEach(function (key) { + delete clone[key]; + }); + return clone; +} +function splitBySpaces(value) { + return value.split(/\s+/).filter(Boolean); +} +function normalizeToArray(value) { + return [].concat(value); +} +function pushIfUnique(arr, value) { + if (arr.indexOf(value) === -1) { + arr.push(value); + } +} +function unique(arr) { + return arr.filter(function (item, index) { + return arr.indexOf(item) === index; + }); +} +function getBasePlacement(placement) { + return placement.split('-')[0]; +} +function arrayFrom(value) { + return [].slice.call(value); +} +function removeUndefinedProps(obj) { + return Object.keys(obj).reduce(function (acc, key) { + if (obj[key] !== undefined) { + acc[key] = obj[key]; + } + + return acc; + }, {}); +} + +function div() { + return document.createElement('div'); +} +function isElement(value) { + return ['Element', 'Fragment'].some(function (type) { + return isType(value, type); + }); +} +function isNodeList(value) { + return isType(value, 'NodeList'); +} +function isMouseEvent(value) { + return isType(value, 'MouseEvent'); +} +function isReferenceElement(value) { + return !!(value && value._tippy && value._tippy.reference === value); +} +function getArrayOfElements(value) { + if (isElement(value)) { + return [value]; + } + + if (isNodeList(value)) { + return arrayFrom(value); + } + + if (Array.isArray(value)) { + return value; + } + + return arrayFrom(document.querySelectorAll(value)); +} +function setTransitionDuration(els, value) { + els.forEach(function (el) { + if (el) { + el.style.transitionDuration = value + "ms"; + } + }); +} +function setVisibilityState(els, state) { + els.forEach(function (el) { + if (el) { + el.setAttribute('data-state', state); + } + }); +} +function getOwnerDocument(elementOrElements) { + var _element$ownerDocumen; + + var _normalizeToArray = normalizeToArray(elementOrElements), + element = _normalizeToArray[0]; // Elements created via a