├── .ask
└── config
├── .github
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── NOTICE
├── README.md
├── docs
├── atmosphere_view.md
├── distance_view.md
├── horizontal_image_list_view.md
├── images
│ ├── familyphoto-atmosphere.jpg
│ ├── familyphoto-distance.jpg
│ ├── familyphoto-horizontal.jpg
│ ├── familyphoto-planet.jpg
│ ├── familyphoto-size.jpg
│ ├── familyphoto-solarsystem.jpg
│ ├── familyphoto-splash.jpg
│ └── familyphoto-transcript.jpg
├── planet_details_view.md
├── size_view.md
├── solar_system_view.md
├── splash_screen_view.md
└── transcript_view.md
├── icons
├── skill-icon-lg.png
└── skill-icon-sm.png
├── lambda
└── custom
│ ├── data
│ ├── images.json
│ └── planets.json
│ ├── documents
│ ├── atmosphere.js
│ ├── distance.js
│ ├── launch.js
│ ├── planet.js
│ ├── satellites.js
│ ├── size.js
│ ├── solarSystem.js
│ ├── solarSystemZone.js
│ ├── test.js
│ └── transcript.js
│ ├── handlers
│ ├── backHandler.js
│ ├── cancelIntentHandler.js
│ ├── cometsHandler.js
│ ├── eventHandler.js
│ ├── exploreObjectHandler.js
│ ├── exploreZoneHandler.js
│ ├── fallbackHandler.js
│ ├── helpRequestHandler.js
│ ├── index.js
│ ├── launchRequestHandler.js
│ ├── moreInfoHandler.js
│ ├── objectAboutHandler.js
│ ├── objectAtmosphereHandler.js
│ ├── objectDistanceHandler.js
│ ├── objectRingHandler.js
│ ├── objectSatellitesHandler.js
│ ├── objectSizeHandler.js
│ ├── ordinalHandler.js
│ ├── otherRegionHandler.js
│ ├── planetsHandler.js
│ ├── plutoHandler.js
│ ├── randomImageHandler.js
│ ├── solarSystemHandler.js
│ └── theMoonHandler.js
│ ├── helpers
│ ├── cdn-path.js
│ └── handler.js
│ ├── index.js
│ ├── multimodal_responses
│ ├── aboutResponse.js
│ ├── atmosphereResponse.js
│ ├── backResponse.js
│ ├── distanceResponse.js
│ ├── exploreResponse.js
│ ├── exploreZoneResponse.js
│ ├── moonResponse.js
│ ├── randomImageResponse.js
│ ├── satellitesResponse.js
│ ├── sizeResponse.js
│ └── solarSystemResponse.js
│ └── package.json
├── models
└── en-US.json
├── packages
├── atmosphere-graphics.json
├── layouts.json
├── soft-stagger.json
└── styles.json
└── skill.json
/.ask/config:
--------------------------------------------------------------------------------
1 | {
2 | "deploy_settings": {
3 | "default": {
4 | "skill_id": "",
5 | "was_cloned": false,
6 | "merge": {
7 | }
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | *Issue #, if available:*
2 |
3 | *Description of changes:*
4 |
5 |
6 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | .eslintrc.json
3 | .prettierrc
4 | *.zip
5 | node_modules
6 | package-lock.json
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
4 | opensource-codeofconduct@amazon.com with any additional questions or comments.
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4 | documentation, we greatly value feedback and contributions from our community.
5 |
6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7 | information to effectively respond to your bug report or contribution.
8 |
9 |
10 | ## Reporting Bugs/Feature Requests
11 |
12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13 |
14 | When filing an issue, please check [existing open](https://github.com/alexa-labs/skill-sample-nodejs-space-explorer/issues), or [recently closed](https://github.com/alexa-labs/skill-sample-nodejs-space-explorer/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already
15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16 |
17 | * A reproducible test case or series of steps
18 | * The version of our code being used
19 | * Any modifications you've made relevant to the bug
20 | * Anything unusual about your environment or deployment
21 |
22 |
23 | ## Contributing via Pull Requests
24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25 |
26 | 1. You are working against the latest source on the *master* branch.
27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29 |
30 | To send us a pull request, please:
31 |
32 | 1. Fork the repository.
33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34 | 3. Ensure local tests pass.
35 | 4. Commit to your fork using clear commit messages.
36 | 5. Send us a pull request, answering any default questions in the pull request interface.
37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
38 |
39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
41 |
42 |
43 | ## Finding contributions to work on
44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/alexa-labs/skill-sample-nodejs-space-explorer/labels/help%20wanted) issues is a great place to start.
45 |
46 |
47 | ## Code of Conduct
48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
50 | opensource-codeofconduct@amazon.com with any additional questions or comments.
51 |
52 |
53 | ## Security issue notifications
54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
55 |
56 |
57 | ## Licensing
58 |
59 | See the [LICENSE](https://github.com/alexa-labs/skill-sample-nodejs-space-explorer/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
60 |
61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.
62 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Amazon Software License 1.0
2 |
3 | This Amazon Software License ("License") governs your use, reproduction, and
4 | distribution of the accompanying software as specified below.
5 |
6 | 1. Definitions
7 |
8 | "Licensor" means any person or entity that distributes its Work.
9 |
10 | "Software" means the original work of authorship made available under this
11 | License.
12 |
13 | "Work" means the Software and any additions to or derivative works of the
14 | Software that are made available under this License.
15 |
16 | The terms "reproduce," "reproduction," "derivative works," and
17 | "distribution" have the meaning as provided under U.S. copyright law;
18 | provided, however, that for the purposes of this License, derivative works
19 | shall not include works that remain separable from, or merely link (or bind
20 | by name) to the interfaces of, the Work.
21 |
22 | Works, including the Software, are "made available" under this License by
23 | including in or with the Work either (a) a copyright notice referencing the
24 | applicability of this License to the Work, or (b) a copy of this License.
25 |
26 | 2. License Grants
27 |
28 | 2.1 Copyright Grant. Subject to the terms and conditions of this License,
29 | each Licensor grants to you a perpetual, worldwide, non-exclusive,
30 | royalty-free, copyright license to reproduce, prepare derivative works of,
31 | publicly display, publicly perform, sublicense and distribute its Work and
32 | any resulting derivative works in any form.
33 |
34 | 2.2 Patent Grant. Subject to the terms and conditions of this License, each
35 | Licensor grants to you a perpetual, worldwide, non-exclusive, royalty-free
36 | patent license to make, have made, use, sell, offer for sale, import, and
37 | otherwise transfer its Work, in whole or in part. The foregoing license
38 | applies only to the patent claims licensable by Licensor that would be
39 | infringed by Licensor's Work (or portion thereof) individually and
40 | excluding any combinations with any other materials or technology.
41 |
42 | 3. Limitations
43 |
44 | 3.1 Redistribution. You may reproduce or distribute the Work only if
45 | (a) you do so under this License, (b) you include a complete copy of this
46 | License with your distribution, and (c) you retain without modification
47 | any copyright, patent, trademark, or attribution notices that are present
48 | in the Work.
49 |
50 | 3.2 Derivative Works. You may specify that additional or different terms
51 | apply to the use, reproduction, and distribution of your derivative works
52 | of the Work ("Your Terms") only if (a) Your Terms provide that the use
53 | limitation in Section 3.3 applies to your derivative works, and (b) you
54 | identify the specific derivative works that are subject to Your Terms.
55 | Notwithstanding Your Terms, this License (including the redistribution
56 | requirements in Section 3.1) will continue to apply to the Work itself.
57 |
58 | 3.3 Use Limitation. The Work and any derivative works thereof only may be
59 | used or intended for use with the web services, computing platforms or
60 | applications provided by Amazon.com, Inc. or its affiliates, including
61 | Amazon Web Services, Inc.
62 |
63 | 3.4 Patent Claims. If you bring or threaten to bring a patent claim against
64 | any Licensor (including any claim, cross-claim or counterclaim in a
65 | lawsuit) to enforce any patents that you allege are infringed by any Work,
66 | then your rights under this License from such Licensor (including the
67 | grants in Sections 2.1 and 2.2) will terminate immediately.
68 |
69 | 3.5 Trademarks. This License does not grant any rights to use any
70 | Licensor's or its affiliates' names, logos, or trademarks, except as
71 | necessary to reproduce the notices described in this License.
72 |
73 | 3.6 Termination. If you violate any term of this License, then your rights
74 | under this License (including the grants in Sections 2.1 and 2.2) will
75 | terminate immediately.
76 |
77 | 4. Disclaimer of Warranty.
78 |
79 | THE WORK IS PROVIDED "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
80 | EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF
81 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR
82 | NON-INFRINGEMENT. YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER
83 | THIS LICENSE. SOME STATES' CONSUMER LAWS DO NOT ALLOW EXCLUSION OF AN
84 | IMPLIED WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO YOU.
85 |
86 | 5. Limitation of Liability.
87 |
88 | EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL
89 | THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE
90 | SHALL ANY LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT,
91 | INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR
92 | RELATED TO THIS LICENSE, THE USE OR INABILITY TO USE THE WORK (INCLUDING
93 | BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION, LOST PROFITS
94 | OR DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER COMM ERCIAL DAMAGES
95 | OR LOSSES), EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF
96 | SUCH DAMAGES.
97 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | Skill Sample Nodejs Space Explorer
2 | Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Skill Sample Nodejs Space Explorer
2 |
3 |
4 |
5 | Alexa Presentation Language (APL) gives developers the ability to create rich, engaging and unique visual experiences for users. This skill is meant to be an example of how to use the language, the capabilities of APL, and how to think about and develop true, multi-modal experiences for Alexa-enabled devices with a screen.
6 |
7 | ## APL 1.1 Release Updates
8 |
9 | With the release of APL 1.1, Space Explorer includes updates to demonstrate new features, including:
10 |
11 | - Video
12 | - Animations
13 | - Alexa Vector Graphics (AVG)
14 | - Alexa Responsive Layouts
15 |
16 | ### Animations
17 |
18 | The new animation package allows you to apply the same animation framework across all pages. This drastically reduces the amount of code written, allows parameterization of custom animations, and maintains a consistent feel across the skill. See [soft-stagger.json](packages/soft-stagger.json) for the code behind how this is achieved.
19 |
20 | ### AVG
21 |
22 | Because of the dynamic nature of APL responses, vector graphics for the atmosphere data on larger screens are served with a new graphics package. See [atmosphere-graphics.json](packages/atmosphere-graphics.json) for an example of an AVG package.
23 |
24 | ### Alexa Responsive Layouts
25 |
26 | Alexa Responsive Layouts are pre-made layouts built by Amazon to work across all device categories and viewport sizes. Including these simplifies the code and conditional statements throughout the skill. It also alleviates the need to update the skill every time a new device comes online. Visit the Alexa Design Guide's [Responsive Components](https://developer.amazon.com/docs/alexa-design/background.html) section for more information and usage.
27 |
28 | ## Quicklinks
29 |
30 | - [Tenets](#design-tenets)
31 | - [Voice Navigation](#voice-navigation-supported-utterances)
32 | - [Views](#views)
33 | - [Data](#data)
34 | - [Documentation](#documentation)
35 |
36 | ## Design Tenets
37 |
38 | ### Be Voice-Forward, but not Voice-Only
39 |
40 | - Anything a user can touch should have a voice counterpart. However, everything said in voice does not need a touch input.
41 | - What Alexa says should be relevant to what she shows and vice versa.
42 | - Users will likely alternate between looking at a device and looking away throughout the experience. Be sure the voice flow and screen flow are comprehensive on their own and complimentary together. Screens should provide additional context when Alexa is speaking.
43 |
44 | ### Honor User Modality
45 |
46 | If a user speaks to Alexa, then Alexa should respond with voice. If a user touches the screen, then Alexa should not respond with voice.
47 |
48 | ### Emphasize Patterns & Consistency
49 |
50 | Adherence to common patterns will reduce cognitive overhead for users.
51 |
52 | ## Development Tenents
53 |
54 | ### Reusability
55 |
56 | Don't create new layouts for each new page. Reuse where possible and make components as flexible as possible.
57 |
58 | ### Logical Structure
59 |
60 | Don't make the code unnecessarily complex, but break things up where it makes sense for reusability.
61 |
62 | ## Voice Navigation (_Supported Utterances_)
63 |
64 | ### Exploring
65 |
66 | Visit any planet in the Solar System by saying:
67 |
68 | - _Alexa, **take me to** Mars._
69 | - _Alexa, **go to** Venus._
70 | - _Alexa, **show me** Neptune._
71 |
72 | Throughout the skill, you can return to your previous destination by saying:
73 |
74 | - _Alexa, **go back**._
75 |
76 | ### Learning
77 |
78 | Once you've arrived at a planet, you can learn more about it by saying:
79 |
80 | - _Alexa, number one._
81 | - _Alexa, tell me about it._
82 | - _Alexa, how big is it?_
83 | - _Alexa, how far away is it?_
84 | - _Alexa, what's in its atmosphere?_
85 | - _Alexa, how many moons does it have?_
86 |
87 | ### Astronomy Pictures
88 |
89 | You can view a random image from NASA's Astronomy Picture of the Day archives by saying:
90 |
91 | - _Alexa, show me a random image._
92 | - _Alexa, show me a space image._
93 |
94 | If you're curious about it, say:
95 |
96 | - _Alexa, tell me about it._
97 |
98 | ### Learn more
99 |
100 | Curious about other things in our solar system? Try saying:
101 |
102 | - _Alexa, tell me about the Kuiper Belt._
103 | - _Alexa, how much bigger is Uranus than Neptune?_
104 | - _Alexa, tell me about Saturn's rings._
105 | - _Alexa, what happened to Pluto?_
106 |
107 | ## Views
108 |
109 | Space Explorer uses a number of page templates to create engaging experiences for users. The goal is to reuse and be flexible, rather than create new layouts for each viewport class.
110 |
111 | A single page template exists for each primary view within the skill. Layouts were authored with Large Landscape Hubs as the starting point, then responsive breakpoints were added for larger and smaller devices (Extra Large TV, Medium Landscape Hub, Small Round Hub). When the layout for a particular device varied significantly, an alternative device-specific template was authored, such as the Solar System View on a Small Round Hub.
112 |
113 | ### Solar System View
114 |
115 | [Solar System View](docs/solar_system_view.md)
116 |
117 | ### Horizontal Image List View
118 |
119 | [Horizontal Image List View](docs/horizontal_image_list_view.md)
120 |
121 | ### Planet Details
122 |
123 | [Planet Details View](docs/planet_details_view.md)
124 |
125 | ### Transcript View
126 |
127 | [Transcript View](docs/transcript_view.md)
128 |
129 | ### Size
130 |
131 | [Size View](docs/size_view.md)
132 |
133 | ### Distance
134 |
135 | [Distance View](docs/distance_view.md)
136 |
137 | ### Atmosphere
138 |
139 | [Atmosphere View](docs/atmosphere_view.md)
140 |
141 | ## Data
142 |
143 | The data for this skill is self-contained for training purposes. This was done to ensure you could easily view, edit, and test our sample skill without any issues or added complexity from API keys. We recommend finding or creating an API for data when building skills for distribution in the Skills Store.
144 |
145 | ## Documentation
146 |
147 | ### Technical Documentation
148 |
149 | [https://developer.amazon.com/docs/alexa-presentation-language/apl-overview.html](https://developer.amazon.com/docs/alexa-presentation-language/apl-overview.html)
150 |
151 | ## License
152 |
153 | This library is licensed under the Amazon Software License.
154 |
--------------------------------------------------------------------------------
/docs/atmosphere_view.md:
--------------------------------------------------------------------------------
1 | # Atmosphere View
2 |
3 |
4 |
5 | ## Overview
6 |
7 | Shown when the user requests information about a planet's atmosphere. Using periodic-table-esque graphics to represent atmospheric elements and text to describe actual percentages. The layout changes drastically on larger screens.
8 |
9 | ### Updates
10 |
11 | Staggered animations were added that use the document's `onMount` field to trigger when the page loads. The PNGs used in the TV views were replaced with Alexa Vector Graphics.
12 |
13 | ### Layout Notes
14 |
15 | New layouts were created for the element tiles on hubs, using `Frames`, `Text` and `Images` to achieve the design. Text is styled using the alexa-styles package.
16 |
17 | ## Layout
18 |
19 | - [/lambda/custom/documents/atmosphere.js](../lambda/custom/documents/atmosphere.js)
20 |
21 | ## External Packages Used
22 |
23 | - alexa-styles
24 | - alexa-layouts
25 |
26 | ## Components Used
27 |
28 | - Container
29 | - Frame
30 | - Text
31 | - Image
32 | - Sequence
33 | - alexa-layouts:AlexaHeader
34 | - alexa-layouts:AlexaFooter
35 |
36 | ## Variations
37 |
38 | ### **Extra Large TV**
39 |
40 | Because of the larger screen size, the layout is completely changed, using a vertical list to display the element names and proportions. Each list item consists of a Frame for the color and Text for the name and percentage. The donut graph is now an AVG served from a custom graphics package, [atmosphere-graphics.json](../packages/atmosphere-graphics.json).
41 |
42 | ### **Small Hubs**
43 |
44 | To maintain readability, each element has been moved to its own page in a Pager.
45 |
--------------------------------------------------------------------------------
/docs/distance_view.md:
--------------------------------------------------------------------------------
1 | # Distance View
2 |
3 |
4 |
5 | ## Overview
6 |
7 | This is a comparison view for distance. Graphics represent a planet's distance from the sun, relative to the farthest planet. Graphics are highlighted when they correspond with the planet(s) in question.
8 |
9 | ### Updates
10 |
11 | Stagger animations were added to the document's `onMount` field and the distance graphics were animated to scale in at a constant rate, relative to their distance from the sun.
12 |
13 | ### Layout Notes
14 |
15 | - Distance graphics are created using Containers, Frames and TouchWrappers that are sized according to distance data.
16 | - Within the footer, a `textToHint` transform is used to create a Hint, which adds the user-defined wake word to a provided string. This is then supplied to the `AlexaFooter`'s `footerHint`\* _property_.\*
17 |
18 | ## Layout
19 |
20 | - [/lambda/custom/documents/distance.js](../lambda/custom/documents/distance.js)
21 |
22 | ## External Packages Used
23 |
24 | - alexa-styles
25 | - alexa-layouts
26 |
27 | ## Components Used
28 |
29 | - Container
30 | - Frame
31 | - TouchWrapper
32 | - Image
33 | - Text
34 | - alexa-layouts:AlexaHeader
35 | - alexa-layouts:AlexaFooter
36 |
37 | ## Variations
38 |
39 | ### **Extra Large TV/Large Hubs**
40 |
41 | The Layouts are the same for these devices, with Text callouts positioned at the bottom. The callout on the right is only shown when the distance is relative to the sun and not another planet.
42 |
43 | ### **Medium and Small Hubs**
44 |
45 | Vertical height limits the number of planet graphics that can fit on screen, so it is constrained to three at a time.
46 |
47 | ### **Small Round Hubs**
48 |
49 | The screen size prevents effective imagery, so the layout is altered to show only the relevant information.
50 |
--------------------------------------------------------------------------------
/docs/horizontal_image_list_view.md:
--------------------------------------------------------------------------------
1 | # Horizontal Image List View
2 |
3 |
4 |
5 | ## Overview
6 |
7 | This is an image-forward list that includes ordinals. The ordinals allow for easy voice navigation. TouchWrappers surround each item for easy touch-forward navigation. Text sizing is handled by the _alexa-styles_ package to ensure proper sizing for legibility across multiple viewing distances and screen sizes. The view also uses the AlexaHeader and AlexaFooter provided by the alexa-layouts package.
8 |
9 | ### Layout Notes
10 |
11 | - Used By:
12 | - Inner/Outer Planets
13 | - Moons
14 | - Within the footer, a `textToHint` transform is used to create a Hint, which adds the user-defined wake word to a provided string. This is then supplied to the `AlexaFooter`'s `footerHint`\* _property_.\*
15 |
16 | ## Layout
17 |
18 | - /packages/layouts.json
19 | - [ZoneList](../packages/layouts.json#L555)
20 | - [MoonList](../packages/layouts.json#L788)
21 |
22 | ## **External Packages Used**
23 |
24 | - alexa-layouts
25 | - alexa-styles
26 |
27 | ## **Components Used**
28 |
29 | - Container
30 | - Image
31 | - TouchWrapper
32 | - Text
33 | - Pager
34 | - alexa-layouts:AlexaHeader
35 | - alexa-layouts:AlexaFooter
36 |
37 | ## Variations
38 |
39 | ### **Extra Large TV**
40 |
41 | Focus states allow users to visually identify targets. Pressed states provide feedback
42 |
43 | ### **Medium and Large Hubs**
44 |
45 | Pressed states provide feedback for interactions.
46 |
47 | ### **Small Round Hubs**
48 |
49 | The horizontal list is converted to a Pager with full-screen TouchWrappers and images. This is the same pattern used by the solar system view.
50 |
--------------------------------------------------------------------------------
/docs/images/familyphoto-atmosphere.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexa-labs/skill-sample-nodejs-space-explorer/df8a14cf21b6436eb072d8a6de251de13023e894/docs/images/familyphoto-atmosphere.jpg
--------------------------------------------------------------------------------
/docs/images/familyphoto-distance.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexa-labs/skill-sample-nodejs-space-explorer/df8a14cf21b6436eb072d8a6de251de13023e894/docs/images/familyphoto-distance.jpg
--------------------------------------------------------------------------------
/docs/images/familyphoto-horizontal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexa-labs/skill-sample-nodejs-space-explorer/df8a14cf21b6436eb072d8a6de251de13023e894/docs/images/familyphoto-horizontal.jpg
--------------------------------------------------------------------------------
/docs/images/familyphoto-planet.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexa-labs/skill-sample-nodejs-space-explorer/df8a14cf21b6436eb072d8a6de251de13023e894/docs/images/familyphoto-planet.jpg
--------------------------------------------------------------------------------
/docs/images/familyphoto-size.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexa-labs/skill-sample-nodejs-space-explorer/df8a14cf21b6436eb072d8a6de251de13023e894/docs/images/familyphoto-size.jpg
--------------------------------------------------------------------------------
/docs/images/familyphoto-solarsystem.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexa-labs/skill-sample-nodejs-space-explorer/df8a14cf21b6436eb072d8a6de251de13023e894/docs/images/familyphoto-solarsystem.jpg
--------------------------------------------------------------------------------
/docs/images/familyphoto-splash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexa-labs/skill-sample-nodejs-space-explorer/df8a14cf21b6436eb072d8a6de251de13023e894/docs/images/familyphoto-splash.jpg
--------------------------------------------------------------------------------
/docs/images/familyphoto-transcript.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexa-labs/skill-sample-nodejs-space-explorer/df8a14cf21b6436eb072d8a6de251de13023e894/docs/images/familyphoto-transcript.jpg
--------------------------------------------------------------------------------
/docs/planet_details_view.md:
--------------------------------------------------------------------------------
1 | # Planet Details View
2 |
3 |
4 |
5 | ## Overview
6 |
7 | Each time a user navigates to a planet, we display a Planet Details view that guides the user to a short list of supported detail types. The purpose of this is two-fold; while you can design experiences to be more open-ended, we purposefully defined Overview, Size, Distance, Atmosphere, and Moons so we could show what a framed experience looks like and to inform the user what they can ask readily. Each page consists of a vertical list of `TouchWrappers` with ordinals, `Images` and some conditional `Text` callouts. `Text` components make use of the text styles found in the alexa-styles package to properly size, color and weight the text for optimal visibility across devices.
8 |
9 | ### Updates
10 |
11 | Staggered animations were added that use the document's `onMount` field to trigger when the page loads.
12 |
13 | ### Layout Notes
14 |
15 | Within the footer, a `textToHint` transform is used to create a Hint, which adds the user-defined wake word to a provided string.
16 |
17 | ## Layout
18 |
19 | - /packages/layouts.json
20 | - [PlanetDetailsList](../packages/layouts.json#L707)
21 |
22 | ## External Packages Used
23 |
24 | - alexa-styles
25 | - alexa-layouts
26 |
27 | ## Components Used
28 |
29 | - Container
30 | - Sequence
31 | - TouchWrapper
32 | - Text
33 | - Image
34 | - Frame
35 | - alexa-layouts:AlexaHeader
36 | - alexa-layouts:AlexaFooter
37 |
38 | ## Variations
39 |
40 | ### **Extra Large TV**
41 |
42 | Focus states on the vertical list items allow users to visually identify targets. Because of the larger screen size, 'when' clauses are used to show additional text callouts.
43 |
44 | ### **Medium and Large Hubs**
45 |
46 | Layout is identical to FireTV, minus the text callouts which do not fit within the smaller screen sizes.
47 |
48 | ### **Small Round Hubs**
49 |
50 | The left-aligned list and right-aligned image are centered, while a full-screen scrim increases legibility against the bright background imagery.
51 |
52 | ### **Small Landscape Hubs**
53 |
54 | To save on vertical real estate, the footer was removed and the list allowed to scroll.
55 |
--------------------------------------------------------------------------------
/docs/size_view.md:
--------------------------------------------------------------------------------
1 | # Size View Readme
2 |
3 |
4 |
5 | ## Overview
6 |
7 | This is a comparison view for planet size. `Text` callouts feature relevant information, while `Frames` create graphical representations of size differences.
8 |
9 | ### Updates
10 |
11 | Staggered animations were added that use the document's `onMount` field to trigger when the page loads, and the comparative size graphics were animated to scale in.
12 |
13 | ### Layout Notes
14 |
15 | - The size comparison graphic is created using `Frames` and programmatically determined zIndex and relative sizes.
16 | - Within the footer, a `textToHint` transform is used to create a Hint, which adds the user-defined wake word to a provided string. This is then supplied to the `AlexaFooter`'s `footerHint`\* _property_.\*
17 |
18 | ## Layout
19 |
20 | - [/lambda/custom/documents/size.js](../lambda/custom/documents/size.js)
21 |
22 | ## External Packages Used
23 |
24 | - alexa-layouts
25 | - alexa-styles
26 |
27 | ## Components Used
28 |
29 | - Text
30 | - Frame
31 | - Image
32 | - Container
33 | - Pager
34 | - alexa-layouts:AlexaHeader
35 | - alexa-layouts:AlexaFooter
36 |
37 | ## Variations
38 |
39 | ### **Extra Large TV/Medium and Large Hubs**
40 |
41 | The layout is the same for these devices, with the exception of medium hub dropping some text for size issues.
42 |
43 | ### **Small Round Hubs**
44 |
45 | The layout is converted to a `Pager`, with callout information on one page and programmatically generated `Frames` on the other. The `onPageChanged` event is used to add a transition animation to the page elements.
46 |
--------------------------------------------------------------------------------
/docs/solar_system_view.md:
--------------------------------------------------------------------------------
1 | # Solar System View
2 |
3 |
4 |
5 | ## Overview
6 |
7 | When the skill opens, following the splash screen, the Solar System view is presented showcasing the sun, the 8 planets, and an Image Button for the Space Image of the Day. This view highlights the two paths they can take, either exploring the celestial bodies or viewing a randomized space image. This view uses Images to render each of the planets. Each planet is wrapped with a Touch Wrapper to support touch and Fire TV remote control navigation in addition to voice.
8 |
9 | This view uses Images to render each of the planets. Each planet is wrapped with a Touch Wrapper to support touch and Fire TV remote control navigation in addition to voice.
10 |
11 | ### Updates
12 |
13 | Staggered animations were added that use the document's `onMount` field to trigger when the page loads.
14 |
15 | ### Layout Notes
16 |
17 | - Within the footer, a `textToHint` transform is used to create a Hint, which adds the user-defined wake word to a provided string. This is then supplied to the `AlexaFooter`'s `footerHint`\* _property_.\*
18 |
19 | ## **Layout**
20 |
21 | - /packages/layouts.json
22 | - [SolarSystem](../packages/layouts.json#L318)
23 | - [SolarSystemSmallRoundHub](../packages/layouts.json#L491)
24 |
25 | ## **External Packages Used**
26 |
27 | - alexa-layouts
28 | - alexa-styles
29 |
30 | ## **Components Used**
31 |
32 | - Container
33 | - Image
34 | - TouchWrapper
35 | - Text
36 | - Pager
37 | - alexa-layouts:AlexaHeader
38 | - alexa-layouts:AlexaFooter
39 |
40 | ## Variations
41 |
42 | ### **Extra Large TV**
43 |
44 | On Fire TV devices, the `TouchWrappers` allow for navigation using the remote control, with focus highlighting to indicate location. They also include a pressed state to provide visual feedback for interactions.
45 |
46 | ### **Medium and Large Hubs**
47 |
48 | On our Hub Devices, the layout remains the same as the Fire TV, but we conditionally add additional `TouchWrappers` to account for small targets that allow the user to navigate to a supplimentary view for easier planet selection. Pressed states provide user feedback for interactions.
49 |
50 | ### **Small Round Hubs**
51 |
52 | The layout is drastically altered to accommodate the smaller screen, converting the solar system to a `Pager`, with individual, full-screen `TouchWrappers` containing Images for each planet. Pressed states are still present for interactions. There is a subtle gradient scrim on the bottom of the image to increase legibility of the text while maintaining the vibrancy of the imagery.
53 |
--------------------------------------------------------------------------------
/docs/splash_screen_view.md:
--------------------------------------------------------------------------------
1 | # Splash Screen View
2 |
3 |
4 |
5 | ## Overview
6 |
7 | The splash screen is displayed when first opening the skill. It is intended to mask the loading of the solar system images.
8 |
9 | ### Updates
10 |
11 | The initial `ScrollView` implementation was replaced with a solution that uses the video ending to trigger an opacity transition that reveals the solar system.
12 |
13 | ### Layout Notes
14 |
15 | - See [Solar System View](https://quip-amazon.com/gdEpAcbg3pCA) for additional details.
16 |
17 | ## Layout
18 |
19 | - [/lambda/custom/documents/landing.js](../lambda/custom/documents/landing.js)
20 |
21 | ## Packages Used
22 |
23 | None.
24 |
25 | ## Components Used
26 |
27 | - Frame
28 | - Image
29 | - Video
30 |
31 | ## Variations
32 |
33 | None.
34 |
--------------------------------------------------------------------------------
/docs/transcript_view.md:
--------------------------------------------------------------------------------
1 | # Transcript View
2 |
3 |
4 |
5 | ## Overview
6 |
7 | This is a full-screen image behind a title and source attributions, with text peeking at the bottom of the page to indicate users can scroll for more content. When this page is navigated to via voice (with the exception of Astronomy Images), the text is automatically scrolled into view, while Alexa speaks the content. While speaking, the corresponding line is highlighted. When Alexa has completed speaking, the text is scrolled back to the bottom of the page. Notice that when the page is scrolled a slight scrim appears over the image to increase legibility. With Astronomy Images, users say,_ “Alexa, tell me about it,”_ to start the synchronized speech. Text is styled using the alexa-styles package.
8 |
9 | ### Updates
10 |
11 | Replaced the original highlight styling with updated styles that match the latest Alexa designs.
12 |
13 | ### Layout Notes
14 |
15 | **Used By:**
16 |
17 | - Astronomy Images (no Header, no auto speech)
18 | - Planet Overview
19 | - Interesting Facts (i.e. _“Alexa, what happened to Pluto?”_)
20 |
21 | ## Layout
22 |
23 | - [/lambda/custom/documents/transcript_V2.js](../lambda/custom/documents/transcript.js)
24 |
25 | ## External Packages Used
26 |
27 | - alexa-styles
28 | - alexa-layouts
29 |
30 | ## Components Used
31 |
32 | - Container
33 | - Image
34 | - ScrollView
35 | - Text
36 | - SpeakItem directive
37 | - alexa-layouts:AlexaHeader
38 |
39 | ## Variations
40 |
41 | ### Small Round Hub
42 |
43 | The title and source attribution are centered.
44 |
--------------------------------------------------------------------------------
/icons/skill-icon-lg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexa-labs/skill-sample-nodejs-space-explorer/df8a14cf21b6436eb072d8a6de251de13023e894/icons/skill-icon-lg.png
--------------------------------------------------------------------------------
/icons/skill-icon-sm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexa-labs/skill-sample-nodejs-space-explorer/df8a14cf21b6436eb072d8a6de251de13023e894/icons/skill-icon-sm.png
--------------------------------------------------------------------------------
/lambda/custom/data/images.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "image": "https://d1od0khoye9qi3.cloudfront.net/m2018_08_06Adp.jpg",
4 | "title": "Close Mars",
5 | "description": "Still bright in evening skies, Mars was just past opposition and closest to Earth on July 31, a mere 57.6 million kilometers away. Captured only a week later, this remarkable image shows the Red Planet's disk near its maximum size in earthbound telescopes, but still less than 1/74th the apparent diameter of a Full Moon."
6 | },
7 | {
8 | "image": "https://d1od0khoye9qi3.cloudfront.net/NGC6914_Eder_1024.jpg",
9 | "title": "The NGC 6914 Complex ",
10 | "description": "A study in contrasts, this colorful skyscape features stars, dust, and glowing gas in the vicinity of NGC 6914. The complex of reflection nebulae lies some 6,000 light-years away, toward the high-flying northern constellation Cygnus and the plane of our Milky Way Galaxy."
11 | },
12 | {
13 | "image": "https://d1od0khoye9qi3.cloudfront.net/RSPup_HubbleBond_960.jpg",
14 | "title": "Nearby Cepheid Variable RS Pup",
15 | "description": "In the center is one of the most important stars on the sky. This is partly because, by coincidence, it is surrounded by a dazzling reflection nebula. Pulsating RS Puppis, the brightest star in the image center, is some ten times more massive than our Sun and on average 15,000 times more luminous."
16 | },
17 | {
18 | "image": "https://d1od0khoye9qi3.cloudfront.net/MilkyWayOregon_Montoya_960.jpg",
19 | "title": "Sea and Sky Glows over the Oregon Coast",
20 | "description": "Every step caused the sand to light up blue. That glow was bioluminescence -- a blue radiance that also lights the surf in this surreal scene captured last month at Meyer's Creek Beach in Oregon, USA. Volcanic stacks dot the foreground sea, while a thin fog layer scatters light on the horizon."
21 | },
22 | {
23 | "image": "https://d1od0khoye9qi3.cloudfront.net/fires_mccolgan_960.jpg",
24 | "title": "Fire on Earth",
25 | "description": "Sometimes, regions of planet Earth light up with fire. Since fire is the rapid acquisition of oxygen, and since oxygen is a key indicator of life, fire on any planet would be an indicator of life on that planet. Most of the Earth's land has been scorched by fire at some time in the past."
26 | },
27 | {
28 | "image": "https://d1od0khoye9qi3.cloudfront.net/heic1404b1024.jpg",
29 | "title": "Stripping ESO 137-001",
30 | "description": "Spiral galaxy ESO 137-001 hurtles through massive galaxy cluster Abell 3627 some 220 million light years away. The distant galaxy is seen in this colorful Hubble/Chandra composite image through a foreground of the Milky Way's stars toward the southern constellation Triangulum Australe."
31 | },
32 | {
33 | "image": "https://d1od0khoye9qi3.cloudfront.net/M20M21Bobillo1024.jpg",
34 | "title": "Messier 20 and 21",
35 | "description": "The beautiful Trifid Nebula, also known as Messier 20, is easy to find with a small telescope in the nebula rich constellation Sagittarius. About 5,000 light-years away, the colorful study in cosmic contrasts shares this well-composed, nearly 1 degree wide field with open star cluster Messier 21 (bottom right). "
36 | },
37 | {
38 | "image": "https://d1od0khoye9qi3.cloudfront.net/21p-160818_85_santllop1024.jpg",
39 | "title": "Comet, Heart and Soul",
40 | "description": "The greenish coma of comet 21P/Giacobini-Zinner stands out at the left of this telephoto skyscape spanning over 10 degrees toward the northern constellations Cassiopeia and Perseus. Captured on August 17, the periodic comet is the known parent body of the upcoming Draconid meteor shower."
41 | },
42 | {
43 | "image": "https://d1od0khoye9qi3.cloudfront.net/Ryugu_Hayabusa2_1024.jpg",
44 | "title": "Asteroid Ryugu from Hayabusa2",
45 | "description": "This big space diamond has an estimated value of over 80 billion dollars. It's only diamond in shape, though -- asteroid 162173 Ryugu is thought to be composed of mostly nickel and iron. Asteroids like Ryugu are interesting for several reasons, perhaps foremost because they are near the Earth and might, one day in the far future, pose an impact threat."
46 | },
47 | {
48 | "image": "https://d1od0khoye9qi3.cloudfront.net/SoulNebula_Vargas_960.jpg",
49 | "title": "Glowing Elements in the Soul Nebula",
50 | "description": "Stars are forming in the Soul of the Queen of Aethopia. More specifically, a large star forming region called the Soul Nebula (IC 1898) can be found in the direction of the constellation Cassiopeia, who Greek mythology credits as the vain wife of a King who long ago ruled lands surrounding the upper Nile river."
51 | },
52 | {
53 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_01.jpg",
54 | "title": "Juno Captures Elusive 'Brown Barge'",
55 | "description": "A long, brown oval known as a \"brown barge\" in Jupiter's South Equatorial Belt is captured in this color-enhanced image from NASA's Juno spacecraft."
56 | },
57 | {
58 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_02.jpg",
59 | "title": "Bright Spots On Ceres",
60 | "description": "Bright surface features on the dwarf planet Ceres known as faculae were first discovered by NASA's Dawn spacecraft in 2015."
61 | },
62 | {
63 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_03.jpg",
64 | "title": "Hubble’s Lucky Observation of an Enigmatic Cloud",
65 | "description": "The little-known nebula IRAS 05437+2502 billows out among the bright stars and dark dust clouds that surround it."
66 | },
67 | {
68 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_04.jpg",
69 | "title": "Time-lapse Sequence of Jupiter’s North",
70 | "description": "Striking atmospheric features in Jupiter’s northern hemisphere are captured in this series of color-enhanced images from NASA’s Juno spacecraft."
71 | },
72 | {
73 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_05.jpg",
74 | "title": "Just Another Day on Aerosol Earth",
75 | "description": "Even if the air looks clear, it is nearly certain that you will inhale millions of solid particles and liquid droplets. These ubiquitous specks of matter are known as aerosols, and they can be found in the air over oceans, deserts, mountains, forests, ice and every ecosystem in between."
76 | },
77 | {
78 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_06.jpg",
79 | "title": "World of Change: Columbia Glacier, Alaska",
80 | "description": "The Columbia Glacier descends from an ice field 10,000 feet and into a narrow inlet that leads into Prince William Sound in southeastern Alaska."
81 | },
82 | {
83 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_08.jpg",
84 | "title": "'X'-ploring the Eagle Nebula and 'Pillars of Creation",
85 | "description": "The Eagle Nebula, also known as Messier 16, contains the young star cluster NGC 6611. It also the site of the spectacular star-forming region known as the Pillars of Creation, which is located in the southern portion of the Eagle Nebula."
86 | },
87 | {
88 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_09.jpg",
89 | "title": "Jamming with the 'Spiders' from Mars",
90 | "description": "This image from NASA's Mars Reconnaissance Orbiter, acquired May 13, 2018 during winter at the South Pole of Mars, shows a carbon dioxide ice cap covering the region and as the sun returns in the spring, \"spiders\" begin to emerge from the landscape."
91 | },
92 | {
93 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_10.jpg",
94 | "title": "Chaotic Clouds of Jupiter",
95 | "description": "This image captures swirling cloud belts and tumultuous vortices within Jupiter’s northern hemisphere."
96 | },
97 | {
98 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_11.jpg",
99 | "title": "Another Day at the Office",
100 | "description": "\"Space was our office yesterday,\" said International Space Station astronaut Ricky Arnold on Friday."
101 | },
102 | {
103 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_12.jpg",
104 | "title": "Rover Under the Milky Way - Atacama Rover Astrobiology Drilling Studies",
105 | "description": "The Moon begins to rise behind the ARADS rover during the 2017 season of field tests in Chile’s Atacama Desert."
106 | },
107 | {
108 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_13.jpg",
109 | "title": "Once in a Blue Dune",
110 | "description": "Sand dunes often accumulate in the floors of craters. In this region of Lyot Crater, NASA's Mars Reconnaissance Orbiter (MRO) shows a field of classic barchan dunes on Jan. 24, 2018."
111 | },
112 | {
113 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_14.jpg",
114 | "title": "Evaluating the Noise of Future Aircraft",
115 | "description": "To address the expected noise levels of future aircraft, NASA’s Commercial Supersonic Technology project is already developing technologies focused on reducing the noise produced by an aircraft’s engine exhaust."
116 | },
117 | {
118 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_15.jpg",
119 | "title": "Exposed Bedrock on the Red Planet's Hale Crater",
120 | "description": "This image from NASA's Mars Reconnaissance Orbiter shows Hale Crater, a large impact crater."
121 | },
122 | {
123 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_16.jpg",
124 | "title": "An Amazing View",
125 | "description": "Astronaut Ricky Arnold took this selfie during the May 16, 2018, spacewalk."
126 | },
127 | {
128 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_17.jpg",
129 | "title": "Gravity’s Rainbow",
130 | "description": "Saturn’s rings display their subtle colors in this view captured on Aug. 22, 2009, by NASA’s Cassini spacecraft."
131 | },
132 | {
133 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_18.jpg",
134 | "title": "Celebrating 28 Years of the Hubble Space Telescope",
135 | "description": "This colorful image, taken by NASA’s Hubble Space Telescope, celebrates the Earth-orbiting observatory’s 28th anniversary of viewing the heavens, giving us a window seat to the universe’s extraordinary stellar tapestry of birth and destruction."
136 | },
137 | {
138 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_19.jpg",
139 | "title": "Jovian ‘Twilight Zone’",
140 | "description": "This image captures the swirling cloud formations around the south pole of Jupiter, looking up toward the equatorial region."
141 | },
142 | {
143 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_20.jpg",
144 | "title": "A Lunar Tribute to Former NASA Chief Exploration Scientist",
145 | "description": "Wargo Crater is an 8.6-mile diameter impact crater sitting on the northwest edge of Joule T crater, on the far side of the Moon. Wargo worked at NASA from 1991 until his death in 2013."
146 | },
147 | {
148 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_21.jpg",
149 | "title": "The Fault in Our Mars",
150 | "description": "This image from NASA's Mars Reconnaissance Orbiter (MRO) of northern Meridiani Planum shows faults that have disrupted layered deposits."
151 | },
152 |
153 | {
154 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_22.jpg",
155 | "title": "Chandra Reveals the Elementary Nature of Cassiopeia A",
156 | "description": "Due to its unique evolutionary status, Cassiopeia A (Cas A) is one of the most intensely studied of these supernova remnants."
157 | },
158 | {
159 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_23.jpg",
160 | "title": "Cygnus Cargo Spacecraft at Sunrise",
161 | "description": "NASA astronaut Randy Bresnik photographed Orbital ATK's Cygnus cargo spacecraft at sunrise, prior to its departure from the International Space Station at 8:11 a.m., Dec. 6, 2017. Expedition 53 Flight Engineers Mark Vande Hei and Joe Acaba of NASA gave the station's Canadarm2 robotic arm the command to release Cygnus."
162 | },
163 | {
164 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_24.jpg",
165 | "title": "Star Wanders Too Close to a Black Hole",
166 | "description": "This artist's rendering shows the tidal disruption event named ASASSN-14li, where a star wandering too close to a 3-million-solar-mass black hole was torn apart. The debris gathered into an accretion disk around the black hole."
167 | },
168 | {
169 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_25.jpg",
170 | "title": "Jovian Tempest",
171 | "description": "This color-enhanced image of a massive, raging storm in Jupiter’s northern hemisphere was captured by NASA’s Juno spacecraft."
172 | },
173 | {
174 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_26.jpg",
175 | "title": "Rare Encircling Filament",
176 | "description": "NASA's Solar Dynamics Observatory came across an oddity that the spacecraft has rarely observed before: a dark filament encircling an active region (Oct. 29-31, 2017). Solar filaments are clouds of charged particles that float above the sun, tethered to it by magnetic forces."
177 | },
178 | {
179 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_27.jpg",
180 | "title": "Northern Lights Over Canada",
181 | "description": "The spectacular aurora borealis, or the “northern lights,” over Canada is sighted from the International Space Station near the highest point of its orbital path. The station’s main solar arrays are seen in the left foreground. This photograph was taken by a member of the Expedition 53 crew aboard the station on Sept. 15, 2017."
182 | },
183 | {
184 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_28.jpg",
185 | "title": "A World of Snowy Dunes on Mars",
186 | "description": "It was spring in the Northern hemisphere when this image was taken on May 21, 2017, by the HiRISE camera on NASA's Mars Reconnaissance Orbiter. Over the winter, snow and ice have inexorably covered the dunes. Unlike on Earth, this snow and ice is carbon dioxide, better known to us as dry ice."
187 | },
188 | {
189 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_29.jpg",
190 | "title": "Highlighting Titan's Hazes",
191 | "description": "NASA's Cassini spacecraft looks toward the night side of Saturn's moon Titan in a view that highlights the extended, hazy nature of the moon's atmosphere."
192 | },
193 | {
194 | "image": "https://d1od0khoye9qi3.cloudfront.net/iod_30.jpg",
195 | "title": "Moon Rise From the Space Station",
196 | "description": "From his vantage point aboard the International Space Station, NASA astronaut Randy Bresnik pointed his camera toward the rising Moon and captured this beautiful image on August 3, 2017. Bresnik wrote, \"Gorgeous moon rise! Such great detail when seen from space. Next full moon marks #Eclipse2017. We’ll be watching from @Space_Station.\""
197 | }
198 | ]
199 |
--------------------------------------------------------------------------------
/lambda/custom/documents/atmosphere.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const planetData = require('../data/planets.json');
17 | const cdnPath = require('../helpers/cdn-path');
18 |
19 | function capitalize(string) {
20 | const arr = string.split('');
21 |
22 | arr[0] = arr[0].toUpperCase();
23 | return arr.join('');
24 | }
25 |
26 | module.exports = (planet, comp) => {
27 | const elements = [];
28 | const pagerItems = [];
29 |
30 | if (comp) {
31 | comp.forEach(item => {
32 | elements.push({
33 | type: 'Element',
34 | id: item.element.replace(/\s/g, '_'),
35 | element: item.element,
36 | title: item.element.toUpperCase(),
37 | notation: `\${payload.data.properties.elements['${item.element}'].notation}`,
38 | color: `\${payload.data.properties.elements['${item.element}'].color}`,
39 | percentage: item.percentage,
40 | spacing: '32dp'
41 | });
42 | });
43 | }
44 |
45 | elements.forEach((item, i) => {
46 | pagerItems.push({
47 | type: 'Container',
48 | alignItems: 'center',
49 | id: `page_${i}`,
50 | justifyContent: 'center',
51 | width: '100%',
52 | height: '100%',
53 | paddingLeft: '6vw',
54 | paddingRight: '6vw',
55 | paddingTop: 50,
56 | direction: 'row',
57 | opacity: i === 0 ? 1 : 0,
58 | item
59 | });
60 | });
61 |
62 | return {
63 | type: 'Alexa.Presentation.APL.RenderDocument',
64 | token: 'atmospheric-composition',
65 | document: {
66 | type: 'APL',
67 | version: '1.0',
68 | import: [
69 | {
70 | name: 'alexa-styles',
71 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
72 | },
73 | {
74 | name: 'alexa-layouts',
75 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
76 | },
77 | {
78 | name: 'layouts',
79 | version: '1.0.0',
80 | source: `${cdnPath}apl/layouts.json`
81 | },
82 | {
83 | name: 'styles',
84 | version: '1.0.0',
85 | source: `${cdnPath}apl/styles.json`
86 | },
87 | {
88 | name: 'soft-stagger',
89 | version: '1.0.0',
90 | source: `${cdnPath}apl/soft-stagger.json`
91 | },
92 | {
93 | name: 'atmosphere-graphics',
94 | version: '1.0.0',
95 | source: `${cdnPath}apl/atmosphere-graphics.json`
96 | }
97 | ],
98 | commands: {
99 | onLoad: {
100 | parameters: [],
101 | command: {
102 | type: 'Parallel',
103 | delay: 250,
104 | commands: [
105 | ...elements.map((item, i) => {
106 | return {
107 | type: 'SoftStaggerItemTargetted',
108 | componentId: item.id,
109 | order: i + 1,
110 | fromDirection: 'bottom'
111 | }
112 | }),
113 | {
114 | type: 'SoftStaggerItemTargetted',
115 | componentId: 'compositionImage',
116 | order: elements.length,
117 | fromDirection: 'right'
118 | },
119 | {
120 | type: 'SoftStaggerBackgroundTargetted',
121 | componentId: 'background'
122 | },
123 | {
124 | type: 'SoftStaggerBackgroundTargetted',
125 | componentId: 'listContainer'
126 | },
127 | {
128 | type: 'SoftStaggerChromeTargetted',
129 | componentId: 'header',
130 | fromDirection: 'bottom'
131 | },
132 | {
133 | type: 'SoftStaggerHintTargetted',
134 | componentId: 'footer',
135 | fromDirection: 'bottom'
136 | }
137 | ]
138 | }
139 | }
140 | },
141 | onMount: [
142 | {
143 | type: 'onLoad'
144 | }
145 | ],
146 | mainTemplate: {
147 | parameters: ['payload'],
148 | items: [
149 | {
150 | type: 'Container',
151 | width: '100%',
152 | height: '100%',
153 | alignItems: 'center',
154 | justifyContent: 'center',
155 | items: [
156 | {
157 | type: 'AlexaBackground',
158 | id: 'background',
159 | backgroundImageSource: planetData.backgroundImage,
160 | backgroundScale: 'best-fill',
161 | opacity: 0
162 | },
163 | {
164 | when: '${@viewportProfile != @hubRoundSmall}',
165 | type: 'AlexaHeader',
166 | id: 'header',
167 | headerTitle: `${planet.toUpperCase()} · ATMOSPHERE`,
168 | headerBackButton: true,
169 | width: '100%',
170 | opacity: 0
171 | },
172 | {
173 | when: '${@viewportProfile == @hubRoundSmall}',
174 | type: 'AlexaHeader',
175 | id: 'header',
176 | headerTitle: `${planet.toUpperCase()} · ATMOSPHERE`,
177 | headerBackButton: true,
178 | headerAttributionPrimacy: false,
179 | width: '100%',
180 | opacity: 0,
181 | position: 'absolute',
182 | top: 0,
183 | left: 0
184 | },
185 | {
186 | when: '${@viewportProfile == @hubRoundSmall}',
187 | type: 'Pager',
188 | id: 'pager',
189 | width: '100%',
190 | height: '100%',
191 | bind: [
192 | {
193 | name: 'currentPage',
194 | value: 0
195 | }
196 | ],
197 | onPageChanged: [
198 | {
199 | type: 'Parallel',
200 | commands: [
201 | {
202 | type: 'SoftStaggerItemTargetted',
203 | componentId: '${\'page_\' + event.source.value}',
204 | order: 2,
205 | fromDirection: '${event.source.value < currentPage ? \'left\' : \'right\'}'
206 | },
207 | {
208 | type: 'SoftStaggerOutTargetted',
209 | componentId: '${\'page_\' + currentPage}'
210 | }
211 | ]
212 | },
213 | {
214 | type: 'SetValue',
215 | componentId: 'pager',
216 | property: 'currentPage',
217 | value: '${event.source.value}'
218 | }
219 | ],
220 | items: [
221 | ...pagerItems,
222 | {
223 | when: elements.length === 0,
224 | type: 'Container',
225 | height: '100%',
226 | width: '100%',
227 | alignItems: 'center',
228 | justifyContent: 'center',
229 | item: {
230 | type: 'Text',
231 | style: 'textStyleDisplay3',
232 | textAlign: 'center',
233 | text: `${capitalize(planet)} has no atmosphere`
234 | }
235 | }
236 | ]
237 | },
238 | {
239 | when: '${@viewportProfile == @tvLandscapeXLarge}',
240 | type: 'Container',
241 | width: '100%',
242 | height: '70%',
243 | paddingLeft: '@marginHorizontal',
244 | paddingRight: '@marginHorizontal',
245 | direction: 'row',
246 | justifyContent: 'spaceBetween',
247 | alignItems: 'start',
248 | items: [
249 | {
250 | when: elements.length !== 0,
251 | type: 'Container',
252 | id: 'listContainer',
253 | width: '50%',
254 | height: '100%',
255 | direction: 'column',
256 | spacing: '@spacingLarge',
257 | opacity: 0,
258 | items: [
259 | {
260 | type: 'Sequence',
261 | width: '100%',
262 | height: '100%',
263 | items: elements
264 | }
265 | ]
266 | },
267 | {
268 | when: elements.length !== 0,
269 | type: 'Container',
270 | id: 'compositionImage',
271 | width: '40%',
272 | alignItems: 'center',
273 | justifyContent: 'center',
274 | opacity: 0,
275 | items: [
276 | {
277 | type: 'VectorGraphic',
278 | width: '100%',
279 | height: '100%',
280 | scale: 'best-fit',
281 | source: `${planet}_atmosphere`
282 | }
283 | ]
284 | },
285 | {
286 | when: elements.length === 0,
287 | type: 'Container',
288 | width: '100%',
289 | height: '100%',
290 | alignItems: 'center',
291 | justifyContent: 'center',
292 | items: [
293 | {
294 | type: 'Text',
295 | style: 'textStyleDisplay4',
296 | text: `${capitalize(planet)} has no atmosphere`,
297 | textAlign: 'center'
298 | }
299 | ]
300 | }
301 | ]
302 | },
303 | {
304 | when: '${@viewportProfile != @tvLandscapeXLarge && @viewportProfile != @hubRoundSmall}',
305 | type: 'Container',
306 | alignItems: 'center',
307 | justifyContent: 'spaceAround',
308 | width: '100%',
309 | grow: 1,
310 | paddingLeft: '@marginHorizontal',
311 | paddingRight: '@marginHorizontal',
312 | direction: 'row',
313 | items: [
314 | ...elements,
315 | {
316 | when: elements.length === 0,
317 | type: 'Text',
318 | style: 'textStyleDisplay3',
319 | textAlign: 'center',
320 | text: `${capitalize(planet)} has no atmosphere`
321 | }
322 | ]
323 | },
324 | {
325 | when: '${@viewportProfile != @hubRoundSmall}',
326 | type: 'AlexaFooter',
327 | id: 'footer',
328 | opacity: 0,
329 | hintText: '${payload.data.properties.hint}'
330 | }
331 | ]
332 | }
333 | ]
334 | }
335 | },
336 | datasources: {
337 | data: {
338 | type: 'object',
339 | properties: {
340 | hintText: "what's in Earth's atmosphere?",
341 | elements: {
342 | argon: {
343 | notation: 'Ar',
344 | color: '#893592'
345 | },
346 | 'carbon dioxide': {
347 | notation: 'CO2',
348 | color: '#d94623'
349 | },
350 | helium: {
351 | notation: 'He',
352 | color: '#b83b5e'
353 | },
354 | hydrogen: {
355 | notation: 'H',
356 | color: '#3875bb'
357 | },
358 | methane: {
359 | notation: 'CH4',
360 | color: '#df7140'
361 | },
362 | nitrogen: {
363 | notation: 'N2',
364 | color: '#339b9e'
365 | },
366 | oxygen: {
367 | notation: 'O2',
368 | color: '#699b30'
369 | },
370 | sodium: {
371 | notation: 'Na',
372 | color: '#a0a0a0'
373 | },
374 | potassium: {
375 | notation: 'K',
376 | color: '#f0f000'
377 | }
378 | }
379 | },
380 | transformers: [
381 | {
382 | inputPath: 'hintText',
383 | outputName: 'hint',
384 | transformer: 'textToHint'
385 | }
386 | ]
387 | }
388 | }
389 | };
390 | };
391 |
--------------------------------------------------------------------------------
/lambda/custom/documents/distance.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const planetData = require('../data/planets.json');
17 | const cdnPath = require('../helpers/cdn-path');
18 |
19 | const planets = ['mercury', 'venus', 'earth', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune'];
20 |
21 | module.exports = (planet1, planet2) => {
22 | const elements = [];
23 | const diffString = Math.abs(
24 | planetData[planet1].distance - planetData[planet2].distance
25 | ).toLocaleString();
26 |
27 | Object.keys(planetData).forEach(k => {
28 | if (k !== 'the sun' && k !== 'backgroundImage') {
29 | const item = planetData[k];
30 | let itemWidth = Math.min(
31 | (item.distance / planetData[planet1 === 'pluto' || planet2 === 'pluto' ? 'pluto' : 'neptune'].distance) * 100 + 3,
32 | 100
33 | );
34 |
35 | if (k !== 'pluto' || ((planet1 === 'pluto' || planet2 === 'pluto') && k === 'pluto')) {
36 | elements.push({
37 | when: `\${(@viewportProfile != @hubLandscapeMedium && @viewportProfile != @hubLandscapeSmall) || ${(k === planet1 || k === planet2) || (planets.indexOf(k) === planets.indexOf(planet1) + 1 || planets.indexOf(k) === planets.indexOf(planet1) - 1)}}`,
38 | type: 'DistanceGraphic',
39 | id: `distance_${k}`,
40 | color: item.color,
41 | width: Math.round(itemWidth),
42 | name: k,
43 | active: k === planet1 || k === planet2
44 | })
45 | }
46 | }
47 | });
48 |
49 | elements.sort((a, b) => a.width - b.width);
50 |
51 | return {
52 | type: 'Alexa.Presentation.APL.RenderDocument',
53 | token: 'distance',
54 | document: {
55 | type: 'APL',
56 | version: '1.0',
57 | import: [
58 | {
59 | name: 'alexa-styles',
60 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
61 | },
62 | {
63 | name: 'alexa-layouts',
64 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
65 | },
66 | {
67 | name: 'layouts',
68 | version: '1.0.0',
69 | source: `${cdnPath}apl/layouts.json`
70 | },
71 | {
72 | name: 'styles',
73 | version: '1.0.0',
74 | source: `${cdnPath}apl/styles.json`
75 | },
76 | {
77 | name: 'soft-stagger',
78 | version: '1.0.0',
79 | source: `${cdnPath}apl/soft-stagger.json`
80 | }
81 | ],
82 | commands: {
83 | DistanceReveal: {
84 | parameters: [ 'componentId' ],
85 | command: {
86 | type: 'AnimateItem',
87 | componentId: '${componentId}',
88 | easing: '@alexa-out',
89 | delay: 250,
90 | duration: '${10 * width}',
91 | value: [
92 | {
93 | property: 'transform',
94 | from: {
95 | translateX: '-100%'
96 | },
97 | to: {
98 | translateX: '0%'
99 | }
100 | }
101 | ]
102 | }
103 | },
104 | onLoad: {
105 | parameters: [],
106 | command: {
107 | type: 'Parallel',
108 | commands: [
109 | {
110 | type: 'SoftStaggerBackgroundTargetted',
111 | componentId: 'background'
112 | },
113 | {
114 | type: 'SoftStaggerChromeTargetted',
115 | componentId: 'header',
116 | fromDirection: 'bottom'
117 | },
118 | {
119 | type: 'SoftStaggerHintTargetted',
120 | componentId: 'footer',
121 | fromDirection: 'bottom'
122 | },
123 | {
124 | type: 'SoftStaggerItemTargetted',
125 | componentId: 'distanceText',
126 | fromDirection: 'bottom',
127 | order: 1
128 | },
129 | {
130 | type: 'SoftStaggerItemTargetted',
131 | componentId: 'sunlightText',
132 | fromDirection: 'bottom',
133 | order: 2
134 | },
135 | {
136 | type: 'DistanceReveal',
137 | componentId: 'distance_mercury'
138 | },
139 | {
140 | type: 'DistanceReveal',
141 | componentId: 'distance_venus'
142 | },
143 | {
144 | type: 'DistanceReveal',
145 | componentId: 'distance_earth'
146 | },
147 | {
148 | type: 'DistanceReveal',
149 | componentId: 'distance_mars'
150 | },
151 | {
152 | type: 'DistanceReveal',
153 | componentId: 'distance_jupiter'
154 | },
155 | {
156 | type: 'DistanceReveal',
157 | componentId: 'distance_saturn'
158 | },
159 | {
160 | type: 'DistanceReveal',
161 | componentId: 'distance_uranus'
162 | },
163 | {
164 | type: 'DistanceReveal',
165 | componentId: 'distance_neptune'
166 | },
167 | {
168 | type: 'DistanceReveal',
169 | componentId: 'distance_pluto'
170 | }
171 | ]
172 | }
173 | }
174 | },
175 | onMount: [
176 | {
177 | type: 'onLoad'
178 | }
179 | ],
180 | mainTemplate: {
181 | parameters: ['payload'],
182 | item: {
183 | type: 'Frame',
184 | backgroundColor: 'black',
185 | item: [
186 | {
187 | when: '${@viewportProfile == @hubRoundSmall}',
188 | type: 'Container',
189 | direction: 'column',
190 | height: '100%',
191 | width: '100%',
192 | alignItems: 'center',
193 | justifyContent: 'center',
194 | items: [
195 | {
196 | type: 'AlexaBackground',
197 | backgroundImageSource: '${payload.data.properties.planetData.backgroundImage}'
198 | },
199 | {
200 | type: 'Image',
201 | source: `${cdnPath}assets/rook-full-scrim.png`,
202 | width: '100%',
203 | height: '100%',
204 | position: 'absolute',
205 | scale: 'best-fit'
206 | },
207 | {
208 | type: 'AlexaHeader',
209 | id: 'header',
210 | headerTitle: 'DISTANCE',
211 | headerAttributionPrimacy: false,
212 | width: '100%',
213 | position: 'absolute',
214 | top: 0,
215 | left: 0,
216 | opacity: 0
217 | },
218 | {
219 | type: 'Container',
220 | width: '100%',
221 | height: '100%',
222 | direction: 'column',
223 | alignItems: 'center',
224 | justifyContent: 'center',
225 | items: [
226 | {
227 | type: 'Container',
228 | id: 'distanceText',
229 | direction: 'column',
230 | alignItems: 'center',
231 | opacity: 0,
232 | items: [
233 | {
234 | type: 'Text',
235 | style: 'textStyleCallout',
236 | spacing: 10,
237 | opacity: 0.6,
238 | text: `DISTANCE FROM ${planet2.toUpperCase()}`
239 | },
240 | {
241 | type: 'Text',
242 | text: `${diffString} mi`,
243 | style: 'textStyleDisplay4'
244 | }
245 | ]
246 | }
247 | ]
248 | }
249 | ]
250 | },
251 | {
252 | when: '${@viewportProfile != @hubRoundSmall}',
253 | type: 'Container',
254 | width: '100%',
255 | height: '100%',
256 | items: [
257 | {
258 | type: 'AlexaBackground',
259 | id: 'background',
260 | backgroundImageSource: planetData.backgroundImage,
261 | opacity: 0
262 | },
263 | {
264 | type: 'AlexaHeader',
265 | headerTitle: `${planet1.toUpperCase()} · DISTANCE`,
266 | headerBackButton: true,
267 | headerNavigationAction: 'backEvent',
268 | id: 'header',
269 | opacity: 0
270 | },
271 | {
272 | type: 'Container',
273 | width: '100%',
274 | grow: 1,
275 | shrink: 1,
276 | paddingLeft: '6vw',
277 | paddingRight: '6vw',
278 | justifyContent: 'spaceAround',
279 | items: elements.concat([
280 | {
281 | type: 'Container',
282 | direction: 'row',
283 | width: '100%',
284 | alignItems: 'center',
285 | spacing: '48dp',
286 | items: [
287 | {
288 | type: 'Container',
289 | id: 'distanceText',
290 | opacity: 0,
291 | items: [
292 | {
293 | type: 'Text',
294 | style: 'textStyleCallout',
295 | opacity: 0.6,
296 | text: `DISTANCE FROM ${planet2.toUpperCase()}`
297 | },
298 | {
299 | type: 'Text',
300 | style: 'textStyleDisplay4',
301 | text: `${diffString} mi`
302 | }
303 | ]
304 | },
305 | {
306 | when: `\${viewport.height > 600 && ${planet2 ===
307 | 'the sun'}}`,
308 | type: 'Container',
309 | spacing: '68dp',
310 | id: 'sunlightText',
311 | opacity: 0,
312 | items: [
313 | {
314 | type: 'Text',
315 | style: '${@viewportProfileCategory == @tvLandscape ? \'textStyleBody\' : \'textStyleCallout\'}',
316 | opacity: 0.6,
317 | text: 'SUNLIGHT TO TRAVEL'
318 | },
319 | {
320 | type: 'Text',
321 | style: '${@viewportProfileCategory == @tvLandscape ? \'textStyleDisplay2\' : \'textStyleDisplay4\'}',
322 | text: `\${payload.data.properties.planetData['${planet1}'].lightTravel + ' minutes'}`
323 | }
324 | ]
325 | }
326 | ]
327 | }
328 | ])
329 | },
330 | {
331 | type: 'AlexaFooter',
332 | id: 'footer',
333 | opacity: 0,
334 | hintText: '${payload.data.properties.hint}'
335 | }
336 | ]
337 | }
338 | ]
339 | }
340 | }
341 | },
342 | datasources: {
343 | data: {
344 | type: 'object',
345 | properties: {
346 | hintText: 'how far away is Neptune?',
347 | planet2,
348 | planetData
349 | },
350 | transformers: [
351 | {
352 | inputPath: 'hintText',
353 | outputName: 'hint',
354 | transformer: 'textToHint'
355 | }
356 | ]
357 | }
358 | }
359 | };
360 | };
361 |
--------------------------------------------------------------------------------
/lambda/custom/documents/launch.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const data = require('../data/planets.json');
17 | const cdnPath = require('../helpers/cdn-path');
18 |
19 | module.exports = () => {
20 | const planets = [];
21 |
22 | Object.keys(data).forEach(k => {
23 | if (k !== 'backgroundImage' && k !== 'pluto') {
24 | planets.push(data[k]);
25 | }
26 | });
27 |
28 | planets.sort((a, b) => a.distance - b.distance);
29 |
30 | return {
31 | type: 'Alexa.Presentation.APL.RenderDocument',
32 | token: 'splash-screen',
33 | document: {
34 | type: 'APL',
35 | version: '1.0',
36 | theme: 'dark',
37 | import: [
38 | {
39 | name: 'alexa-styles',
40 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
41 | },
42 | {
43 | name: 'alexa-layouts',
44 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
45 | },
46 | {
47 | name: 'layouts',
48 | version: '1.0.0',
49 | source: `${cdnPath}apl/layouts.json`
50 | },
51 | {
52 | name: 'styles',
53 | version: '1.0.0',
54 | source: `${cdnPath}apl/styles.json`
55 | }
56 | ],
57 | resources: [
58 | {
59 | strings: {
60 | videoLandingVideo: `${cdnPath}videos/SpaceExplorer_Splash_v2.mp4`
61 | }
62 | },
63 | {
64 | strings: {
65 | when: '${@viewportProfile == @hubRoundSmall || viewport.height <= 480}',
66 | videoLandingVideo: `${cdnPath}videos/SpaceExplorer_Splash_480.mp4`
67 | }
68 | }
69 | ],
70 | commands: {
71 | Reveal: {
72 | parameters: [],
73 | command: {
74 | type: 'Sequential',
75 | commands: [
76 | {
77 | type: 'Parallel',
78 | commands: [
79 | {
80 | type: 'AnimateItem',
81 | componentId: 'solarSystem',
82 | value: [
83 | {
84 | property: 'opacity',
85 | from: 0,
86 | to: 1
87 | }
88 | ],
89 | duration: 1000
90 | },
91 | {
92 | type: 'AnimateItem',
93 | componentId: 'videoContainer',
94 | value: [
95 | {
96 | property: 'opacity',
97 | from: 1,
98 | to: 0
99 | }
100 | ],
101 | duration: 1000
102 | },
103 | {
104 | type: 'SolarSystemReveal'
105 | }
106 | ]
107 | }
108 | ]
109 | }
110 | }
111 | },
112 | mainTemplate: {
113 | parameters: ['payload'],
114 | item: {
115 | type: 'Container',
116 | direction: 'column',
117 | height: '100vh',
118 | width: '100vw',
119 | position: 'absolute',
120 | top: 0,
121 | bottom: 0,
122 | items: [
123 | {
124 | type: 'Container',
125 | id: 'videoContainer',
126 | position: 'absolute',
127 | top: 0,
128 | right: 0,
129 | bottom: 0,
130 | left: 0,
131 | alignItems: 'center',
132 | justifyContent: 'center',
133 | opacity: 1,
134 | item: [
135 | {
136 | type: 'Frame',
137 | width: '100%',
138 | height: '100%',
139 | backgroundColor: 'red',
140 | position: 'absolute'
141 | },
142 | {
143 | type: 'Video',
144 | id: 'splashVideo',
145 | width: '${@viewportProfile == @hubLandscapeSmall ? \'200vh\' : \'180vh\'}',
146 | height: '100vh',
147 | scale: 'best-fill',
148 | position: 'absolute',
149 | autoplay: true,
150 | audioTrack: 'foreground',
151 | source: '@videoLandingVideo',
152 | onEnd: [
153 | {
154 | type: 'Reveal'
155 | }
156 | ]
157 | }
158 | ]
159 | },
160 | {
161 | type: 'Container',
162 | id: 'solarSystem',
163 | opacity: 0,
164 | items: [
165 | {
166 | when: '${@viewportProfile == @hubRoundSmall}',
167 | type: 'SolarSystemSmallRoundHub',
168 | data: '${payload.data.properties.data}'
169 | },
170 | {
171 | when: '${@viewportProfile != @hubRoundSmall}',
172 | type: 'SolarSystem',
173 | data: '${payload.data.properties.data}',
174 | hintText: '${payloaddata.properties.hint}'
175 | }
176 | ]
177 | }
178 | ]
179 | }
180 | }
181 | },
182 | datasources: {
183 | data: {
184 | properties: {
185 | hintText: 'take me to the inner planets.',
186 | speechssml: 'What would you like to explore?',
187 | data
188 | },
189 | transformers: [
190 | {
191 | inputPath: 'hintText',
192 | outputName: 'hint',
193 | transformer: 'textToHint'
194 | },
195 | {
196 | inputPath: 'speechssml',
197 | outputName: 'speech',
198 | transformer: 'ssmlToSpeech'
199 | }
200 | ]
201 | }
202 | }
203 | };
204 | };
205 |
--------------------------------------------------------------------------------
/lambda/custom/documents/planet.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const data = require('../data/planets.json');
17 | const cdnPath = require('../helpers/cdn-path');
18 |
19 | module.exports = planet => {
20 | const datasource = data[planet];
21 |
22 | return {
23 | type: 'Alexa.Presentation.APL.RenderDocument',
24 | token: 'planet-details',
25 | document: {
26 | type: 'APML',
27 | version: '1.0',
28 | theme: 'dark',
29 | import: [
30 | {
31 | name: 'alexa-styles',
32 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
33 | },
34 | {
35 | name: 'alexa-layouts',
36 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
37 | },
38 | {
39 | name: 'layouts',
40 | version: '1.0.0',
41 | source: `${cdnPath}apl/layouts.json`
42 | },
43 | {
44 | name: 'styles',
45 | version: '1.0.0',
46 | source: `${cdnPath}apl/styles.json`
47 | },
48 | {
49 | name: 'soft-stagger',
50 | version: '1.0.0',
51 | source: `${cdnPath}apl/soft-stagger.json`
52 | }
53 | ],
54 | commands: {
55 | onMount: {
56 | command: {
57 | type: 'Parallel',
58 | commands: [
59 | {
60 | type: 'SoftStaggerBackgroundTargetted',
61 | componentId: 'background'
62 | },
63 | {
64 | type: 'AnimateItem',
65 | componentId: 'planetImage',
66 | duration: 1000,
67 | easing: '@alexa-out',
68 | value: [
69 | {
70 | property: 'transform',
71 | from: [
72 | {
73 | translateX: 100
74 | }
75 | ],
76 | to: [
77 | {
78 | translateX: 0
79 | }
80 | ]
81 | },
82 | {
83 | property: 'opacity',
84 | from: 0,
85 | to: 1
86 | }
87 | ]
88 | },
89 | {
90 | type: 'SoftStaggerBackgroundTargetted',
91 | componentId: 'listContainer'
92 | },
93 | {
94 | type: 'SoftStaggerChromeTargetted',
95 | componentId: 'header',
96 | fromDirection: 'bottom'
97 | },
98 | {
99 | type: 'SoftStaggerHintTargetted',
100 | componentId: 'footer',
101 | fromDirection: 'bottom'
102 | },
103 | {
104 | type: 'SoftStaggerItemTargetted',
105 | when: planet === 'the sun',
106 | componentId: 'starType',
107 | order: 1,
108 | fromDirection: 'bottom'
109 | },
110 | {
111 | type: 'SoftStaggerItemTargetted',
112 | when: planet === 'the sun',
113 | componentId: 'starAge',
114 | order: 2,
115 | fromDirection: 'bottom'
116 | },
117 | {
118 | type: 'SoftStaggerItemTargetted',
119 | when: `\${@viewportProfile == @tvLandscapeXLarge && '${planet}' != 'the sun'}`,
120 | componentId: 'yearLength',
121 | order: 1,
122 | fromDirection: 'bottom'
123 | },
124 | {
125 | type: 'SoftStaggerItemTargetted',
126 | when: `\${@viewportProfile == @tvLandscapeXLarge && '${planet}' != 'the sun'}`,
127 | componentId: 'dayLength',
128 | order: 2,
129 | fromDirection: 'bottom'
130 | },
131 | {
132 | type: 'PlanetListReveal',
133 | planet: planet
134 | }
135 | ]
136 | }
137 | }
138 | },
139 | onMount: [
140 | {
141 | type: 'onMount'
142 | }
143 | ],
144 | mainTemplate: {
145 | parameters: ['payload'],
146 | item: {
147 | type: 'Frame',
148 | backgroundColor: 'black',
149 | item: [
150 | {
151 | when: '${@viewportProfile != @hubRoundSmall}',
152 | type: 'Container',
153 | direction: 'column',
154 | id: 'container',
155 | height: '100%',
156 | width: '100%',
157 | items: [
158 | {
159 | type: 'AlexaBackground',
160 | id: 'background',
161 | backgroundImageSource: '${payload.data.backgroundImage}',
162 | opacity: 0
163 | },
164 | {
165 | type: 'Image',
166 | id: 'planetImage',
167 | source: '${payload.data.image}',
168 | left: planet === 'saturn' ? '-20%' : '42%',
169 | bottom: planet === 'saturn' ? '-30%' : '20%',
170 | width: planet === 'saturn' ? '200%' : '100%',
171 | height: planet === 'saturn' ? '200%' : '100%',
172 | position: 'absolute',
173 | scale: 'best-fit',
174 | opacity: 0
175 | },
176 | {
177 | type: 'Image',
178 | source: `${cdnPath}assets/scrim-planetdetails.png`,
179 | right: 0,
180 | bottom: 0,
181 | height: '100vh',
182 | width: planet === 'saturn' ? '100vw' : '100vh',
183 | position: 'absolute',
184 | scale: 'best-fill'
185 | },
186 | {
187 | type: 'AlexaHeader',
188 | id: 'header',
189 | headerTitle: planet.toUpperCase(),
190 | headerBackButton: true,
191 | width: '100%',
192 | opacity: 0
193 | },
194 | {
195 | type: 'Container',
196 | id: 'listContainer',
197 | paddingLeft: '@marginHorizontal',
198 | grow: 1,
199 | shrink: 1,
200 | opacity: 0,
201 | items: [
202 | {
203 | type: 'PlanetDetailsList',
204 | planet: planet.toLowerCase()
205 | },
206 | {
207 | when: '${@viewportProfile == @hubLandscapeSmall}',
208 | type: 'Image',
209 | height: 120,
210 | width: '100%',
211 | scale: 'best-fill',
212 | position: 'absolute',
213 | left: 0,
214 | bottom: 0,
215 | source: 'https://ddg-skill.s3-us-west-2.amazonaws.com/1px.png',
216 | overlayGradient: {
217 | type: 'linear',
218 | colorRange: [
219 | 'black',
220 | 'transparent'
221 | ],
222 | inputRange: [
223 | 0,
224 | 0.4
225 | ]
226 | }
227 | },
228 | {
229 | when: planet === 'the sun',
230 | type: 'Container',
231 | direction: 'row',
232 | paddingBottom: '15dp',
233 | items: [
234 | {
235 | type: 'Container',
236 | id: 'starType',
237 | spacing: '68dp',
238 | items: [
239 | {
240 | type: 'Text',
241 | style: 'textStyleCaption',
242 | opacity: 0.75,
243 | text: 'STAR-TYPE'
244 | },
245 | { type: 'Text', style: 'textStyleCallout', text: datasource.type }
246 | ]
247 | },
248 | {
249 | type: 'Container',
250 | id: 'starAge',
251 | spacing: '68dp',
252 | items: [
253 | {
254 | type: 'Text',
255 | style: 'textStyleCaption',
256 | opacity: 0.75,
257 | text: 'APPROXIMATE AGE'
258 | },
259 | { type: 'Text', style: 'textStyleCallout', text: datasource.age }
260 | ]
261 | }
262 | ]
263 | },
264 | {
265 | when: `\${@viewportProfile == @tvLandscapeXLarge && '${planet}' != 'the sun'}`,
266 | type: 'Container',
267 | direction: 'row',
268 | paddingBottom: '15dp',
269 | items: [
270 | {
271 | type: 'Container',
272 | id: 'yearLength',
273 | spacing: '68dp',
274 | items: [
275 | {
276 | type: 'Text',
277 | style: 'textStyleCaption',
278 | opacity: 0.75,
279 | text: 'LENGTH OF YEAR'
280 | },
281 | {
282 | type: 'Text',
283 | style: 'textStyleCallout',
284 | text: `${datasource.year.toLocaleString()} Earth Days`
285 | }
286 | ]
287 | },
288 | {
289 | type: 'Container',
290 | id: 'dayLength',
291 | spacing: '68dp',
292 | items: [
293 | {
294 | type: 'Text',
295 | style: 'textStyleCaption',
296 | opacity: 0.75,
297 | text: 'LENGTH OF DAY'
298 | },
299 | {
300 | type: 'Text',
301 | style: 'textStyleCallout',
302 | text: `${datasource.day.toLocaleString()} Earth Hours`
303 | }
304 | ]
305 | }
306 | ]
307 | }
308 | ]
309 | },
310 | {
311 | when: '${@viewportProfile != @hubLandscapeSmall}',
312 | type: 'AlexaFooter',
313 | id: 'footer',
314 | hintText: '${payload.data.properties.hint}',
315 | opacity: 0
316 | }
317 | ]
318 | },
319 | {
320 | when: '${@viewportProfile == @hubRoundSmall}',
321 | type: 'Container',
322 | direction: 'column',
323 | height: '100%',
324 | width: '100%',
325 | items: [
326 | {
327 | type: 'Image',
328 | id: 'planetImage',
329 | source: '${payload.data.image}',
330 | width: '100%',
331 | height: '100%',
332 | position: 'absolute',
333 | scale: 'best-fit',
334 | opacity: 0
335 | },
336 | {
337 | type: 'Image',
338 | source: `${cdnPath}assets/rook-full-scrim.png`,
339 | width: '100%',
340 | height: '100%',
341 | position: 'absolute',
342 | scale: 'best-fit'
343 | },
344 | {
345 | type: 'AlexaHeader',
346 | id: 'header',
347 | headerTitle: planet.toUpperCase(),
348 | headerAttributionPrimacy: false,
349 | position: 'absolute',
350 | width: '100%',
351 | opacity: 0
352 | },
353 | {
354 | type: 'Container',
355 | id: 'listContainer',
356 | paddingLeft: '@marginHorizontal',
357 | paddingRight: '${@marginHorizontal / 2}',
358 | paddingTop: '25vh',
359 | height: '100%',
360 | opacity: 0,
361 | items: [
362 | {
363 | type: 'PlanetDetailsList',
364 | planet: planet.toLowerCase()
365 | }
366 | ]
367 | }
368 | ]
369 | }
370 | ]
371 | }
372 | }
373 | },
374 | datasources: {
375 | data: {
376 | backgroundImage: data.backgroundImage,
377 | ...datasource,
378 | properties: {
379 | hintText: planet === 'the sun' ? 'tell me about it.' : 'how far away is it?'
380 | },
381 | transformers: [{ inputPath: 'hintText', outputName: 'hint', transformer: 'textToHint' }]
382 | }
383 | }
384 | };
385 | };
386 |
--------------------------------------------------------------------------------
/lambda/custom/documents/satellites.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const data = require('../data/planets.json');
17 | const cdnPath = require('../helpers/cdn-path');
18 |
19 | function capitalize(string) {
20 | const arr = string.split('');
21 |
22 | arr[0] = arr[0].toUpperCase();
23 | return arr.join('');
24 | }
25 |
26 | module.exports = planet => ({
27 | type: 'Alexa.Presentation.APL.RenderDocument',
28 | token: 'object_satellites',
29 | document: {
30 | type: 'APML',
31 | version: '1.0',
32 | theme: 'dark',
33 | import: [
34 | {
35 | name: 'alexa-styles',
36 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
37 | },
38 | {
39 | name: 'alexa-layouts',
40 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
41 | },
42 | {
43 | name: 'layouts',
44 | version: '1.0.0',
45 | source: `${cdnPath}apl/layouts.json`
46 | },
47 | {
48 | name: 'styles',
49 | version: '1.0.0',
50 | source: `${cdnPath}apl/styles.json`
51 | }
52 | ],
53 | mainTemplate: {
54 | parameters: ['payload'],
55 | item: {
56 | type: 'ImageList',
57 | backgroundImage: '${payload.data.properties.backgroundImage}',
58 | hintText: '${payload.data.properties.hint}',
59 | listData: '${payload.data.properties.listItems}',
60 | planet: capitalize(planet),
61 | title: `${planet.toUpperCase()} • MOONS`,
62 | opacity: 0,
63 | onMount: [
64 | {
65 | type: 'AnimateItem',
66 | duration: 500,
67 | easing: 'linear',
68 | value: [
69 | {
70 | property: 'opacity',
71 | from: 0,
72 | to: 1
73 | }
74 | ]
75 | }
76 | ]
77 | }
78 | }
79 | },
80 | datasources: {
81 | data: {
82 | type: 'object',
83 | properties: {
84 | backgroundImage: data.backgroundImage,
85 | listItems: data[planet].satellites.interesting,
86 | hintText: 'how many moons does Venus have?'
87 | },
88 | transformers: [
89 | {
90 | inputPath: 'hintText',
91 | outputName: 'hint',
92 | transformer: 'textToHint'
93 | }
94 | ]
95 | }
96 | }
97 | });
98 |
--------------------------------------------------------------------------------
/lambda/custom/documents/solarSystem.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const data = require('../data/planets.json');
17 | const cdnPath = require('../helpers/cdn-path');
18 |
19 | module.exports = () => ({
20 | type: 'Alexa.Presentation.APL.RenderDocument',
21 | token: 'solar-system',
22 | document: {
23 | type: 'APL',
24 | version: '1.1',
25 | theme: 'dark',
26 | import: [
27 | {
28 | name: 'alexa-styles',
29 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
30 | },
31 | {
32 | name: 'alexa-layouts',
33 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
34 | },
35 | {
36 | name: 'layouts',
37 | version: '1.0.0',
38 | source: `${cdnPath}apl/layouts.json`
39 | },
40 | {
41 | name: 'styles',
42 | version: '1.0.0',
43 | source: `${cdnPath}apl/styles.json`
44 | }
45 | ],
46 | mainTemplate: {
47 | parameters: ['payload'],
48 | item: {
49 | type: 'Frame',
50 | backgroundColor: 'black',
51 | onMount: [
52 | {
53 | type: 'SolarSystemReveal'
54 | }
55 | ],
56 | items: [
57 | {
58 | when: '${@viewportProfile == @hubRoundSmall}',
59 | type: 'SolarSystemSmallRoundHub',
60 | data: '${payload.data.properties.data}'
61 | },
62 | {
63 | when: '${@viewportProfile != @hubRoundSmall}',
64 | type: 'SolarSystem',
65 | data: '${payload.data.properties.data}',
66 | hintText: '${payloaddata.properties.hint}'
67 | }
68 | ]
69 | }
70 | }
71 | },
72 | datasources: {
73 | data: {
74 | properties: {
75 | hintText: 'take me to the outer planets.',
76 | data
77 | },
78 | transformers: [
79 | {
80 | inputPath: 'hintText',
81 | outputName: 'hint',
82 | transformer: 'textToHint'
83 | }
84 | ]
85 | }
86 | }
87 | });
88 |
--------------------------------------------------------------------------------
/lambda/custom/documents/solarSystemZone.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const planetData = require('../data/planets.json');
17 | const cdnPath = require('../helpers/cdn-path');
18 |
19 | module.exports = zone => {
20 | const planets = [];
21 |
22 | Object.keys(planetData).forEach(k => {
23 | const item = planetData[k];
24 | if (item.region && item.region === zone.toLowerCase()) {
25 | planets.push(item);
26 | }
27 | });
28 |
29 | planets.sort((a, b) => a.distance - b.distance);
30 |
31 | return {
32 | type: 'Alexa.Presentation.APL.RenderDocument',
33 | token: 'solar-system-zone',
34 | document: {
35 | type: 'APML',
36 | version: '1.0',
37 | theme: 'dark',
38 | import: [
39 | {
40 | name: 'alexa-styles',
41 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
42 | },
43 | {
44 | name: 'alexa-layouts',
45 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
46 | },
47 | {
48 | name: 'layouts',
49 | version: '1.0.0',
50 | source: `${cdnPath}apl/layouts.json`
51 | },
52 | {
53 | name: 'styles',
54 | version: '1.0.0',
55 | source: `${cdnPath}apl/styles.json`
56 | }
57 | ],
58 | mainTemplate: {
59 | parameters: ['payload'],
60 | item: {
61 | type: 'ImageList',
62 | backgroundImage: '${payload.data.properties.backgroundImage}',
63 | title: `${zone.toUpperCase()} SOLAR SYSTEM`,
64 | hintText: '${payload.data.properties.hint}',
65 | listData: '${payload.data.properties.planets}'
66 | }
67 | }
68 | },
69 | datasources: {
70 | data: {
71 | type: 'object',
72 | properties: {
73 | planets,
74 | backgroundImage: planetData.backgroundImage,
75 | hintText: 'take me to Venus.'
76 | },
77 | transformers: [
78 | {
79 | inputPath: 'hintText',
80 | outputName: 'hint',
81 | transformer: 'textToHint'
82 | }
83 | ]
84 | }
85 | }
86 | };
87 | };
88 |
--------------------------------------------------------------------------------
/lambda/custom/documents/test.js:
--------------------------------------------------------------------------------
1 | module.exports = () => {
2 | return {
3 | type: 'Alexa.Presentation.APL.RenderDocument',
4 | token: 'object-size',
5 | document: {
6 | "type": "APL",
7 | "version": "1.1",
8 | "theme": "dark",
9 | "import": [
10 | {
11 | "name": "soft-stagger",
12 | "version": "1.0.0",
13 | "source": "https://s3-us-west-2.amazonaws.com/ddg-skill/apl/soft-stagger.json"
14 | }
15 | ],
16 | "commands": {
17 | "test": {
18 | "command": {
19 | "type": "AnimateItem",
20 | "componentId": "target",
21 | "easing": "ease-out",
22 | "duration": 666,
23 | "value": [
24 | {
25 | "property": "opacity",
26 | "from": 0,
27 | "to": 1
28 | },
29 | {
30 | "property": "transform",
31 | "from": {
32 | "tranlateY": 80
33 | },
34 | "to": {
35 | "translateY": 0
36 | }
37 | }
38 | ]
39 | }
40 | }
41 | },
42 | "onMount": [
43 | {
44 | "type": "test"
45 | }
46 | ],
47 | "mainTemplate": {
48 | "parameters": [],
49 | "item": {
50 | "type": "Container",
51 | "width": "100vw",
52 | "height": "100vh",
53 | "items": [
54 | {
55 | "type": "TouchWrapper",
56 | "onPress": [
57 | {
58 | "type": "test"
59 | }
60 | ],
61 | "item": {
62 | "type": "Frame",
63 | "width": 200,
64 | "height": 60,
65 | "backgroundColor": "red"
66 | }
67 | },
68 | {
69 | "type": "Frame",
70 | "width": 100,
71 | "height": 100,
72 | "backgroundColor": "white",
73 | "opacity": 0,
74 | "id": "target",
75 | "position": "absolute",
76 | "top": "48vh",
77 | "left": "48vw"
78 | }
79 | ]
80 | }
81 | }
82 | }
83 | };
84 | }
--------------------------------------------------------------------------------
/lambda/custom/documents/transcript.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const cdnPath = require('../helpers/cdn-path');
17 |
18 | module.exports = (resource, title = null) => ({
19 | type: 'Alexa.Presentation.APL.RenderDocument',
20 | token: 'transcript_document',
21 | document: {
22 | type: 'APL',
23 | version: '1.1',
24 | theme: 'dark',
25 | import: [
26 | {
27 | name: 'alexa-styles',
28 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
29 | },
30 | {
31 | name: 'alexa-layouts',
32 | version: '1.1.0-eifjccgiclfvkinnkcftdcdeklbrnlhchfcihjjdghdi'
33 | },
34 | {
35 | name: 'layouts',
36 | version: '1.0.0',
37 | source: `${cdnPath}apl/layouts.json`
38 | },
39 | {
40 | name: 'styles',
41 | version: '1.0.0',
42 | source: `${cdnPath}apl/styles.json`
43 | }
44 | ],
45 | styles: {
46 | karaokeStyle: {
47 | extends: 'textStyleKaraoke',
48 | values: [
49 | {
50 | color: '@colorText'
51 | },
52 | {
53 | "when": "${state.karaoke}",
54 | "color": "rgba(218,218,218,0.5)"
55 | },
56 | {
57 | "when": "${state.karaokeTarget}",
58 | "color": "rgba(218,218,218,1)"
59 | }
60 | ]
61 | }
62 | },
63 | mainTemplate: {
64 | parameters: ['payload'],
65 | item: [
66 | {
67 | type: 'Container',
68 | width: '100%',
69 | height: '100%',
70 | item: [
71 | {
72 | type: 'Container',
73 | width: '100vw',
74 | height: '100vh',
75 | position: 'absolute',
76 | items: [
77 | {
78 | when: resource.video != null || resource.video != undefined,
79 | type: 'Video',
80 | id: 'videoPlayer',
81 | source: resource.video,
82 | audioTrack: 'none',
83 | autoplay: true,
84 | height: '100vh',
85 | width: 'auto',
86 | scale: 'best-fill',
87 | onEnd: [
88 | {
89 | type: 'ControlMedia',
90 | componentId: 'videoPlayer',
91 | command: 'rewind'
92 | },
93 | {
94 | type: 'ControlMedia',
95 | componentId: 'videoPlayer',
96 | command: 'play'
97 | }
98 | ]
99 | },
100 | {
101 | when: !resource.video,
102 | type: 'Image',
103 | scale: 'best-fill',
104 | width: '100vw',
105 | height: '100vh',
106 | source: resource.image,
107 | opacity: 1
108 | },
109 | {
110 | type: 'Frame',
111 | position: 'absolute',
112 | id: 'mediaScrim',
113 | width: '100vw',
114 | height: '100vh',
115 | backgroundColor: 'black',
116 | opacity: 0
117 | },
118 | {
119 | type: 'Image',
120 | position: 'absolute',
121 | scale: 'best-fill',
122 | width: '100vw',
123 | height: '100vh',
124 | top: 0,
125 | left: 0,
126 | right: 0,
127 | bottom: 0,
128 | source: 'https://d1od0khoye9qi3.cloudfront.net/image_scrim.png'
129 | }
130 | ]
131 | },
132 | {
133 | type: 'ScrollView',
134 | width: '100%',
135 | height: '100%',
136 | id: 'scrollContainer',
137 | onScroll: [
138 | {
139 | type: 'Parallel',
140 | commands: [
141 | {
142 | type: 'SetValue',
143 | componentId: 'mediaScrim',
144 | property: 'opacity',
145 | value: '${Math.min(event.source.value * 2, 0.6)}'
146 | },
147 | {
148 | type: 'SetValue',
149 | componentId: 'header',
150 | property: 'opacity',
151 | value: '${1 - (event.source.value * 2)}'
152 | }
153 | ]
154 | }
155 | ],
156 | items: [
157 | {
158 | type: 'Container',
159 | paddingTop: '${viewport.height >= 600 ? \'75vh\' : \'65vh\'}',
160 | paddingLeft: '@marginHorizontal',
161 | paddingRight: '@marginHorizontal',
162 | paddingBottom: 150,
163 | width: '100%',
164 | backgroundColor: 'black',
165 | alignItems: "${@viewportProfile == @hubRoundSmall ? 'center' : 'start'}",
166 | inheritParentState: true,
167 | item: [
168 | {
169 | type: 'Text',
170 | style: 'textStyleBodyAlt',
171 | spacing: resource.source ? '10dp' : 0,
172 | text: resource.title
173 | },
174 | {
175 | when: resource.source !== undefined,
176 | type: 'Text',
177 | style: 'textStyleCallout',
178 | paddingBottom: '26dp',
179 | text: `${resource.video !== null ? 'Video' : 'Image'}: ${resource.source}`
180 | },
181 | {
182 | type: 'Text',
183 | id: 'karaokeText',
184 | style: 'karaokeStyle',
185 | spacing: resource.source ? '26dp' : '60dp',
186 | text: '${payload.resource.properties.text}',
187 | speech: '${payload.resource.properties.speech}'
188 | }
189 | ]
190 | }
191 | ]
192 | },
193 | {
194 | when: title !== null,
195 | type: 'AlexaHeader',
196 | id: 'header',
197 | position: 'absolute',
198 | top: 0,
199 | left: 0,
200 | width: '100%',
201 | headerTitle: title,
202 | headerBackButton: true
203 | },
204 | ]
205 | }
206 | ]
207 | }
208 | },
209 | datasources: {
210 | resource: {
211 | type: 'object',
212 | properties: {
213 | ssml: `${resource.description}`,
214 | text: resource.description
215 | },
216 | transformers: [
217 | {
218 | inputPath: 'ssml',
219 | outputName: 'speech',
220 | transformer: 'ssmlToSpeech'
221 | }
222 | ]
223 | }
224 | }
225 | });
226 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/backHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const backResponse = require('../multimodal_responses/backResponse');
18 |
19 | const BackResponseHandler = Handler('GoBack', handlerInput => backResponse(handlerInput));
20 |
21 | module.exports = BackResponseHandler;
22 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/cancelIntentHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 |
18 | const CancelIntentHandler = {
19 | canHandle(handlerInput) {
20 | return handlerInput.requestEnvelope.request.type === 'IntentRequest' &&
21 | (handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent' ||
22 | handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent');
23 | },
24 | handle(handlerInput) {
25 | return handlerInput.responseBuilder.getResponse()
26 | }
27 | }
28 |
29 | module.exports = CancelIntentHandler;
30 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/cometsHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const cdnPath = require('../helpers/cdn-path');
18 | const TranscriptDirective = require('../documents/transcript');
19 |
20 | const description =
21 | "Comets are cosmic snowballs of frozen gases, rock and dust that orbit the Sun. When frozen, they are the size of a small town. When a comet's orbit brings it close to the Sun, it heats up and spews dust and gases into a giant glowing head larger than most planets. The dust and gases form a tail that stretches away from the Sun for millions of miles. There are likely billions of comets orbiting our Sun in the Kuiper Belt and even more distant Oort Cloud. The current number of known comets is: 3,535";
22 |
23 |
24 | const CometsRequestHandler = Handler('CometsIntent', handlerInput => {
25 | const attributes = handlerInput.attributesManager.getSessionAttributes();
26 | const { location } = attributes;
27 |
28 | if (
29 | attributes.previousLocation &&
30 | attributes.previousLocation[attributes.previousLocation.length - 1] !== location
31 | ) {
32 | attributes.previousLocation.push(location);
33 | }
34 |
35 | if (!attributes.previousLocation) {
36 | attributes.previousLocation = ['solar system'];
37 | }
38 |
39 | handlerInput.attributesManager.setSessionAttributes(attributes);
40 |
41 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
42 | return handlerInput.responseBuilder
43 | .addDirective(
44 | TranscriptDirective({
45 | image: `${cdnPath}assets/comet.jpg`,
46 | title: 'Comets',
47 | source: 'NASA',
48 | description
49 | })
50 | )
51 | .addDirective({
52 | type: 'Alexa.Presentation.APL.ExecuteCommands',
53 | token: 'transcript_document',
54 | commands: [
55 | {
56 | type: 'Sequential',
57 | commands: [
58 | {
59 | type: 'SpeakItem',
60 | componentId: 'karaokeText',
61 | highlightMode: 'line',
62 | align: 'center'
63 | },
64 | {
65 | type: 'Scroll',
66 | componentId: 'scrollContainer',
67 | distance: -10000
68 | }
69 | ]
70 | }
71 | ]
72 | })
73 | .getResponse();
74 | } else {
75 | return handlerInput.responseBuilder
76 | .speak(description)
77 | .getResponse();
78 | }
79 | });
80 |
81 | module.exports = CometsRequestHandler;
82 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/eventHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const SolarSystemResponse = require('../multimodal_responses/solarSystemResponse');
17 | const ExploreResponse = require('../multimodal_responses/exploreResponse');
18 | const ExploreZoneResponse = require('../multimodal_responses/exploreZoneResponse');
19 | const DistanceResponse = require('../multimodal_responses/distanceResponse');
20 | const SizeResponse = require('../multimodal_responses/sizeResponse');
21 | const AtmosphereResponse = require('../multimodal_responses/atmosphereResponse');
22 | const SatellitesResponse = require('../multimodal_responses/satellitesResponse');
23 | const BackResponse = require('../multimodal_responses/backResponse');
24 | const RandomImageResponse = require('../multimodal_responses/randomImageResponse');
25 | const AboutResponse = require('../multimodal_responses/aboutResponse');
26 |
27 | const MoonResponse = require('../multimodal_responses/moonResponse');
28 |
29 | const EventHandler = {
30 | canHandle: handlerInput =>
31 | handlerInput.requestEnvelope.request.type === 'Alexa.Presentation.APL.UserEvent',
32 | handle: handlerInput => {
33 | const args = handlerInput.requestEnvelope.request.arguments;
34 | const event = args[0];
35 | const data = args[1];
36 |
37 | switch (event) {
38 | case 'transcriptMediaEndedEvent':
39 | return handlerInput.responseBuilder
40 | .addDirective({
41 | type: 'Alexa.Presentation.APL.ExecuteCommands',
42 | token: 'transcript_document',
43 | commands: [
44 | {
45 | type: "ControlMedia",
46 | componentId: "myAudioPlayer",
47 | command: "rewind"
48 | },
49 | {
50 | type: "ControlMedia",
51 | componentId: "videoPlayer",
52 | command: "play"
53 | }
54 | ]
55 | }).getResponse();
56 | case 'startEvent':
57 | return SolarSystemResponse(handlerInput);
58 | case 'exploreEvent':
59 | // return handlerInput.responseBuilder.speak(data).getResponse();
60 | return data === 'the moon'
61 | ? MoonResponse(handlerInput, false)
62 | : ExploreResponse(handlerInput, data, false);
63 | case 'exploreZoneEvent':
64 | return ExploreZoneResponse(handlerInput, data, false);
65 | case 'aboutEvent':
66 | return AboutResponse(handlerInput, data, false);
67 | case 'distanceEvent':
68 | return DistanceResponse(handlerInput, data, 'the sun', null, false);
69 | case 'sizeEvent':
70 | return SizeResponse(handlerInput, data, 'earth', null, false);
71 | case 'compositionEvent':
72 | return AtmosphereResponse(handlerInput, data, false);
73 | case 'satellitesEvent':
74 | return SatellitesResponse(handlerInput, data, false);
75 | case 'backEvent':
76 | case 'goBack':
77 | return BackResponse(handlerInput);
78 | case 'imageEvent':
79 | return RandomImageResponse(handlerInput, '');
80 | default:
81 | return SolarSystemResponse(handlerInput);
82 | }
83 | }
84 | };
85 |
86 | module.exports = EventHandler;
87 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/exploreObjectHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const exploreResponse = require('../multimodal_responses/exploreResponse');
18 |
19 | const ExploreObjectRequestHandler = Handler('ExploreObject', handlerInput => {
20 | const slot = handlerInput.requestEnvelope.request.intent.slots.celestial_object.value.toLowerCase();
21 |
22 | return exploreResponse(handlerInput, slot);
23 | });
24 |
25 | module.exports = ExploreObjectRequestHandler;
26 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/exploreZoneHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const ExploreZoneResponse = require('../multimodal_responses/exploreZoneResponse');
18 |
19 | const ExploreZoneRequestHandler = Handler('ExploreZones', handlerInput => {
20 | const zone = handlerInput.requestEnvelope.request.intent.slots.zone.value;
21 |
22 | return ExploreZoneResponse(handlerInput, zone);
23 | });
24 |
25 | module.exports = ExploreZoneRequestHandler;
26 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/fallbackHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 |
18 | const FallbackHandler = Handler('AMAZON.FallbackIntent', handlerInput =>
19 | handlerInput.responseBuilder
20 | .speak("I'm sorry, I didn't get that. What did you say?")
21 | .addConfirmIntentDirective()
22 | .getResponse()
23 | );
24 |
25 | module.exports = FallbackHandler;
26 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/helpRequestHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 |
18 | const HelpRequestHandler = Handler('AMAZON.HelpIntent', handlerInput => {
19 | const { location } = handlerInput.attributesManager.getSessionAttributes();
20 | let speech;
21 | let respeech;
22 |
23 | switch (location) {
24 | case 'apod':
25 | speech = 'I can tell you about the image. Try, "Tell me about it."';
26 | respeech =
27 | 'You can also ask to explore a planet, or learn something else about the solar system. Try, "Tell me about the Oort Cloud."';
28 | break;
29 | case 'the sun':
30 | speech =
31 | 'I can give you an overview of the sun, or tell you about its size. Try, "How big is it?".';
32 | respeech = 'You can also ask to explore a planet, or view a random space image';
33 | break;
34 | case 'mercury':
35 | case 'venus':
36 | case 'earth':
37 | case 'mars':
38 | case 'jupiter':
39 | case 'saturn':
40 | case 'uranus':
41 | case 'neptune':
42 | case 'pluto':
43 | speech =
44 | 'You can ask for an overview of the planet or information about size, distance, the atmosphere or its moons. Try, "Tell me about it," or, "How big is it?".';
45 | respeech = 'You can also ask to explore another planet, or view a random space image';
46 | break;
47 | default:
48 | speech =
49 | 'I can take you almost anywhere you want to go in our solar system. Try "Take me to Saturn," or, "I\'d like to explore Saturn".';
50 | respeech =
51 | 'You can also ask me specific things about the planets, like, "Tell me about Saturn\'s rings."';
52 | break;
53 | }
54 |
55 | return handlerInput.responseBuilder
56 | .speak(speech)
57 | .reprompt(respeech)
58 | .addConfirmIntentDirective()
59 | .getResponse();
60 | });
61 |
62 | module.exports = HelpRequestHandler;
63 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const LaunchRequestHandler = require('./launchRequestHandler');
17 | const HelpRequestHandler = require('./helpRequestHandler');
18 | const EventHandler = require('./eventHandler');
19 | const CancelIntentHandler = require('./cancelIntentHandler');
20 | const FallbackHandler = require('./fallbackHandler');
21 |
22 | const ExploreZoneRequestHandler = require('./exploreZoneHandler');
23 | const ExploreObjectRequestHandler = require('./exploreObjectHandler');
24 | const ObjectAboutHandler = require('./objectAboutHandler');
25 | const ObjectAtmosphereHandler = require('./objectAtmosphereHandler');
26 | const ObjectSizeHandler = require('./objectSizeHandler');
27 | const ObjectDistanceHandler = require('./objectDistanceHandler');
28 | const ObjectSatellitesHandler = require('./objectSatellitesHandler');
29 | const RandomImageRequestHandler = require('./randomImageHandler');
30 | const ObjectRingHandler = require('./objectRingHandler');
31 | const MoreInfoRequestHandler = require('./moreInfoHandler');
32 | const SolarSystemRequestHandler = require('./solarSystemHandler');
33 | const BackRequestHandler = require('./backHandler');
34 | const OrdinalRequestHandler = require('./ordinalHandler');
35 |
36 | const PlanetRequestHandler = require('./planetsHandler');
37 | const PlutoRequestHandler = require('./plutoHandler');
38 | const CometsRequestHandler = require('./cometsHandler');
39 | const OtherRegionRequestHandler = require('./otherRegionHandler');
40 | const TheMoonRequestHandler = require('./theMoonHandler');
41 |
42 | module.exports = {
43 | LaunchRequestHandler,
44 | HelpRequestHandler,
45 | EventHandler,
46 | CancelIntentHandler,
47 | FallbackHandler,
48 | ExploreZoneRequestHandler,
49 | ExploreObjectRequestHandler,
50 | ObjectAboutHandler,
51 | ObjectAtmosphereHandler,
52 | ObjectSizeHandler,
53 | ObjectDistanceHandler,
54 | ObjectRingHandler,
55 | ObjectSatellitesHandler,
56 | RandomImageRequestHandler,
57 | MoreInfoRequestHandler,
58 | SolarSystemRequestHandler,
59 | BackRequestHandler,
60 | OrdinalRequestHandler,
61 | PlanetRequestHandler,
62 | PlutoRequestHandler,
63 | CometsRequestHandler,
64 | OtherRegionRequestHandler,
65 | TheMoonRequestHandler
66 | };
67 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/launchRequestHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const SolarSystemDirective = require('../documents/launch');
17 |
18 | const LaunchRequestHandler = {
19 | canHandle(handlerInput) {
20 | return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
21 | },
22 | handle(handlerInput) {
23 | handlerInput.attributesManager.setSessionAttributes({
24 | location: 'solar system',
25 | previousLocation: [],
26 | imageResource: null
27 | });
28 |
29 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
30 | return handlerInput.responseBuilder
31 | .addDirective(SolarSystemDirective())
32 | .getResponse();
33 | } else {
34 | return handlerInput.responseBuilder
35 | .speak(
36 | 'Welcome to our solar system. It is made up of a star, eight planets and countless smaller bodies. Where would you like to explore? You can ask me to take you anywhere in our solar system. Try, "take me to Mars."'
37 | )
38 | .reprompt('Where would you like to explore?')
39 | .getResponse();
40 | }
41 |
42 | }
43 | };
44 |
45 | module.exports = LaunchRequestHandler;
46 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/moreInfoHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const AboutResponse = require('../multimodal_responses/aboutResponse');
18 | const data = require('../data/planets.json');
19 |
20 | const planets = [
21 | 'the sun',
22 | 'mercury',
23 | 'venus',
24 | 'earth',
25 | 'mars',
26 | 'jupiter',
27 | 'saturn',
28 | 'uranus',
29 | 'neptune',
30 | 'pluto'
31 | ];
32 |
33 | const MoreInfoRequestHandler = Handler('MoreInfo', handlerInput => {
34 | const { location, imageResource } = handlerInput.attributesManager.getSessionAttributes();
35 |
36 | if (location === 'apod' || location === 'the moon') {
37 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
38 | return handlerInput.responseBuilder
39 | .addDirective({
40 | type: 'Alexa.Presentation.APL.ExecuteCommands',
41 | token: 'transcript_document',
42 | commands: [
43 | {
44 | type: 'Sequential',
45 | commands: [
46 | {
47 | type: 'SpeakItem',
48 | componentId: 'karaokeText',
49 | highlightMode: 'line',
50 | align: 'center'
51 | },
52 | {
53 | type: 'Scroll',
54 | componentId: 'scrollContainer',
55 | distance: -10000
56 | }
57 | ]
58 | }
59 | ]
60 | })
61 | .getResponse();
62 | } else {
63 | return handlerInput.responseBuilder
64 | .speak(location === 'apod' ? imageResource.description : data.earth.satellites[0].description )
65 | .reprompt('Would you like to learn about something else?')
66 | .getResponse();
67 | }
68 | }
69 | if (planets.indexOf(location) !== -1) {
70 | return AboutResponse(handlerInput, location);
71 | }
72 | return handlerInput.responseBuilder.speak("I'm sorry, I don't know that one.").getResponse();
73 | });
74 |
75 | module.exports = MoreInfoRequestHandler;
76 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/objectAboutHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const AboutResponse = require('../multimodal_responses/aboutResponse');
18 |
19 | const ObjectAboutHandler = Handler('ObjectAbout', handlerInput => {
20 | const slot = handlerInput.requestEnvelope.request.intent.slots.celestial_object.value;
21 | const location = slot || handlerInput.attributesManager.getSessionAttributes().location;
22 |
23 | return AboutResponse(handlerInput, location.toLowerCase());
24 | });
25 |
26 | module.exports = ObjectAboutHandler;
27 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/objectAtmosphereHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const AtmosphereResponse = require('../multimodal_responses/atmosphereResponse');
18 |
19 | const ObjectAtmosphereHandler = Handler('ObjectAtmosphere', handlerInput => {
20 | const slot = handlerInput.requestEnvelope.request.intent.slots.celestial_object.value;
21 | const location = slot || handlerInput.attributesManager.getSessionAttributes().location;
22 |
23 | return AtmosphereResponse(handlerInput, location);
24 | });
25 |
26 | module.exports = ObjectAtmosphereHandler;
27 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/objectDistanceHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const data = require('../data/planets.json');
18 | const DistanceResponse = require('../multimodal_responses/distanceResponse');
19 |
20 | const ObjectDistanceHandler = Handler('ObjectDistance', handlerInput => {
21 | let fromSlot =
22 | handlerInput.requestEnvelope.request.intent.slots.celestial_object.value || 'earth';
23 | const objectSlot = handlerInput.requestEnvelope.request.intent.slots.celestial_object_two.value;
24 | const location = objectSlot || handlerInput.attributesManager.getSessionAttributes().location;
25 | const comparison = handlerInput.requestEnvelope.request.intent.slots.distance_comparison.value;
26 | let speech = '';
27 |
28 | if (fromSlot.toLowerCase() === location) {
29 | fromSlot = 'the sun';
30 | }
31 |
32 | if (!comparison && location && data[location.toLowerCase()]) {
33 | return DistanceResponse(handlerInput, location, fromSlot, null);
34 | }
35 | if (comparison && location && data[location.toLowerCase()]) {
36 | const basis = data.earth.distance;
37 |
38 | if (comparison === 'closer' || comparison === 'nearer') {
39 | const dist1 = Math.abs(basis - data[location.toLowerCase()]);
40 | const dist2 = Math.abs(basis - data[fromSlot.toLowerCase()]);
41 | const diff = dist1 - dist2;
42 |
43 | if (diff > 0) {
44 | speech = `${fromSlot}'s orbit is ${diff} miles closer than ${location}'s`;
45 | } else {
46 | speech = `${fromSlot}'s orbit is actually ${Math.abs(
47 | diff
48 | )} miles farther away than ${location}'s`;
49 | }
50 | } else if (
51 | comparison === 'father' ||
52 | comparison === 'further' ||
53 | comparison === 'father away' ||
54 | comparison === 'further away'
55 | ) {
56 | const dist1 = Math.abs(basis - data[location.toLowerCase()].distance);
57 | const dist2 = Math.abs(basis - data[fromSlot.toLowerCase()].distance);
58 | const diff = dist2 - dist1;
59 |
60 | // speech = comparison + ' ' + diff
61 |
62 | if (diff > 0) {
63 | speech = `${fromSlot}'s orbit is ${diff} miles farther away than ${location}'s`;
64 | } else {
65 | speech = `${fromSlot}'s orbit is actually ${Math.abs(
66 | diff
67 | )} miles closer than ${location}'s`;
68 | }
69 | }
70 | } else {
71 | speech = "I'm not sure I know that one.";
72 | }
73 |
74 | return DistanceResponse(handlerInput, location, fromSlot, speech);
75 | });
76 |
77 | module.exports = ObjectDistanceHandler;
78 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/objectRingHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const cdnPath = require('../helpers/cdn-path');
18 | const data = require('../data/planets.json');
19 | const TranscriptDirective = require('../documents/transcript');
20 |
21 | const ObjectRingHandler = Handler('ObjectRings', handlerInput => {
22 | let speech = '';
23 | const attributes = handlerInput.attributesManager.getSessionAttributes();
24 | const location =
25 | handlerInput.requestEnvelope.request.intent.slots.celestial_object.value || attributes.location;
26 |
27 | if (location) {
28 | const { rings } = data[location.toLowerCase()];
29 | speech = !rings ? `${location} doesn't have a ring system.` : '';
30 | } else {
31 | speech = "Hmm. I don't know that one.";
32 | }
33 |
34 | if (
35 | attributes.previousLocation &&
36 | attributes.previousLocation[attributes.previousLocation.length - 1] !== location
37 | ) {
38 | attributes.previousLocation.push(location);
39 | }
40 |
41 | if (!attributes.previousLocation) {
42 | attributes.previousLocation = ['solar system'];
43 | }
44 |
45 | handlerInput.attributesManager.setSessionAttributes(attributes);
46 |
47 | if (speech) {
48 | return handlerInput.responseBuilder.speak(speech).getResponse();
49 | }
50 |
51 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
52 | return handlerInput.responseBuilder
53 | .addDirective(
54 | TranscriptDirective(
55 | {
56 | image: `${cdnPath}assets/rings_${location.toLowerCase()}.jpg`,
57 | description: data[location.toLowerCase()].rings,
58 | source: 'NASA'
59 | },
60 | `${location.toUpperCase()} · RINGS`
61 | )
62 | )
63 | .addDirective({
64 | type: 'Alexa.Presentation.APL.ExecuteCommands',
65 | token: 'transcript_document',
66 | commands: [
67 | {
68 | type: 'Sequential',
69 | commands: [
70 | {
71 | type: 'SpeakItem',
72 | componentId: 'karaokeText',
73 | highlightMode: 'line',
74 | align: 'center'
75 | },
76 | {
77 | type: 'Scroll',
78 | componentId: 'scrollContainer',
79 | distance: -10000
80 | }
81 | ]
82 | }
83 | ]
84 | })
85 | .getResponse();
86 | } else {
87 | return handlerInput.responseBuilder
88 | .speak(data[location.toLowerCase()].rings)
89 | .getResponse();
90 | }
91 | });
92 |
93 | module.exports = ObjectRingHandler;
94 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/objectSatellitesHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const SatellitesResponse = require('../multimodal_responses/satellitesResponse');
18 |
19 | const ObjectSatellitesHandler = Handler('ObjectSatellites', handlerInput => {
20 | const slot = handlerInput.requestEnvelope.request.intent.slots.celestial_object.value;
21 | const location = slot || handlerInput.attributesManager.getSessionAttributes().location;
22 |
23 | return SatellitesResponse(handlerInput, location.toLowerCase());
24 | });
25 |
26 | module.exports = ObjectSatellitesHandler;
27 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/objectSizeHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const data = require('../data/planets.json');
18 | const SizeResponse = require('../multimodal_responses/sizeResponse');
19 |
20 | const ObjectSizeHandler = Handler('ObjectSize', handlerInput => {
21 | const slot = handlerInput.requestEnvelope.request.intent.slots.celestial_object.value;
22 | const location = slot || handlerInput.attributesManager.getSessionAttributes().location;
23 | const comparison = handlerInput.requestEnvelope.request.intent.slots.size_comparison
24 | ? handlerInput.requestEnvelope.request.intent.slots.size_comparison.value
25 | : 'bigger';
26 | const comparator =
27 | handlerInput.requestEnvelope.request.intent.slots.celestial_object_two &&
28 | handlerInput.requestEnvelope.request.intent.slots.celestial_object_two.value
29 | ? handlerInput.requestEnvelope.request.intent.slots.celestial_object_two.value
30 | : 'earth';
31 | let speech = '';
32 | let diff;
33 |
34 | if (location && data[location.toLowerCase()]) {
35 | // speech = 'Comparator is ' + comparator + '. The comparison is ' + comparison;
36 |
37 | if (slot && comparator && (comparison === 'bigger' || comparison === 'larger')) {
38 | diff = data[location.toLowerCase()].diameter - data[comparator.toLowerCase()].diameter;
39 |
40 | if (diff > 0) {
41 | speech = `${location}'s diameter is ${diff} miles larger than ${comparator}'s`;
42 | } else {
43 | speech = `${location}'s diameter is ${Math.abs(diff)} miles smaller than ${comparator}'s`;
44 | }
45 | } else if (comparator && (comparison === 'bigger' || comparison === 'larger')) {
46 | diff = data[comparator.toLowerCase()].diameter - data[location.toLowerCase()].diameter;
47 |
48 | if (diff > 0) {
49 | speech = `${comparator}'s diameter is ${diff} miles larger than ${location}'s`;
50 | } else {
51 | speech = `${comparator}'s diameter is ${Math.abs(diff)} miles smaller than ${location}'s`;
52 | }
53 | } else if (slot && comparator && (comparison === 'smaller' || comparison === 'littler')) {
54 | diff = data[comparator.toLowerCase()].diameter - data[location.toLowerCase()].diameter;
55 |
56 | if (diff > 0) {
57 | speech = `${location}'s diameter is ${diff} miles smaller than ${comparator}'s`;
58 | } else {
59 | speech = `${location}'s diameter is ${Math.abs(diff)} miles larger than ${comparator}'s`;
60 | }
61 | } else if (comparator && (comparison === 'smaller' || comparison === 'littler')) {
62 | diff = data[location.toLowerCase()].diameter - data[comparator.toLowerCase()].diameter;
63 |
64 | if (diff > 0) {
65 | speech = `${comparator}'s diameter is ${diff} miles smaller than ${location}'s`;
66 | } else {
67 | speech = `${comparator}'s diameter is ${Math.abs(diff)} miles larger than ${location}'s`;
68 | }
69 | }
70 | } else {
71 | speech = "I'm not sure I know that one.";
72 | return handlerInput.responseBuilder.speak(speech).getResponse();
73 | }
74 |
75 | return SizeResponse(handlerInput, location, comparator, speech);
76 | });
77 |
78 | module.exports = ObjectSizeHandler;
79 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/ordinalHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const exploreResponse = require('../multimodal_responses/exploreResponse');
18 |
19 | const planets = [
20 | 'the sun',
21 | 'mercury',
22 | 'venus',
23 | 'earth',
24 | 'mars',
25 | 'jupiter',
26 | 'saturn',
27 | 'uranus',
28 | 'neptune'
29 | ];
30 |
31 | const aboutResponse = require('../multimodal_responses/aboutResponse');
32 | const sizeResponse = require('../multimodal_responses/sizeResponse');
33 | const distanceResponse = require('../multimodal_responses/distanceResponse');
34 | const atmosphereResponse = require('../multimodal_responses/atmosphereResponse');
35 | const satellitesResponse = require('../multimodal_responses/satellitesResponse');
36 |
37 | const ordinalResponses = [
38 | null,
39 | aboutResponse,
40 | sizeResponse,
41 | distanceResponse,
42 | atmosphereResponse,
43 | satellitesResponse
44 | ];
45 |
46 | const OrdinalRequestHandler = Handler('OrdinalIntent', handlerInput => {
47 | const slot = handlerInput.requestEnvelope.request.intent.slots.number.value;
48 | const { location } = handlerInput.attributesManager.getSessionAttributes();
49 |
50 | if (location === 'solar system' && planets[slot]) {
51 | return exploreResponse(handlerInput, planets[slot]);
52 | }
53 | if (location === 'inner' && planets[slot] && slot <= 4) {
54 | return exploreResponse(handlerInput, planets[slot]);
55 | }
56 | if (location === 'outer' && planets[parseInt(slot, 10) + 4] && slot <= 4) {
57 | return exploreResponse(handlerInput, planets[parseInt(slot, 10) + 4]);
58 | }
59 | if (location !== 'apod' && ordinalResponses[slot]) {
60 | if (slot === 2) {
61 | return ordinalResponses[slot](handlerInput, location, 'earth', null);
62 | }
63 |
64 | if (slot === 3) {
65 | return ordinalResponses[slot](handlerInput, location, 'the sun', null);
66 | }
67 |
68 | return ordinalResponses[slot](handlerInput, location);
69 | }
70 | return handlerInput.responseBuilder.speak("I'm sorry, I can't do that right now.").getResponse();
71 | });
72 |
73 | module.exports = OrdinalRequestHandler;
74 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/otherRegionHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const cdnPath = require('../helpers/cdn-path');
18 | const TranscriptDirective = require('../documents/transcript');
19 |
20 | const data = {
21 | 'kuiper belt': {
22 | image: `${cdnPath}kuiper_belt.jpeg`,
23 | description:
24 | 'The Kuiper Belt is a disc-shaped region beyond Neptune that extends from about 30 to 55 astronomical units (compared to Earth which is one astronomical unit, or AU, from the Sun). Comets from the Kuiper Belt, known as short period comets, take less than 200 years to orbit the Sun and travel approximately in the plane in which most of the planets orbit the Sun. There may be hundreds of thousands of icy bodies and a trillion or more comets in this distant region of our solar system.'
25 | },
26 | 'oort cloud': {
27 | image: `${cdnPath}oort_cloud.jpeg`,
28 | description:
29 | "The Oort Cloud lies far beyond Pluto and the most distant edges of the Kuiper Belt. While the planets of our solar system orbit in a flat plane, the Oort Cloud is believed to be a giant spherical shell surrounding the Sun, planets, and Kuiper Belt Objects. It is like a big, thick bubble around our solar system. The Oort Cloud's icy bodies can be as large as mountains — and sometimes larger."
30 | },
31 | 'asteroid belt': {
32 | image: `${cdnPath}asteroid_belt.jpeg`,
33 | description:
34 | 'Asteroids are rocky, airless worlds that orbit our Sun, but are too small to be called planets. Tens of thousands of these minor planets are gathered in the main asteroid belt, a vast doughnut-shaped ring between the orbits of Mars and Jupiter. Asteroids that pass close to Earth—and merit close watch—are called Near-Earth Objects, or NEOs.'
35 | }
36 | };
37 |
38 | function capitalize(string) {
39 | const words = string.split(' ');
40 | words[0] = words[0].split('');
41 | words[1] = words[1].split('');
42 |
43 | words[0][0] = words[0][0].toUpperCase();
44 | words[1][0] = words[1][0].toUpperCase();
45 |
46 | words[0] = words[0].join('');
47 | words[1] = words[1].join('');
48 |
49 | return words.join(' ');
50 | }
51 |
52 | const OtherRegionRequestHandler = Handler('OtherRegionIntent', handlerInput => {
53 | const slot = handlerInput.requestEnvelope.request.intent.slots.other_region.value;
54 |
55 | const attributes = handlerInput.attributesManager.getSessionAttributes();
56 | const location = attributes.location || 'solar system';
57 |
58 | if (
59 | attributes.previousLocation &&
60 | attributes.previousLocation[attributes.previousLocation.length - 1] !== location
61 | ) {
62 | attributes.previousLocation.push(location);
63 | }
64 |
65 | if (!attributes.previousLocation) {
66 | attributes.previousLocation = ['solar system'];
67 | }
68 |
69 | handlerInput.attributesManager.setSessionAttributes(attributes);
70 |
71 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
72 | return handlerInput.responseBuilder
73 | .addDirective(
74 | TranscriptDirective(
75 | {
76 | title: capitalize(slot),
77 | image: data[slot].image,
78 | source: 'NASA',
79 | description: data[slot].description
80 | },
81 | 'LEARN MORE'
82 | )
83 | )
84 | .addDirective({
85 | type: 'Alexa.Presentation.APL.ExecuteCommands',
86 | token: 'transcript_document',
87 | commands: [
88 | {
89 | type: 'Sequential',
90 | commands: [
91 | {
92 | type: 'SpeakItem',
93 | componentId: 'karaokeText',
94 | highlightMode: 'line',
95 | align: 'center'
96 | },
97 | {
98 | type: 'Scroll',
99 | componentId: 'scrollContainer',
100 | distance: -10000
101 | }
102 | ]
103 | }
104 | ]
105 | })
106 | .getResponse();
107 | } else {
108 | return handlerInput.responseBuilder
109 | .speak(data[slot].description)
110 | .reprompt('What else would you like to know?')
111 | .getResponse();
112 | }
113 | });
114 |
115 | module.exports = OtherRegionRequestHandler;
116 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/planetsHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 |
18 | const PlanetRequestHandler = Handler('PlanetsIntent', handlerInput =>
19 | handlerInput.responseBuilder
20 | .speak(
21 | 'There are eight planets in our solar system. In order of distance from the son, they are: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Neptune.'
22 | )
23 | .getResponse()
24 | );
25 |
26 | module.exports = PlanetRequestHandler;
27 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/plutoHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const data = require('../data/planets.json');
18 | const TranscriptDirective = require('../documents/transcript');
19 |
20 | const description = 'In 2006, after the discovery of more massive objects in the distant region of our solar system known as the Kuiper Belt, the official definition of the term "planet" was revised. This revision excluded Pluto, which was reclassified as a dwarf planet.'
21 |
22 | const PlutoRequestHandler = Handler('PlutoIntent', handlerInput => {
23 | const index = Math.floor(Math.random() * 4);
24 |
25 | const attributes = handlerInput.attributesManager.getSessionAttributes();
26 | const location = attributes.location || 'solar system';
27 |
28 | if (
29 | attributes.previousLocation &&
30 | attributes.previousLocation[attributes.previousLocation.length - 1] !== location
31 | ) {
32 | attributes.previousLocation.push(location);
33 | }
34 |
35 | if (!attributes.previousLocation) {
36 | attributes.previousLocation = ['solar system'];
37 | }
38 |
39 | handlerInput.attributesManager.setSessionAttributes(attributes);
40 |
41 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
42 | return handlerInput.responseBuilder
43 | .addDirective(
44 | TranscriptDirective(
45 | {
46 | image: data.pluto.about.images[index],
47 | title: "Pluto's Fate",
48 | source: 'NASA',
49 | description: description
50 | },
51 | 'LEARN MORE'
52 | )
53 | )
54 | .addDirective({
55 | type: 'Alexa.Presentation.APL.ExecuteCommands',
56 | token: 'transcript_document',
57 | commands: [
58 | {
59 | type: 'Sequential',
60 | commands: [
61 | {
62 | type: 'SpeakItem',
63 | componentId: 'karaokeText',
64 | highlightMode: 'line',
65 | align: 'center'
66 | },
67 | {
68 | type: 'Scroll',
69 | componentId: 'scrollContainer',
70 | distance: -10000
71 | }
72 | ]
73 | }
74 | ]
75 | })
76 | .getResponse();
77 | } else {
78 | return handlerInput.responseBuilder
79 | .speak(description)
80 | .reprompt('Were you curious about something else?')
81 | .getResponse();
82 | }
83 | });
84 |
85 | module.exports = PlutoRequestHandler;
86 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/randomImageHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const RandomImageResponse = require('../multimodal_responses/randomImageResponse');
18 | const data = require('../data/images.json');
19 |
20 | const RandomImageRequestHandler = Handler('RandomImage', handlerInput => {
21 | const resource = data[Math.round(Math.random() * data.length)];
22 | const attributes = handlerInput.attributesManager.getSessionAttributes();
23 |
24 | attributes.imageResource = resource;
25 | handlerInput.attributesManager.setSessionAttributes(attributes);
26 |
27 | return RandomImageResponse(
28 | handlerInput,
29 | 'Okay, here is your random space image from the Astronomy Picture of the Day archives.'
30 | );
31 | });
32 |
33 | module.exports = RandomImageRequestHandler;
34 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/solarSystemHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const SolarSystemResponse = require('../multimodal_responses/solarSystemResponse');
18 |
19 | const SolarSystemRequestHandler = Handler('SolarSystem', handlerInput =>
20 | SolarSystemResponse(handlerInput)
21 | );
22 |
23 | module.exports = SolarSystemRequestHandler;
24 |
--------------------------------------------------------------------------------
/lambda/custom/handlers/theMoonHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Handler = require('../helpers/handler');
17 | const MoonResponse = require('../multimodal_responses/moonResponse');
18 |
19 | const TheMoonRequestHandler = Handler('TheMoonIntent', handlerInput => MoonResponse(handlerInput));
20 |
21 | module.exports = TheMoonRequestHandler;
22 |
--------------------------------------------------------------------------------
/lambda/custom/helpers/cdn-path.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | 'use strict';
17 |
18 | module.exports = 'https://d1od0khoye9qi3.cloudfront.net/';
19 |
--------------------------------------------------------------------------------
/lambda/custom/helpers/handler.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | 'use strict';
17 |
18 | // @params
19 | // intent: String
20 | // handle: Function : Response
21 | //
22 | function Handler(intent, handle) {
23 | return {
24 | canHandle(handlerInput) {
25 | return handlerInput.requestEnvelope.request.type === 'IntentRequest'
26 | && handlerInput.requestEnvelope.request.intent.name === intent;
27 | },
28 | handle: handle
29 | };
30 | }
31 |
32 | module.exports = Handler;
33 |
--------------------------------------------------------------------------------
/lambda/custom/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const Alexa = require('ask-sdk-core');
17 |
18 | const {
19 | LaunchRequestHandler,
20 | HelpRequestHandler,
21 | EventHandler,
22 | FallbackHandler,
23 | CancelIntentHandler,
24 | ExploreZoneRequestHandler,
25 | ExploreObjectRequestHandler,
26 | ObjectAboutHandler,
27 | ObjectAtmosphereHandler,
28 | ObjectSizeHandler,
29 | ObjectDistanceHandler,
30 | ObjectRingHandler,
31 | ObjectSatellitesHandler,
32 | RandomImageRequestHandler,
33 | MoreInfoRequestHandler,
34 | SolarSystemRequestHandler,
35 | BackRequestHandler,
36 | OrdinalRequestHandler,
37 | PlanetRequestHandler,
38 | PlutoRequestHandler,
39 | CometsRequestHandler,
40 | OtherRegionRequestHandler,
41 | TheMoonRequestHandler
42 | } = require('./handlers');
43 |
44 | const SessionEndedRequestHandler = {
45 | canHandle(handlerInput) {
46 | return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
47 | },
48 | handle(handlerInput) {
49 | return;
50 | }
51 | };
52 |
53 | exports.handler = Alexa.SkillBuilders.custom()
54 | .addRequestHandlers(
55 | LaunchRequestHandler,
56 | HelpRequestHandler,
57 | EventHandler,
58 | FallbackHandler,
59 | CancelIntentHandler,
60 | ExploreZoneRequestHandler,
61 | ExploreObjectRequestHandler,
62 | ObjectAboutHandler,
63 | ObjectAtmosphereHandler,
64 | ObjectSizeHandler,
65 | ObjectDistanceHandler,
66 | ObjectRingHandler,
67 | ObjectSatellitesHandler,
68 | RandomImageRequestHandler,
69 | MoreInfoRequestHandler,
70 | SolarSystemRequestHandler,
71 | BackRequestHandler,
72 | OrdinalRequestHandler,
73 | PlanetRequestHandler,
74 | PlutoRequestHandler,
75 | CometsRequestHandler,
76 | OtherRegionRequestHandler,
77 | TheMoonRequestHandler,
78 | SessionEndedRequestHandler
79 | )
80 | .lambda();
81 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/aboutResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const data = require('../data/planets.json');
17 | const TranscriptDirective = require('../documents/transcript');
18 |
19 | module.exports = (handlerInput, planet, speak = true) => {
20 | const { about } = data[planet];
21 |
22 | about.image = about.images[Math.floor(Math.random() * about.images.length)];
23 |
24 | const attributes = handlerInput.attributesManager.getSessionAttributes();
25 |
26 | if (
27 | attributes.previousLocation &&
28 | attributes.previousLocation[attributes.previousLocation.length - 1] !== planet
29 | ) {
30 | attributes.previousLocation.push(attributes.location);
31 | }
32 |
33 | attributes.location = planet;
34 | handlerInput.attributesManager.setSessionAttributes(attributes);
35 |
36 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
37 | return handlerInput.responseBuilder
38 | .addDirective(TranscriptDirective(about, `${planet.toUpperCase()} · OVERVIEW`))
39 | .addDirective({
40 | type: 'Alexa.Presentation.APL.ExecuteCommands',
41 | token: 'transcript_document',
42 | commands: [
43 | {
44 | type: 'Sequential',
45 | commands: [
46 | {
47 | type: 'SpeakItem',
48 | componentId: speak ? 'karaokeText' : 'doNothing',
49 | highlightMode: 'line',
50 | align: 'center'
51 | },
52 | {
53 | type: 'Scroll',
54 | componentId: 'scrollContainer',
55 | distance: -10000
56 | }
57 | ]
58 | }
59 | ]
60 | })
61 | .getResponse();
62 | } else {
63 | return handlerInput.responseBuilder
64 | .speak(about.description)
65 | .getResponse();
66 | }
67 | };
68 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/atmosphereResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const CompositionDirective = require('../documents/atmosphere');
17 | const data = require('../data/planets.json');
18 |
19 | module.exports = (handlerInput, location, speak = true) => {
20 | let speech = '';
21 | let comp;
22 |
23 | if (location && data[location.toLowerCase()]) {
24 | comp = data[location.toLowerCase()].atmosphere;
25 | speech = `${location}'s atmosphere is made up of `;
26 |
27 | comp.forEach((item, i) => {
28 | let percentage;
29 | const cleaned = item.percentage.toString();
30 |
31 | if (cleaned.search('~') !== -1) {
32 | percentage = `about ${cleaned.substr(1)}`;
33 | } else if (cleaned.search('<') !== -1) {
34 | percentage = `less than ${cleaned.substr(1)}`;
35 | } else {
36 | percentage = cleaned;
37 | }
38 |
39 | speech += `${(i === comp.length - 1 && comp.length > 1 ? 'and ' : '') + percentage}% ${
40 | item.element
41 | }${i === comp.length - 1 ? '.' : ', '}`;
42 | });
43 | } else {
44 | speech = "I'm not sure I know that one.";
45 | }
46 |
47 | const attributes = handlerInput.attributesManager.getSessionAttributes();
48 |
49 | if (
50 | attributes.previousLocation &&
51 | attributes.previousLocation[attributes.previousLocation.length - 1] !== location
52 | ) {
53 | attributes.previousLocation.push(location);
54 | }
55 |
56 | handlerInput.attributesManager.setSessionAttributes(attributes);
57 |
58 | if (comp.length === 0) {
59 | speech = `${location} has no atmosphere.`;
60 | }
61 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
62 | return handlerInput.responseBuilder
63 | .addDirective(CompositionDirective(location.toLowerCase(), comp))
64 | // .addDirective({
65 | // type: 'Alexa.Presentation.APL.ExecuteCommands',
66 | // token: 'atmospheric-composition',
67 | // commands: [
68 | // {
69 | // type: 'onLoad'
70 | // }
71 | // ]
72 | // })
73 | .speak(speak && speech)
74 | .getResponse();
75 | } else {
76 | return handlerInput.responseBuilder
77 | .speak(speech)
78 | .getResponse();
79 | }
80 | };
81 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/backResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const planetDirective = require('../documents/planet');
17 | const solarSystemDirective = require('../documents/solarSystem');
18 | const solarSystemZoneDirective = require('../documents/solarSystemZone');
19 | const karaoke = require('../documents/transcript');
20 |
21 | module.exports = handlerInput => {
22 | const sA = handlerInput.attributesManager.getSessionAttributes();
23 | const previous = sA.previousLocation;
24 | let directive;
25 |
26 | // if (!previous) {
27 | // handlerInput.attributesManager.setSessionAttributes({
28 | // previousLocation: [],
29 | // location: 'solar system'
30 | // });
31 |
32 | // if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
33 | // return handlerInput.responseBuilder.addDirective(solarSystemDirective()).getResponse();
34 | // } else {
35 |
36 | // }
37 | // }
38 |
39 | if (previous && previous.length) {
40 | const loc = previous.pop();
41 | let cleanedLoc = loc;
42 |
43 | switch (loc) {
44 | case 'apod':
45 | directive = karaoke(sA.imageResource);
46 | cleanedLoc = 'your random space image';
47 | break;
48 | case 'solar system':
49 | directive = solarSystemDirective();
50 | cleanedLoc = 'the solar system';
51 | break;
52 | case 'inner':
53 | case 'outer':
54 | directive = solarSystemZoneDirective(loc);
55 | cleanedLoc = `the ${loc} solar system`;
56 | break;
57 | default:
58 | directive = planetDirective(loc);
59 | break;
60 | }
61 |
62 | handlerInput.attributesManager.setSessionAttributes({
63 | previousLocation: previous,
64 | location: loc
65 | });
66 |
67 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
68 | return handlerInput.responseBuilder.addDirective(directive).getResponse();
69 | } else {
70 | return handlerInput.responseBuilder
71 | .speak(`Okay. Heading back to ${cleanedLoc}.`)
72 | .getResponse();
73 | }
74 | }
75 | if (previous) {
76 | return handlerInput.responseBuilder
77 | .speak('Sorry, I can\'t go back any further. If you would like to exit, say "exit".')
78 | .reprompt(
79 | 'If you would like to exit, say "exit". Or ask to visit a planet in the solar system.'
80 | )
81 | .getResponse();
82 | }
83 |
84 | handlerInput.attributesManager.setSessionAttributes({
85 | previousLocation: [],
86 | location: 'solar system'
87 | });
88 |
89 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
90 | return handlerInput.responseBuilder.addDirective(solarSystemDirective()).getResponse();
91 | } else {
92 | return handlerInput.responseBuilder
93 | .speak('Okay. Heading back to the solar system. Where would you like to explore? You can ask me to take you anywhere in our solar system. Try, "take me to Mercury."')
94 | .reprompt('Where would you like to explore?')
95 | .getResponse();
96 | }
97 | };
98 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/distanceResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const DistanceDirective = require('../documents/distance');
17 | const data = require('../data/planets.json');
18 |
19 | module.exports = (handlerInput, object1, object2 = 'the sun', text, speak = true) => {
20 | const distance = data[object1.toLowerCase()].distance - data[object2.toLowerCase()].distance;
21 | const speech =
22 | text ||
23 | `${object1}'s orbit is ${Math.abs(distance)} miles from ${
24 | object2 === 'the sun' ? object2 : `${object2}'s orbit`
25 | }`;
26 |
27 | const attributes = handlerInput.attributesManager.getSessionAttributes();
28 |
29 | if (
30 | attributes.previousLocation &&
31 | attributes.previousLocation[attributes.previousLocation.length - 1] !== attributes.location
32 | ) {
33 | attributes.previousLocation.push(attributes.location);
34 | }
35 |
36 | handlerInput.attributesManager.setSessionAttributes(attributes);
37 |
38 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
39 | return handlerInput.responseBuilder
40 | .speak(speak && speech)
41 | .addDirective(DistanceDirective(object1.toLowerCase(), object2.toLowerCase()))
42 | .getResponse();
43 | } else {
44 | return handlerInput.responseBuilder
45 | .speak(speech)
46 | .getResponse();
47 | }
48 | };
49 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/exploreResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const planetDirective = require('../documents/planet');
17 |
18 | module.exports = (handlerInput, destination, speak = true) => {
19 | const attributes = handlerInput.attributesManager.getSessionAttributes() || {};
20 | const { location } = attributes;
21 | let text = `Okay. Approaching ${destination}.`;
22 |
23 | if (location !== 'solar system' && location !== undefined) {
24 | const loc = location === 'apod' ? 'your random image' : location;
25 |
26 | text = `Okay. Leaving ${
27 | loc === 'inner' || loc === 'outer' ? `the ${location} solar system` : location
28 | } and heading to ${destination}.`;
29 | }
30 |
31 | if (
32 | attributes.previousLocation &&
33 | attributes.previousLocation[attributes.previousLocation.length - 1] !== location
34 | ) {
35 | attributes.previousLocation.push(location);
36 | }
37 |
38 | attributes.location = destination;
39 | handlerInput.attributesManager.setSessionAttributes(attributes);
40 |
41 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
42 | return handlerInput.responseBuilder
43 | .speak(speak && text)
44 | .addDirective(planetDirective(destination))
45 | .getResponse();
46 | } else {
47 | return handlerInput.responseBuilder
48 | .speak(`${text} What would you like to learn? You can ask me how big it is, how far away it is, what its atmosphere is made of, and how many moons it has. Or, you can just ask me to tell you about it.`)
49 | .reprompt('What would you like to learn?')
50 | .getResponse();
51 | }
52 | };
53 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/exploreZoneResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const ExploreZoneDirective = require('../documents/solarSystemZone');
17 |
18 | module.exports = (handlerInput, zone, speak = true) => {
19 | const cleanedZone = zone.search('inner') !== -1 ? 'inner' : 'outer';
20 |
21 | const attributes = handlerInput.attributesManager.getSessionAttributes();
22 |
23 | if (
24 | attributes.previousLocation &&
25 | attributes.previousLocation[attributes.previousLocation.length - 1] !== attributes.location
26 | ) {
27 | attributes.previousLocation.push(attributes.location);
28 | }
29 |
30 | if (!attributes.previousLocation) {
31 | attributes.previousLocation = ['solar system'];
32 | }
33 |
34 | attributes.location = cleanedZone;
35 |
36 | handlerInput.attributesManager.setSessionAttributes(attributes);
37 |
38 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
39 | return handlerInput.responseBuilder
40 | .addDirective(ExploreZoneDirective(cleanedZone))
41 | .speak(
42 | speak && `Welcome to the ${cleanedZone} solar system. Which planet would you like to visit?`
43 | )
44 | .getResponse();
45 | } else {
46 | return handlerInput.responseBuilder
47 | .speak(`Welcome to the ${cleanedZone} solar system. Which planet would you like to visit?`)
48 | .reprompt('Which planet would you like to visit?')
49 | .getResponse();
50 | }
51 | };
52 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/moonResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const TranscriptDirective = require('../documents/transcript');
17 |
18 | const data = require('../data/planets.json');
19 |
20 | module.exports = (handlerInput, speak = true) => {
21 | const moon = data.earth.satellites.interesting[0];
22 |
23 | const attributes = handlerInput.attributesManager.getSessionAttributes();
24 | const { location } = attributes;
25 |
26 | if (
27 | attributes.previousLocation &&
28 | attributes.previousLocation[attributes.previousLocation.length - 1] !== location
29 | ) {
30 | attributes.previousLocation.push(location);
31 | }
32 |
33 | attributes.location = 'the moon';
34 | handlerInput.attributesManager.setSessionAttributes(attributes);
35 |
36 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
37 | return handlerInput.responseBuilder
38 | .addDirective(
39 | TranscriptDirective(
40 | {
41 | image: moon.image,
42 | source: 'NASA',
43 | title: moon.label,
44 | description: moon.description
45 | },
46 | 'EARTH · THE MOON'
47 | )
48 | )
49 | .addDirective({
50 | type: 'Alexa.Presentation.APL.ExecuteCommands',
51 | token: 'transcript_document',
52 | commands: [
53 | {
54 | type: 'Sequential',
55 | commands: [
56 | {
57 | type: 'SpeakItem',
58 | componentId: speak ? 'karaokeText' : 'doNothing',
59 | highlightMode: 'line',
60 | align: 'center'
61 | },
62 | {
63 | type: 'Scroll',
64 | componentId: 'scrollContainer',
65 | distance: -10000
66 | }
67 | ]
68 | }
69 | ]
70 | })
71 | .getResponse();
72 | } else {
73 | return handlerInput.responseBuilder
74 | .speak(moon.description)
75 | .getResponse();
76 | }
77 | };
78 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/randomImageResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const data = require('../data/images.json');
17 | const TranscriptDirective = require('../documents/transcript');
18 |
19 | module.exports = (handlerInput, text) => {
20 | const attributes = handlerInput.attributesManager.getSessionAttributes();
21 | const resource = attributes.imageResource || data[Math.round(Math.random() * data.length)];
22 |
23 | resource.source = 'NASA';
24 |
25 | const { location } = attributes;
26 |
27 | if (
28 | attributes.previousLocation &&
29 | attributes.previousLocation[attributes.previousLocation.length - 1] !== location
30 | ) {
31 | attributes.previousLocation.push(location);
32 | }
33 |
34 | attributes.location = 'apod';
35 | attributes.imageResource = resource;
36 |
37 | handlerInput.attributesManager.setSessionAttributes(attributes);
38 |
39 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
40 | return handlerInput.responseBuilder
41 | .addDirective(TranscriptDirective(resource))
42 | .speak(text)
43 | .getResponse();
44 | } else {
45 | return handlerInput.responseBuilder
46 | .speak('Welcome to your randome space image. This area is optimized for devices with screens. I can still tell you about this image, or you can say, "Go back."')
47 | .reprompt('What would you like to do?')
48 | .getResponse();
49 | }
50 | };
51 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/satellitesResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const data = require('../data/planets.json');
17 | const SatellitesDirective = require('../documents/satellites');
18 |
19 | module.exports = (handlerInput, location, speak = true) => {
20 | const info = data[location.toLowerCase()].satellites;
21 |
22 | let speech = `${location} has a total of ${info.total} moon${
23 | info.total === 1 ? '' : 's'
24 | }. Of those, ${info.interesting.length}${
25 | info.interesting.length > 1 ? ' are' : ' is'
26 | } of interest: `;
27 |
28 | info.interesting.forEach((item, i) => {
29 | speech +=
30 | i < info.interesting.length - 1 || info.interesting.length === 1
31 | ? `${item.label}, `
32 | : `and ${item.label}.`;
33 | });
34 |
35 | if (info.total === 0) {
36 | speech = `${location} has no moons.`;
37 | }
38 |
39 | const attributes = handlerInput.attributesManager.getSessionAttributes();
40 |
41 | if (
42 | attributes.previousLocation &&
43 | attributes.previousLocation[attributes.previousLocation.length - 1] !== attributes.location
44 | ) {
45 | attributes.previousLocation.push(attributes.location);
46 | }
47 |
48 | handlerInput.attributesManager.setSessionAttributes(attributes);
49 |
50 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
51 | return handlerInput.responseBuilder
52 | .addDirective(SatellitesDirective(location.toLowerCase()))
53 | .speak(speak && speech)
54 | .getResponse();
55 | } else {
56 | return handlerInput.responseBuilder
57 | .speak(speech)
58 | .getResponse();
59 | }
60 | };
61 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/sizeResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const SizeDirective = require('../documents/size');
17 | const data = require('../data/planets.json');
18 |
19 | module.exports = (handlerInput, object1, object2 = 'earth', text, speak = true) => {
20 | let speech;
21 | let obj2 = object2;
22 |
23 | if (object1.toLowerCase() === 'earth' && object2.toLowerCase() === 'earth') {
24 | obj2 = 'the sun';
25 | }
26 |
27 | speech = text || `${object1}'s diameter is ${data[object1.toLowerCase()].diameter} miles.`;
28 |
29 | const object1W = data[object1.toLowerCase()].diameter;
30 | const object2W = obj2 ? data[obj2.toLowerCase()].diameter : data.earth.diameter;
31 | const comparator =
32 | object1W > object2W
33 | ? `${(object1W / object2W).toFixed(2)} times larger`
34 | : `${(object2W / object1W).toFixed(2)} times smaller`;
35 |
36 | if (!text) {
37 | speech += ` That's ${comparator} than ${object2}`;
38 | }
39 |
40 | const attributes = handlerInput.attributesManager.getSessionAttributes();
41 |
42 | if (
43 | attributes.previousLocation &&
44 | attributes.previousLocation[attributes.previousLocation.length - 1] !== attributes.location
45 | ) {
46 | attributes.previousLocation.push(attributes.location);
47 | }
48 |
49 | handlerInput.attributesManager.setSessionAttributes(attributes);
50 |
51 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
52 | return handlerInput.responseBuilder
53 | .addDirective(SizeDirective(object1.toLowerCase(), obj2.toLowerCase(), comparator))
54 | .speak(speak !== false && speech)
55 | .getResponse();
56 | } else {
57 | return handlerInput.responseBuilder
58 | .speak(speech)
59 | .getResponse();
60 | }
61 | };
62 |
--------------------------------------------------------------------------------
/lambda/custom/multimodal_responses/solarSystemResponse.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Amazon Software License (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http: //aws.amazon.com/asl/
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | const SolarSystemDirective = require('../documents/solarSystem');
17 |
18 | module.exports = handlerInput => {
19 | const directive = SolarSystemDirective();
20 |
21 | const attributes = handlerInput.attributesManager.getSessionAttributes() || {};
22 | const { location, previousLocation } = attributes;
23 |
24 | if (previousLocation && previousLocation[previousLocation.length - 1] !== location) {
25 | attributes.previousLocation.push(location);
26 | }
27 |
28 | attributes.location = 'solar system';
29 | handlerInput.attributesManager.setSessionAttributes(attributes);
30 |
31 | if (handlerInput.requestEnvelope.context.System.device.supportedInterfaces['Alexa.Presentation.APL']) {
32 | return handlerInput.responseBuilder
33 | .addDirective(directive)
34 | .speak('Heading to the solar system. Where would you like to explore next?')
35 | .getResponse();
36 | } else {
37 | return handlerInput.responseBuilder
38 | .speak('Heading to the solar system. Where would you like to explore next?')
39 | .reprompt('Where would you like to explore next?')
40 | .getResponse();
41 | }
42 | };
43 |
--------------------------------------------------------------------------------
/lambda/custom/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DDG-HeroSkillJM",
3 | "productName": "",
4 | "version": "0.0.1",
5 | "description": "",
6 | "license": "MIT",
7 | "repository": "",
8 | "author": {
9 | "name": "Mongan, Jon",
10 | "email": "monganj@amazon.com",
11 | "url": "null"
12 | },
13 | "dependencies": {
14 | "ask-sdk-core": "^2.1.0-beta.4",
15 | "ask-sdk-model": "^1.4.0-beta.1"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/atmosphere-graphics.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "APL",
3 | "version": "1.1",
4 | "graphics": {
5 | "venus_atmosphere": {
6 | "type": "AVG",
7 | "version": "1.0",
8 | "width": 480,
9 | "height": 480,
10 | "items": [
11 | {
12 | "type": "path",
13 | "pathData": "M240,60.77V0c-18.17-0.04-36.29,2.02-53.99,6.15l13.68,59.24C212.91,62.33,226.43,60.78,240,60.77z",
14 | "fill": "#339B9E"
15 | },
16 | {
17 | "type": "path",
18 | "pathData": "M240,0v60.77h0.29c98.95,0,179.17,80.22,179.17,179.17s-80.22,179.17-179.17,179.17S61.12,338.9,61.12,239.94 c0-84.99,59.18-156.16,138.58-174.55L186.01,6.16C74.94,31.8,0,126.01,0,240c0,132.55,107.45,240,240,240s240-107.45,240-240 S372.55,0,240,0z",
19 | "fill": "#D94622"
20 | }
21 | ]
22 | },
23 | "earth_atmosphere": {
24 | "type": "AVG",
25 | "version": "1.0",
26 | "width": 480,
27 | "height": 480,
28 | "items": [
29 | {
30 | "type": "path",
31 | "pathData": "M240,59.18V0c-5.17,0-11.58,0.22-16.74,0.58l4.13,59.04C231.56,59.34,235.76,59.18,240,59.18z",
32 | "fill": "#FFFFFF"
33 | },
34 | {
35 | "type": "path",
36 | "pathData": "M227.39,59.62l-4.13-59.04c-5.16,0.36-11.54,1.03-16.66,1.75l8.24,58.6 C218.98,60.35,223.16,59.92,227.39,59.62z",
37 | "fill": "#893691"
38 | },
39 | {
40 | "type": "path",
41 | "pathData": "M214.83,60.93l-8.24-58.6C97.52,17.67,17.67,97.52,2.34,206.6l58.6,8.24 C72.03,135.11,135.11,72.03,214.83,60.93z",
42 | "fill": "#6A9A40"
43 | },
44 | {
45 | "type": "path",
46 | "pathData": "M240,0v59.18c99.86,0,180.82,80.96,180.82,180.82S339.86,420.82,240,420.82S59.18,339.86,59.18,240 c0-8.54,0.61-16.94,1.75-25.17l-58.6-8.24C0.69,218.28,0,228.2,0,240c0,132.55,107.45,240,240,240s240-107.45,240-240 C480,107.45,372.55,0,240,0z",
47 | "fill": "#329A9D"
48 | }
49 | ]
50 | },
51 | "mars_atmosphere": {
52 | "type": "AVG",
53 | "version": "1.0",
54 | "width": 480,
55 | "height": 480,
56 | "items": [
57 | {
58 | "type": "path",
59 | "pathData": "M240,60.83V0c-0.93,0-3.26,0-4.19,0.04l1.06,60.83C237.92,60.83,238.95,60.83,240,60.83z",
60 | "fill": "#699B30"
61 | },
62 | {
63 | "type": "path",
64 | "pathData": "M236.87,60.87l-1.06-60.83c-9.78,0.12-19.53,0.89-29.21,2.29l8.46,60.24 C222.29,61.56,229.57,60.99,236.87,60.87z",
65 | "fill": "#893592"
66 | },
67 | {
68 | "type": "path",
69 | "pathData": "M215.06,62.56L206.6,2.33c-9.68,1.36-19.28,3.31-28.72,5.85l15.74,58.73 C200.67,65.02,207.83,63.57,215.06,62.56z",
70 | "fill": "#339B9E"
71 | },
72 | {
73 | "type": "path",
74 | "pathData": "M240,0v60.83c98.95,0,179.17,80.22,179.17,179.17S338.95,419.17,240,419.17S60.83,338.95,60.83,240 c0-82.91,56.31-152.66,132.79-173.09L177.88,8.18C70.98,36.82,0,129.32,0,240c0,132.55,107.45,240,240,240s240-107.45,240-240S372.55,0,240,0z",
75 | "fill": "#D94622"
76 | }
77 | ]
78 | },
79 | "jupiter_atmosphere": {
80 | "type": "AVG",
81 | "version": "1.0",
82 | "width": 480,
83 | "height": 480,
84 | "items": [
85 | {
86 | "type": "path",
87 | "pathData": "M239.7,60.61h0.3V0c-5.3,0-11.45,0.21-16.74,0.59l4.23,60.45C231.52,60.76,235.6,60.61,239.7,60.61z",
88 | "fill": "#ffffff"
89 | },
90 | {
91 | "type": "path",
92 | "pathData": "M60.53,239.78c0-94.85,73.7-172.47,166.96-178.75l-4.23-60.45C96.36,9.46,0,112.75,0,239.99h60.53V239.78z",
93 | "fill": "#B83B5E"
94 | },
95 | {
96 | "type": "path",
97 | "pathData": "M240,0v60.61c98.81,0.17,178.87,80.32,178.87,179.17S338.65,418.95,239.7,418.95S60.65,338.85,60.53,239.99H0 c0,132.55,107.45,240,240,240s240-107.45,240-240S372.55,0,240,0z",
98 | "fill": "#1781CB"
99 | }
100 | ]
101 | },
102 | "saturn_atmosphere": {
103 | "type": "AVG",
104 | "version": "1.0",
105 | "width": 480,
106 | "height": 480,
107 | "items": [
108 | {
109 | "type": "path",
110 | "pathData": "M240,59.18V0c-5.3,0-11.45,0.21-16.74,0.58l4.13,59.04C231.56,59.34,235.76,59.18,240,59.18z",
111 | "fill": "#FFFFFF"
112 | },
113 | {
114 | "type": "path",
115 | "pathData": "M227.39,59.62l-4.13-59.04c-15.87,1.11-30.01,3.48-45.38,7.59l15.31,57.13 C204.21,62.37,215.64,60.43,227.39,59.62z",
116 | "fill": "#B83B5E"
117 | },
118 | {
119 | "type": "path",
120 | "pathData": "M240,0v59.18c99.86,0,180.82,80.96,180.82,180.82S339.86,420.82,240,420.82S59.18,339.86,59.18,240 c0-83.67,56.84-154.06,134.01-174.69L177.88,8.18C70.34,36.99,0,128.66,0,240c0,132.55,107.45,240,240,240s240-107.45,240-240 C480,107.45,372.55,0,240,0z",
121 | "fill": "#2380C3"
122 | }
123 | ]
124 | },
125 | "uranus_atmosphere": {
126 | "type": "AVG",
127 | "version": "1.0",
128 | "width": 480,
129 | "height": 480,
130 | "items": [
131 | {
132 | "type": "path",
133 | "pathData": "M240,59.18V0c-13.12,0-24.58,0.9-37.54,2.95l9.25,58.43C220.93,59.94,230.38,59.18,240,59.18z",
134 | "fill": "#DE7140"
135 | },
136 | {
137 | "type": "path",
138 | "pathData": "M211.71,61.39l-9.25-58.43C124.3,15.33,62.08,60.54,26.16,131.04l52.7,26.85 C104.67,107.32,153.6,70.52,211.71,61.39z",
139 | "fill": "#B83B5E"
140 | },
141 | {
142 | "type": "path",
143 | "pathData": "M240,0v59.18c99.86,0,180.82,80.96,180.82,180.82S339.86,420.82,240,420.82S59.18,339.86,59.18,240 c0-29.56,7.1-57.47,19.68-82.11l-52.7-26.85C7.93,166.83,0,199.84,0,240c0,132.55,107.45,240,240,240s240-107.45,240-240 C480,107.45,372.55,0,240,0z",
144 | "fill": "#2380C3"
145 | }
146 | ]
147 | },
148 | "neptune_atmosphere": {
149 | "type": "AVG",
150 | "version": "1.0",
151 | "width": 480,
152 | "height": 480,
153 | "items": [
154 | {
155 | "type": "path",
156 | "pathData": "M237.31,59.18c0.9,0,1.79,0.02,2.69,0.03V0c-5.3,0-11.45,0.21-16.74,0.58l4.12,58.87 C230.66,59.28,233.98,59.18,237.31,59.18z",
157 | "fill": "#ffffff"
158 | },
159 | {
160 | "type": "path",
161 | "pathData": "M227.38,59.46l-4.12-58.87C122.77,7.61,42.88,70.03,11.75,165.84l53.82,17.49 C88.35,114.22,151.67,63.56,227.38,59.46z",
162 | "fill": "#B83B5E"
163 | },
164 | {
165 | "type": "path",
166 | "pathData": "M240,0v59.21c98.62,1.44,178.13,81.82,178.13,180.79c0,99.86-80.96,180.82-180.82,180.82 S56.49,339.86,56.49,240c0-19.8,3.19-38.85,9.07-56.68l-53.82-17.49C3.55,191.05,0,213.49,0,240c0,132.55,107.45,240,240,240 s240-107.45,240-240S372.55,0,240,0z",
167 | "fill": "#2380C3"
168 | }
169 | ]
170 | },
171 | "pluto_atmosphere": {
172 | "type": "AVG",
173 | "version": "1.0",
174 | "width": 480,
175 | "height": 480,
176 | "items": [
177 | {
178 | "type": "path",
179 | "pathData": "M240,59.18V0c-2.65,0-5.73,0.05-8.38,0.15l2.07,59.16C235.79,59.23,237.89,59.18,240,59.18z",
180 | "fill": "#FFFFFF"
181 | },
182 | {
183 | "type": "path",
184 | "pathData": "M233.69,59.3l-2.07-59.16c-13.25,0.46-24.41,1.73-37.42,4.26l11.29,58.07 C214.67,60.71,224.08,59.63,233.69,59.3z",
185 | "fill": "#DE7140"
186 | },
187 | {
188 | "type": "path",
189 | "pathData": "M240,0v59.18c99.86,0,180.82,80.96,180.82,180.82S339.86,420.82,240,420.82S59.18,339.86,59.18,240 c0-88.06,62.96-161.41,146.31-177.52L194.21,4.41C79.71,26.67,0,123.36,0,240c0,132.55,107.45,240,240,240s240-107.45,240-240 S372.55,0,240,0z",
190 | "fill": "#329A9D"
191 | }
192 | ]
193 | }
194 | }
195 | }
--------------------------------------------------------------------------------
/packages/styles.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "APL",
3 | "version": "1.0.0",
4 | "import": [
5 | {
6 | "name": "alexa-viewport-profiles",
7 | "version": "1.1.0"
8 | }
9 | ],
10 | "resources": [
11 | {
12 | "strings": {
13 | "fontFamilyRomanSans": "amazon-ember-display"
14 | }
15 | },
16 | {
17 | "description": "default sizing",
18 | "dimensions": {
19 | "ordinalSize": "52dp",
20 | "itemHeight": "107dp"
21 | }
22 | },
23 | {
24 | "description": "sizing for smaller hubs",
25 | "when": "${@viewportProfile == @hubLandscapeSmall || @viewportProfile == @hubLandscapeMedium}",
26 | "dimensions": {
27 | "itemHeight": "72dp"
28 | }
29 | },
30 | {
31 | "description": "sizing for tv",
32 | "when": "${@viewportProfile == @tvLandscapeXLarge}",
33 | "dimensions": {
34 | "ordinalSize": "26dp",
35 | "itemHeight": "54dp"
36 | }
37 | },
38 | {
39 | "description": "Size definitions for distance indicators on hub",
40 | "dimensions": {
41 | "indicatorSize": "28dp",
42 | "indicatorStroke": "4dp",
43 | "indicatorRadius": "14dp",
44 | "indicatorSpacing": "20dp"
45 | }
46 | },
47 | {
48 | "description": "Size definitions for distance indicators on tv",
49 | "when": "${@viewportProfile == @tvLandscapeXLarge}",
50 | "dimensions": {
51 | "indicatorSize": "21dp",
52 | "indicatorStroke": "3dp",
53 | "indicatorSpacing": "13dp"
54 | }
55 | }
56 | ],
57 | "styles": {
58 | "backgroundWithFocusPress": {
59 | "values": [
60 | {
61 | "backgroundColor": "transparent"
62 | },
63 | {
64 | "when": "${state.focused && !state.pressed && @viewportProfile != @hubRoundSmall}",
65 | "backgroundColor": "rgba(255, 255, 255, 0.1)"
66 | },
67 | {
68 | "when": "${state.pressed}",
69 | "backgroundColor": "rgba(255, 255, 255, 0.3)"
70 | }
71 | ]
72 | },
73 | "backgroundWithFocusNoPress": {
74 | "extend": "backgroundWithFocusPress",
75 | "values": [
76 | {
77 | "when": "${state.pressed}",
78 | "backgroundColor": "rgba(255, 255, 255, 0.1)"
79 | }
80 | ]
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/skill.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest": {
3 | "publishingInformation": {
4 | "locales": {
5 | "en-US": {
6 | "summary": "Space Explorer Sample",
7 | "examplePhrases": [
8 | "Alexa open hello world",
9 | "Alexa tell hello world hello",
10 | "Alexa ask hello world say hello"
11 | ],
12 | "name": "Space Explorer APL Sample Skill",
13 | "description": "Build beautiful, functional interfaces for your users. This sample skill contains best practices and examples of how to develop high-quality visual experiences using APL."
14 | }
15 | },
16 | "isAvailableWorldwide": true,
17 | "testingInstructions": "Sample Testing Instructions.",
18 | "category": "EDUCATION_AND_REFERENCE",
19 | "distributionCountries": []
20 | },
21 | "apis": {
22 | "custom": {
23 | "endpoint": {
24 | "sourceDir": "lambda/custom",
25 | "uri": "ask-space-explorer"
26 | },
27 | "interfaces": [
28 | {
29 | "type": "ALEXA_PRESENTATION_APL"
30 | },
31 | {
32 | "type": "RENDER_TEMPLATE"
33 | }
34 | ]
35 | }
36 | },
37 | "manifestVersion": "1.0"
38 | }
39 | }
--------------------------------------------------------------------------------